From 85a2a5697b78fde72f50a1f074f4064cd26f4b03 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Mon, 12 Oct 2020 22:18:22 -0700 Subject: [PATCH] feat: frame.check/uncheck (#7) --- .../microsoft/playwright/impl/FrameImpl.java | 88 ++++++++++- .../microsoft/playwright/impl/PageImpl.java | 9 +- .../com/microsoft/playwright/TestCheck.java | 139 ++++++++++++++++++ 3 files changed, 225 insertions(+), 11 deletions(-) create mode 100644 playwright/src/test/java/com/microsoft/playwright/TestCheck.java diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java index de31ecbd..8611fedc 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/FrameImpl.java @@ -17,10 +17,15 @@ package com.microsoft.playwright.impl; import com.google.gson.Gson; +import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.microsoft.playwright.*; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -90,7 +95,18 @@ public class FrameImpl extends ChannelOwner implements Frame { @Override public List querySelectorAll(String selector) { - return null; + JsonObject params = new JsonObject(); + params.addProperty("selector", selector); + JsonElement json = sendMessage("querySelectorAll", params); + JsonArray elements = json.getAsJsonObject().getAsJsonArray("elements"); + if (elements == null) { + return null; + } + List handles = new ArrayList<>(); + for (JsonElement item : elements) { + handles.add(connection.getExistingObject(item.getAsJsonObject().get("guid").getAsString())); + } + return handles; } @Override @@ -107,22 +123,68 @@ public class FrameImpl extends ChannelOwner implements Frame { @Override public Object evalOnSelectorAll(String selector, String pageFunction, Object arg) { - return null; + JsonObject params = new JsonObject(); + params.addProperty("selector", selector); + params.addProperty("expression", pageFunction); + params.addProperty("isFunction", isFunctionBody(pageFunction)); + params.add("arg", new Gson().toJsonTree(serializeArgument(arg))); + JsonElement json = sendMessage("evalOnSelectorAll", params); + SerializedValue value = new Gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class); + return deserialize(value); } @Override public ElementHandle addScriptTag(AddScriptTagOptions options) { - return null; + if (options == null) { + options = new AddScriptTagOptions(); + } + JsonObject params = new Gson().toJsonTree(options).getAsJsonObject(); + if (options.path != null) { + params.remove("path"); + byte[] encoded = new byte[0]; + try { + encoded = Files.readAllBytes(Paths.get(options.path)); + } catch (IOException e) { + throw new RuntimeException("Failed to read from file", e); + } + String content = new String(encoded, StandardCharsets.UTF_8); + content += "//# sourceURL=" + options.path.replace("\n", ""); + params.addProperty("content", content); + } + JsonElement json = sendMessage("addScriptTag", params); + return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("element").get("guid").getAsString()); } @Override public ElementHandle addStyleTag(AddStyleTagOptions options) { - return null; + if (options == null) { + options = new AddStyleTagOptions(); + } + JsonObject params = new Gson().toJsonTree(options).getAsJsonObject(); + if (options.path != null) { + params.remove("path"); + byte[] encoded = new byte[0]; + try { + encoded = Files.readAllBytes(Paths.get(options.path)); + } catch (IOException e) { + throw new RuntimeException("Failed to read from file", e); + } + String content = new String(encoded, StandardCharsets.UTF_8); + content += "/*# sourceURL=" + options.path.replace("\n", "") + "*/"; + params.addProperty("content", content); + } + JsonElement json = sendMessage("addStyleTag", params); + return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("element").get("guid").getAsString()); } @Override public void check(String selector, CheckOptions options) { - + if (options == null) { + options = new CheckOptions(); + } + JsonObject params = new Gson().toJsonTree(options).getAsJsonObject(); + params.addProperty("selector", selector); + sendMessage("check", params); } @Override @@ -153,7 +215,7 @@ public class FrameImpl extends ChannelOwner implements Frame { @Override public String content() { - return null; + return sendMessage("content", new JsonObject()).getAsJsonObject().get("value").getAsString(); } @Override @@ -332,7 +394,12 @@ public class FrameImpl extends ChannelOwner implements Frame { @Override public String textContent(String selector, TextContentOptions options) { - return null; + if (options == null) { + options = new TextContentOptions(); + } + JsonObject params = new Gson().toJsonTree(options).getAsJsonObject(); + params.addProperty("selector", selector); + return sendMessage("textContent", params).getAsJsonObject().get("value").getAsString(); } @Override @@ -348,7 +415,12 @@ public class FrameImpl extends ChannelOwner implements Frame { @Override public void uncheck(String selector, UncheckOptions options) { - + if (options == null) { + options = new UncheckOptions(); + } + JsonObject params = new Gson().toJsonTree(options).getAsJsonObject(); + params.addProperty("selector", selector); + sendMessage("uncheck", params); } @Override diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java index 802d2e4e..9280078f 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java @@ -165,17 +165,20 @@ public class PageImpl extends ChannelOwner implements Page { @Override public void addInitScript(String script, Object arg) { - + JsonObject params = new JsonObject(); + // TODO: support or drop arg + params.addProperty("source", script); + sendMessage("addInitScript", params); } @Override public ElementHandle addScriptTag(AddScriptTagOptions options) { - return null; + return mainFrame.addScriptTag(convertViaJson(options, Frame.AddScriptTagOptions.class)); } @Override public ElementHandle addStyleTag(AddStyleTagOptions options) { - return null; + return mainFrame.addStyleTag(convertViaJson(options, Frame.AddStyleTagOptions.class)); } @Override diff --git a/playwright/src/test/java/com/microsoft/playwright/TestCheck.java b/playwright/src/test/java/com/microsoft/playwright/TestCheck.java new file mode 100644 index 00000000..cbd27d73 --- /dev/null +++ b/playwright/src/test/java/com/microsoft/playwright/TestCheck.java @@ -0,0 +1,139 @@ +/** + * 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 static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class TestCheck { + private static Playwright playwright; + private static Server server; + 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(); + browser = playwright.chromium().launch(options); + isChromium = true; + isWebKit = false; + headful = false; + } + + @BeforeAll + static void startServer() throws IOException { + server = new Server(8907); + } + + @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 shouldCheckTheBox() { + page.setContent(""); + page.check("input"); + assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked")); + } + + @Test + void shouldNotCheckTheCheckedBox() { + page.setContent(""); + page.check("input"); + assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked")); + } + + @Test + void shouldUncheckTheBox() { + page.setContent(""); + page.uncheck("input"); + assertEquals(false, page.evaluate("() => window['checkbox'].checked")); + } + + @Test + void shouldNotUncheckTheUncheckedBox() { + page.setContent(""); + page.uncheck("input"); + assertEquals(false, page.evaluate("() => window['checkbox'].checked")); + } + + @Test + void shouldCheckTheBoxByLabel() { + page.setContent(""); + page.check("label"); + assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked")); + } + + @Test + void shouldCheckTheBoxOutsideLabel() { + page.setContent("
"); + page.check("label"); + assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked")); + } + + @Test + void shouldCheckTheBoxInsideLabelWOId() { + page.setContent(""); + page.check("label"); + assertTrue((Boolean) page.evaluate("() => window['checkbox'].checked")); + } + + @Test + void shouldCheckRadio() { + page.setContent("one\n" + + "two\n" + + "three"); + page.check("#two"); + assertTrue((Boolean) page.evaluate("() => window['two'].checked")); + } + + @Test + void shouldCheckTheBoxByAriaRole() { + page.setContent("\n" + + " "); + page.check("div"); + assertEquals("true", page.evaluate("() => window['checkbox'].getAttribute('aria-checked')")); + } +}