1 package io.guixer.tools.dom;
2
3 import static com.google.common.base.Preconditions.checkNotNull;
4 import static java.util.Locale.ENGLISH;
5
6 import java.util.List;
7 import java.util.stream.Collectors;
8
9 import javax.annotation.Nullable;
10
11 import org.openqa.selenium.By;
12 import org.openqa.selenium.JavascriptExecutor;
13 import org.openqa.selenium.WebDriver;
14 import org.openqa.selenium.WebElement;
15
16 public class WebDom implements Dom {
17
18 private final WebDriver driver;
19
20 public WebDom(
21 final WebDriver driver
22 ) {
23
24 this.driver = checkNotNull(driver, "driver");
25 }
26
27 @Override
28 @Nullable
29 public DomElement getParentElement(
30 final DomElement element
31 ) {
32
33 checkNotNull(element, "element");
34
35 final JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
36
37 final WebElement parent = (WebElement) jsExecutor.executeScript(
38 "return arguments[0].parentNode",
39 ((WebDomElement) element).webElement);
40
41 return (parent == null) ? null : new WebDomElement(parent);
42 }
43
44 @Override
45 @Nullable
46 public String getHrefFromJs(
47 final DomElement element
48 ) {
49
50 checkNotNull(element, "element");
51
52 final JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
53
54 final Object hrefFromJs = jsExecutor.executeScript(
55 "return arguments[0].attributes['href'].value",
56 ((WebDomElement) element).webElement);
57
58 return (hrefFromJs == null) ? null : hrefFromJs.toString();
59 }
60
61 @Override
62 public List<DomElement> findElements(
63 final By by
64 ) {
65
66 checkNotNull(by, "by");
67
68 return driver.findElements(by).stream()
69 .map(element -> new WebDomElement(element))
70 .collect(Collectors.toList());
71 }
72
73 @Override
74 public int calcPreviousSiblingCount(
75 final DomElement element,
76 final String tagName
77 ) {
78
79 final JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
80
81 final Object count = jsExecutor.executeScript(
82 "var count = 0;"
83 + "for (var previousSibling = arguments[0].previousSibling;"
84 + " previousSibling !== null;"
85 + " previousSibling = previousSibling.previousSibling) {"
86 + " if (previousSibling.tagName === arguments[1]) {"
87 + " ++count;"
88 + " }"
89 + "}"
90 + "return count;",
91 ((WebDomElement) element).webElement,
92 tagName.toUpperCase(ENGLISH));
93
94 return ((Long) count).intValue();
95 }
96 }