diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/JSHandleImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/JSHandleImpl.java index dcf8ad2a..5020b111 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/JSHandleImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/JSHandleImpl.java @@ -28,8 +28,11 @@ import static com.microsoft.playwright.impl.Serialization.*; import static com.microsoft.playwright.impl.Utils.isFunctionBody; public class JSHandleImpl extends ChannelOwner implements JSHandle { + private String preview; + public JSHandleImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) { super(parent, type, guid, initializer); + this.preview = initializer.get("preview").getAsString(); } @Override @@ -101,4 +104,17 @@ public class JSHandleImpl extends ChannelOwner implements JSHandle { return deserialize(value); }); } + + @Override + void handleEvent(String event, JsonObject parameters) { + if ("previewUpdated".equals(event)) { + preview = parameters.get("preview").getAsString(); + } + super.handleEvent(event, parameters); + } + + @Override + public String toString() { + return preview; + } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestElementHandleConvenience.java b/playwright/src/test/java/com/microsoft/playwright/TestElementHandleConvenience.java index 7fac9cec..97cb4cc9 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestElementHandleConvenience.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestElementHandleConvenience.java @@ -21,6 +21,164 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; public class TestElementHandleConvenience extends TestBase { + @Test + void shouldHaveANicePreview() { + page.navigate(server.PREFIX + "/dom.html"); + ElementHandle outer = page.querySelector("#outer"); + ElementHandle inner = page.querySelector("#inner"); + ElementHandle check = page.querySelector("#check"); + JSHandle text = inner.evaluateHandle("e => e.firstChild"); + page.evaluate("() => 1"); // Give them a chance to calculate the preview. + assertEquals("JSHandle@
", outer.toString()); + assertEquals("JSHandle@
Text,↵more text
", inner.toString()); + assertEquals("JSHandle@#text=Text,↵more text", text.toString()); + assertEquals("JSHandle@", check.toString()); + } + + @Test + void getAttributeShouldWork() { + page.navigate(server.PREFIX + "/dom.html"); + ElementHandle handle = page.querySelector("#outer"); + assertEquals("value", handle.getAttribute("name")); + assertNull(handle.getAttribute("foo")); + assertEquals("value", page.getAttribute("#outer", "name")); + assertNull(page.getAttribute("#outer", "foo")); + } + + @Test + void innerHTMLShouldWork() { + page.navigate(server.PREFIX + "/dom.html"); + ElementHandle handle = page.querySelector("#outer"); + assertEquals("
Text,\nmore text
", handle.innerHTML()); + assertEquals("
Text,\nmore text
", page.innerHTML("#outer")); + } + + @Test + void innerTextShouldWork() { + page.navigate(server.PREFIX + "/dom.html"); + ElementHandle handle = page.querySelector("#inner"); + assertEquals("Text, more text", handle.innerText()); + assertEquals("Text, more text", page.innerText("#inner")); + } + + @Test + void innerTextShouldThrow() { + page.setContent("text"); + try { + page.innerText("svg"); + fail("did not throw"); + } catch (PlaywrightException e) { + assertTrue(e.getMessage().contains("Not an HTMLElement")); + } + ElementHandle handle = page.querySelector("svg"); + try { + handle.innerText(); + fail("did not throw"); + } catch (PlaywrightException e) { + assertTrue(e.getMessage().contains("Not an HTMLElement")); + } + } + + @Test + void textContentShouldWork() { + page.navigate(server.PREFIX + "/dom.html"); + ElementHandle handle = page.querySelector("#inner"); + assertEquals("Text,\nmore text", handle.textContent()); + assertEquals("Text,\nmore text", page.textContent("#inner")); + } + + @Test + void textContentShouldBeAtomic() { + String createDummySelector = "{\n" + + " query(root, selector) {\n" + + " const result = root.querySelector(selector);\n" + + " if (result)\n" + + " Promise.resolve().then(() => result.textContent = 'modified');\n" + + " return result;\n" + + " },\n" + + " queryAll(root, selector) {\n" + + " const result = Array.from(root.querySelectorAll(selector));\n" + + " for (const e of result)\n" + + " Promise.resolve().then(() => e.textContent = 'modified');\n" + + " return result;\n" + + " }\n" + + "}\n"; + playwright.selectors().register("textContent", createDummySelector); + page.setContent("
Hello
"); + String tc = page.textContent("textContent=div"); + assertEquals("Hello", tc); + assertEquals("modified", page.evaluate("() => document.querySelector('div').textContent")); + } + + @Test + void innerTextShouldBeAtomic() { + String createDummySelector = "{\n" + + " query(root, selector) {\n" + + " const result = root.querySelector(selector);\n" + + " if (result)\n" + + " Promise.resolve().then(() => result.textContent = 'modified');\n" + + " return result;\n" + + " },\n" + + " queryAll(root, selector) {\n" + + " const result = Array.from(root.querySelectorAll(selector));\n" + + " for (const e of result)\n" + + " Promise.resolve().then(() => e.textContent = 'modified');\n" + + " return result;\n" + + " }\n" + + "}\n"; + playwright.selectors().register("innerText", createDummySelector); + page.setContent("
Hello
"); + String tc = page.innerText("innerText=div"); + assertEquals("Hello", tc); + assertEquals("modified", page.evaluate("() => document.querySelector('div').innerText")); + } + + @Test + void innerHTMLShouldBeAtomic() { + String createDummySelector = "{\n" + + " query(root, selector) {\n" + + " const result = root.querySelector(selector);\n" + + " if (result)\n" + + " Promise.resolve().then(() => result.textContent = 'modified');\n" + + " return result;\n" + + " },\n" + + " queryAll(root, selector) {\n" + + " const result = Array.from(root.querySelectorAll(selector));\n" + + " for (const e of result)\n" + + " Promise.resolve().then(() => e.textContent = 'modified');\n" + + " return result;\n" + + " }\n" + + "}\n"; + playwright.selectors().register("innerHTML", createDummySelector); + page.setContent("
Helloworld
"); + String tc = page.innerHTML("innerHTML=div"); + assertEquals("Helloworld", tc); + assertEquals("modified", page.evaluate("() => document.querySelector('div').innerHTML")); + } + + @Test + void getAttributeShouldBeAtomic() { + String createDummySelector = "{\n" + + " query(root, selector) {\n" + + " const result = root.querySelector(selector);\n" + + " if (result)\n" + + " Promise.resolve().then(() => result.setAttribute('foo', 'modified'));\n" + + " return result;\n" + + " },\n" + + " queryAll(root, selector) {\n" + + " const result = Array.from(root.querySelectorAll(selector));\n" + + " for (const e of result)\n" + + " Promise.resolve().then(() => e.setAttribute('foo', 'modified'));\n" + + " return result;\n" + + " }\n" + + "}\n"; + playwright.selectors().register("getAttribute", createDummySelector); + page.setContent("
"); + String tc = page.getAttribute("getAttribute=div", "foo"); + assertEquals("hello", tc); + assertEquals("modified", page.evaluate("() => document.querySelector('div').getAttribute('foo')")); + } + @Test void isVisibleAndIsHiddenShouldWork() { page.setContent("
Hi
");