1 package com.atlassian.webdriver.rule;
2
3 import com.atlassian.webdriver.testing.rule.WebDriverScreenshotRule;
4 import com.google.common.base.Suppliers;
5 import org.apache.commons.io.FileUtils;
6 import org.junit.Before;
7 import org.junit.Rule;
8 import org.junit.Test;
9 import org.junit.rules.TemporaryFolder;
10 import org.junit.runner.Description;
11 import org.junit.runner.RunWith;
12 import org.junit.runners.model.Statement;
13 import org.mockito.Mock;
14 import org.mockito.runners.MockitoJUnitRunner;
15 import org.openqa.selenium.OutputType;
16 import org.openqa.selenium.TakesScreenshot;
17 import org.openqa.selenium.WebDriver;
18
19 import java.io.File;
20 import java.io.IOException;
21
22 import static com.atlassian.webdriver.matchers.FileMatchers.*;
23 import static org.apache.commons.io.FileUtils.readFileToString;
24 import static org.hamcrest.Matchers.not;
25 import static org.junit.Assert.*;
26 import static org.mockito.Mockito.*;
27
28
29
30
31
32
33 @RunWith(MockitoJUnitRunner.class)
34 public class TestWebDriverScreenshotRule
35 {
36
37 @Mock private Statement mockTest;
38
39 private WebDriver webDriver;
40
41 @Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
42
43 @Before
44 public void initWebDriver()
45 {
46 webDriver = mock(WebDriver.class, withSettings().extraInterfaces(TakesScreenshot.class));
47 }
48
49 @Test
50 public void shouldTakeScreenshotAndPageDump() throws Throwable
51 {
52 final String fakeScreenshotContent = "FAKE SCREENSHOT!";
53 when(asTakingScreenshot().getScreenshotAs(OutputType.FILE)).thenReturn(prepareFakeScreenshot("fake.png", fakeScreenshotContent));
54 when(webDriver.getCurrentUrl()).thenReturn("something");
55 final String pageSource = "<html>some source</html>";
56 when(webDriver.getPageSource()).thenReturn(pageSource);
57 doThrow(new RuntimeException("failed")).when(mockTest).evaluate();
58 final WebDriverScreenshotRule rule = createRule();
59 final Description description = Description.createTestDescription(TestWebDriverScreenshotRule.class, "someTest");
60 new SafeStatementInvoker(rule.apply(mockTest, description)).invokeSafely();
61 assertThat(expectedTargetDir(), isDirectory());
62 assertFilesGeneratedProperly(fakeScreenshotContent, pageSource, "someTest.html", "someTest.png");
63 }
64
65 private File prepareFakeScreenshot(final String fileName, final String data) throws IOException {
66 final File fakeScreenshot = temporaryFolder.newFile(fileName);
67 FileUtils.writeStringToFile(fakeScreenshot, data);
68 return fakeScreenshot;
69 }
70
71 @Test
72 public void shouldNotOverrideScreenshotAndPageDump() throws Throwable {
73 final String[] screenshotContents = {"Fake Screenshot 1", "Fake Screenshot 2", "Fake Screenshot 3"};
74 when(asTakingScreenshot().getScreenshotAs(OutputType.FILE))
75 .thenReturn(prepareFakeScreenshot("fake-1.png", screenshotContents[0]))
76 .thenReturn(prepareFakeScreenshot("fake-2.png", screenshotContents[1]))
77 .thenReturn(prepareFakeScreenshot("fake-3.png", screenshotContents[2]));
78
79 when(webDriver.getCurrentUrl()).thenReturn("something");
80 final String[] sourceConents = {"<html>source 1</html>", "<html>source 2</html>", "<html>source 3</html>"};
81 when(webDriver.getPageSource()).thenReturn(sourceConents[0]).thenReturn(sourceConents[1]).thenReturn(sourceConents[2]);
82
83 doThrow(new RuntimeException("failed")).when(mockTest).evaluate();
84 final WebDriverScreenshotRule rule = createRule();
85 final Description description = Description.createTestDescription(TestWebDriverScreenshotRule.class, "someTest");
86
87
88 final String[] expectedFileNames = {"someTest", "someTest-1", "someTest-2"};
89 for (int i = 0; i < screenshotContents.length; i++) {
90 new SafeStatementInvoker(rule.apply(mockTest, description)).invokeSafely();
91 assertThat(expectedTargetDir(), isDirectory());
92 final String fn = expectedFileNames[i];
93 assertFilesGeneratedProperly(screenshotContents[i], sourceConents[i], fn + ".html", fn + ".png");
94 }
95 }
96
97 private void assertFilesGeneratedProperly(String firstFakeScreenshotContent, String sourceForFirstTest, String htmlFileName,
98 String screenshotFileName) throws IOException {
99 final File firstExpectedHtmlFile = expectedTargetFile(htmlFileName);
100 final File firstExpectedScreenshotfile = expectedTargetFile(screenshotFileName);
101
102 assertThat(firstExpectedHtmlFile, isFile());
103 assertEquals(sourceForFirstTest, readFileToString(firstExpectedHtmlFile));
104 assertThat(firstExpectedScreenshotfile, isFile());
105 assertEquals(firstFakeScreenshotContent, readFileToString(firstExpectedScreenshotfile));
106 }
107
108 @Test
109 public void shouldNotTakeScreenshotIfNotFailed() throws Throwable
110 {
111 when(webDriver.getCurrentUrl()).thenReturn("something");
112 when(webDriver.getPageSource()).thenReturn("<html>some source</html>");
113 final WebDriverScreenshotRule rule = createRule();
114 final Description description = Description.createTestDescription(TestWebDriverScreenshotRule.class, "someTest");
115 new SafeStatementInvoker(rule.apply(mockTest, description)).invokeSafely();
116 verifyZeroInteractions(webDriver);
117 assertThat(expectedTargetDir(), isDirectory());
118 assertThat(expectedTargetFile("someTest.html"), not(exists()));
119 assertThat(expectedTargetFile("someTest.png"), not(exists()));
120 }
121
122 private TakesScreenshot asTakingScreenshot()
123 {
124 return (TakesScreenshot) webDriver;
125 }
126
127 private File expectedTargetDir()
128 {
129 return new File(temporaryFolder.getRoot(), TestWebDriverScreenshotRule.class.getName());
130 }
131
132 private File expectedTargetFile(String name)
133 {
134 return new File(expectedTargetDir(), name);
135 }
136
137 private WebDriverScreenshotRule createRule()
138 {
139 return new WebDriverScreenshotRule(Suppliers.ofInstance(webDriver))
140 .artifactDir(temporaryFolder.getRoot());
141 }
142 }