/** * Run steps before or after a collection of stories. Steps are execute only <b>once</b> per * collection of stories. * * @param configuration the Configuration used to find the steps to run * @param candidateSteps the List of CandidateSteps containing the candidate steps methods * @param stage the Stage * @return The State after running the steps */ public State runBeforeOrAfterStories( Configuration configuration, List<CandidateSteps> candidateSteps, Stage stage) { String storyPath = capitalizeFirstLetter(stage.name().toLowerCase()) + "Stories"; reporter.set(configuration.storyReporter(storyPath)); reporter.get().beforeStory(new Story(storyPath), false); RunContext context = new RunContext(configuration, candidateSteps, storyPath, MetaFilter.EMPTY); if (stage == Stage.BEFORE) { resetStoryFailure(context); } if (stage == Stage.AFTER && storiesState.get() != null) { context.stateIs(storiesState.get()); } try { runStepsWhileKeepingState( context, configuration .stepCollector() .collectBeforeOrAfterStoriesSteps(context.candidateSteps(), stage)); } catch (InterruptedException e) { throw new UUIDExceptionWrapper(e); } reporter.get().afterStory(false); storiesState.set(context.state()); // if we are running with multiple threads, call delayed // methods, otherwise we will forget to close files on BeforeStories if (stage == Stage.BEFORE) { if (reporter.get() instanceof ConcurrentStoryReporter) { ((ConcurrentStoryReporter) reporter.get()).invokeDelayed(); } } // handle any after stories failure according to strategy if (stage == Stage.AFTER) { try { handleStoryFailureByStrategy(); } catch (Throwable e) { return new SomethingHappened(storyFailure.get()); } finally { if (reporter.get() instanceof ConcurrentStoryReporter) { ((ConcurrentStoryReporter) reporter.get()).invokeDelayed(); } } } return context.state(); }
private void runStepsWhileKeepingState(RunContext context, List<Step> steps) throws InterruptedException { if (steps == null || steps.size() == 0) { return; } State state = context.state(); for (Step step : steps) { try { context.interruptIfCancelled(); state = state.run(step); } catch (RestartingScenarioFailure e) { reporter.get().restarted(step.toString(), e); throw e; } } context.stateIs(state); }