Invoke After Scenario hooks after After Step hooks (#444)

* Invoke After Scenario hooks after After Step hooks

* Update CHANGELOG.md

Co-authored-by: Matt Wynne <matt@cucumber.io>
Этот коммит содержится в:
Viacheslav Poturaev 2021-12-03 01:09:23 +01:00 коммит произвёл GitHub
родитель 82bcce7bdc
коммит b850b44b48
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 22 добавлений и 22 удалений

Просмотреть файл

@ -12,6 +12,7 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
### Fixed ### Fixed
- After Scenario hook is called before After Step ([444](https://github.com/cucumber/godog/pull/444) - [vearutop])
- `check-go-version` in Makefile to run on WSL. ([443](https://github.com/cucumber/godog/pull/443) - [mxygem]) - `check-go-version` in Makefile to run on WSL. ([443](https://github.com/cucumber/godog/pull/443) - [mxygem])
## [v0.12.2] ## [v0.12.2]

Просмотреть файл

@ -72,9 +72,9 @@ Feature: suite events
Scenario: two Scenario: two
Then passing step Then passing step
And failing step
And adding step state to context And adding step state to context
And having correct context And having correct context
And failing step
Scenario Outline: three Scenario Outline: three
Then passing step Then passing step

Просмотреть файл

@ -89,26 +89,24 @@ func (s *suite) runStep(ctx context.Context, pickle *Scenario, step *Step, prevS
} }
} }
defer func() { earlyReturn := prevStepErr != nil || err == ErrUndefined
// run after step handlers
rctx, err = s.runAfterStepHooks(ctx, step, sr.Status, err)
}()
if prevStepErr != nil { if !earlyReturn {
return sr = models.NewStepResult(pickle.Id, step.Id, match)
} }
if err == ErrUndefined { // Run after step handlers.
return rctx, err = s.runAfterStepHooks(ctx, step, sr.Status, err)
}
sr = models.NewStepResult(pickle.Id, step.Id, match)
// Trigger after scenario on failing or last step to attach possible hook error to step. // Trigger after scenario on failing or last step to attach possible hook error to step.
if (err == nil && isLast) || err != nil { if sr.Status != StepSkipped && ((err == nil && isLast) || err != nil) {
rctx, err = s.runAfterScenarioHooks(rctx, pickle, err) rctx, err = s.runAfterScenarioHooks(rctx, pickle, err)
} }
if earlyReturn {
return
}
switch err { switch err {
case nil: case nil:
sr.Status = models.Passed sr.Status = models.Passed

Просмотреть файл

@ -423,12 +423,12 @@ func (tc *godogFeaturesScenario) iAmListeningToSuiteEvents() error {
scenarioContext.Before(func(ctx context.Context, pickle *Scenario) (context.Context, error) { scenarioContext.Before(func(ctx context.Context, pickle *Scenario) (context.Context, error) {
tc.events = append(tc.events, &firedEvent{"BeforeScenario", []interface{}{pickle}}) tc.events = append(tc.events, &firedEvent{"BeforeScenario", []interface{}{pickle}})
return context.WithValue(ctx, ctxKey("BeforeScenario"), true), nil return context.WithValue(ctx, ctxKey("BeforeScenario"), pickle.Name), nil
}) })
scenarioContext.Before(func(ctx context.Context, sc *Scenario) (context.Context, error) { scenarioContext.Before(func(ctx context.Context, sc *Scenario) (context.Context, error) {
if sc.Name == "failing before and after scenario" || sc.Name == "failing before scenario" { if sc.Name == "failing before and after scenario" || sc.Name == "failing before scenario" {
return context.WithValue(ctx, ctxKey("AfterStep"), true), errors.New("failed in before scenario hook") return context.WithValue(ctx, ctxKey("AfterStep"), sc.Name), errors.New("failed in before scenario hook")
} }
return ctx, nil return ctx, nil
@ -453,7 +453,7 @@ func (tc *godogFeaturesScenario) iAmListeningToSuiteEvents() error {
return ctx, errors.New("missing AfterStep in context") return ctx, errors.New("missing AfterStep in context")
} }
return context.WithValue(ctx, ctxKey("AfterScenario"), true), nil return context.WithValue(ctx, ctxKey("AfterScenario"), pickle.Name), nil
}) })
scenarioContext.StepContext().Before(func(ctx context.Context, step *Step) (context.Context, error) { scenarioContext.StepContext().Before(func(ctx context.Context, step *Step) (context.Context, error) {
@ -463,7 +463,7 @@ func (tc *godogFeaturesScenario) iAmListeningToSuiteEvents() error {
return ctx, errors.New("missing BeforeScenario in context") return ctx, errors.New("missing BeforeScenario in context")
} }
return context.WithValue(ctx, ctxKey("BeforeStep"), true), nil return context.WithValue(ctx, ctxKey("BeforeStep"), step.Text), nil
}) })
scenarioContext.StepContext().After(func(ctx context.Context, step *Step, status StepResultStatus, err error) (context.Context, error) { scenarioContext.StepContext().After(func(ctx context.Context, step *Step, status StepResultStatus, err error) (context.Context, error) {
@ -473,6 +473,10 @@ func (tc *godogFeaturesScenario) iAmListeningToSuiteEvents() error {
return ctx, errors.New("missing BeforeScenario in context") return ctx, errors.New("missing BeforeScenario in context")
} }
if ctx.Value(ctxKey("AfterScenario")) != nil && status != models.Skipped {
panic("unexpected premature AfterScenario during AfterStep: " + ctx.Value(ctxKey("AfterScenario")).(string))
}
if ctx.Value(ctxKey("BeforeStep")) == nil { if ctx.Value(ctxKey("BeforeStep")) == nil {
return ctx, errors.New("missing BeforeStep in context") return ctx, errors.New("missing BeforeStep in context")
} }
@ -485,7 +489,7 @@ func (tc *godogFeaturesScenario) iAmListeningToSuiteEvents() error {
return ctx, errors.New("missing Step in context") return ctx, errors.New("missing Step in context")
} }
return context.WithValue(ctx, ctxKey("AfterStep"), true), nil return context.WithValue(ctx, ctxKey("AfterStep"), step.Text), nil
}) })
return nil return nil
@ -699,10 +703,7 @@ func (tc *godogFeaturesScenario) theRenderOutputWillBe(docstring *DocString) err
actualTrimmed := actual actualTrimmed := actual
actual = trimAllLines(actual) actual = trimAllLines(actual)
expectedRows := strings.Split(expected, "\n") return assertExpectedAndActual(assert.Equal, expected, actual, actualTrimmed)
actualRows := strings.Split(actual, "\n")
return assertExpectedAndActual(assert.ElementsMatch, expectedRows, actualRows, actualTrimmed)
} }
func (tc *godogFeaturesScenario) theRenderXMLWillBe(docstring *DocString) error { func (tc *godogFeaturesScenario) theRenderXMLWillBe(docstring *DocString) error {