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      public WebDriverScreenshotRule(@Nonnull Supplier<? extends WebDriver> driverSupplier, @Nonnull File artifactDir)
48      {
49          this(WebDriverSupport.forSupplier(driverSupplier), artifactDir);
50      }
51  
52      @SuppressWarnings("UnusedDeclaration")
53  	public WebDriverScreenshotRule(@Nonnull Supplier<? extends WebDriver> driverSupplier)
54      {
55          this(driverSupplier, defaultArtifactDir());
56      }
57  
58  	@SuppressWarnings("UnusedDeclaration")
59  	public WebDriverScreenshotRule(@Nonnull WebDriver webDriver)
60      {
61          this(WebDriverSupport.forInstance(webDriver), defaultArtifactDir());
62      }
63  
64      @Inject
65      public WebDriverScreenshotRule(@Nonnull WebDriverDebug webDriverDebug)
66      {
67          this(webDriverDebug, defaultArtifactDir());
68      }
69  
70      public WebDriverScreenshotRule()
71      {
72          this(WebDriverSupport.fromAutoInstall(), defaultArtifactDir());
73      }
74  
75  
76  
77      @Override
78      protected void starting(@Nonnull final Description description)
79      {
80          File dir = getTargetDir(description);
81          if (!dir.exists())
82          {
83              checkState(dir.mkdirs(), "Unable to create screenshot output directory " + dir.getAbsolutePath());
84          }
85      }
86  
87      @Override
88      protected void failed(@Nonnull final Throwable e, @Nonnull final Description description)
89      {
90          final File dumpFile = getTargetFile(description, "html");
91          final File screenShotFile = getTargetFile(description, "png");
92          log.info("----- {} failed. ", description.getDisplayName());
93          log.info("----- At page: " + debug.getCurrentUrl());
94          log.info("----- Dumping page source to {} and screenshot to {}", dumpFile.getAbsolutePath(),
95                  screenShotFile.getAbsolutePath());
96          debug.dumpSourceTo(dumpFile);
97          debug.takeScreenshotTo(screenShotFile);
98      }
99  
100     private File getTargetDir(Description description)
101     {
102         return new File(artifactDir, description.getClassName());
103     }
104 
105     private File getTargetFile(Description description, String extension)
106     {
107 		File file = new File(getTargetDir(description), description.getMethodName() + "." + extension);
108 		int fileNum = 1;
109 		while (file.exists()) {
110 			file = new File(getTargetDir(description), description.getMethodName() + "-" + (fileNum++) + "." + extension);
111 		}
112 		return file;
113     }
114 
115 }