test: convert page-expose-function.spec.ts (#22)

This commit is contained in:
Yury Semikhatsky 2020-10-19 17:39:16 -07:00 committed by GitHub
parent aa1448355a
commit fc91cb7866
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 276 additions and 6 deletions

View File

@ -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.*;

View File

@ -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"));
}
}
}