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