fix: move exposed binding and funcion callbacks to top level (#278)

This commit is contained in:
Yury Semikhatsky 2021-02-10 18:14:24 -08:00 committed by GitHub
parent d4ef6d6431
commit 5bf883a456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 101 deletions

View File

@ -144,7 +144,7 @@ public interface BrowserContext extends AutoCloseable {
* @param urls Optional list of URLs.
*/
List<Cookie> cookies(List<String> urls);
default void exposeBinding(String name, Page.Binding callback) {
default void exposeBinding(String name, BindingCallback callback) {
exposeBinding(name, callback, null);
}
/**
@ -161,7 +161,7 @@ public interface BrowserContext extends AutoCloseable {
* @param name Name of the function on the window object.
* @param callback Callback function that will be called in the Playwright's context.
*/
void exposeBinding(String name, Page.Binding callback, ExposeBindingOptions options);
void exposeBinding(String name, BindingCallback callback, ExposeBindingOptions options);
/**
* The method adds a function called {@code name} on the {@code window} object of every frame in every page in the context. When
* called, the function executes {@code callback} and returns a [Promise] which resolves to the return value of {@code callback}.
@ -174,7 +174,7 @@ public interface BrowserContext extends AutoCloseable {
* @param name Name of the function on the window object.
* @param callback Callback function that will be called in the Playwright's context.
*/
void exposeFunction(String name, Page.Function callback);
void exposeFunction(String name, FunctionCallback callback);
default void grantPermissions(List<String> permissions) {
grantPermissions(permissions, null);
}

View File

@ -37,26 +37,6 @@ import java.util.regex.Pattern;
* <p> To unsubscribe from events use the {@code removeListener} method:
*/
public interface Page extends AutoCloseable {
interface Function {
Object call(Object... args);
}
interface Binding {
interface Source {
BrowserContext context();
Page page();
Frame frame();
}
Object call(Source source, Object... args);
}
interface Error {
String message();
String name();
String stack();
}
void onClose(Consumer<Page> handler);
void offClose(Consumer<Page> handler);
@ -91,8 +71,8 @@ public interface Page extends AutoCloseable {
void onLoad(Consumer<Page> handler);
void offLoad(Consumer<Page> handler);
void onPageError(Consumer<Error> handler);
void offPageError(Consumer<Error> handler);
void onPageError(Consumer<String> handler);
void offPageError(Consumer<String> handler);
void onPopup(Consumer<Page> handler);
void offPopup(Consumer<Page> handler);
@ -1612,7 +1592,7 @@ public interface Page extends AutoCloseable {
* @param arg Optional argument to pass to {@code expression}.
*/
JSHandle evaluateHandle(String expression, Object arg);
default void exposeBinding(String name, Binding callback) {
default void exposeBinding(String name, BindingCallback callback) {
exposeBinding(name, callback, null);
}
/**
@ -1631,7 +1611,7 @@ public interface Page extends AutoCloseable {
* @param name Name of the function on the window object.
* @param callback Callback function that will be called in the Playwright's context.
*/
void exposeBinding(String name, Binding callback, ExposeBindingOptions options);
void exposeBinding(String name, BindingCallback callback, ExposeBindingOptions options);
/**
* The method adds a function called {@code name} on the {@code window} object of every frame in the page. When called, the function
* executes {@code callback} and returns a [Promise] which resolves to the return value of {@code callback}.
@ -1646,7 +1626,7 @@ public interface Page extends AutoCloseable {
* @param name Name of the function on the window object
* @param callback Callback function which will be called in Playwright's context.
*/
void exposeFunction(String name, Function callback);
void exposeFunction(String name, FunctionCallback callback);
default void fill(String selector, String value) {
fill(selector, value, null);
}

View File

@ -22,6 +22,7 @@ import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Frame;
import com.microsoft.playwright.JSHandle;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.options.BindingCallback;
import java.util.ArrayList;
import java.util.List;
@ -29,7 +30,7 @@ import java.util.List;
import static com.microsoft.playwright.impl.Serialization.*;
class BindingCall extends ChannelOwner {
private static class SourceImpl implements Page.Binding.Source {
private static class SourceImpl implements BindingCallback.Source {
private final Frame frame;
public SourceImpl(Frame frame) {
@ -60,10 +61,10 @@ class BindingCall extends ChannelOwner {
return initializer.get("name").getAsString();
}
void call(Page.Binding binding) {
void call(BindingCallback binding) {
try {
Frame frame = connection.getExistingObject(initializer.getAsJsonObject("frame").get("guid").getAsString());
Page.Binding.Source source = new SourceImpl(frame);
BindingCallback.Source source = new SourceImpl(frame);
List<Object> args = new ArrayList<>();
if (initializer.has("handle")) {
JSHandle handle = connection.getExistingObject(initializer.getAsJsonObject("handle").get("guid").getAsString());

View File

@ -38,7 +38,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
final List<PageImpl> pages = new ArrayList<>();
final Router routes = new Router();
private boolean isClosedOrClosing;
final Map<String, Page.Binding> bindings = new HashMap<>();
final Map<String, BindingCallback> bindings = new HashMap<>();
PageImpl ownerPage;
private final ListenerCollection<EventType> listeners = new ListenerCollection<>();
final TimeoutSettings timeoutSettings = new TimeoutSettings();
@ -167,11 +167,11 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
}
@Override
public void exposeBinding(String name, Page.Binding playwrightBinding, ExposeBindingOptions options) {
public void exposeBinding(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
withLogging("BrowserContext.exposeBinding", () -> exposeBindingImpl(name, playwrightBinding, options));
}
private void exposeBindingImpl(String name, Page.Binding playwrightBinding, ExposeBindingOptions options) {
private void exposeBindingImpl(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
if (bindings.containsKey(name)) {
throw new PlaywrightException("Function \"" + name + "\" has been already registered");
}
@ -191,9 +191,9 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
}
@Override
public void exposeFunction(String name, Page.Function playwrightFunction) {
public void exposeFunction(String name, FunctionCallback playwrightFunction) {
withLogging("BrowserContext.exposeFunction",
() -> exposeBindingImpl(name, (Page.Binding.Source source, Object... args) -> playwrightFunction.call(args), null));
() -> exposeBindingImpl(name, (BindingCallback.Source source, Object... args) -> playwrightFunction.call(args), null));
}
@Override
@ -380,7 +380,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
pages.add(page);
} else if ("bindingCall".equals(event)) {
BindingCall bindingCall = connection.getExistingObject(params.getAsJsonObject("binding").get("guid").getAsString());
Page.Binding binding = bindings.get(bindingCall.name());
BindingCallback binding = bindings.get(bindingCall.name());
if (binding != null) {
bindingCall.call(binding);
}

View File

@ -62,7 +62,7 @@ public class PageImpl extends ChannelOwner implements Page {
}
}
};
final Map<String, Binding> bindings = new HashMap<>();
final Map<String, BindingCallback> bindings = new HashMap<>();
BrowserContextImpl ownedContext;
private boolean isClosed;
final Set<Worker> workers = new HashSet<>();
@ -148,7 +148,7 @@ public class PageImpl extends ChannelOwner implements Page {
} else if ("bindingCall".equals(event)) {
String guid = params.getAsJsonObject("binding").get("guid").getAsString();
BindingCall bindingCall = connection.getExistingObject(guid);
Binding binding = bindings.get(bindingCall.name());
BindingCallback binding = bindings.get(bindingCall.name());
if (binding == null) {
binding = browserContext.bindings.get(bindingCall.name());
}
@ -213,7 +213,14 @@ public class PageImpl extends ChannelOwner implements Page {
video().setRelativePath(params.get("relativePath").getAsString());
} else if ("pageError".equals(event)) {
SerializedError error = gson().fromJson(params.getAsJsonObject("error"), SerializedError.class);
listeners.notify(EventType.PAGEERROR, new ErrorImpl(error));
String errorStr = "";
if (error.error != null) {
errorStr = error.error.name + ": " + error.error.message;
if (error.error.stack != null && !error.error.stack.isEmpty()) {
errorStr += "\n" + error.error.stack;
}
}
listeners.notify(EventType.PAGEERROR, errorStr);
} else if ("crash".equals(event)) {
listeners.notify(EventType.CRASH, this);
} else if ("close".equals(event)) {
@ -352,12 +359,12 @@ public class PageImpl extends ChannelOwner implements Page {
}
@Override
public void onPageError(Consumer<Error> handler) {
public void onPageError(Consumer<String> handler) {
listeners.add(EventType.PAGEERROR, handler);
}
@Override
public void offPageError(Consumer<Error> handler) {
public void offPageError(Consumer<String> handler) {
listeners.remove(EventType.PAGEERROR, handler);
}
@ -623,11 +630,11 @@ public class PageImpl extends ChannelOwner implements Page {
}
@Override
public void exposeBinding(String name, Binding playwrightBinding, ExposeBindingOptions options) {
public void exposeBinding(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
withLogging("Page.exposeBinding", () -> exposeBindingImpl(name, playwrightBinding, options));
}
private void exposeBindingImpl(String name, Binding playwrightBinding, ExposeBindingOptions options) {
private void exposeBindingImpl(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
if (bindings.containsKey(name)) {
throw new PlaywrightException("Function \"" + name + "\" has been already registered");
}
@ -645,9 +652,9 @@ public class PageImpl extends ChannelOwner implements Page {
}
@Override
public void exposeFunction(String name, Function playwrightFunction) {
public void exposeFunction(String name, FunctionCallback playwrightFunction) {
withLogging("Page.exposeFunction",
() -> exposeBindingImpl(name, (Binding.Source source, Object... args) -> playwrightFunction.call(args), null));
() -> exposeBindingImpl(name, (BindingCallback.Source source, Object... args) -> playwrightFunction.call(args), null));
}
@Override
@ -1146,29 +1153,6 @@ public class PageImpl extends ChannelOwner implements Page {
listeners.notify(EventType.FRAMENAVIGATED, frame);
}
private static class ErrorImpl implements Error {
private final SerializedError error;
ErrorImpl(SerializedError error) {
this.error = error;
}
@Override
public String message() {
return error.error.message;
}
@Override
public String name() {
return error.error.name;
}
@Override
public String stack() {
return error.error.stack;
}
}
private class WaitableFrameDetach extends WaitableEvent<EventType, Frame> {
WaitableFrameDetach(Frame frameArg) {
super(PageImpl.this.listeners, EventType.FRAMEDETACHED, detachedFrame -> frameArg.equals(detachedFrame));

View File

@ -0,0 +1,31 @@
/*
* 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.options;
import com.microsoft.playwright.BrowserContext;
import com.microsoft.playwright.Frame;
import com.microsoft.playwright.Page;
public interface BindingCallback {
interface Source {
BrowserContext context();
Page page();
Frame frame();
}
Object call(Source source, Object... args);
}

View File

@ -0,0 +1,21 @@
/*
* 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.options;
public interface FunctionCallback {
Object call(Object... args);
}

View File

@ -16,6 +16,7 @@
package com.microsoft.playwright;
import com.microsoft.playwright.options.BindingCallback;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
@ -29,7 +30,7 @@ public class TestBrowserContextExposeFunction extends TestBase {
@Test
void exposeBindingShouldWork() {
Page.Binding.Source[] bindingSource = {null};
BindingCallback.Source[] bindingSource = {null};
context.exposeBinding("add", (source, args) -> {
bindingSource[0] = source;
return (Integer) args[0] + (Integer) args[1];

View File

@ -16,6 +16,7 @@
package com.microsoft.playwright;
import com.microsoft.playwright.options.BindingCallback;
import org.junit.jupiter.api.Test;
import java.util.Map;
@ -31,7 +32,7 @@ public class TestPageExposeFunction extends TestBase {
void exposeBindingShouldWork() {
BrowserContext context = browser.newContext();
Page page = context.newPage();
Page.Binding.Source[] bindingSource = { null };
BindingCallback.Source[] bindingSource = { null };
page.exposeBinding("add", (source, args) -> {
bindingSource[0] = source;
return (Integer) args[0] + (Integer) args[1];

View File

@ -81,7 +81,7 @@ public class TestWorkers extends TestBase {
@Test
void shouldReportErrors() {
Page.Error[] errorLog = {null};
String[] errorLog = {null};
page.onPageError(e -> errorLog[0] = e);
page.evaluate("() => new Worker(URL.createObjectURL(new Blob([`\n" +
" setTimeout(() => {\n" +
@ -95,7 +95,7 @@ public class TestWorkers extends TestBase {
page.waitForTimeout(100);
assertTrue(Duration.between(start, Instant.now()).getSeconds() < 30, "Timed out");
}
assertTrue(errorLog[0].message().contains("this is my error"));
assertTrue(errorLog[0].contains("this is my error"));
}
@Test

View File

@ -954,30 +954,6 @@ class Interface extends TypeDefinition {
private void writeSharedTypes(List<String> output, String offset) {
switch (jsonName) {
case "Page": {
output.add(offset + "interface Function {");
output.add(offset + " Object call(Object... args);");
output.add(offset + "}");
output.add("");
output.add(offset + "interface Binding {");
output.add(offset + " interface Source {");
output.add(offset + " BrowserContext context();");
output.add(offset + " Page page();");
output.add(offset + " Frame frame();");
output.add(offset + " }");
output.add("");
output.add(offset + " Object call(Source source, Object... args);");
output.add(offset + "}");
output.add("");
output.add(offset + "interface Error {");
output.add(offset + " String message();");
output.add(offset + " String name();");
output.add(offset + " String stack();");
output.add(offset + "}");
output.add("");
break;
}
case "ElementHandle": {
output.add(offset + "class SelectOption {");
output.add(offset + " public String value;");

View File

@ -46,10 +46,10 @@ class Types {
Types() {
// Viewport size.
add("BrowserContext.exposeBinding.callback", "function", "Page.Binding");
add("BrowserContext.exposeFunction.callback", "function", "Page.Function");
add("Page.exposeBinding.callback", "function", "Binding");
add("Page.exposeFunction.callback", "function", "Function");
add("BrowserContext.exposeBinding.callback", "function", "BindingCallback");
add("BrowserContext.exposeFunction.callback", "function", "FunctionCallback");
add("Page.exposeBinding.callback", "function", "BindingCallback");
add("Page.exposeFunction.callback", "function", "FunctionCallback");
add("BrowserContext.addInitScript.script", "Object|function|string", "String");
add("Page.addInitScript.script", "Object|function|string", "String");