chore: roll driver to 1.25.0 (#1026)
This commit is contained in:
@@ -30,15 +30,15 @@ import java.nio.file.Path;
|
||||
*
|
||||
* <p> **Cookie management**
|
||||
*
|
||||
* <p> {@code APIRequestContext} retuned by {@link BrowserContext#request BrowserContext.request()} and {@link Page#request
|
||||
* <p> {@code APIRequestContext} returned by {@link BrowserContext#request BrowserContext.request()} and {@link Page#request
|
||||
* Page.request()} shares cookie storage with the corresponding {@code BrowserContext}. Each API request will have {@code Cookie}
|
||||
* header populated with the values from the browser context. If the API response contains {@code Set-Cookie} header it will
|
||||
* automatically update {@code BrowserContext} cookies and requests made from the page will pick them up. This means that if you
|
||||
* log in using this API, your e2e test will be logged in and vice versa.
|
||||
*
|
||||
* <p> If you want API requests to not interfere with the browser cookies you shoud create a new {@code APIRequestContext} by calling
|
||||
* {@link APIRequest#newContext APIRequest.newContext()}. Such {@code APIRequestContext} object will have its own isolated cookie
|
||||
* storage.
|
||||
* <p> If you want API requests to not interfere with the browser cookies you should create a new {@code APIRequestContext} by
|
||||
* calling {@link APIRequest#newContext APIRequest.newContext()}. Such {@code APIRequestContext} object will have its own
|
||||
* isolated cookie storage.
|
||||
*/
|
||||
public interface APIRequestContext {
|
||||
class StorageStateOptions {
|
||||
|
||||
@@ -1099,7 +1099,7 @@ public interface Browser extends AutoCloseable {
|
||||
/**
|
||||
* Creates a new browser context. It won't share cookies/cache with other browser contexts.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> If directly using this method to create {@code BrowserContext}s, it is best practice to explicilty close the returned context
|
||||
* <p> <strong>NOTE:</strong> If directly using this method to create {@code BrowserContext}s, it is best practice to explicitly close the returned context
|
||||
* via {@link BrowserContext#close BrowserContext.close()} when your code is done with the {@code BrowserContext}, and before
|
||||
* calling {@link Browser#close Browser.close()}. This will ensure the {@code context} is closed gracefully and any
|
||||
* artifacts—like HARs and videos—are fully flushed and saved.
|
||||
@@ -1111,7 +1111,7 @@ public interface Browser extends AutoCloseable {
|
||||
* Page page = context.newPage();
|
||||
* page.navigate('https://example.com');
|
||||
*
|
||||
* // Gracefull close up everything
|
||||
* // Graceful close up everything
|
||||
* context.close();
|
||||
* browser.close();
|
||||
* }</pre>
|
||||
@@ -1122,7 +1122,7 @@ public interface Browser extends AutoCloseable {
|
||||
/**
|
||||
* Creates a new browser context. It won't share cookies/cache with other browser contexts.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> If directly using this method to create {@code BrowserContext}s, it is best practice to explicilty close the returned context
|
||||
* <p> <strong>NOTE:</strong> If directly using this method to create {@code BrowserContext}s, it is best practice to explicitly close the returned context
|
||||
* via {@link BrowserContext#close BrowserContext.close()} when your code is done with the {@code BrowserContext}, and before
|
||||
* calling {@link Browser#close Browser.close()}. This will ensure the {@code context} is closed gracefully and any
|
||||
* artifacts—like HARs and videos—are fully flushed and saved.
|
||||
@@ -1134,7 +1134,7 @@ public interface Browser extends AutoCloseable {
|
||||
* Page page = context.newPage();
|
||||
* page.navigate('https://example.com');
|
||||
*
|
||||
* // Gracefull close up everything
|
||||
* // Graceful close up everything
|
||||
* context.close();
|
||||
* browser.close();
|
||||
* }</pre>
|
||||
|
||||
@@ -586,7 +586,7 @@ public interface ElementHandle extends JSHandle {
|
||||
*/
|
||||
public ScreenshotCaret caret;
|
||||
/**
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink box
|
||||
* {@code #FF00FF} that completely covers its bounding box.
|
||||
*/
|
||||
public List<Locator> mask;
|
||||
@@ -647,7 +647,7 @@ public interface ElementHandle extends JSHandle {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink box
|
||||
* {@code #FF00FF} that completely covers its bounding box.
|
||||
*/
|
||||
public ScreenshotOptions setMask(List<Locator> mask) {
|
||||
|
||||
@@ -1013,7 +1013,7 @@ public interface Locator {
|
||||
*/
|
||||
public ScreenshotCaret caret;
|
||||
/**
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink box
|
||||
* {@code #FF00FF} that completely covers its bounding box.
|
||||
*/
|
||||
public List<Locator> mask;
|
||||
@@ -1074,7 +1074,7 @@ public interface Locator {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink box
|
||||
* {@code #FF00FF} that completely covers its bounding box.
|
||||
*/
|
||||
public ScreenshotOptions setMask(List<Locator> mask) {
|
||||
|
||||
@@ -2080,7 +2080,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Boolean fullPage;
|
||||
/**
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink box
|
||||
* {@code #FF00FF} that completely covers its bounding box.
|
||||
*/
|
||||
public List<Locator> mask;
|
||||
@@ -2162,7 +2162,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlayed with a pink box
|
||||
* Specify locators that should be masked when the screenshot is taken. Masked elements will be overlaid with a pink box
|
||||
* {@code #FF00FF} that completely covers its bounding box.
|
||||
*/
|
||||
public ScreenshotOptions setMask(List<Locator> mask) {
|
||||
|
||||
@@ -40,7 +40,7 @@ public interface Response {
|
||||
*/
|
||||
Frame frame();
|
||||
/**
|
||||
* Indicates whether this Response was fullfilled by a Service Worker's Fetch Handler (i.e. via <a
|
||||
* Indicates whether this Response was fulfilled by a Service Worker's Fetch Handler (i.e. via <a
|
||||
* href="https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/respondWith">FetchEvent.respondWith</a>).
|
||||
*/
|
||||
boolean fromServiceWorker();
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ public interface PlaywrightAssertions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes default timeout for Playwright assertions from 5 seconds to the speicified value.
|
||||
* Changes default timeout for Playwright assertions from 5 seconds to the specified value.
|
||||
* <pre>{@code
|
||||
* PlaywrightAssertions.setDefaultAssertionTimeout(30_000);
|
||||
* }</pre>
|
||||
|
||||
+16
-1
@@ -21,6 +21,7 @@ import com.microsoft.playwright.assertions.APIResponseAssertions;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class APIResponseAssertionsImpl implements APIResponseAssertions {
|
||||
private final APIResponse actual;
|
||||
@@ -54,6 +55,20 @@ public class APIResponseAssertionsImpl implements APIResponseAssertions {
|
||||
if (!log.isEmpty()) {
|
||||
log = "\nCall log:\n" + log;
|
||||
}
|
||||
throw new AssertionFailedError(message + log);
|
||||
|
||||
String contentType = actual.headers().get("content-type");
|
||||
boolean isTextEncoding = contentType == null ? false : isTextualMimeType(contentType);
|
||||
String responseText = "";
|
||||
if (isTextEncoding) {
|
||||
String text = actual.text();
|
||||
if (text != null) {
|
||||
responseText = "\nResponse text:\n" + (text.length() > 1000 ? text.substring(0, 1000) : text);
|
||||
}
|
||||
}
|
||||
|
||||
throw new AssertionFailedError(message + log + responseText);
|
||||
}
|
||||
static boolean isTextualMimeType(String mimeType) {
|
||||
return Pattern.matches("^(text/.*?|application/(json|(x-)?javascript|xml.*?|ecmascript|graphql|x-www-form-urlencoded)|image/svg(\\+xml)?|application/.*?(\\+json|\\+xml))(;\\s*charset=.*)?$", mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@ public class Server implements HttpHandler {
|
||||
String resourcePath = "resources" + path;
|
||||
InputStream resource = getClass().getClassLoader().getResourceAsStream(resourcePath);
|
||||
if (resource == null) {
|
||||
exchange.getResponseHeaders().add("Content-Type", "text/plain");
|
||||
exchange.sendResponseHeaders(404, 0);
|
||||
try (Writer writer = new OutputStreamWriter(exchange.getResponseBody())) {
|
||||
writer.write("File not found: " + resourcePath);
|
||||
|
||||
@@ -19,8 +19,11 @@ package com.microsoft.playwright;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestAPIResponseAssertions extends TestBase {
|
||||
@Test
|
||||
@@ -38,14 +41,62 @@ public class TestAPIResponseAssertions extends TestBase {
|
||||
@Test
|
||||
void fail() {
|
||||
APIResponse res = page.request().get(server.PREFIX + "/unknown");
|
||||
boolean didThrow = false;
|
||||
try {
|
||||
assertThat(res).isOK();
|
||||
} catch (AssertionFailedError e) {
|
||||
didThrow = true;
|
||||
assertTrue(e.getMessage().contains("→ GET " + server.PREFIX + "/unknown"), "Actual error: " + e.toString());
|
||||
assertTrue(e.getMessage().contains("← 404 Not Found"), "Actual error: " + e.toString());
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> assertThat(res).isOK());
|
||||
assertTrue(e.getMessage().contains("→ GET " + server.PREFIX + "/unknown"), "Actual error: " + e.toString());
|
||||
assertTrue(e.getMessage().contains("← 404 Not Found"), "Actual error: " + e.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldPrintResponseTextIfIdOkFails() {
|
||||
APIResponse res = page.request().get(server.PREFIX + "/unknown");
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> assertThat(res).isOK());
|
||||
assertTrue(e.getMessage().contains("File not found"), "Actual error: " + e.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldOnlyPrintResponseWithTextContentTypeIfIsOkFails() {
|
||||
{
|
||||
server.setRoute("/text-content-type", exchange -> {
|
||||
exchange.getResponseHeaders().set("Content-type", "text/plain");
|
||||
exchange.sendResponseHeaders(404, 0);
|
||||
try (Writer writer = new OutputStreamWriter(exchange.getResponseBody())) {
|
||||
writer.write("Text error");
|
||||
}
|
||||
});
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> assertThat(page.request().get(server.PREFIX + "/text-content-type")).isOK());
|
||||
assertTrue(e.getMessage().contains("Text error"), "Actual error: " + e);
|
||||
}
|
||||
{
|
||||
server.setRoute("/svg-xml-content-type", exchange -> {
|
||||
exchange.getResponseHeaders().set("Content-type", "image/svg+xml");
|
||||
exchange.sendResponseHeaders(404, 0);
|
||||
try (Writer writer = new OutputStreamWriter(exchange.getResponseBody())) {
|
||||
writer.write("Json error");
|
||||
}
|
||||
});
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> assertThat(page.request().get(server.PREFIX + "/svg-xml-content-type")).isOK());
|
||||
assertTrue(e.getMessage().contains("Json error"), "Actual error: " + e);
|
||||
}
|
||||
{
|
||||
server.setRoute("/no-content-type", exchange -> {
|
||||
exchange.sendResponseHeaders(404, 0);
|
||||
try (Writer writer = new OutputStreamWriter(exchange.getResponseBody())) {
|
||||
writer.write("No content type error");
|
||||
}
|
||||
});
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> assertThat(page.request().get(server.PREFIX + "/no-content-type")).isOK());
|
||||
assertFalse(e.getMessage().contains("No content type error"), "Actual error: " + e);
|
||||
}
|
||||
{
|
||||
server.setRoute("/image-content-type", exchange -> {
|
||||
exchange.getResponseHeaders().set("Content-type", "image/bmp");
|
||||
exchange.sendResponseHeaders(404, 0);
|
||||
try (Writer writer = new OutputStreamWriter(exchange.getResponseBody())) {
|
||||
writer.write("Image type error");
|
||||
}
|
||||
});
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> assertThat(page.request().get(server.PREFIX + "/image-content-type")).isOK());
|
||||
assertFalse(e.getMessage().contains("Image type error"), "Actual error: " + e);
|
||||
}
|
||||
assertTrue(didThrow);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
1.25.0-alpha-1659998098000
|
||||
1.25.0
|
||||
|
||||
Reference in New Issue
Block a user