View Javadoc

1   package com.atlassian.webdriver.visualcomparison;
2   
3   import com.atlassian.selenium.visualcomparison.ScreenElement;
4   import com.atlassian.selenium.visualcomparison.VisualComparableClient;
5   import com.atlassian.selenium.visualcomparison.utils.ScreenResolution;
6   import com.atlassian.webdriver.AtlassianWebDriver;
7   import com.google.common.base.Function;
8   import org.openqa.selenium.By;
9   import org.openqa.selenium.Dimension;
10  import org.openqa.selenium.JavascriptExecutor;
11  import org.openqa.selenium.SearchContext;
12  import org.openqa.selenium.WebDriver;
13  import org.openqa.selenium.WebElement;
14  
15  import java.io.File;
16  import java.util.ArrayList;
17  import java.util.List;
18  
19  /**
20   * @since 2.1
21   */
22  public class WebDriverVisualComparableClient implements VisualComparableClient
23  {
24      private final AtlassianWebDriver driver;
25      private Dimension documentSize;
26      private Dimension viewportSize;
27  
28      public WebDriverVisualComparableClient(final AtlassianWebDriver driver)
29      {
30          this.driver = driver;
31      }
32  
33      public void captureEntirePageScreenshot (String filePath)
34      {
35          driver.takeScreenshotTo(new File(filePath));
36          documentSize = getDimensionsFor("document");
37          viewportSize = getDimensionsFor("window");
38      }
39  
40      private Dimension getDimensionsFor(String selector)
41      {
42          int x = Integer.parseInt(execute("return jQuery(" + selector + ").width();").toString());
43          int y = Integer.parseInt(execute("return jQuery(" + selector + ").height();").toString());
44          return new Dimension(x,y);
45      }
46  
47      public ScreenElement getElementAtPoint(int x, int y)
48      {
49          int deltaY = documentSize.height - viewportSize.height;
50          int scrollY = Math.min(deltaY, y);
51          int relY = y - scrollY; // number between 0 and viewportSize.height
52  
53          int deltaX = documentSize.width - viewportSize.width;
54          int scrollX = Math.min(deltaX, x);
55          int relX = x - scrollX; // number between 0 and viewportSize.width
56  
57          execute(String.format("window.scrollTo(%d,%d)",scrollX,scrollY));
58          WebElement el = driver.findElement(atPointInDom(relX,relY));
59          return new WebDriverScreenElement(el);
60      }
61  
62      private By atPointInDom(int relX, int relY)
63      {
64          final String domSel = String.format("return document.elementFromPoint(%d,%d);",relX,relY);
65          final Object o = driver.executeScript(domSel);
66  
67          if (o instanceof WebElement) {
68              return new By() {
69                  @Override
70                  public List<WebElement> findElements(SearchContext searchContext) {
71                      return new ArrayList<WebElement>() {
72                          {
73                              add((WebElement) o);
74                          }
75                      };
76                  }
77              };
78          }
79  
80          return null;
81      }
82  
83      public void evaluate (String command)
84      {
85          execute(command);
86      }
87  
88      public Object execute (String command, Object... arguments)
89      {
90          return driver.executeScript(command, arguments);
91      }
92  
93      public boolean resizeScreen(ScreenResolution resolution, boolean refresh)
94      {
95          driver.getDriver().manage().window().setSize(new Dimension(resolution.width, resolution.height));
96          viewportSize = getDimensionsFor("window");
97          if (refresh)
98          {
99              refreshAndWait();
100         }
101         return true;
102     }
103 
104     public void refreshAndWait ()
105     {
106         // WebDriver automatically waits, or so the docs say.
107         driver.navigate().refresh();
108     }
109 
110     public boolean waitForJQuery (long waitTimeMillis)
111     {
112         try
113         {
114             driver.waitUntil(new Function<WebDriver, Boolean>() {
115                 public Boolean apply(WebDriver webDriver) {
116                     String jQueryActive = ((JavascriptExecutor)webDriver).executeScript("return (window.jQuery.active)").toString();
117                     return (jQueryActive).equals ("0");
118                 }
119             }, (int)waitTimeMillis);
120             Thread.sleep(400);
121         }
122         catch (InterruptedException e)
123         {
124             return false;
125         }
126         return true;
127     }
128 
129     private class WebDriverScreenElement implements ScreenElement
130     {
131         private final WebElement element;
132 
133         WebDriverScreenElement(WebElement el)
134         {
135             this.element = el;
136         }
137 
138         @Override
139         public String getHtml()
140         {
141             return (String)execute("var d = document.createElement('div'); d.appendChild(arguments[0].cloneNode(true)); return d.innerHTML;", element);
142         }
143     }
144 
145 }