package net.thucydides.core.steps;
import net.thucydides.core.Thucydides;
import net.thucydides.core.annotations.*;
import net.thucydides.core.model.TestOutcome;
import net.thucydides.core.pages.Pages;
import net.thucydides.core.util.EnvironmentVariables;
import net.thucydides.core.util.ExtendedTemporaryFolder;
import net.thucydides.core.util.MockEnvironmentVariables;
import org.junit.*;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.verify;
public class WhenUsingTheStepEventBus {
@SuppressWarnings("serial")
static class SimpleTestScenarioSteps extends ScenarioSteps {
@Managed
WebDriver driver;
public SimpleTestScenarioSteps(Pages pages) {
super(pages);
}
@Step
public void assumption_failed() {
Assume.assumeTrue(false);
}
@Step
public void step1() {
getDriver().get("step_one");
}
@Step
public void step2() {
getDriver().get("step_two");
}
@Step
public void step3() {
getDriver().get("step_three");
}
@Step
public void step4() {
step5();
step6();
}
@Step
public void step5() {
getDriver().get("step_five");
}
@Step
public void step6() {
getDriver().get("step_six");
}
@Step
public void step7() {
step1();
failingStep();
step2();
}
@Step
public void step8() {
step1();
failingStep();
step4();
}
@Step
public void step9() {
step1();
pendingStep();
step4();
}
@Step
public void nested_steps() {
step1();
nested_steps1();
step4();
}
@Step
public void nested_steps1() {
step1();
nested_steps2();
step4();
}
@Step
public void nested_steps2() {
step1();
step4();
}
@Step
public void failingStep() {
getDriver().get("failing_step");
assertThat(true, is(false));
}
@Pending
@Step
public void pendingStep() {
}
@Step
public SimpleTestScenarioSteps stepThatReturnsAStep() {
return this;
}
@Step
public SimpleTestScenarioSteps stepThatFailsAndReturnsAStep() {
assertThat(true, is(false));
return this;
}
@StepGroup
public void legacyStepGroup() {
step1();
step2();
step3();
}
}
static class SampleTestScenario {
@Steps
SimpleTestScenarioSteps steps;
public void sampleTest() {
steps.step1();
steps.step2();
steps.step3();
}
public void some_test() {}
}
static class SampleTestScenarioWithFailedAssumption {
@Steps
SimpleTestScenarioSteps steps;
public void sampleTest() {
steps.assumption_failed();
steps.step1();
steps.step2();
steps.step3();
}
public void some_test() {}
}
@Mock
WebDriver driver;
@Mock
StepListener listener;
@Mock
TestOutcome testOutcome;
EnvironmentVariables environmentVariables;
ConsoleStepListener consoleStepListener;
BaseStepListener baseStepListener;
ConsoleLoggingListener consoleLoggingListener;
private StepFactory factory;
Logger logger = LoggerFactory.getLogger(Thucydides.class);
@Rule
public ExtendedTemporaryFolder temp = new ExtendedTemporaryFolder();
@Before
public void initMocks() throws IOException {
MockitoAnnotations.initMocks(this);
environmentVariables = new MockEnvironmentVariables();
environmentVariables.setProperty("thucydides.logging","VERBOSE");
factory = new StepFactory(new Pages(driver));
consoleStepListener = new ConsoleStepListener();
consoleLoggingListener = new ConsoleLoggingListener(environmentVariables);
baseStepListener = new BaseStepListener(temp.newFolder());
StepEventBus.getEventBus().clear();
StepEventBus.getEventBus().registerListener(listener);
StepEventBus.getEventBus().registerListener(consoleStepListener);
StepEventBus.getEventBus().registerListener(consoleLoggingListener);
StepEventBus.getEventBus().registerListener(baseStepListener);
}
@After
public void clearListener() {
StepEventBus.getEventBus().dropAllListeners();
}
@Test
public void should_execute_steps_transparently() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("some_test", SampleTestScenario.class);
steps.step1();
steps.step2();
steps.step3();
StepEventBus.getEventBus().testFinished(testOutcome);
verify(driver).get("step_one");
verify(driver).get("step_two");
verify(driver).get("step_three");
}
@Test
public void the_step_event_bus_can_be_used_to_sent_notification_events_about_steps() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testSuiteStarted(SampleTestScenario.class);
StepEventBus.getEventBus().testStarted("some_test");
StepEventBus.getEventBus().stepStarted(ExecutedStepDescription.withTitle("a step"));
verify(listener).stepStarted(any(ExecutedStepDescription.class));
}
@Test
public void should_notify_listeners_when_a_step_starts() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("some_test", SampleTestScenario.class);
steps.step1();
StepEventBus.getEventBus().testFinished(testOutcome);
ArgumentCaptor<ExecutedStepDescription> argument = ArgumentCaptor.forClass(ExecutedStepDescription.class);
verify(listener).stepStarted(argument.capture());
assertThat(argument.getValue().getName(), is("step1"));
}
@Test
public void should_record_when_a_test_starts_and_finishes() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_notify_listeners_when_the_test_suite_finishes() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testSuiteStarted(SampleTestScenario.class);
StepEventBus.getEventBus().testStarted("some_test", SampleTestScenario.class);
steps.step1();
StepEventBus.getEventBus().testFinished(testOutcome);
StepEventBus.getEventBus().testSuiteFinished();
verify(listener).testSuiteFinished();
}
@Test
public void should_record_nested_test_steps() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step4();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step4\n"
+ "--step5\n"
+ "----> STEP DONE\n"
+ "--step6\n"
+ "----> STEP DONE\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_record_groups_as_nested_test_steps() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.nested_steps();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-nested_steps\n"
+ "--step1\n"
+ "----> STEP DONE\n"
+ "--nested_steps1\n"
+ "---step1\n"
+ "-----> STEP DONE\n"
+ "---nested_steps2\n"
+ "----step1\n"
+ "------> STEP DONE\n"
+ "----step4\n"
+ "-----step5\n"
+ "-------> STEP DONE\n"
+ "-----step6\n"
+ "-------> STEP DONE\n"
+ "------> STEP DONE\n"
+ "-----> STEP DONE\n"
+ "---step4\n"
+ "----step5\n"
+ "------> STEP DONE\n"
+ "----step6\n"
+ "------> STEP DONE\n"
+ "-----> STEP DONE\n"
+ "----> STEP DONE\n"
+ "--step4\n"
+ "---step5\n"
+ "-----> STEP DONE\n"
+ "---step6\n"
+ "-----> STEP DONE\n"
+ "----> STEP DONE\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_record_deeply_nested_test_steps() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.legacyStepGroup();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-legacyStepGroup\n"
+ "--step1\n"
+ "----> STEP DONE\n"
+ "--step2\n"
+ "----> STEP DONE\n"
+ "--step3\n"
+ "----> STEP DONE\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_record_step_failures() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.failingStep();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-failingStep\n"
+ "---> STEP FAILED\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_be_able_to_record_step_failures_after_a_step_ends() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.step2();
StepFailure failure = new StepFailure(ExecutedStepDescription.withTitle("Oops!"), new AssertionError());
StepEventBus.getEventBus().lastStepFailed(failure);
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-step2\n"
+ "---> STEP DONE\n"
+ "--> STEP FAILED\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_record_pending_steps() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.pendingStep();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-pendingStep\n"
+ "--> TEST PENDING\n"
+ "---> STEP PENDING\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_record_nested_step_failures() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.step8();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-step8\n"
+ "--step1\n"
+ "----> STEP DONE\n"
+ "--failingStep\n"
+ "----> STEP FAILED\n"
+ "--step4\n"
+ "---step5\n"
+ "-----> STEP IGNORED\n"
+ "---step6\n"
+ "-----> STEP IGNORED\n"
+ "----> STEP IGNORED\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_record_nested_pending_steps() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.step9();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-step9\n"
+ "--step1\n"
+ "----> STEP DONE\n"
+ "--pendingStep\n"
+ "--> TEST PENDING\n"
+ "----> STEP PENDING\n"
+ "--step4\n"
+ "---step5\n"
+ "-----> STEP IGNORED\n"
+ "---step6\n"
+ "-----> STEP IGNORED\n"
+ "----> STEP IGNORED\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_skip_steps_after_a_step_failure() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.step7();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-step7\n"
+ "--step1\n"
+ "----> STEP DONE\n"
+ "--failingStep\n"
+ "----> STEP FAILED\n"
+ "--step2\n"
+ "----> STEP IGNORED\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_skip_steps_after_a_failed_assumption() {
SampleTestScenarioWithFailedAssumption sampleTest = factory.getStepLibraryFor(SampleTestScenarioWithFailedAssumption.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenarioWithFailedAssumption.class);
sampleTest.sampleTest();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n" +
"-assumption_failed\n" +
"--> TEST IGNORED\n" +
"---> ASSUMPTION VIOLATED\n" +
"-step1\n" +
"---> STEP IGNORED\n" +
"-step2\n" +
"---> STEP IGNORED\n" +
"-step3\n" +
"---> STEP IGNORED\n" +
"TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_skip_nested_steps_after_a_step_failure() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.step7();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-step7\n"
+ "--step1\n"
+ "----> STEP DONE\n"
+ "--failingStep\n"
+ "----> STEP FAILED\n"
+ "--step2\n"
+ "----> STEP IGNORED\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_not_use_the_browser() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.step1();
steps.step7();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-step1\n"
+ "---> STEP DONE\n"
+ "-step7\n"
+ "--step1\n"
+ "----> STEP DONE\n"
+ "--failingStep\n"
+ "----> STEP FAILED\n"
+ "--step2\n"
+ "----> STEP IGNORED\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void a_step_can_return_a_step_object() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.stepThatReturnsAStep().stepThatReturnsAStep().stepThatReturnsAStep();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-stepThatReturnsAStep\n"
+ "---> STEP DONE\n"
+ "-stepThatReturnsAStep\n"
+ "---> STEP DONE\n"
+ "-stepThatReturnsAStep\n"
+ "---> STEP DONE\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void a_step_can_return_a_step_object_if_a_failure_occurs() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
steps.stepThatFailsAndReturnsAStep().stepThatReturnsAStep();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-stepThatFailsAndReturnsAStep\n"
+ "---> STEP FAILED\n"
+ "-stepThatReturnsAStep\n"
+ "---> STEP IGNORED\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void when_an_entier_test_is_pending_all_the_contained_steps_are_skipped() {
SimpleTestScenarioSteps steps = factory.getStepLibraryFor(SimpleTestScenarioSteps.class);
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().testPending();
steps.step1();
steps.step2();
steps.step3();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "--> TEST PENDING\n"
+ "-step1\n"
+ "---> STEP IGNORED\n"
+ "-step2\n"
+ "---> STEP IGNORED\n"
+ "-step3\n"
+ "---> STEP IGNORED\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void a_step_can_be_marked_pending() {
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().stepStarted(ExecutedStepDescription.withTitle("a step"));
StepEventBus.getEventBus().stepPending();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "-a step\n"
+ "--> TEST PENDING\n"
+ "---> STEP PENDING\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void when_an_entier_test_is_ignored_the_test_is_marked_as_ignored() {
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().testIgnored();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "--> TEST IGNORED\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void when_an_entier_test_is_skipped_the_test_is_marked_as_skipped() {
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().testSkipped();
StepEventBus.getEventBus().testFinished(testOutcome);
String expectedSteps =
"TEST a_test\n"
+ "--> TEST SKIPPED\n"
+ "TEST DONE\n";
assertThat(consoleStepListener.toString(), is(expectedSteps));
}
@Test
public void should_clear_all_listeners_when_requested() {
StepEventBus.getEventBus().dropAllListeners();
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().stepStarted(ExecutedStepDescription.withTitle("a step"));
StepEventBus.getEventBus().stepPending();
StepEventBus.getEventBus().testFinished(testOutcome);
assertThat(consoleStepListener.toString(), is(""));
}
@Test
public void shouldIndicateWhenATestIsRunning() {
StepEventBus.getEventBus().dropAllListeners();
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().stepStarted(ExecutedStepDescription.withTitle("a step"));
assertThat(StepEventBus.getEventBus().areStepsRunning(), is(true));
}
@Test
public void shouldIndicateWhenALongerTestIsRunning() {
StepEventBus.getEventBus().dropAllListeners();
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().testPending();
StepEventBus.getEventBus().testStarted("another_test");
StepEventBus.getEventBus().stepStarted(ExecutedStepDescription.withTitle("a step"));
assertThat(StepEventBus.getEventBus().areStepsRunning(), is(true));
}
@Test
public void shouldIndicateWhenATestIsRunningHasNotStarted() {
StepEventBus.getEventBus().dropAllListeners();
assertThat(StepEventBus.getEventBus().areStepsRunning(), is(false));
}
@Test
public void shouldIndicateWhenATestHasFinished() {
StepEventBus.getEventBus().dropAllListeners();
StepEventBus.getEventBus().testStarted("a_test", SampleTestScenario.class);
StepEventBus.getEventBus().stepStarted(ExecutedStepDescription.withTitle("a step"));
StepEventBus.getEventBus().testFinished(testOutcome);
assertThat(StepEventBus.getEventBus().areStepsRunning(), is(false));
}
}