private boolean shouldRunBeforeOrAfterScenarioSteps(RunContext context) { Configuration configuration = context.configuration(); if (!configuration.storyControls().skipBeforeAndAfterScenarioStepsIfGivenStory()) { return true; } return !context.givenStory(); }
private void resetStoryFailure(RunContext context) { if (context.givenStory()) { // do not reset failure for given stories return; } currentStrategy.set(context.configuration().failureStrategy()); storyFailure.set(null); }
private StoryReporter reporterFor(RunContext context, Story story) { Configuration configuration = context.configuration(); if (context.givenStory()) { return configuration.storyReporter(reporterStoryPath.get()); } else { // store parent story path for reporting reporterStoryPath.set(story.getPath()); return configuration.storyReporter(reporterStoryPath.get()); } }
/** * Runs a Story with the given steps factory, applying the given meta filter, and staring from * given state. * * @param configuration the Configuration used to run story * @param stepsFactory the InjectableStepsFactory used to created the candidate steps methods * @param story the Story to run * @param filter the Filter to apply to the story Meta * @param beforeStories the State before running any of the stories, if not <code>null</code> * @throws Throwable if failures occurred and FailureStrategy dictates it to be re-thrown. */ public void run( Configuration configuration, InjectableStepsFactory stepsFactory, Story story, MetaFilter filter, State beforeStories) throws Throwable { RunContext context = new RunContext(configuration, stepsFactory, story.getPath(), filter); if (beforeStories != null) { context.stateIs(beforeStories); } Map<String, String> storyParameters = new HashMap<String, String>(); run(context, story, storyParameters); }
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); }
private void runGivenStories( GivenStories givenStories, Map<String, String> parameters, RunContext context) throws Throwable { if (givenStories.getPaths().size() > 0) { reporter.get().givenStories(givenStories); for (GivenStory givenStory : givenStories.getStories()) { RunContext childContext = context.childContextFor(givenStory); // run given story, using any parameters provided Story story = storyOfPath(context.configuration(), childContext.path()); if (givenStory.hasAnchorParameters()) { story = storyWithMatchingScenarios(story, givenStory.getAnchorParameters()); } parameters.putAll(givenStory.getParameters()); run(childContext, story, parameters); } } }
/** * 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(); }
/** * Utility method: commit step if the mode is {@link RunMode#SHARP}, rollback in other modes. Used * in migrations and migration-like statements. * * @param ctx context, used to provide run mode * @param connection database connection to commit/rollback * @throws SQLException error committing/rollbacking */ protected void commitStep(RunContext ctx, Connection connection) throws SQLException { // the most important thing: commit switch (ctx.getRunMode()) { case SHARP: connection.commit(); break; default: connection.rollback(); } }
private void runBeforeOrAfterScenarioSteps( RunContext context, Scenario scenario, Meta storyAndScenarioMeta, Stage stage, ScenarioType type) throws InterruptedException { runStepsWhileKeepingState( context, context.collectBeforeOrAfterScenarioSteps(storyAndScenarioMeta, stage, type)); }
private void runScenariosParametrisedByExamples( RunContext context, Scenario scenario, Lifecycle lifecycle, Meta storyAndScenarioMeta) throws Throwable { ExamplesTable table = scenario.getExamplesTable(); reporter.get().beforeExamples(scenario.getSteps(), table); Keywords keywords = context.configuration().keywords(); for (Map<String, String> scenarioParameters : table.getRows()) { Meta parameterMeta = parameterMeta(keywords, scenarioParameters); if (!parameterMeta.isEmpty() && !context.filter.allow(parameterMeta)) { continue; } reporter.get().example(scenarioParameters); if (context.configuration().storyControls().resetStateBeforeScenario()) { context.resetState(); } runBeforeOrAfterScenarioSteps( context, scenario, storyAndScenarioMeta, Stage.BEFORE, ScenarioType.EXAMPLE); runStepWithLifecycle(context, lifecycle, scenarioParameters, scenario, storyAndScenarioMeta); runBeforeOrAfterScenarioSteps( context, scenario, storyAndScenarioMeta, Stage.AFTER, ScenarioType.EXAMPLE); } reporter.get().afterExamples(); }
private void runScenarioSteps( RunContext context, Scenario scenario, Map<String, String> scenarioParameters) throws InterruptedException { boolean restart = true; while (restart) { restart = false; List<Step> steps = context.collectScenarioSteps(scenario, scenarioParameters); try { runStepsWhileKeepingState(context, steps); } catch (RestartingScenarioFailure e) { restart = true; continue; } generatePendingStepMethods(context, steps); } }
private void run(RunContext context, Story story, Map<String, String> storyParameters) throws Throwable { try { runCancellable(context, story, storyParameters); } catch (Throwable e) { if (cancelledStories.containsKey(story)) { reporter.get().storyCancelled(story, cancelledStories.get(story)); reporter.get().afterScenario(); reporter.get().afterStory(context.givenStory); } throw e; } finally { if (!context.givenStory() && reporter.get() instanceof ConcurrentStoryReporter) { ((ConcurrentStoryReporter) reporter.get()).invokeDelayed(); } } }
private void generatePendingStepMethods(RunContext context, List<Step> steps) { List<PendingStep> pendingSteps = new ArrayList<PendingStep>(); for (Step step : steps) { if (step instanceof PendingStep) { pendingSteps.add((PendingStep) step); } } if (!pendingSteps.isEmpty()) { PendingStepMethodGenerator generator = new PendingStepMethodGenerator(context.configuration().keywords()); List<String> methods = new ArrayList<String>(); for (PendingStep pendingStep : pendingSteps) { if (!pendingStep.annotated()) { methods.add(generator.generateMethod(pendingStep)); } } reporter.get().pendingMethods(methods); } }
private void runBeforeOrAfterStorySteps(RunContext context, Story story, Stage stage) throws InterruptedException { runStepsWhileKeepingState(context, context.collectBeforeOrAfterStorySteps(story, stage)); }
public void stateIs(State state) { this.state = state; if (parentContext != null) { parentContext.stateIs(state); } }
private void runCancellable(RunContext context, Story story, Map<String, String> storyParameters) throws Throwable { if (!context.givenStory()) { reporter.set(reporterFor(context, story)); } pendingStepStrategy.set(context.configuration().pendingStepStrategy()); failureStrategy.set(context.configuration().failureStrategy()); resetStoryFailure(context); if (context.dryRun()) { reporter.get().dryRun(); } if (context.configuration().storyControls().resetStateBeforeStory()) { context.resetState(); } // run before story steps, if any reporter.get().beforeStory(story, context.givenStory()); boolean storyAllowed = true; FilteredStory filterContext = context.filter(story); Meta storyMeta = story.getMeta(); if (!filterContext.allowed()) { reporter.get().storyNotAllowed(story, context.metaFilterAsString()); storyAllowed = false; } if (storyAllowed) { reporter.get().narrative(story.getNarrative()); runBeforeOrAfterStorySteps(context, story, Stage.BEFORE); addMetaParameters(storyParameters, storyMeta); runGivenStories(story.getGivenStories(), storyParameters, context); // determine if before and after scenario steps should be run boolean runBeforeAndAfterScenarioSteps = shouldRunBeforeOrAfterScenarioSteps(context); reporter.get().lifecyle(story.getLifecycle()); for (Scenario scenario : story.getScenarios()) { // scenario also inherits meta from story boolean scenarioAllowed = true; if (failureOccurred(context) && context.configuration().storyControls().skipScenariosAfterFailure()) { continue; } reporter.get().beforeScenario(scenario.getTitle()); reporter.get().scenarioMeta(scenario.getMeta()); if (!filterContext.allowed(scenario)) { reporter.get().scenarioNotAllowed(scenario, context.metaFilterAsString()); scenarioAllowed = false; } if (scenarioAllowed) { if (context.configuration().storyControls().resetStateBeforeScenario()) { context.resetState(); } Meta storyAndScenarioMeta = scenario.getMeta().inheritFrom(storyMeta); // run before scenario steps, if allowed if (runBeforeAndAfterScenarioSteps) { runBeforeOrAfterScenarioSteps( context, scenario, storyAndScenarioMeta, Stage.BEFORE, ScenarioType.NORMAL); } if (isParameterisedByExamples(scenario)) { // run parametrised scenarios by examples runScenariosParametrisedByExamples( context, scenario, story.getLifecycle(), storyAndScenarioMeta); } else { // run as plain old scenario runStepWithLifecycle( context, story.getLifecycle(), storyParameters, scenario, storyAndScenarioMeta); } // run after scenario steps, if allowed if (runBeforeAndAfterScenarioSteps) { runBeforeOrAfterScenarioSteps( context, scenario, storyAndScenarioMeta, Stage.AFTER, ScenarioType.NORMAL); } } reporter.get().afterScenario(); } // run after story steps, if any runBeforeOrAfterStorySteps(context, story, Stage.AFTER); } reporter.get().afterStory(context.givenStory()); // handle any failure according to strategy if (!context.givenStory()) { handleStoryFailureByStrategy(); } }
private boolean failureOccurred(RunContext context) { return context.failureOccurred(); }
private void runLifecycleSteps( RunContext context, Lifecycle lifecycle, Stage stage, Meta storyAndScenarioMeta) throws InterruptedException { runStepsWhileKeepingState( context, context.collectLifecycleSteps(lifecycle, storyAndScenarioMeta, stage)); }