View Javadoc

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   * Test case for {@link com.atlassian.webdriver.testing.rule.WebDriverScreenshotRule}.
30   *
31   * @since 2.1
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  		// test three failures in row
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()); // should still create the directory
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 }