package com.softwaremill.common.test.web.email;
import com.thoughtworks.selenium.CommandProcessor;
import org.mockito.Matchers;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.softwaremill.common.test.web.selenium.screenshots.ScreenshotHttpCommandProcessor;
import com.softwaremill.common.test.web.selenium.screenshots.Screenshotter;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Created by Pawel Stawicki on Mar 19, 2011 10:40:55 AM
*/
public class ScreenshotHttpCommandPRocessorTest {
private static final String VALID_COMMAND = "valid command";
private static final String EXCEPTION_THROWING_COMMAND = "throw exception";
private CommandProcessor parentProcessor;
private ExceptionThrowingScreenshotter exceptionThrowingScreenshotter;
private ScreenshotHttpCommandProcessor processor;
@BeforeTest
private void initializeMocks() {
parentProcessor = mock(CommandProcessor.class);
when(parentProcessor.doCommand(eq(VALID_COMMAND), Matchers.<String[]>any())).thenReturn(null);
when(parentProcessor.doCommand(eq(EXCEPTION_THROWING_COMMAND), Matchers.<String[]>any()))
.thenThrow(new RuntimeException());
exceptionThrowingScreenshotter = new ExceptionThrowingScreenshotter();
processor = new ScreenshotHttpCommandProcessor(parentProcessor, exceptionThrowingScreenshotter);
}
@BeforeMethod
private void resetScreenshots() {
exceptionThrowingScreenshotter.resetScreenshotsCount();
}
@Test(expectedExceptions = RuntimeException.class)
public void shouldNotFallIntoIniniteLoopIfCaptureScreenshotThrowsException() throws Exception {
//when
//Do some command that throws exception. Taking screenshot also throws exception, it should
// not fall into infinite loop.
exceptionThrowingScreenshotter.setExceptionThrowing(true);
processor.doCommand(EXCEPTION_THROWING_COMMAND, null);
}
/*
1. A command that throws exception
2. Try to take screenshot, it also throws exception. Don't fall into infinite loop
3. New command that throws exception
4. Should take screenshot correctly
*/
@Test
public void shouldTakeScreenshotForCommandAfterThrowingExceptionWhileTakingScreenshot() throws Exception {
//when
//Do some command that throws exception. Taking screenshot also throws exception, it should
// not fall into infinite loop. Screenshot not taken.
try {
exceptionThrowingScreenshotter.setExceptionThrowing(true);
processor.doCommand(EXCEPTION_THROWING_COMMAND, null);
Assert.fail("Exception should be thrown");
} catch (RuntimeException e) {
//It's ok. This exception was expected.
}
//then
Assert.assertEquals(exceptionThrowingScreenshotter.screenshotsCount(), 0);
//Now again issue "exceptional" command, but this time screenshot should be captured.
try {
exceptionThrowingScreenshotter.setExceptionThrowing(false);
processor.doCommand(EXCEPTION_THROWING_COMMAND, null);
Assert.fail("Exception should be thrown");
} catch (RuntimeException e) {
//It's ok. This exception was expected.
}
//then
Assert.assertEquals(exceptionThrowingScreenshotter.screenshotsCount(), 1);
}
//Simulate situation where taking screenshot throws exception.
private class ExceptionThrowingScreenshotter implements Screenshotter {
private boolean throwException;
private int screenshots;
@Override
public void doScreenshot() {
if (throwException) {
processor.doCommand(EXCEPTION_THROWING_COMMAND, null);
} else {
screenshots++;
}
}
public void setExceptionThrowing(boolean throwException) {
this.throwException = throwException;
}
public int screenshotsCount() {
return screenshots;
}
public void resetScreenshotsCount() {
screenshots = 0;
}
}
}