Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
feat(protractor): Photo taking strategies for the Photographer
- Loading branch information
Showing
17 changed files
with
537 additions
and
229 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
import { EventRecorder, expect, givenFollowingEvents, PickEvent } from '@integration/testing-tools'; | ||
import { | ||
Activity, | ||
AssertionError, | ||
ImplementationPendingError, | ||
Interaction, | ||
LogicError, | ||
Task, | ||
} from '@serenity-js/core'; | ||
import { | ||
ArtifactGenerated, | ||
SceneFinished, | ||
SceneStarts, | ||
TaskFinished, | ||
TaskStarts, | ||
TestRunFinished, | ||
} from '@serenity-js/core/lib/events'; | ||
import { FileSystemLocation, Path } from '@serenity-js/core/lib/io'; | ||
import { | ||
ActivityDetails, | ||
Category, | ||
ExecutionCompromised, | ||
ExecutionFailedWithAssertionError, | ||
ExecutionFailedWithError, | ||
ExecutionIgnored, | ||
ExecutionSkipped, | ||
ExecutionSuccessful, | ||
ImplementationPending, | ||
Name, | ||
Outcome, | ||
Photo, | ||
ScenarioDetails, | ||
} from '@serenity-js/core/lib/model'; | ||
import { Stage } from '@serenity-js/core/lib/stage'; | ||
import { given } from 'mocha-testdata'; | ||
import { Photographer, TakePhotosOfFailures } from '../../../src/stage'; | ||
import { create } from './create'; | ||
|
||
describe('Photographer', () => { | ||
|
||
const | ||
defaultCardScenario = new ScenarioDetails( | ||
new Name('Paying with a default card'), | ||
new Category('Online Checkout'), | ||
new FileSystemLocation( | ||
new Path(`payments/checkout.feature`), | ||
), | ||
), | ||
pickACard = new ActivityDetails(new Name('Pick the default credit card')); | ||
|
||
it(`complains when sent DomainEvents before getting assigned to a Stage`, () => { | ||
const photographer = new Photographer(new TakePhotosOfFailures()); | ||
expect(() => photographer.notifyOf(new SceneStarts(defaultCardScenario))) | ||
.to.throw(LogicError, `Photographer needs to be assigned to the Stage before it can be notified of any DomainEvents`); | ||
}); | ||
|
||
describe(`when there's no actor in the spotlight`, () => { | ||
|
||
given( | ||
new ExecutionSkipped(), | ||
new ExecutionIgnored(), | ||
new ExecutionSuccessful(), | ||
). | ||
it(`doesn't take a picture if everything goes well`, (outcome: Outcome) => { | ||
const { stage, recorder } = create(); | ||
|
||
const photographer = new Photographer(new TakePhotosOfFailures(), stage); | ||
stage.manager.register(photographer); | ||
|
||
givenFollowingEvents( | ||
new SceneStarts(defaultCardScenario), | ||
new TaskStarts(pickACard), | ||
new TaskFinished(pickACard, outcome), | ||
new SceneFinished(defaultCardScenario, outcome), | ||
new TestRunFinished(), | ||
).areSentTo(photographer); | ||
|
||
return stage.manager.waitForNextCue().then(() => { | ||
expect(recorder.events).to.have.lengthOf(0); | ||
}); | ||
}); | ||
|
||
given( | ||
{ description: 'compromised', outcome: new ExecutionCompromised(new Error('Database is down')) }, | ||
{ description: 'error', outcome: new ExecutionFailedWithError(new TypeError()) }, | ||
{ description: 'assertion error', outcome: new ExecutionFailedWithAssertionError(new AssertionError(`expected false to equal true`, false, true)) }, | ||
{ description: 'implementation pending', outcome: new ImplementationPending(new ImplementationPendingError('method missing')) }, | ||
). | ||
it(`does nothing, even when a problem occurs`, ({ outcome }) => { | ||
const { stage, recorder } = create(); | ||
|
||
const photographer = new Photographer(new TakePhotosOfFailures(), stage); | ||
stage.manager.register(photographer); | ||
|
||
givenFollowingEvents( | ||
new SceneStarts(defaultCardScenario), | ||
new SceneFinished(defaultCardScenario, outcome), | ||
new TestRunFinished(), | ||
).areSentTo(photographer); | ||
|
||
return stage.manager.waitForNextCue().then(() => { | ||
expect(recorder.events).to.have.lengthOf(0); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { EventRecorder } from '@integration/testing-tools'; | ||
import { Actor, Duration } from '@serenity-js/core'; | ||
import { Clock, Stage, StageManager } from '@serenity-js/core/lib/stage'; | ||
import { protractor } from 'protractor'; | ||
import { BrowseTheWeb } from '../../../src/screenplay/abilities'; | ||
|
||
export function create(timeout: Duration = Duration.ofSeconds(1)) { | ||
const clock = new Clock(); | ||
|
||
const | ||
stageManager = new StageManager(timeout, clock), | ||
actors = { actor: (name: string) => { | ||
return new Actor(name, stageManager, clock) | ||
.whoCan(BrowseTheWeb.using(protractor.browser)); | ||
}}, | ||
stage = new Stage(actors, stageManager), | ||
recorder = new EventRecorder(); | ||
|
||
stage.assign(recorder); | ||
|
||
return { stage, recorder }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Activity, Interaction, Task } from '@serenity-js/core'; | ||
|
||
export class Perform { | ||
static interactionThatSucceeds = (id: number = 1) => | ||
Interaction.where(`#actor succeeds (#${id})`, actor => void 0) | ||
|
||
static interactionThatFailsWith = (errorType: new (message: string) => Error) => | ||
Interaction.where(`#actor fails due to ${ errorType.name }`, actor => { throw new errorType('failure'); }) | ||
|
||
static taskWith = (...activities: Activity[]) => Task.where(`#actor performs activities`, ...activities); | ||
} |
Oops, something went wrong.