fix: support different url matchers in Page.waitForRequest/Response (#128)

This commit is contained in:
Yury Semikhatsky 2020-12-14 22:30:40 -08:00 committed by GitHub
parent bab778dc0e
commit 612dc5838e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 254 additions and 35 deletions

View File

@ -369,6 +369,23 @@ class Method extends Element {
customSignature.put("BrowserContext.waitForEvent", waitForEvent);
customSignature.put("WebSocket.waitForEvent", waitForEvent);
customSignature.put("Page.waitForRequest", new String[] {
"default Deferred<Request> waitForRequest(String urlGlob) { return waitForRequest(urlGlob, null); }",
"default Deferred<Request> waitForRequest(Pattern urlPattern) { return waitForRequest(urlPattern, null); }",
"default Deferred<Request> waitForRequest(Predicate<String> urlPredicate) { return waitForRequest(urlPredicate, null); }",
"Deferred<Request> waitForRequest(String urlGlob, WaitForRequestOptions options);",
"Deferred<Request> waitForRequest(Pattern urlPattern, WaitForRequestOptions options);",
"Deferred<Request> waitForRequest(Predicate<String> urlPredicate, WaitForRequestOptions options);"
});
customSignature.put("Page.waitForResponse", new String[] {
"default Deferred<Response> waitForResponse(String urlGlob) { return waitForResponse(urlGlob, null); }",
"default Deferred<Response> waitForResponse(Pattern urlPattern) { return waitForResponse(urlPattern, null); }",
"default Deferred<Response> waitForResponse(Predicate<String> urlPredicate) { return waitForResponse(urlPredicate, null); }",
"Deferred<Response> waitForResponse(String urlGlob, WaitForResponseOptions options);",
"Deferred<Response> waitForResponse(Pattern urlPattern, WaitForResponseOptions options);",
"Deferred<Response> waitForResponse(Predicate<String> urlPredicate, WaitForResponseOptions options);"
});
String[] selectOption = {
"default List<String> selectOption(String selector, String value) {",
" return selectOption(selector, value, null);",
@ -428,8 +445,10 @@ class Method extends Element {
private static Set<String> skipJavadoc = new HashSet<>(asList(
"BrowserContext.waitForEvent.optionsOrPredicate",
"Page.waitForEvent.optionsOrPredicate",
"WebSocket.waitForEvent.optionsOrPredicate",
"Page.frame.options",
"WebSocket.waitForEvent.optionsOrPredicate"
"Page.waitForRequest",
"Page.waitForResponse"
));
Method(TypeDefinition parent, JsonObject jsonElement) {
@ -503,6 +522,9 @@ class Method extends Element {
}
private void writeJavadoc(List<String> output, String offset) {
if (skipJavadoc.contains(jsonPath)) {
return;
}
List<String> sections = new ArrayList<>();
sections.add(formattedComment());
if (!params.isEmpty()) {

View File

@ -2128,26 +2128,18 @@ public interface Page {
* Shortcut for main frame's frame.waitForNavigation([options]).
*/
Deferred<Response> waitForNavigation(WaitForNavigationOptions options);
default Deferred<Request> waitForRequest(String urlOrPredicate) {
return waitForRequest(urlOrPredicate, null);
}
/**
* Returns promise that resolves to the matched request.
* <p>
*
* @param urlOrPredicate Request URL string, regex or predicate receiving Request object.
*/
Deferred<Request> waitForRequest(String urlOrPredicate, WaitForRequestOptions options);
default Deferred<Response> waitForResponse(String urlOrPredicate) {
return waitForResponse(urlOrPredicate, null);
}
/**
* Returns the matched response.
* <p>
*
* @param urlOrPredicate Request URL string, regex or predicate receiving Response object.
*/
Deferred<Response> waitForResponse(String urlOrPredicate, WaitForResponseOptions options);
default Deferred<Request> waitForRequest(String urlGlob) { return waitForRequest(urlGlob, null); }
default Deferred<Request> waitForRequest(Pattern urlPattern) { return waitForRequest(urlPattern, null); }
default Deferred<Request> waitForRequest(Predicate<String> urlPredicate) { return waitForRequest(urlPredicate, null); }
Deferred<Request> waitForRequest(String urlGlob, WaitForRequestOptions options);
Deferred<Request> waitForRequest(Pattern urlPattern, WaitForRequestOptions options);
Deferred<Request> waitForRequest(Predicate<String> urlPredicate, WaitForRequestOptions options);
default Deferred<Response> waitForResponse(String urlGlob) { return waitForResponse(urlGlob, null); }
default Deferred<Response> waitForResponse(Pattern urlPattern) { return waitForResponse(urlPattern, null); }
default Deferred<Response> waitForResponse(Predicate<String> urlPredicate) { return waitForResponse(urlPredicate, null); }
Deferred<Response> waitForResponse(String urlGlob, WaitForResponseOptions options);
Deferred<Response> waitForResponse(Pattern urlPattern, WaitForResponseOptions options);
Deferred<Response> waitForResponse(Predicate<String> urlPredicate, WaitForResponseOptions options);
default Deferred<ElementHandle> waitForSelector(String selector) {
return waitForSelector(selector, null);
}

View File

@ -850,34 +850,54 @@ public class PageImpl extends ChannelOwner implements Page {
}
@Override
public Deferred<Request> waitForRequest(String urlOrPredicate, WaitForRequestOptions options) {
public Deferred<Request> waitForRequest(String urlGlob, WaitForRequestOptions options) {
return waitForRequest(new UrlMatcher(urlGlob), options);
}
@Override
public Deferred<Request> waitForRequest(Pattern urlPattern, WaitForRequestOptions options) {
return waitForRequest(new UrlMatcher(urlPattern), options);
}
@Override
public Deferred<Request> waitForRequest(Predicate<String> urlPredicate, WaitForRequestOptions options) {
return waitForRequest(new UrlMatcher(urlPredicate), options);
}
private Deferred<Request> waitForRequest(UrlMatcher matcher, WaitForRequestOptions options) {
if (options == null) {
options = new WaitForRequestOptions();
}
List<Waitable<Request>> waitables = new ArrayList<>();
waitables.add(new WaitableEvent<>(listeners, EventType.REQUEST,e -> {
if (urlOrPredicate == null) {
return true;
}
return urlOrPredicate.equals(((Request) e.data()).url());
}).apply(event -> (Request) event.data()));
waitables.add(new WaitableEvent<>(listeners, EventType.REQUEST, e -> matcher.test(((Request) e.data()).url()))
.apply(event -> (Request) event.data()));
waitables.add(createWaitForCloseHelper());
waitables.add(createWaitableTimeout(options.timeout));
return toDeferred(new WaitableRace<>(waitables));
}
@Override
public Deferred<Response> waitForResponse(String urlOrPredicate, WaitForResponseOptions options) {
public Deferred<Response> waitForResponse(String urlGlob, WaitForResponseOptions options) {
return waitForResponse(new UrlMatcher(urlGlob), options);
}
@Override
public Deferred<Response> waitForResponse(Pattern urlPattern, WaitForResponseOptions options) {
return waitForResponse(new UrlMatcher(urlPattern), options);
}
@Override
public Deferred<Response> waitForResponse(Predicate<String> urlPredicate, WaitForResponseOptions options) {
return waitForResponse(new UrlMatcher(urlPredicate), options);
}
private Deferred<Response> waitForResponse(UrlMatcher matcher, WaitForResponseOptions options) {
if (options == null) {
options = new WaitForResponseOptions();
}
List<Waitable<Response>> waitables = new ArrayList<>();
waitables.add(new WaitableEvent<>(listeners, EventType.RESPONSE, e -> {
if (urlOrPredicate == null) {
return true;
}
return urlOrPredicate.equals(((Response) e.data()).url());
}).apply(event -> (Response) event.data()));
waitables.add(new WaitableEvent<>(listeners, EventType.RESPONSE, e -> matcher.test(((Response) e.data()).url()))
.apply(event -> (Response) event.data()));
waitables.add(createWaitForCloseHelper());
waitables.add(createWaitableTimeout(options.timeout));
return toDeferred(new WaitableRace<>(waitables));

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.microsoft.playwright;
import org.junit.jupiter.api.Test;
import java.util.regex.Pattern;
import static com.microsoft.playwright.Page.EventType.REQUEST;
import static org.junit.jupiter.api.Assertions.*;
public class TestPageWaitForRequest extends TestBase {
@Test
void shouldWork() {
page.navigate(server.EMPTY_PAGE);
Deferred<Request> request = page.waitForRequest(server.PREFIX + "/digits/2.png");
page.evaluate("() => {\n" +
" fetch('/digits/1.png');\n" +
" fetch('/digits/2.png');\n" +
" fetch('/digits/3.png');\n" +
"}");
assertEquals(server.PREFIX + "/digits/2.png", request.get().url());
}
@Test
void shouldWorkWithPredicate() {
page.navigate(server.EMPTY_PAGE);
Deferred<Request> request = page.waitForRequest(url -> url.equals(server.PREFIX + "/digits/2.png"));
page.evaluate("() => {\n" +
" fetch('/digits/1.png');\n" +
" fetch('/digits/2.png');\n" +
" fetch('/digits/3.png');\n" +
"}");
assertEquals(server.PREFIX + "/digits/2.png", request.get().url());
}
@Test
void shouldRespectTimeout() {
try {
page.waitForEvent(REQUEST, new Page.WaitForEventOptions()
.withPredicate(url -> false).withTimeout(1)).get();
fail("did not throw");
} catch (PlaywrightException e) {
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
}
}
@Test
void shouldRespectDefaultTimeout() {
page.setDefaultTimeout(1);
try {
page.waitForEvent(REQUEST, url -> false).get();
fail("did not throw");
} catch (PlaywrightException e) {
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
}
}
@Test
void shouldWorkWithNoTimeout() {
page.navigate(server.EMPTY_PAGE);
Deferred<Request> request = page.waitForRequest(server.PREFIX + "/digits/2.png",
new Page.WaitForRequestOptions().withTimeout(0));
page.evaluate("() => setTimeout(() => {\n" +
" fetch('/digits/1.png');\n" +
" fetch('/digits/2.png');\n" +
" fetch('/digits/3.png');\n" +
"}, 50)");
assertEquals(server.PREFIX + "/digits/2.png", request.get().url());
}
@Test
void shouldWorkWithUrlMatch() {
page.navigate(server.EMPTY_PAGE);
Deferred<Request> request = page.waitForRequest(Pattern.compile(".*digits/\\d\\.png"));
page.evaluate("() => {\n" +
" fetch('/digits/1.png');\n" +
"}");
assertEquals(server.PREFIX + "/digits/1.png", request.get().url());
}
void shouldWorkWithUrlMatchRegularExpressionFromADifferentContext() {
// Node.js specific
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.microsoft.playwright;
import org.junit.jupiter.api.Test;
import static com.microsoft.playwright.Page.EventType.REQUEST;
import static com.microsoft.playwright.Page.EventType.RESPONSE;
import static org.junit.jupiter.api.Assertions.*;
public class TestPageWaitForResponse extends TestBase {
@Test
void shouldWork() {
page.navigate(server.EMPTY_PAGE);
Deferred<Response> response = page.waitForResponse(server.PREFIX + "/digits/2.png");
page.evaluate("() => {\n" +
" fetch('/digits/1.png');\n" +
" fetch('/digits/2.png');\n" +
" fetch('/digits/3.png');\n" +
"}");
assertEquals(server.PREFIX + "/digits/2.png", response.get().url());
}
@Test
void shouldRespectTimeout() {
page.navigate(server.EMPTY_PAGE);
Deferred<Response> response = page.waitForResponse(url -> url.equals(server.PREFIX + "/digits/2.png"));
page.evaluate("() => {\n" +
" fetch('/digits/1.png');\n" +
" fetch('/digits/2.png');\n" +
" fetch('/digits/3.png');\n" +
"}");
assertEquals(server.PREFIX + "/digits/2.png", response.get().url());
}
@Test
void shouldWorkWithPredicate() {
page.navigate(server.EMPTY_PAGE);
Deferred<Response> response = page.waitForResponse(url -> url.equals(server.PREFIX + "/digits/2.png"));
page.evaluate("() => {\n" +
" fetch('/digits/1.png');\n" +
" fetch('/digits/2.png');\n" +
" fetch('/digits/3.png');\n" +
"}");
assertEquals(server.PREFIX + "/digits/2.png", response.get().url());
}
@Test
void shouldRespectDefaultTimeout() {
page.setDefaultTimeout(1);
try {
page.waitForEvent(RESPONSE, url -> false).get();
fail("did not throw");
} catch (PlaywrightException e) {
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
}
}
@Test
void shouldWorkWithNoTimeout() {
page.navigate(server.EMPTY_PAGE);
Deferred<Response> response = page.waitForResponse(server.PREFIX + "/digits/2.png",
new Page.WaitForResponseOptions().withTimeout(0));
page.evaluate("() => setTimeout(() => {\n" +
" fetch('/digits/1.png');\n" +
" fetch('/digits/2.png');\n" +
" fetch('/digits/3.png');\n" +
"}, 50)");
assertEquals(server.PREFIX + "/digits/2.png", response.get().url());
}
}