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
20
21
22
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 }