From e8d04db1305344d9c56e86d7e28257f41f020a23 Mon Sep 17 00:00:00 2001 From: Simon Stewart Date: Sun, 14 Jul 2019 14:07:19 +0100 Subject: [PATCH] Make our By classes serializable over json --- java/client/src/org/openqa/selenium/By.java | 74 ++++++++++++++++++- .../test/org/openqa/selenium/ByTest.java | 48 +++++++++--- 2 files changed, 111 insertions(+), 11 deletions(-) diff --git a/java/client/src/org/openqa/selenium/By.java b/java/client/src/org/openqa/selenium/By.java index 3814119c20086..9c3b18a71b869 100644 --- a/java/client/src/org/openqa/selenium/By.java +++ b/java/client/src/org/openqa/selenium/By.java @@ -26,7 +26,15 @@ import org.openqa.selenium.internal.FindsByXPath; import java.io.Serializable; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.joining; /** * Mechanism used to locate elements within a document. In order to create your own locating @@ -194,6 +202,13 @@ public WebElement findElement(SearchContext context) { public String toString() { return "By.id: " + id; } + + private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "css selector"); + asJson.put("value", Stream.of(id.split("\\s+")).map(str -> "#" + str).collect(joining(" "))); + return Collections.unmodifiableMap(asJson); + } } public static class ByLinkText extends By implements Serializable { @@ -224,6 +239,13 @@ public WebElement findElement(SearchContext context) { public String toString() { return "By.linkText: " + linkText; } + + private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "link text"); + asJson.put("value", linkText); + return Collections.unmodifiableMap(asJson); + } } public static class ByPartialLinkText extends By implements Serializable { @@ -254,6 +276,13 @@ public WebElement findElement(SearchContext context) { public String toString() { return "By.partialLinkText: " + partialLinkText; } + + private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "partial link text"); + asJson.put("value", partialLinkText); + return Collections.unmodifiableMap(asJson); + } } public static class ByName extends By implements Serializable { @@ -290,6 +319,13 @@ public WebElement findElement(SearchContext context) { public String toString() { return "By.name: " + name; } + + private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "css selector"); + asJson.put("value", String.format("*[name='%s']", name.replace("'", "\\'"))); + return Collections.unmodifiableMap(asJson); + } } public static class ByTagName extends By implements Serializable { @@ -326,6 +362,13 @@ public WebElement findElement(SearchContext context) { public String toString() { return "By.tagName: " + tagName; } + + private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "tag name"); + asJson.put("value", tagName); + return Collections.unmodifiableMap(asJson); + } } public static class ByXPath extends By implements Serializable { @@ -357,6 +400,13 @@ public WebElement findElement(SearchContext context) { public String toString() { return "By.xpath: " + xpathExpression; } + + private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "xpath"); + asJson.put("value", xpathExpression); + return Collections.unmodifiableMap(asJson); + } } public static class ByClassName extends By implements Serializable { @@ -396,7 +446,13 @@ public WebElement findElement(SearchContext context) { * Generate a partial XPath expression that matches an element whose specified attribute * contains the given CSS word. So to match <div class='foo bar'> you would say "//div[" + * containingWord("class", "foo") + "]". - * + * private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "link text"); + asJson.put("value", linkText); + return Collections.unmodifiableMap(asJson); + } + * @param attribute name * @param word name * @return XPath fragment @@ -409,6 +465,15 @@ private String containingWord(String attribute, String word) { public String toString() { return "By.className: " + className; } + + private Map toJson() { + + Map asJson = new HashMap<>(); + asJson.put("using", "css selector"); + asJson.put("value", Stream.of(className.split("\\s+")).map(str -> "." + str).collect(joining(" "))); + return Collections.unmodifiableMap(asJson); + } + } public static class ByCssSelector extends By implements Serializable { @@ -449,5 +514,12 @@ public List findElements(SearchContext context) { public String toString() { return "By.cssSelector: " + cssSelector; } + + private Map toJson() { + Map asJson = new HashMap<>(); + asJson.put("using", "css selector"); + asJson.put("value", cssSelector); + return Collections.unmodifiableMap(asJson); + } } } diff --git a/java/client/test/org/openqa/selenium/ByTest.java b/java/client/test/org/openqa/selenium/ByTest.java index daae17942a668..dda742bae528f 100644 --- a/java/client/test/org/openqa/selenium/ByTest.java +++ b/java/client/test/org/openqa/selenium/ByTest.java @@ -17,6 +17,18 @@ package org.openqa.selenium; +import org.junit.Test; +import org.openqa.selenium.internal.FindsByClassName; +import org.openqa.selenium.internal.FindsById; +import org.openqa.selenium.internal.FindsByLinkText; +import org.openqa.selenium.internal.FindsByName; +import org.openqa.selenium.internal.FindsByTagName; +import org.openqa.selenium.internal.FindsByXPath; +import org.openqa.selenium.json.Json; + +import java.util.List; +import java.util.Map; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -29,16 +41,7 @@ import static org.openqa.selenium.By.ByPartialLinkText; import static org.openqa.selenium.By.ByTagName; import static org.openqa.selenium.By.ByXPath; - -import org.junit.Test; -import org.openqa.selenium.internal.FindsByClassName; -import org.openqa.selenium.internal.FindsById; -import org.openqa.selenium.internal.FindsByLinkText; -import org.openqa.selenium.internal.FindsByName; -import org.openqa.selenium.internal.FindsByTagName; -import org.openqa.selenium.internal.FindsByXPath; - -import java.util.List; +import static org.openqa.selenium.json.Json.MAP_TYPE; public class ByTest { @@ -164,6 +167,31 @@ public List findElements(SearchContext context) { locator.hashCode(); } + @Test + public void ensureClassNameIsSerializedProperly() { + // Although it's not legal, make sure we handle the case where people use spaces. + By by = By.className("one two"); + + Json json = new Json(); + Map blob = json.toType(json.toJson(by), MAP_TYPE); + + assertThat(blob.get("using")).isEqualTo("css selector"); + assertThat(blob.get("value")).isEqualTo(".one .two"); + } + + @Test + public void ensureIdIsSerializedProperly() { + // Although it's not legal, make sure we handle the case where people use spaces. + By by = By.id("one two"); + + Json json = new Json(); + Map blob = json.toType(json.toJson(by), MAP_TYPE); + + assertThat(blob.get("using")).isEqualTo("css selector"); + assertThat(blob.get("value")).isEqualTo("#one #two"); + + } + private interface AllDriver extends FindsById, FindsByLinkText, FindsByName, FindsByXPath, FindsByTagName, FindsByClassName, SearchContext {