mirror of
https://github.com/microsoft/playwright-java.git
synced 2025-09-08 21:01:00 +00:00
test: convert page-expose-function.spec.ts (#22)
This commit is contained in:
parent
aa1448355a
commit
fc91cb7866
@ -19,15 +19,9 @@ 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.*;
|
||||
|
@ -0,0 +1,276 @@
|
||||
/**
|
||||
* 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.util.Map;
|
||||
|
||||
import static com.microsoft.playwright.Frame.LoadState.LOAD;
|
||||
import static com.microsoft.playwright.Utils.mapOf;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestPageExposeFunction {
|
||||
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() {
|
||||
BrowserContext context = browser.newContext();
|
||||
Page page = context.newPage();
|
||||
Page.Binding.Source[] bindingSource = { null };
|
||||
page.exposeBinding("add", (source, args) -> {
|
||||
bindingSource[0] = source;
|
||||
return (Integer) args[0] + (Integer) args[1];
|
||||
});
|
||||
Object result = page.evaluate("async function() {\n" +
|
||||
" return window['add'](5, 6);\n" +
|
||||
"}");
|
||||
assertEquals(context, bindingSource[0].context());
|
||||
assertEquals(page, bindingSource[0].page());
|
||||
assertEquals(page.mainFrame(), bindingSource[0].frame());
|
||||
assertEquals(11, result);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWork() {
|
||||
page.exposeFunction("compute", args -> (Integer) args[0] * (Integer) args[1]);
|
||||
Object result = page.evaluate("async function() {\n" +
|
||||
" return await window['compute'](9, 4);\n" +
|
||||
"}");
|
||||
assertEquals(36, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithHandlesAndComplexObjects() {
|
||||
JSHandle fooHandle = page.evaluateHandle("() => {\n" +
|
||||
" window['fooValue'] = { bar: 2 };\n" +
|
||||
" return window['fooValue'];\n" +
|
||||
"}");
|
||||
page.exposeFunction("handle", args -> asList(mapOf("foo", fooHandle)));
|
||||
Object equals = page.evaluate("async function() {\n" +
|
||||
" const value = await window['handle']();\n" +
|
||||
" const [{ foo }] = value;\n" +
|
||||
" return foo === window['fooValue'];\n" +
|
||||
"}");
|
||||
assertEquals(true, equals);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void shouldThrowExceptionInPageContext() {
|
||||
page.exposeFunction("woof", args -> {
|
||||
throw new RuntimeException("WOOF WOOF");
|
||||
});
|
||||
Object result = page.evaluate("async () => {\n" +
|
||||
" try {\n" +
|
||||
" await window[\"woof\"]();\n" +
|
||||
" } catch (e) {\n" +
|
||||
" return {message: e.message, stack: e.stack};\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
assertTrue(result instanceof Map);
|
||||
Map<String, String> m = (Map<String, String>) result;
|
||||
assertEquals("WOOF WOOF", m.get("message"));
|
||||
assertTrue(m.get("stack").contains("shouldThrowExceptionInPageContext"));
|
||||
}
|
||||
|
||||
void shouldSupportThrowingNull() {
|
||||
// Throwing null would lead to NullPointerException in Java.
|
||||
}
|
||||
@Test
|
||||
void shouldBeCallableFromInsideAddInitScript() {
|
||||
boolean[] called = { false };
|
||||
page.exposeFunction("woof", args -> called[0] = true);
|
||||
page.addInitScript("window['woof']()");
|
||||
page.reload();
|
||||
assertTrue(called[0]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSurviveNavigation() {
|
||||
page.exposeFunction("compute", args -> (Integer) args[0] * (Integer) args[1]);
|
||||
Object result = page.evaluate("async function() {\n" +
|
||||
" return await window['compute'](9, 4);\n" +
|
||||
"}");
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
assertEquals(36, result);
|
||||
}
|
||||
|
||||
void shouldAwaitReturnedPromise() {
|
||||
// Java callback cannot return promise.
|
||||
}
|
||||
@Test
|
||||
void shouldWorkOnFrames() {
|
||||
page.exposeFunction("compute", args -> (Integer) args[0] * (Integer) args[1]);
|
||||
page.navigate(server.PREFIX + "/frames/nested-frames.html");
|
||||
Frame frame = page.frames().get(1);
|
||||
Object result = frame.evaluate("async function() {\n" +
|
||||
" return window['compute'](3, 5);\n" +
|
||||
"}");
|
||||
assertEquals(15, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkOnFramesBeforeNavigation() {
|
||||
page.navigate(server.PREFIX + "/frames/nested-frames.html");
|
||||
page.exposeFunction("compute", args -> (Integer) args[0] * (Integer) args[1]);
|
||||
|
||||
Frame frame = page.frames().get(1);
|
||||
Object result = frame.evaluate("async function() {\n" +
|
||||
" return window['compute'](3, 5);\n" +
|
||||
"}");
|
||||
assertEquals(15, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkAfterCrossOriginNavigation() {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
page.exposeFunction("compute", args -> (Integer) args[0] * (Integer) args[1]);
|
||||
|
||||
page.navigate(server.CROSS_PROCESS_PREFIX + "/empty.html");
|
||||
Object result = page.evaluate("window['compute'](9, 4)");
|
||||
assertEquals(36, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithComplexObjects() {
|
||||
page.exposeFunction("complexObject", args -> {
|
||||
Map<String, Integer> a = (Map<String, Integer>) args[0];
|
||||
Map<String, Integer> b = (Map<String, Integer>) args[1];
|
||||
int sum = a.get("x") + b.get("x");
|
||||
return mapOf("x", sum);
|
||||
});
|
||||
Object result = page.evaluate("async () => window['complexObject']({x: 5}, {x: 2})");
|
||||
assertTrue(result instanceof Map);
|
||||
assertEquals( 7, ((Map) result).get("x"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void exposeBindingHandleShouldWork() {
|
||||
JSHandle[] target = { null };
|
||||
page.exposeBinding("logme", (source, args) -> {
|
||||
target[0] = (JSHandle) args[0];
|
||||
return 17;
|
||||
}, new Page.ExposeBindingOptions().withHandle(true));
|
||||
Object result = page.evaluate("async function() {\n" +
|
||||
" return window['logme']({ foo: 42 });\n" +
|
||||
"}");
|
||||
assertEquals(42, target[0].evaluate("x => x.foo"));
|
||||
assertEquals(17, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
void exposeBindingHandleShouldNotThrowDuringNavigation() {
|
||||
page.exposeBinding("logme", (source, args) -> {
|
||||
return 17;
|
||||
}, new Page.ExposeBindingOptions().withHandle(true));
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
|
||||
Deferred<Response> navigation = page.waitForNavigation(new Page.WaitForNavigationOptions().withWaitUntil(LOAD));
|
||||
|
||||
page.evaluate("async url => {\n" +
|
||||
" window['logme']({ foo: 42 });\n" +
|
||||
" window.location.href = url;\n" +
|
||||
"}", server.PREFIX + "/one-style.html");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowForDuplicateRegistrations() {
|
||||
page.exposeFunction("foo", args -> null);
|
||||
try {
|
||||
page.exposeFunction("foo", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void exposeBindingHandleShouldThrowForMultipleArguments() {
|
||||
page.exposeBinding("logme", (source, args) -> {
|
||||
return 17;
|
||||
}, new Page.ExposeBindingOptions().withHandle(true));
|
||||
assertEquals(17, page.evaluate("async function() {\n" +
|
||||
" return window['logme']({ foo: 42 });\n" +
|
||||
"}"));
|
||||
assertEquals(17, page.evaluate("async function() {\n" +
|
||||
" return window['logme']({ foo: 42 }, undefined, undefined);\n" +
|
||||
"}"));
|
||||
assertEquals(17, page.evaluate("async function() {\n" +
|
||||
" return window['logme'](undefined, undefined, undefined);\n" +
|
||||
"}"));
|
||||
try {
|
||||
page.evaluate("async function() {\n" +
|
||||
" return window['logme'](1, 2);\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains("exposeBindingHandle supports a single argument, 2 received"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user