@Test
 public void we_can_record_the_lifetime_of_a_test_step() throws InterruptedException {
   TestStep step = new TestStep("a narrative description");
   Thread.sleep(150);
   step.recordDuration();
   assertThat(step.getDuration(), is(greaterThanOrEqualTo(100L)));
 }
  @Test
  public void a_test_result_can_be_defined_for_a_step() throws InterruptedException {
    TestStep step = new TestStep("a narrative description");
    step.setResult(TestResult.SUCCESS);

    assertThat(step.getResult(), is(TestResult.SUCCESS));
  }
  @Test
  public void when_a_step_fails_the_error_message_can_be_recorded() throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.setResult(TestResult.FAILURE);
    step.failedWith(new Exception("Oh nose!"));
    assertThat(step.getErrorMessage(), containsString("Oh nose!"));
  }
 @Test
 public void we_can_display_the_lifetime_of_a_test_step_in_seconds() throws InterruptedException {
   TestStep step = new TestStep("a narrative description");
   Thread.sleep(150);
   step.recordDuration();
   double expectedDuration = step.getDuration() / 1000.0;
   assertThat(step.getDurationInSeconds(), closeTo(expectedDuration, 0.01));
 }
  @Test
  public void when_a_step_fails_the_stack_trace_is_also_recorded() throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.setResult(TestResult.FAILURE);
    Throwable e = new IllegalStateException();
    step.failedWith(new Exception("Oh nose", e));
    assertThat(step.getException().getStackTrace(), is(notNullValue()));
  }
  @Test
  public void the_short_error_message_should_only_include_the_first_line() throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.setResult(TestResult.FAILURE);
    Throwable e = new IllegalStateException("Original error\nwith lots of messy details");
    step.failedWith(new Exception("Oh nose", e));
    assertThat(step.getShortErrorMessage(), is("Original error"));
  }
  @Test
  public void the_short_error_message_should_remove_double_quotes() throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.setResult(TestResult.FAILURE);
    Throwable e = new IllegalStateException("Original error");
    step.failedWith(new Exception("Oh nose", e));
    assertThat(step.getShortErrorMessage(), is("Original error"));
  }
  @Test
  public void a_test_step_with_successful_child_steps_is_successful() throws InterruptedException {
    TestStep step = new TestStep("a narrative description");
    step.addChildStep(successfulTestStepCalled("child step 1"));
    step.addChildStep(successfulTestStepCalled("child step 2"));
    step.addChildStep(successfulTestStepCalled("child step 3"));

    assertThat(step.getResult(), is(TestResult.SUCCESS));
  }
  @Test
  public void when_a_step_fails_with_a_cause_the_original_message_is_used() throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.setResult(TestResult.FAILURE);
    Throwable e = new IllegalStateException("Original error");
    step.failedWith(new Exception("Oh nose", e));
    assertThat(step.getErrorMessage(), containsString("Original error"));
  }
  @Test
  public void if_a_step_fails_the_error_message_should_be_returned_with_the_result() {

    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 1"));
    testOutcome.recordStep(forAFailingTestStepCalled("Step 2", new AssertionError("Oh bother!")));
    testOutcome.recordStep(forASkippedTestStepCalled("Step 3"));

    TestStep failingStep = testOutcome.getTestSteps().get(1);
    assertThat(failingStep.getErrorMessage(), is("Oh bother!"));
  }
 public List<TestStep> getFlattenedTestSteps() {
   List<TestStep> flattenedTestSteps = new ArrayList<TestStep>();
   for (TestStep step : getTestSteps()) {
     flattenedTestSteps.add(step);
     if (step.isAGroup()) {
       flattenedTestSteps.addAll(step.getFlattenedSteps());
     }
   }
   return ImmutableList.copyOf(flattenedTestSteps);
 }
  /**
   * The current step is the last step in the step list, or the last step in the children of the
   * current step group.
   */
  public TestStep getCurrentStep() {
    checkState(!testSteps.isEmpty());

    if (!inGroup()) {
      return lastStepIn(testSteps);
    } else {
      TestStep currentStepGroup = groupStack.peek();
      return lastStepIn(currentStepGroup.getChildren());
    }
  }
  @Test
  public void a_test_step_with_empty_child_steps_is_successful_unless_marked_as_pending()
      throws InterruptedException {
    TestStep step = new TestStep("a narrative description");
    step.addChildStep(new TestStep("child step 1"));
    step.addChildStep(new TestStep("child step 2"));
    step.addChildStep(new TestStep("child step 3"));

    assertThat(step.getResult(), is(TestResult.SUCCESS));
  }
  @Test
  public void the_short_error_message_should_replace_double_quotes_with_single_quotes()
      throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.setResult(TestResult.FAILURE);
    Throwable e = new IllegalStateException("Original \"error\"\nwith lots of messy details");
    step.failedWith(new Exception("Oh nose", e));
    assertThat(step.getShortErrorMessage(), is("Original 'error'"));
  }
 private Integer countLeafStepsIn(List<TestStep> testSteps) {
   int leafCount = 0;
   for (TestStep step : testSteps) {
     if (step.isAGroup()) {
       leafCount += countLeafStepsIn(step.getChildren());
     } else {
       leafCount++;
     }
   }
   return leafCount;
 }
 public List<TestStep> getLeafTestSteps() {
   List<TestStep> leafTestSteps = new ArrayList<TestStep>();
   for (TestStep step : getTestSteps()) {
     if (step.isAGroup()) {
       leafTestSteps.addAll(step.getLeafTestSteps());
     } else {
       leafTestSteps.add(step);
     }
   }
   return ImmutableList.copyOf(leafTestSteps);
 }
  @Test
  public void if_a_screenshot_is_identical_to_the_previous_one_in_the_step_it_wont_be_added()
      throws IOException {
    TestStep step = new TestStep("a narrative description");

    File screenshot = temporaryFolder.newFile("screenshot.png");
    File source = temporaryFolder.newFile("screenshot.html");
    step.addScreenshot(new ScreenshotAndHtmlSource(screenshot, source));
    step.addScreenshot(new ScreenshotAndHtmlSource(screenshot, source));

    assertThat(step.getScreenshots().size(), is(1));
  }
  @Test
  public void a_test_group_with_a_pending_test_is_pending() {

    testOutcome.startGroup("A group");
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 1"));
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 2"));
    testOutcome.recordStep(forAPendingTestStepCalled("Step 3"));
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 4"));
    testOutcome.endGroup();

    TestStep aGroup = testOutcome.getTestSteps().get(0);
    assertThat(aGroup.getResult(), is(TestResult.PENDING));
  }
  @Test
  public void a_test_group_with_only_successful_tests_is_successful() {

    testOutcome.recordStep(forASuccessfulTestStepCalled("A group"));
    testOutcome.startGroup();
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 1"));
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 2"));
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 3"));
    testOutcome.endGroup();

    TestStep aGroup = testOutcome.getTestSteps().get(0);
    assertThat(aGroup.getResult(), is(TestResult.SUCCESS));
  }
  @Test
  public void a_test_group_with_only_ignored_tests_is_ignored() {

    testOutcome.startGroup("A group");
    testOutcome.recordStep(forAnIgnoredTestStepCalled("Step 1"));
    testOutcome.recordStep(forAnIgnoredTestStepCalled("Step 2"));
    testOutcome.recordStep(forAnIgnoredTestStepCalled("Step 3"));
    testOutcome.endGroup();
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 4"));

    TestStep aGroup = testOutcome.getTestSteps().get(0);
    assertThat(aGroup.getResult(), is(TestResult.IGNORED));
  }
  @Test
  public void the_test_step_can_have_an_illustration() throws IOException {
    TestStep step = new TestStep("a narrative description");

    File screenshot = temporaryFolder.newFile("screenshot.png");
    File source = temporaryFolder.newFile("screenshot.html");

    assertThat(step.hasScreenshots(), is(false));

    step.addScreenshot(new ScreenshotAndHtmlSource(screenshot, source));

    assertThat(step.hasScreenshots(), is(true));
    assertThat(step.getScreenshots().get(0).getScreenshot(), is(screenshot));
    assertThat(step.getScreenshots().get(0).getHtmlSource().get(), is(source));
  }
  @Test
  public void a_test_group_with_a_nested_group_containing_a_failure_is_a_failure() {
    testOutcome.startGroup("A group");
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 1"));
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 2"));
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 3"));
    testOutcome.startGroup("Another group");
    testOutcome.recordStep(forASuccessfulTestStepCalled("Step 4"));
    testOutcome.recordStep(forAFailingTestStepCalled("Step 5", new AssertionError("Oh bother!")));
    testOutcome.endGroup();
    testOutcome.endGroup();

    TestStep aGroup = testOutcome.getTestSteps().get(0);
    assertThat(aGroup.getResult(), is(TestResult.FAILURE));
  }
  @Test
  public void the_first_screenshot_can_be_used_to_represent_the_step() throws IOException {
    TestStep step = new TestStep("a narrative description");

    File screenshot = temporaryFolder.newFile("screenshot.png");
    File source = temporaryFolder.newFile("screenshot.html");
    step.addScreenshot(new ScreenshotAndHtmlSource(screenshot, source));

    File screenshot2 = temporaryFolder.newFile("screenshot2.png");
    File source2 = temporaryFolder.newFile("screenshot2.html");
    step.addScreenshot(new ScreenshotAndHtmlSource(screenshot2, source2));

    assertThat(step.getFirstScreenshot().getScreenshot(), is(screenshot));
    assertThat(step.getFirstScreenshot().getHtmlSource().get(), is(source));
  }
 /** Add a test step to this acceptance test. */
 public void recordStep(final TestStep step) {
   checkNotNull(step.getDescription(), "The test step description was not defined.");
   if (inGroup()) {
     getCurrentStepGroup().addChildStep(step);
   } else {
     testSteps.add(step);
   }
 }
  @Test
  public void the_test_step_knows_how_many_illustrations_it_has() throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.addScreenshot(
        forScreenshotWithImage("/screenshots/google_page_1.png")
            .and()
            .withSource("screenshot.html"));
    step.addScreenshot(
        forScreenshotWithImage("/screenshots/google_page_2.png")
            .and()
            .withSource("screenshot2.html"));
    step.addScreenshot(
        forScreenshotWithImage("/screenshots/google_page_3.png")
            .and()
            .withSource("screenshot2.html"));

    assertThat(step.getScreenshotCount(), is(3));
  }
 @XmlTransient
 public TestStep getTestSequence()
     throws IOException, JAXBException, ParserConfigurationException, SAXException, SVNException,
         URISyntaxException {
   //   disabled the support of writing test sequences into project files
   //        if (getSubversionUrl() == null) {
   //            TestStep ts = (TestStep) TestStep.getUnmarshaller().unmarshal(new
   // ByteArrayInputStream(getText().getBytes("UTF-8")));
   //            ts.setCreator(getCreator());
   //            return ts;
   //        }
   return TestStep.unmarshal(getFileRevision(getTestType().getCreator()), true);
 }
  @Test
  public void the_test_step_can_have_more_than_one_illustration() throws IOException {
    TestStep step = new TestStep("a narrative description");

    step.addScreenshot(
        forScreenshotWithImage("/screenshots/google_page_1.png")
            .and()
            .withSource("screenshot.html"));
    step.addScreenshot(
        forScreenshotWithImage("/screenshots/google_page_2.png")
            .and()
            .withSource("screenshot2.html"));

    ScreenshotAndHtmlSource screenshot1 = step.getScreenshots().get(0);
    ScreenshotAndHtmlSource screenshot2 = step.getScreenshots().get(1);

    assertThat(screenshot1.getScreenshot().getName(), is("google_page_1.png"));
    assertThat(screenshot1.getHtmlSource().get().getName(), is("screenshot.html"));

    assertThat(screenshot2.getScreenshot().getName(), is("google_page_2.png"));
    assertThat(screenshot2.getHtmlSource().get().getName(), is("screenshot2.html"));

    assertThat(screenshot1.hashCode(), is(not(screenshot2.hashCode())));
  }
  private void recordTestOutcomeAsSteps(TestOutcome testOutcome, TestOutcome scenarioOutcome) {
    TestStep nestedStep =
        TestStep.forStepCalled(testOutcome.getTitle()).withResult(testOutcome.getResult());
    List<TestStep> testSteps = testOutcome.getTestSteps();

    if (testOutcome.getTestFailureCause() != null) {
      nestedStep.failedWith(testOutcome.getTestFailureCause().toException());
    }

    if (!testSteps.isEmpty()) {
      for (TestStep nextStep : testSteps) {
        nextStep.setDescription(
            normalizeTestStepDescription(
                nextStep.getDescription(), scenarioOutcome.getTestSteps().size() + 1));
        nestedStep.addChildStep(nextStep);
      }
    }
    scenarioOutcome.recordStep(nestedStep);
  }
  public List<Screenshot> getScreenshots() {
    List<Screenshot> screenshots = new ArrayList<Screenshot>();
    List<TestStep> testSteps = getFlattenedTestSteps();

    for (TestStep currentStep : testSteps) {
      if (!currentStep.isAGroup() && currentStep.getScreenshots() != null) {
        for (RecordedScreenshot screenshot : currentStep.getScreenshots()) {
          screenshots.add(
              new Screenshot(
                  screenshot.getScreenshot().getName(),
                  currentStep.getDescription(),
                  widthOf(screenshot.getScreenshot()),
                  currentStep.getException()));
        }
      }
    }
    return ImmutableList.copyOf(screenshots);
  }
 public TestResult convert(final TestStep step) {
   return step.getResult();
 }