View Javadoc

1   package com.atlassian.webdriver.testing.rule;
2   
3   import com.atlassian.webdriver.debug.WebDriverDebug;
4   import com.google.common.base.Supplier;
5   import org.junit.rules.TestWatcher;
6   import org.junit.runner.Description;
7   import org.openqa.selenium.WebDriver;
8   import org.slf4j.Logger;
9   import org.slf4j.LoggerFactory;
10  
11  import javax.annotation.Nonnull;
12  import javax.inject.Inject;
13  import java.io.File;
14  
15  import static com.google.common.base.Preconditions.checkNotNull;
16  import static com.google.common.base.Preconditions.checkState;
17  
18  /**
19   * A rule for taking screen-shots when a WebDriver test fails. It will also dump the html source of the page to
20   * the target/webDriverTests directory.
21   *
22   * @since 2.1
23   */
24  public class WebDriverScreenshotRule extends TestWatcher
25  {
26      private static final Logger log = LoggerFactory.getLogger(WebDriverScreenshotRule.class);
27  
28      private final WebDriverDebug debug;
29      private final File artifactDir;
30  
31      private static File defaultArtifactDir()
32      {
33          return new File("target/webdriverTests");
34      }
35  
36      protected WebDriverScreenshotRule(@Nonnull WebDriverDebug webDriverDebug, @Nonnull File artifactDir)
37      {
38          this.debug = checkNotNull(webDriverDebug, "webDriverDebug");
39          this.artifactDir = checkNotNull(artifactDir, "artifactDir");
40      }
41  
42      protected WebDriverScreenshotRule(@Nonnull WebDriverSupport<? extends WebDriver> support, @Nonnull File artifactDir)
43      {
44          this(new WebDriverDebug(checkNotNull(support, "support").getDriver()), artifactDir);
45      }
46  
47      /**
48       * @deprecated  Will be removed in version 3.0; instead, use one of the other constructors to set the driver,
49       *   then call {@link #artifactDir(File)} 
50       */
51      @Deprecated
52      public WebDriverScreenshotRule(@Nonnull Supplier<? extends WebDriver> driverSupplier, @Nonnull File artifactDir)
53      {
54          this(WebDriverSupport.forSupplier(driverSupplier), artifactDir);
55      }
56  
57      @SuppressWarnings("UnusedDeclaration")
58  	public WebDriverScreenshotRule(@Nonnull Supplier<? extends WebDriver> driverSupplier)
59      {
60          this(driverSupplier, defaultArtifactDir());
61      }
62  
63  	@SuppressWarnings("UnusedDeclaration")
64  	public WebDriverScreenshotRule(@Nonnull WebDriver webDriver)
65      {
66          this(WebDriverSupport.forInstance(webDriver), defaultArtifactDir());
67      }
68  
69      @Inject
70      public WebDriverScreenshotRule(@Nonnull WebDriverDebug webDriverDebug)
71      {
72          this(webDriverDebug, defaultArtifactDir());
73      }
74  
75      public WebDriverScreenshotRule()
76      {
77          this(WebDriverSupport.fromAutoInstall(), defaultArtifactDir());
78      }
79  
80      /**
81       * Returns a copy of this rule, specifying a different artifact directory than the default.
82       * @param artifactDir  the directory in which screenshots should be stored
83       * @return  a new WebDriverScreenshotRule based on the current instance
84       * @since 2.3
85       */
86      public WebDriverScreenshotRule artifactDir(File artifactDir)
87      {
88          return new WebDriverScreenshotRule(this.debug, artifactDir);
89      }
90  
91      @Override
92      protected void starting(@Nonnull final Description description)
93      {
94          File dir = getTargetDir(description);
95          if (!dir.exists())
96          {
97              checkState(dir.mkdirs(), "Unable to create screenshot output directory " + dir.getAbsolutePath());
98          }
99      }
100 
101     @Override
102     protected void failed(@Nonnull final Throwable e, @Nonnull final Description description)
103     {
104         final File dumpFile = getTargetFile(description, "html");
105         final File screenShotFile = getTargetFile(description, "png");
106         log.info("----- {} failed. ", description.getDisplayName());
107         log.info("----- At page: " + debug.getCurrentUrl());
108         log.info("----- Dumping page source to {} and screenshot to {}", dumpFile.getAbsolutePath(),
109                 screenShotFile.getAbsolutePath());
110         debug.dumpSourceTo(dumpFile);
111         debug.takeScreenshotTo(screenShotFile);
112     }
113 
114     private File getTargetDir(Description description)
115     {
116         return new File(artifactDir, description.getClassName());
117     }
118 
119     private File getTargetFile(Description description, String extension)
120     {
121 		File file = new File(getTargetDir(description), description.getMethodName() + "." + extension);
122 		int fileNum = 1;
123 		while (file.exists()) {
124 			file = new File(getTargetDir(description), description.getMethodName() + "-" + (fileNum++) + "." + extension);
125 		}
126 		return file;
127     }
128 
129 }