mirror of
https://github.com/microsoft/playwright-java.git
synced 2025-09-08 21:01:00 +00:00
feat: implement Page.exposeBinding and convert more binding tests (#21)
This commit is contained in:
parent
36ec91762f
commit
aa1448355a
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@ -29,13 +29,13 @@ jobs:
|
||||
run: |
|
||||
FILE_NAME="unkwnown"
|
||||
if [[ $OS == *"ubuntu"* ]]; then
|
||||
FILE_NAME=playwright-cli-0.5.3-linux.zip
|
||||
FILE_NAME=playwright-cli-0.151.0-linux.zip
|
||||
fi
|
||||
if [[ $OS == *"macos"* ]]; then
|
||||
FILE_NAME=playwright-cli-0.5.3-mac.zip
|
||||
FILE_NAME=playwright-cli-0.151.0-mac.zip
|
||||
fi
|
||||
if [[ $OS == *"windows"* ]]; then
|
||||
FILE_NAME=playwright-cli-0.5.3-win32_x64.zip
|
||||
FILE_NAME=playwright-cli-0.151.0-win32_x64.zip
|
||||
fi
|
||||
echo "Downloading from $FILE_NAME"
|
||||
curl -O https://playwright.azureedge.net/builds/cli/$FILE_NAME
|
||||
|
@ -16,8 +16,8 @@ cd playwright-java
|
||||
```bash
|
||||
mkdir driver
|
||||
cd driver
|
||||
curl -O https://playwright.azureedge.net/builds/cli/playwright-cli-0.5.3-linux.zip
|
||||
unzip playwright-cli-0.5.3-linux.zip -d .
|
||||
curl -O https://playwright.azureedge.net/builds/cli/playwright-cli-0.151.0-linux.zip
|
||||
unzip playwright-cli-0.151.0-linux.zip -d .
|
||||
./playwright-cli install
|
||||
```
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -88,10 +88,8 @@ public interface Browser {
|
||||
public BrowserContext.HTTPCredentials httpCredentials;
|
||||
public ColorScheme colorScheme;
|
||||
public Logger logger;
|
||||
public String relativeArtifactsPath;
|
||||
public Boolean recordVideos;
|
||||
public String videosPath;
|
||||
public VideoSize videoSize;
|
||||
public Boolean recordTrace;
|
||||
|
||||
public NewContextOptions withAcceptDownloads(Boolean acceptDownloads) {
|
||||
this.acceptDownloads = acceptDownloads;
|
||||
@ -165,22 +163,14 @@ public interface Browser {
|
||||
this.logger = logger;
|
||||
return this;
|
||||
}
|
||||
public NewContextOptions withRelativeArtifactsPath(String relativeArtifactsPath) {
|
||||
this.relativeArtifactsPath = relativeArtifactsPath;
|
||||
return this;
|
||||
}
|
||||
public NewContextOptions withRecordVideos(Boolean recordVideos) {
|
||||
this.recordVideos = recordVideos;
|
||||
public NewContextOptions withVideosPath(String videosPath) {
|
||||
this.videosPath = videosPath;
|
||||
return this;
|
||||
}
|
||||
public VideoSize setVideoSize() {
|
||||
this.videoSize = new VideoSize();
|
||||
return this.videoSize;
|
||||
}
|
||||
public NewContextOptions withRecordTrace(Boolean recordTrace) {
|
||||
this.recordTrace = recordTrace;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class NewPageOptions {
|
||||
public enum ColorScheme { DARK, LIGHT, NO_PREFERENCE }
|
||||
@ -245,10 +235,8 @@ public interface Browser {
|
||||
public BrowserContext.HTTPCredentials httpCredentials;
|
||||
public ColorScheme colorScheme;
|
||||
public Logger logger;
|
||||
public String relativeArtifactsPath;
|
||||
public Boolean recordVideos;
|
||||
public String videosPath;
|
||||
public VideoSize videoSize;
|
||||
public Boolean recordTrace;
|
||||
|
||||
public NewPageOptions withAcceptDownloads(Boolean acceptDownloads) {
|
||||
this.acceptDownloads = acceptDownloads;
|
||||
@ -322,22 +310,14 @@ public interface Browser {
|
||||
this.logger = logger;
|
||||
return this;
|
||||
}
|
||||
public NewPageOptions withRelativeArtifactsPath(String relativeArtifactsPath) {
|
||||
this.relativeArtifactsPath = relativeArtifactsPath;
|
||||
return this;
|
||||
}
|
||||
public NewPageOptions withRecordVideos(Boolean recordVideos) {
|
||||
this.recordVideos = recordVideos;
|
||||
public NewPageOptions withVideosPath(String videosPath) {
|
||||
this.videosPath = videosPath;
|
||||
return this;
|
||||
}
|
||||
public VideoSize setVideoSize() {
|
||||
this.videoSize = new VideoSize();
|
||||
return this.videoSize;
|
||||
}
|
||||
public NewPageOptions withRecordTrace(Boolean recordTrace) {
|
||||
this.recordTrace = recordTrace;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
void close();
|
||||
List<BrowserContext> contexts();
|
||||
|
@ -46,6 +46,14 @@ public interface BrowserContext {
|
||||
|
||||
void addListener(EventType type, Listener<EventType> listener);
|
||||
void removeListener(EventType type, Listener<EventType> listener);
|
||||
class ExposeBindingOptions {
|
||||
public Boolean handle;
|
||||
|
||||
public ExposeBindingOptions withHandle(Boolean handle) {
|
||||
this.handle = handle;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class GrantPermissionsOptions {
|
||||
public String origin;
|
||||
|
||||
@ -85,7 +93,10 @@ public interface BrowserContext {
|
||||
return cookies(null);
|
||||
}
|
||||
List<Object> cookies(String urls);
|
||||
void exposeBinding(String name, Page.Binding playwrightBinding);
|
||||
default void exposeBinding(String name, Page.Binding playwrightBinding) {
|
||||
exposeBinding(name, playwrightBinding, null);
|
||||
}
|
||||
void exposeBinding(String name, Page.Binding playwrightBinding, ExposeBindingOptions options);
|
||||
void exposeFunction(String name, Page.Function playwrightFunction);
|
||||
default void grantPermissions(List<String> permissions) {
|
||||
grantPermissions(permissions, null);
|
||||
|
@ -78,7 +78,6 @@ public interface BrowserType {
|
||||
public Boolean ignoreDefaultArgs;
|
||||
public Proxy proxy;
|
||||
public String downloadsPath;
|
||||
public String artifactsPath;
|
||||
public Boolean chromiumSandbox;
|
||||
public String firefoxUserPrefs;
|
||||
public Boolean handleSIGINT;
|
||||
@ -114,10 +113,6 @@ public interface BrowserType {
|
||||
this.downloadsPath = downloadsPath;
|
||||
return this;
|
||||
}
|
||||
public LaunchOptions withArtifactsPath(String artifactsPath) {
|
||||
this.artifactsPath = artifactsPath;
|
||||
return this;
|
||||
}
|
||||
public LaunchOptions withChromiumSandbox(Boolean chromiumSandbox) {
|
||||
this.chromiumSandbox = chromiumSandbox;
|
||||
return this;
|
||||
@ -240,7 +235,6 @@ public interface BrowserType {
|
||||
public Proxy proxy;
|
||||
public Boolean acceptDownloads;
|
||||
public String downloadsPath;
|
||||
public String artifactsPath;
|
||||
public Boolean chromiumSandbox;
|
||||
public Boolean handleSIGINT;
|
||||
public Boolean handleSIGTERM;
|
||||
@ -266,10 +260,8 @@ public interface BrowserType {
|
||||
public Boolean offline;
|
||||
public BrowserContext.HTTPCredentials httpCredentials;
|
||||
public ColorScheme colorScheme;
|
||||
public String relativeArtifactsPath;
|
||||
public Boolean recordVideos;
|
||||
public String videosPath;
|
||||
public VideoSize videoSize;
|
||||
public Boolean recordTrace;
|
||||
|
||||
public LaunchPersistentContextOptions withHeadless(Boolean headless) {
|
||||
this.headless = headless;
|
||||
@ -299,10 +291,6 @@ public interface BrowserType {
|
||||
this.downloadsPath = downloadsPath;
|
||||
return this;
|
||||
}
|
||||
public LaunchPersistentContextOptions withArtifactsPath(String artifactsPath) {
|
||||
this.artifactsPath = artifactsPath;
|
||||
return this;
|
||||
}
|
||||
public LaunchPersistentContextOptions withChromiumSandbox(Boolean chromiumSandbox) {
|
||||
this.chromiumSandbox = chromiumSandbox;
|
||||
return this;
|
||||
@ -403,22 +391,14 @@ public interface BrowserType {
|
||||
this.colorScheme = colorScheme;
|
||||
return this;
|
||||
}
|
||||
public LaunchPersistentContextOptions withRelativeArtifactsPath(String relativeArtifactsPath) {
|
||||
this.relativeArtifactsPath = relativeArtifactsPath;
|
||||
return this;
|
||||
}
|
||||
public LaunchPersistentContextOptions withRecordVideos(Boolean recordVideos) {
|
||||
this.recordVideos = recordVideos;
|
||||
public LaunchPersistentContextOptions withVideosPath(String videosPath) {
|
||||
this.videosPath = videosPath;
|
||||
return this;
|
||||
}
|
||||
public VideoSize setVideoSize() {
|
||||
this.videoSize = new VideoSize();
|
||||
return this.videoSize;
|
||||
}
|
||||
public LaunchPersistentContextOptions withRecordTrace(Boolean recordTrace) {
|
||||
this.recordTrace = recordTrace;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class LaunchServerOptions {
|
||||
public class Proxy {
|
||||
@ -457,7 +437,6 @@ public interface BrowserType {
|
||||
public String ignoreDefaultArgs;
|
||||
public Proxy proxy;
|
||||
public String downloadsPath;
|
||||
public String artifactsPath;
|
||||
public Boolean chromiumSandbox;
|
||||
public String firefoxUserPrefs;
|
||||
public Boolean handleSIGINT;
|
||||
@ -496,10 +475,6 @@ public interface BrowserType {
|
||||
this.downloadsPath = downloadsPath;
|
||||
return this;
|
||||
}
|
||||
public LaunchServerOptions withArtifactsPath(String artifactsPath) {
|
||||
this.artifactsPath = artifactsPath;
|
||||
return this;
|
||||
}
|
||||
public LaunchServerOptions withChromiumSandbox(Boolean chromiumSandbox) {
|
||||
this.chromiumSandbox = chromiumSandbox;
|
||||
return this;
|
||||
|
@ -294,6 +294,14 @@ public interface Page {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class ExposeBindingOptions {
|
||||
public Boolean handle;
|
||||
|
||||
public ExposeBindingOptions withHandle(Boolean handle) {
|
||||
this.handle = handle;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class FillOptions {
|
||||
public Boolean noWaitAfter;
|
||||
public Integer timeout;
|
||||
@ -836,7 +844,10 @@ public interface Page {
|
||||
return evaluateHandle(pageFunction, null);
|
||||
}
|
||||
JSHandle evaluateHandle(String pageFunction, Object arg);
|
||||
void exposeBinding(String name, Binding playwrightBinding);
|
||||
default void exposeBinding(String name, Binding playwrightBinding) {
|
||||
exposeBinding(name, playwrightBinding, null);
|
||||
}
|
||||
void exposeBinding(String name, Binding playwrightBinding, ExposeBindingOptions options);
|
||||
void exposeFunction(String name, Function playwrightFunction);
|
||||
default void fill(String selector, String value) {
|
||||
fill(selector, value, null);
|
||||
@ -939,6 +950,7 @@ public interface Page {
|
||||
void unroute(Pattern url, BiConsumer<Route, Request> handler);
|
||||
void unroute(Predicate<String> url, BiConsumer<Route, Request> handler);
|
||||
String url();
|
||||
Video video();
|
||||
Viewport viewportSize();
|
||||
default Deferred<Event<EventType>> waitForEvent(EventType event) {
|
||||
return waitForEvent(event, null);
|
||||
|
24
playwright/src/main/java/com/microsoft/playwright/Video.java
Normal file
24
playwright/src/main/java/com/microsoft/playwright/Video.java
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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 java.util.*;
|
||||
|
||||
public interface Video {
|
||||
String path();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.BrowserContext;
|
||||
import com.microsoft.playwright.Frame;
|
||||
import com.microsoft.playwright.JSHandle;
|
||||
import com.microsoft.playwright.Page;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -65,9 +66,14 @@ class BindingCall extends ChannelOwner {
|
||||
Frame frame = connection.getExistingObject(initializer.getAsJsonObject("frame").get("guid").getAsString());
|
||||
Page.Binding.Source source = new SourceImpl(frame);
|
||||
List<Object> args = new ArrayList<>();
|
||||
if (initializer.has("handle")) {
|
||||
JSHandle handle = connection.getExistingObject(initializer.getAsJsonObject("handle").get("guid").getAsString());
|
||||
args.add(handle);
|
||||
} else {
|
||||
for (JsonElement arg : initializer.getAsJsonArray("args")) {
|
||||
args.add(deserialize(new Gson().fromJson(arg, SerializedValue.class)));
|
||||
}
|
||||
}
|
||||
Object result = binding.call(source, args.toArray());
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
|
@ -102,19 +102,22 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exposeBinding(String name, Page.Binding playwrightBinding) {
|
||||
public void exposeBinding(String name, Page.Binding playwrightBinding, ExposeBindingOptions options) {
|
||||
if (bindings.containsKey(name)) {
|
||||
throw new RuntimeException("Function " + name + " has already been registered");
|
||||
throw new RuntimeException("Function \"" + name + "\" has been already registered");
|
||||
}
|
||||
for (PageImpl page : pages) {
|
||||
if (page.bindings.containsKey(name)) {
|
||||
throw new Error("Function " + name + " has already been registered in one of the pages");
|
||||
throw new RuntimeException("Function \"" + name + "\" has been already registered in one of the pages");
|
||||
}
|
||||
}
|
||||
bindings.put(name, playwrightBinding);
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("name", name);
|
||||
if (options != null && options.handle != null && options.handle) {
|
||||
params.addProperty("needsHandle", true);
|
||||
}
|
||||
sendMessage("exposeBinding", params);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
@ -37,10 +36,9 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
private final MouseImpl mouse;
|
||||
private Viewport viewport;
|
||||
private final Router routes = new Router();
|
||||
// TODO: do not rely on the frame order in the tests
|
||||
private final Set<FrameImpl> frames = new LinkedHashSet<>();
|
||||
private final ListenerCollection<EventType> listeners = new ListenerCollection<>();
|
||||
final Map<String, Binding> bindings = new HashMap<String, Binding>();
|
||||
final Map<String, Binding> bindings = new HashMap<>();
|
||||
BrowserContextImpl ownedContext;
|
||||
private boolean isClosed;
|
||||
final Set<Worker> workers = new HashSet<>();
|
||||
@ -55,15 +53,6 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
frames.add(mainFrame);
|
||||
}
|
||||
|
||||
public Deferred<Page> waitForPopup() {
|
||||
CompletableFuture<JsonObject> popupFuture = futureForEvent("popup");
|
||||
return () -> {
|
||||
JsonObject params = waitForCompletion(popupFuture);
|
||||
String guid = params.getAsJsonObject("page").get("guid").getAsString();
|
||||
return connection.getExistingObject(guid);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleEvent(String event, JsonObject params) {
|
||||
if ("dialog".equals(event)) {
|
||||
@ -96,6 +85,20 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
String guid = params.getAsJsonObject("element").get("guid").getAsString();
|
||||
FileChooser fileChooser = connection.getExistingObject(guid);
|
||||
listeners.notify(EventType.FILECHOOSER, fileChooser);
|
||||
} else if ("bindingCall".equals(event)) {
|
||||
String guid = params.getAsJsonObject("binding").get("guid").getAsString();
|
||||
BindingCall bindingCall = connection.getExistingObject(guid);
|
||||
Binding binding = bindings.get(bindingCall.name());
|
||||
if (binding == null) {
|
||||
binding = browserContext.bindings.get(bindingCall.name());
|
||||
}
|
||||
if (binding != null) {
|
||||
try {
|
||||
bindingCall.call(binding);
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else if ("load".equals(event)) {
|
||||
listeners.notify(EventType.LOAD, null);
|
||||
} else if ("domcontentloaded".equals(event)) {
|
||||
@ -303,17 +306,20 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exposeBinding(String name, Binding playwrightBinding) {
|
||||
public void exposeBinding(String name, Binding playwrightBinding, ExposeBindingOptions options) {
|
||||
if (bindings.containsKey(name)) {
|
||||
throw new RuntimeException("Function " + name + " has already been registered");
|
||||
throw new RuntimeException("Function \"" + name + "\" has been already registered");
|
||||
}
|
||||
if (browserContext.bindings.containsKey(name)) {
|
||||
throw new RuntimeException("Function " + name + " has already been registered in the browser context");
|
||||
throw new RuntimeException("Function \"" + name + "\" has been already registered in the browser context");
|
||||
}
|
||||
bindings.put(name, playwrightBinding);
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("name", name);
|
||||
if (options != null && options.handle != null && options.handle) {
|
||||
params.addProperty("needsHandle", true);
|
||||
}
|
||||
sendMessage("exposeBinding", params);
|
||||
}
|
||||
|
||||
@ -609,6 +615,11 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
return mainFrame.url();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Video video() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Viewport viewportSize() {
|
||||
return viewport;
|
||||
@ -740,7 +751,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}));
|
||||
waitables.add(createWaitForCloseHelper());
|
||||
if (options != null && options.timeout != null) {
|
||||
waitables.add(new WaitableTimeout(options.timeout.intValue()));
|
||||
waitables.add(new WaitableTimeout(options.timeout));
|
||||
}
|
||||
return toDeferred(new WaitableRace(waitables));
|
||||
}
|
||||
@ -756,7 +767,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}));
|
||||
waitables.add(createWaitForCloseHelper());
|
||||
if (options != null && options.timeout != null) {
|
||||
waitables.add(new WaitableTimeout(options.timeout.intValue()));
|
||||
waitables.add(new WaitableTimeout(options.timeout));
|
||||
}
|
||||
return toDeferred(new WaitableRace(waitables));
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.microsoft.playwright.Mouse;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
|
||||
class Serialization {
|
||||
@ -49,31 +50,32 @@ class Serialization {
|
||||
handles.add((JSHandleImpl) value);
|
||||
return result;
|
||||
}
|
||||
if (value == null)
|
||||
if (value == null) {
|
||||
result.v = "undefined";
|
||||
else if (value instanceof Double) {
|
||||
} else if (value instanceof Double) {
|
||||
double d = ((Double) value).doubleValue();
|
||||
if (d == Double.POSITIVE_INFINITY)
|
||||
if (d == Double.POSITIVE_INFINITY) {
|
||||
result.v = "Infinity";
|
||||
else if (d == Double.NEGATIVE_INFINITY)
|
||||
} else if (d == Double.NEGATIVE_INFINITY) {
|
||||
result.v = "-Infinity";
|
||||
else if (d == -0)
|
||||
} else if (d == -0) {
|
||||
result.v = "-0";
|
||||
else if (Double.isNaN(d))
|
||||
result.v="NaN";
|
||||
else
|
||||
} else if (Double.isNaN(d)) {
|
||||
result.v = "NaN";
|
||||
} else {
|
||||
result.n = d;
|
||||
}
|
||||
else if (value instanceof Boolean)
|
||||
} else if (value instanceof Boolean) {
|
||||
result.b = (Boolean) value;
|
||||
else if (value instanceof Integer)
|
||||
} else if (value instanceof Integer) {
|
||||
result.n = (Integer) value;
|
||||
else if (value instanceof String)
|
||||
} else if (value instanceof String) {
|
||||
result.s = (String) value;
|
||||
else if (value instanceof List) {
|
||||
} else if (value instanceof List) {
|
||||
List<SerializedValue> list = new ArrayList<>();
|
||||
for (Object o : (List) value)
|
||||
for (Object o : (List) value) {
|
||||
list.add(serializeValue(o, handles, depth + 1));
|
||||
}
|
||||
result.a = list.toArray(new SerializedValue[0]);
|
||||
} else if (value instanceof Map) {
|
||||
List<SerializedValue.O> list = new ArrayList<>();
|
||||
@ -85,8 +87,15 @@ class Serialization {
|
||||
list.add(o);
|
||||
}
|
||||
result.o = list.toArray(new SerializedValue.O[0]);
|
||||
} else
|
||||
} else if (value instanceof Object[]) {
|
||||
List<SerializedValue> list = new ArrayList<>();
|
||||
for (Object o : (Object[]) value) {
|
||||
list.add(serializeValue(o, handles, depth + 1));
|
||||
}
|
||||
result.a = list.toArray(new SerializedValue[0]);
|
||||
} else {
|
||||
throw new RuntimeException("Unsupported type of argument: " + value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -106,8 +115,9 @@ class Serialization {
|
||||
|
||||
static <T> T deserialize(SerializedValue value) {
|
||||
if (value.n != null) {
|
||||
if (value.n.doubleValue() == (double) value.n.intValue())
|
||||
if (value.n.doubleValue() == (double) value.n.intValue()) {
|
||||
return (T) Integer.valueOf(value.n.intValue());
|
||||
}
|
||||
return (T) Double.valueOf(value.n.doubleValue());
|
||||
}
|
||||
if (value.b != null)
|
||||
@ -133,14 +143,16 @@ class Serialization {
|
||||
}
|
||||
if (value.a != null) {
|
||||
List list = new ArrayList();
|
||||
for (SerializedValue v : value.a)
|
||||
for (SerializedValue v : value.a) {
|
||||
list.add(deserialize(v));
|
||||
}
|
||||
return (T) list;
|
||||
}
|
||||
if (value.o != null) {
|
||||
Map map = new LinkedHashMap<>();
|
||||
for (SerializedValue.O o : value.o)
|
||||
for (SerializedValue.O o : value.o) {
|
||||
map.put(o.k, deserialize(o.v));
|
||||
}
|
||||
return (T) map;
|
||||
}
|
||||
throw new RuntimeException("Unexpected result: " + new Gson().toJson(value));
|
||||
|
@ -0,0 +1,167 @@
|
||||
/**
|
||||
* 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.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.microsoft.playwright.Page.EventType.FRAMENAVIGATED;
|
||||
import static com.microsoft.playwright.Utils.expectedSSLError;
|
||||
import static com.microsoft.playwright.Utils.mapOf;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestBrowserContextExposeFunction {
|
||||
private static Playwright playwright;
|
||||
private static Server server;
|
||||
private static Server httpsServer;
|
||||
private static BrowserType browserType;
|
||||
private static Browser browser;
|
||||
private static boolean isChromium;
|
||||
private static boolean isWebKit;
|
||||
private static boolean headful;
|
||||
private BrowserContext context;
|
||||
private Page page;
|
||||
|
||||
@BeforeAll
|
||||
static void launchBrowser() {
|
||||
playwright = Playwright.create();
|
||||
BrowserType.LaunchOptions options = new BrowserType.LaunchOptions();
|
||||
browserType = playwright.chromium();
|
||||
browser = browserType.launch(options);
|
||||
isChromium = true;
|
||||
isWebKit = false;
|
||||
headful = false;
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
static void startServer() throws IOException {
|
||||
server = Server.createHttp(8907);
|
||||
httpsServer = Server.createHttps(8908);
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void stopServer() throws IOException {
|
||||
browser.close();
|
||||
server.stop();
|
||||
server = null;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
server.reset();
|
||||
context = browser.newContext();
|
||||
page = context.newPage();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void tearDown() {
|
||||
context.close();
|
||||
context = null;
|
||||
page = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
void exposeBindingShouldWork() {
|
||||
Page.Binding.Source[] bindingSource = {null};
|
||||
context.exposeBinding("add", (source, args) -> {
|
||||
bindingSource[0] = source;
|
||||
return (Integer) args[0] + (Integer) args[1];
|
||||
});
|
||||
Page page = context.newPage();
|
||||
Object result = page.evaluate("add(5, 6)");
|
||||
assertEquals(context, bindingSource[0].context());
|
||||
assertEquals(page, bindingSource[0].page());
|
||||
assertEquals(page.mainFrame(), bindingSource[0].frame());
|
||||
assertEquals(11, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWork() {
|
||||
context.exposeFunction("add", args -> (Integer) args[0] + (Integer) args[1]);
|
||||
Page page = context.newPage();
|
||||
page.exposeFunction("mul", args -> (Integer) args[0] * (Integer) args[1]);
|
||||
context.exposeFunction("sub", args -> (Integer) args[0] - (Integer) args[1]);
|
||||
context.exposeBinding("addHandle", (source, args) -> source.frame().evaluateHandle("([a, b]) => a + b", args));
|
||||
Object result = page.evaluate("async () => ({ mul: await mul(9, 4), add: await add(9, 4), sub: await sub(9, 4), addHandle: await addHandle(5, 6) })");
|
||||
assertEquals(mapOf("mul", 36, "add", 13, "sub", 5, "addHandle", 11), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowForDuplicateRegistrations() {
|
||||
context.exposeFunction("foo", args -> null);
|
||||
context.exposeFunction("bar", args -> null);
|
||||
try {
|
||||
context.exposeFunction("foo", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered"));
|
||||
}
|
||||
|
||||
Page page = context.newPage();
|
||||
try {
|
||||
page.exposeFunction("foo", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered in the browser context"));
|
||||
}
|
||||
|
||||
page.exposeFunction("baz", args -> null);
|
||||
try {
|
||||
context.exposeFunction("baz", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
System.out.println(e);
|
||||
assertTrue(e.getMessage().contains("Function \"baz\" has been already registered in one of the pages"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldBeCallableFromInsideAddInitScript() {
|
||||
List<Object> actualArgs = new ArrayList<>();
|
||||
context.exposeFunction("woof", args -> actualArgs.add(args[0]));
|
||||
context.addInitScript("window['woof']('context')");
|
||||
Page page = context.newPage();
|
||||
page.addInitScript("window['woof']('page')");
|
||||
actualArgs.clear();
|
||||
page.reload();
|
||||
assertEquals(asList("context", "page"), actualArgs);
|
||||
}
|
||||
|
||||
@Test
|
||||
void exposeBindingHandleShouldWork() {
|
||||
JSHandle[] target = { null };
|
||||
context.exposeBinding("logme", (source, args) -> {
|
||||
target[0] = (JSHandle) args[0];
|
||||
return 17;
|
||||
}, new BrowserContext.ExposeBindingOptions().withHandle(true));
|
||||
Page page = context.newPage();
|
||||
Object result = page.evaluate("async function() {\n" +
|
||||
" return window['logme']({ foo: 42 });\n" +
|
||||
"}");
|
||||
assertNotNull(target[0]);
|
||||
assertEquals(42, target[0].evaluate("x => x.foo"));
|
||||
assertEquals(17, result);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user