package net.thucydides.core.screenshots;
import com.google.common.base.Optional;
import net.thucydides.core.util.EnvironmentVariables;
import net.thucydides.core.util.ExtendedTemporaryFolder;
import net.thucydides.core.util.FileSystemUtils;
import net.thucydides.core.util.MockEnvironmentVariables;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import java.io.File;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.*;
public class WhenScreenshotsAreTaken {
@Rule
public ExtendedTemporaryFolder temporaryDirectory = new ExtendedTemporaryFolder();
private File screenshotDirectory;
private File screenshotTaken;
private File originalScreenshot;
private File expectedResizedScreenshot;
@Mock
private FirefoxDriver driver;
@Mock
private HtmlUnitDriver htmlDriver;
private Photographer photographer;
class MockPhotographer extends Photographer {
public MockPhotographer(final WebDriver driver, final File targetDirectory) {
super(driver, targetDirectory);
}
public MockPhotographer(final WebDriver driver, final File targetDirectory, final BlurLevel blurLevel) {
super(driver, targetDirectory, blurLevel);
}
@Override
protected boolean driverCanTakeSnapshots() {
return (driver != null);
}
@Override
protected File blur(File srcFile) throws IOException {
return srcFile;
}
}
EnvironmentVariables environmentVariables = new MockEnvironmentVariables();
@Before
public void initMocks() throws IOException {
MockitoAnnotations.initMocks(this);
prepareTemporaryFilesAndDirectories();
photographer = new Photographer(driver,
screenshotDirectory);
}
public void prepareTemporaryFilesAndDirectories() throws IOException {
screenshotDirectory = temporaryDirectory.newFolder("screenshots");
originalScreenshot = FileSystemUtils.getResourceAsFile("screenshots/google_page_1.png");
expectedResizedScreenshot = FileSystemUtils.getResourceAsFile("screenshots/resized_google_page_1.png");
screenshotTaken = temporaryDirectory.newFile("google_page_1.png");
FileUtils.copyFile(originalScreenshot, screenshotTaken);
}
@Test
public void the_driver_should_not_take_screenshots_if_the_driver_is_not_available() throws Exception {
Photographer photographer = new MockPhotographer(null, screenshotDirectory);
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
photographer.takeScreenshot();
waitUntilScreenshotsProcessed();
verify(driver,times(0)).getScreenshotAs((OutputType<?>) anyObject());
}
@Test
public void the_driver_should_capture_the_image() throws Exception {
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
photographer.takeScreenshot();
waitUntilScreenshotsProcessed();
verify(driver,times(1)).getScreenshotAs((OutputType<?>) anyObject());
}
@Test
public void should_blur_screenshot_if_requested() throws Exception {
Photographer outOfFocusPhotographer = new Photographer(driver, screenshotDirectory, BlurLevel.HEAVY);
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
Optional<File> blurredScreenshot = outOfFocusPhotographer.takeScreenshot();
waitUntilScreenshotsProcessed();
assertThat(FileUtils.contentEquals(blurredScreenshot.get(), expectedResizedScreenshot), is(false));
}
@Test
public void should_not_blur_screenshot_by_default() throws Exception {
Photographer outOfFocusPhotographer = new Photographer(driver, screenshotDirectory);
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
Optional<File> blurredScreenshot = outOfFocusPhotographer.takeScreenshot();
waitUntilScreenshotsProcessed();
assertThat(FileUtils.contentEquals(blurredScreenshot.get(), expectedResizedScreenshot), is(true));
}
@Test
public void should_not_take_a_snapshot_if_unsupported_by_the_driver() throws Exception {
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
Photographer photographer = new Photographer(htmlDriver, screenshotDirectory);
photographer.takeScreenshot();
waitUntilScreenshotsProcessed();
verify(driver,never()).getScreenshotAs((OutputType<?>) anyObject());
}
@Test
public void the_screenshot_should_be_stored_in_the_target_directory() throws IOException, InterruptedException{
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
String screenshotFile = photographer.takeScreenshot().get().getName();
waitUntilScreenshotsProcessed();
File savedScreenshot = new File(screenshotDirectory, screenshotFile);
savedScreenshot.setReadable(true);
savedScreenshot.setWritable(true);
assertThat(savedScreenshot.isFile(), is(true));
}
private void waitUntilScreenshotsProcessed() throws InterruptedException {
photographer.getScreenshotProcessor().waitUntilDone();
Thread.sleep(50);
}
@Test
public void the_photographer_should_return_the_stored_screenshot_filename() throws IOException, InterruptedException {
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
String savedFileName = photographer.takeScreenshot().get().getName();
waitUntilScreenshotsProcessed();
File savedScreenshot = new File(screenshotDirectory, savedFileName);
assertThat(savedScreenshot.isFile(), is(true));
}
// @Test
// public void the_photographer_should_provide_the_HTML_source_code_for_a_given_screenshot_if_configured() throws Exception {
//
// environmentVariables.setProperty("thucydides.store.html.source","true");
// Photographer photographer = new Photographer(driver, screenshotDirectory,
// Injectors.getInjector().getInstance(ScreenshotProcessor.class),
// null,
// environmentVariables);
//
// when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
// when(driver.getPageSource()).thenReturn("<html/>");
//
// File screenshotFile = photographer.takeScreenshot().get();
// waitUntilScreenshotsProcessed();
//
// File htmlSource = photographer.getMatchingSourceCodeFor(screenshotFile);
//
// assertThat(htmlSource.isFile(), is(true));
// }
@Test
public void calling_api_generates_a_filename_safe_hashed_name_for_the_screenshot() throws Exception {
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
String screenshotFile = photographer.takeScreenshot().get().getName();
waitUntilScreenshotsProcessed();
assertThat(screenshotFile, equalTo("6a0bceeab7f4fe24b6add7e76b1ff833_NONE.png"));
}
@Test
public void by_default_screenshot_files_start_with_Screenshot() throws Exception {
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
String screenshotFile = photographer.takeScreenshot().get().getName();
waitUntilScreenshotsProcessed();
assertThat(screenshotFile, equalTo("6a0bceeab7f4fe24b6add7e76b1ff833_NONE.png"));
}
@Mock
ScreenshotProcessor screenshotProcessor;
@Test
public void should_send_screenshots_to_screenshot_processor() {
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
photographer.setScreenshotProcessor(screenshotProcessor);
photographer.takeScreenshot();
verify(screenshotProcessor).queueScreenshot((QueuedScreenshot) anyObject());
}
@Test
public void should_blur_screenshots_if_blurScreenshots_option_is_present() throws Exception {
Photographer photographer = new MockPhotographer(driver, screenshotDirectory, BlurLevel.HEAVY);
photographer = spy(photographer);
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
photographer.takeScreenshot();
waitUntilScreenshotsProcessed();
verify(photographer, times(1)).blur(any(File.class));
verify(driver,times(1)).getScreenshotAs((OutputType<?>) anyObject());
}
@Test
public void should_not_blur_screenshots_if_blurScreenshots_option_is_absent() throws Exception {
Photographer photographer = new MockPhotographer(driver, screenshotDirectory, null);
photographer = spy(photographer);
when(driver.getScreenshotAs(OutputType.FILE)).thenReturn(screenshotTaken);
photographer.takeScreenshot();
waitUntilScreenshotsProcessed();
verify(photographer, times(0)).blur(any(File.class));
verify(driver,times(1)).getScreenshotAs((OutputType<?>) anyObject());
}
}