@serenity-js/playwright-test 3.0.0-rc.37 → 3.0.0-rc.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/lib/api/PlaywrightTestConfig.d.ts +41 -0
  3. package/lib/api/PlaywrightTestConfig.d.ts.map +1 -0
  4. package/lib/{PlaywrightTestConfig.js → api/PlaywrightTestConfig.js} +0 -0
  5. package/lib/api/PlaywrightTestConfig.js.map +1 -0
  6. package/lib/api/SerenityFixtures.d.ts +128 -0
  7. package/lib/api/SerenityFixtures.d.ts.map +1 -0
  8. package/lib/api/SerenityFixtures.js +3 -0
  9. package/lib/api/SerenityFixtures.js.map +1 -0
  10. package/lib/api/SerenityOptions.d.ts +256 -0
  11. package/lib/api/SerenityOptions.d.ts.map +1 -0
  12. package/lib/api/SerenityOptions.js +3 -0
  13. package/lib/api/SerenityOptions.js.map +1 -0
  14. package/lib/api/SerenityTestType.d.ts +5 -0
  15. package/lib/api/SerenityTestType.d.ts.map +1 -0
  16. package/lib/api/SerenityTestType.js +4 -0
  17. package/lib/api/SerenityTestType.js.map +1 -0
  18. package/lib/api/index.d.ts +6 -0
  19. package/lib/api/index.d.ts.map +1 -0
  20. package/lib/api/index.js +22 -0
  21. package/lib/api/index.js.map +1 -0
  22. package/lib/api/test-api.d.ts +115 -0
  23. package/lib/api/test-api.d.ts.map +1 -0
  24. package/lib/api/test-api.js +229 -0
  25. package/lib/api/test-api.js.map +1 -0
  26. package/lib/index.d.ts +1 -2
  27. package/lib/index.d.ts.map +1 -1
  28. package/lib/index.js +0 -1
  29. package/lib/index.js.map +1 -1
  30. package/lib/reporter/PlaywrightStepReporter.d.ts +3 -0
  31. package/lib/reporter/PlaywrightStepReporter.d.ts.map +1 -1
  32. package/lib/reporter/PlaywrightStepReporter.js +57 -13
  33. package/lib/reporter/PlaywrightStepReporter.js.map +1 -1
  34. package/lib/reporter/SerenityReporterForPlaywrightTest.d.ts +22 -9
  35. package/lib/reporter/SerenityReporterForPlaywrightTest.d.ts.map +1 -1
  36. package/lib/reporter/SerenityReporterForPlaywrightTest.js +4 -8
  37. package/lib/reporter/SerenityReporterForPlaywrightTest.js.map +1 -1
  38. package/package.json +7 -8
  39. package/src/api/PlaywrightTestConfig.ts +42 -0
  40. package/src/api/SerenityFixtures.ts +130 -0
  41. package/src/api/SerenityOptions.ts +261 -0
  42. package/src/api/SerenityTestType.ts +12 -0
  43. package/src/api/index.ts +5 -0
  44. package/src/api/test-api.ts +252 -0
  45. package/src/index.ts +1 -2
  46. package/src/reporter/PlaywrightStepReporter.ts +95 -22
  47. package/src/reporter/SerenityReporterForPlaywrightTest.ts +23 -10
  48. package/lib/PlaywrightTestConfig.d.ts +0 -8
  49. package/lib/PlaywrightTestConfig.d.ts.map +0 -1
  50. package/lib/PlaywrightTestConfig.js.map +0 -1
  51. package/lib/api.d.ts +0 -25
  52. package/lib/api.d.ts.map +0 -1
  53. package/lib/api.js +0 -97
  54. package/lib/api.js.map +0 -1
  55. package/src/PlaywrightTestConfig.ts +0 -6
  56. package/src/api.ts +0 -121
@@ -0,0 +1,252 @@
1
+ import { test as base, TestInfo } from '@playwright/test';
2
+ import { Cast, Duration, serenity as serenityInstance, TakeNotes } from '@serenity-js/core';
3
+ import { SceneFinishes, SceneTagged } from '@serenity-js/core/lib/events';
4
+ import { BrowserTag, PlatformTag } from '@serenity-js/core/lib/model';
5
+ import { BrowseTheWebWithPlaywright, PlaywrightPage } from '@serenity-js/playwright';
6
+ import { Photographer, TakePhotosOfFailures } from '@serenity-js/web';
7
+ import * as os from 'os';
8
+ import { ensure, isFunction, JSONValue, property } from 'tiny-types';
9
+
10
+ import { DomainEventBuffer, PlaywrightStepReporter, SERENITY_JS_DOMAIN_EVENTS_ATTACHMENT_CONTENT_TYPE } from '../reporter';
11
+ import { SerenityFixtures } from './SerenityFixtures';
12
+ import { SerenityOptions } from './SerenityOptions';
13
+ import { SerenityTestType } from './SerenityTestType';
14
+
15
+ /**
16
+ * Declares a single test scenario.
17
+ *
18
+ * ## Example
19
+ *
20
+ * ```typescript
21
+ * import { Ensure, equals } from '@serenity-js/assertions'
22
+ * import { describe, it } from '@serenity-js/playwright-test'
23
+ *
24
+ * describe(`Todo List App`, () => {
25
+ *
26
+ * it(`should allow me to add a todo item`, async ({ actor }) => {
27
+ * await actor.attemptsTo(
28
+ * startWithAnEmptyList(),
29
+ *
30
+ * recordItem('Buy some milk'),
31
+ *
32
+ * Ensure.that(itemNames(), equals([
33
+ * 'Buy some milk',
34
+ * ])),
35
+ * )
36
+ * })
37
+ *
38
+ * it('supports multiple actors using separate browsers', async ({ actorCalled }) => {
39
+ * await actorCalled('Alice').attemptsTo(
40
+ * startWithAListContaining(
41
+ * 'Feed the cat'
42
+ * ),
43
+ * )
44
+ *
45
+ * await actorCalled('Bob').attemptsTo(
46
+ * startWithAListContaining(
47
+ * 'Walk the dog'
48
+ * ),
49
+ * )
50
+ *
51
+ * await actorCalled('Alice').attemptsTo(
52
+ * Ensure.that(itemNames(), equals([
53
+ * 'Feed the cat'
54
+ * ])),
55
+ * )
56
+ *
57
+ * await actorCalled('Bob').attemptsTo(
58
+ * Ensure.that(itemNames(), equals([
59
+ * 'Walk the dog'
60
+ * ])),
61
+ * )
62
+ * })
63
+ * })
64
+ * ```
65
+ *
66
+ * ## Learn more
67
+ * - {@apilink describe|Grouping test scenarios}
68
+ * - {@apilink SerenityFixtures}
69
+ * - [Playwright Test `test` function](https://playwright.dev/docs/api/class-test#test-call)
70
+ * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/)
71
+ */
72
+ export const it: SerenityTestType = base.extend<Omit<SerenityOptions, 'actors'> & SerenityFixtures>({
73
+
74
+ actors: [
75
+ ({ browser, contextOptions }, use) =>
76
+ use(Cast.whereEveryoneCan(
77
+ BrowseTheWebWithPlaywright.using(browser, contextOptions),
78
+ TakeNotes.usingAnEmptyNotepad(),
79
+ )),
80
+ { option: true },
81
+ ],
82
+
83
+ defaultActorName: [
84
+ 'Serena',
85
+ { option: true },
86
+ ],
87
+
88
+ cueTimeout: [
89
+ Duration.ofSeconds(5),
90
+ { option: true },
91
+ ],
92
+
93
+ crew: [
94
+ [
95
+ Photographer.whoWill(TakePhotosOfFailures)
96
+ ],
97
+ { option: true },
98
+ ],
99
+
100
+ // eslint-disable-next-line no-empty-pattern
101
+ platform: ({}, use) => {
102
+ const platform = os.platform();
103
+
104
+ // https://nodejs.org/api/process.html#process_process_platform
105
+ const name = platform === 'win32'
106
+ ? 'Windows'
107
+ : (platform === 'darwin' ? 'macOS' : 'Linux');
108
+
109
+ use({ name, version: os.release() });
110
+ },
111
+
112
+ serenity: async ({ crew, cueTimeout, platform }, use, info: TestInfo) => {
113
+
114
+ const domainEventBuffer = new DomainEventBuffer();
115
+
116
+ serenityInstance.configure({
117
+ cueTimeout: asDuration(cueTimeout),
118
+ crew: [
119
+ ...crew,
120
+ domainEventBuffer,
121
+ new PlaywrightStepReporter(info),
122
+ ],
123
+ });
124
+
125
+ serenityInstance.announce(new SceneTagged(
126
+ serenityInstance.currentSceneId(),
127
+ new PlatformTag(platform.name, platform.version),
128
+ serenityInstance.currentTime(),
129
+ ));
130
+
131
+ await use(serenityInstance);
132
+
133
+ const serialisedEvents: Array<{ type: string, value: JSONValue }> = [];
134
+
135
+ for (const event of domainEventBuffer.flush()) {
136
+ serialisedEvents.push({
137
+ type: event.constructor.name,
138
+ value: event.toJSON(),
139
+ });
140
+
141
+ if (event instanceof SceneTagged) {
142
+ test.info().annotations.push({ type: event.tag.type, description: event.tag.name });
143
+ }
144
+ }
145
+
146
+ base.info().attach('serenity-js-events.json', {
147
+ contentType: SERENITY_JS_DOMAIN_EVENTS_ATTACHMENT_CONTENT_TYPE,
148
+ body: Buffer.from(JSON.stringify(serialisedEvents), 'utf8'),
149
+ });
150
+ },
151
+
152
+ actorCalled: async ({ serenity, actors, browser, browserName, contextOptions }, use) => {
153
+
154
+ const sceneId = serenity.currentSceneId();
155
+
156
+ serenity.engage(asCast(actors));
157
+
158
+ const actorCalled = serenity.theActorCalled.bind(serenity);
159
+
160
+ serenity.announce(new SceneTagged(
161
+ sceneId,
162
+ new BrowserTag(browserName, browser.version()),
163
+ serenity.currentTime(),
164
+ ));
165
+
166
+ await use(actorCalled);
167
+
168
+ serenity.announce(
169
+ new SceneFinishes(sceneId, serenity.currentTime()),
170
+ );
171
+
172
+ await serenityInstance.waitForNextCue();
173
+ },
174
+
175
+ actor: async ({ actorCalled, defaultActorName }, use) => {
176
+ await use(actorCalled(defaultActorName));
177
+ },
178
+
179
+ page: async ({ actor }, use) => {
180
+ const page = (await BrowseTheWebWithPlaywright.as(actor).currentPage()) as PlaywrightPage;
181
+ const nativePage = await page.nativePage();
182
+
183
+ await use(nativePage);
184
+ },
185
+ });
186
+
187
+ function asDuration(maybeDuration: number | Duration): Duration {
188
+ return maybeDuration instanceof Duration
189
+ ? maybeDuration
190
+ : Duration.ofMilliseconds(maybeDuration);
191
+ }
192
+
193
+ function asCast(maybeCast: unknown): Cast {
194
+ return ensure('actors', maybeCast as Cast, property('prepare', isFunction()));
195
+ }
196
+
197
+ export const test: SerenityTestType = it;
198
+
199
+ /**
200
+ * Declares a group of test scenarios.
201
+ *
202
+ * ## Example
203
+ *
204
+ * ```typescript
205
+ * import { Ensure, equals } from '@serenity-js/assertions'
206
+ * import { describe, it, test } from '@serenity-js/playwright-test'
207
+ * import { Photographer, TakePhotosOfFailures, Value } from '@serenity-js/web'
208
+ *
209
+ * describe(`Todo List App`, () => {
210
+ *
211
+ * test.use({
212
+ * defaultActorName: 'Serena',
213
+ * crew: [
214
+ * Photographer.whoWill(TakePhotosOfFailures),
215
+ * ],
216
+ * })
217
+ *
218
+ * it(`should allow me to add a todo item`, async ({ actor }) => {
219
+ * await actor.attemptsTo(
220
+ * startWithAnEmptyList(),
221
+ *
222
+ * recordItem('Buy some milk'),
223
+ *
224
+ * Ensure.that(itemNames(), equals([
225
+ * 'Buy some milk',
226
+ * ])),
227
+ * )
228
+ * })
229
+ *
230
+ * it('should clear text input field when an item is added', async ({ actor }) => {
231
+ * await actor.attemptsTo(
232
+ * startWithAnEmptyList(),
233
+ *
234
+ * recordItem('Buy some milk'),
235
+ *
236
+ * Ensure.that(Value.of(newTodoInput()), equals('')),
237
+ * )
238
+ * })
239
+ * })
240
+ * ```
241
+ *
242
+ * ## Learn more
243
+ * - Declaring a Serenity/JS {@apilink it|test scenario}
244
+ * - [Playwright Test `describe` function](https://playwright.dev/docs/api/class-test#test-describe-1)
245
+ * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/)
246
+ */
247
+ export const describe: SerenityTestType['describe'] = it.describe;
248
+ export const beforeAll: SerenityTestType['beforeAll'] = it.beforeAll;
249
+ export const beforeEach: SerenityTestType['beforeEach'] = it.beforeEach;
250
+ export const afterEach: SerenityTestType['afterEach'] = it.afterEach;
251
+ export const afterAll: SerenityTestType['afterAll'] = it.afterAll;
252
+ export const expect: SerenityTestType['expect'] = it.expect;
package/src/index.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  export * from './api';
2
- export * from './PlaywrightTestConfig';
3
- export { SerenityReporterForPlaywrightTest as default } from './reporter';
2
+ export { SerenityReporterForPlaywrightTest as default, SerenityReporterForPlaywrightTestConfig } from './reporter';
@@ -1,7 +1,24 @@
1
1
  import { TestError, TestInfo } from '@playwright/test';
2
2
  import { Stage, StageCrewMember } from '@serenity-js/core';
3
- import { DomainEvent, InteractionFinished, InteractionStarts, TaskFinished, TaskStarts } from '@serenity-js/core/lib/events';
4
- import { ActivityDetails, ProblemIndication } from '@serenity-js/core/lib/model';
3
+ import {
4
+ ActivityFinished,
5
+ ActivityRelatedArtifactGenerated,
6
+ AsyncOperationAborted,
7
+ AsyncOperationAttempted,
8
+ AsyncOperationCompleted,
9
+ AsyncOperationFailed,
10
+ DomainEvent,
11
+ InteractionStarts,
12
+ SceneTagged,
13
+ TaskStarts,
14
+ } from '@serenity-js/core/lib/events';
15
+ import { FileSystemLocation, Path } from '@serenity-js/core/lib/io';
16
+ import { ActivityDetails, CorrelationId, Description, Name, Photo, ProblemIndication } from '@serenity-js/core/lib/model';
17
+ import { BrowserTag, PlatformTag } from '@serenity-js/core/src/model';
18
+ import { Photographer } from '@serenity-js/web';
19
+ import { match } from 'tiny-types';
20
+
21
+ const genericPathToPhotographer = Path.from(require.resolve('@serenity-js/web'))
5
22
 
6
23
  // https://github.com/microsoft/playwright/blob/04f77f231981780704a3a5e2cea93e3c420809a0/packages/playwright-test/types/testReporter.d.ts#L524
7
24
  interface Location {
@@ -9,12 +26,12 @@ interface Location {
9
26
  * Path to the source file.
10
27
  */
11
28
  file: string;
12
-
29
+
13
30
  /**
14
31
  * Line number in the source file.
15
32
  */
16
33
  line: number;
17
-
34
+
18
35
  /**
19
36
  * Column number in the source file.
20
37
  */
@@ -24,6 +41,7 @@ interface Location {
24
41
  // https://github.com/microsoft/playwright/blob/04f77f231981780704a3a5e2cea93e3c420809a0/packages/playwright-test/src/types.ts#L30
25
42
  interface TestStepInternal {
26
43
  complete(result: { error?: Error | TestError }): void;
44
+
27
45
  title: string;
28
46
  category: string;
29
47
  canHaveChildren: boolean;
@@ -50,25 +68,80 @@ export class PlaywrightStepReporter implements StageCrewMember {
50
68
 
51
69
  notifyOf(event: DomainEvent): void {
52
70
 
53
- if (event instanceof TaskStarts) {
54
- this.steps.set(event.activityId.value, this.createStep(event.details, 'task'));
55
- }
56
-
57
- if (event instanceof InteractionStarts) {
58
- this.steps.set(event.activityId.value, this.createStep(event.details, 'interaction'));
59
- }
60
-
61
- if (event instanceof InteractionFinished || event instanceof TaskFinished) {
62
- if (event.outcome instanceof ProblemIndication) {
63
- this.steps.get(event.activityId.value).complete({ error: event.outcome.error })
64
- }
65
- else {
66
- this.steps.get(event.activityId.value).complete({})
67
- }
68
- }
71
+ match<DomainEvent, void>(event)
72
+ .when(TaskStarts, (e: TaskStarts) => {
73
+ this.steps.set(e.activityId.value, this.createStep(e.details, 'task'))
74
+ })
75
+ .when(InteractionStarts, (e: InteractionStarts) => {
76
+ this.steps.set(e.activityId.value, this.createStep(e.details, 'interaction'));
77
+ })
78
+ .when(AsyncOperationAttempted, (e: AsyncOperationAttempted) => {
79
+ if (this.isAPhotoAttempt(e)) {
80
+ this.steps.set(e.correlationId.value, this.createStep(new ActivityDetails(
81
+ new Name(`${ Photographer.name }: ${ e.description.value }`),
82
+ new FileSystemLocation(genericPathToPhotographer)
83
+ ), 'crew'));
84
+ }
85
+ })
86
+ .when(ActivityFinished, (e: ActivityFinished) => {
87
+ const error = e.outcome instanceof ProblemIndication
88
+ ? e.outcome.error
89
+ : undefined;
90
+
91
+ this.steps.get(e.activityId.value).complete({ error });
92
+ })
93
+ .when(ActivityRelatedArtifactGenerated, (e: ActivityRelatedArtifactGenerated) => {
94
+ if (e.artifact instanceof Photo) {
95
+ this.attachPhotoFrom(e);
96
+ }
97
+ })
98
+ .when(SceneTagged, (e: SceneTagged) => {
99
+ // don't include platform and browser tags as Playwright already includes them
100
+ if (! (e.tag instanceof PlatformTag || e.tag instanceof BrowserTag)) {
101
+ this.testInfo.annotations.push({ type: e.tag.type, description: e.tag.name });
102
+ }
103
+ })
104
+ .else(e => {
105
+ if (this.indicatesCompletionOfAnAsyncOperation(e) && this.steps.has(e.correlationId.value)) {
106
+ const error = event instanceof AsyncOperationFailed
107
+ ? event.error
108
+ : undefined;
109
+
110
+ this.steps.get(e.correlationId.value).complete({ error })
111
+ }
112
+ })
113
+ }
114
+
115
+ private isAPhotoAttempt(event: AsyncOperationAttempted): event is AsyncOperationAttempted {
116
+ return event.name.value.startsWith(Photographer.name);
117
+ }
118
+
119
+ private indicatesCompletionOfAnAsyncOperation(event: DomainEvent): event is AsyncOperationCompleted | AsyncOperationAborted | AsyncOperationFailed {
120
+ return event instanceof AsyncOperationCompleted
121
+ || event instanceof AsyncOperationAborted
122
+ || event instanceof AsyncOperationFailed
123
+ }
124
+
125
+ private attachPhotoFrom(event: ActivityRelatedArtifactGenerated) {
126
+ const id = CorrelationId.create();
127
+
128
+ this.stage.announce(new AsyncOperationAttempted(
129
+ new Name(this.constructor.name),
130
+ new Description(`Attaching screenshot of '${ event.name.value }'...`),
131
+ id,
132
+ this.stage.currentTime(),
133
+ ));
134
+
135
+ this.testInfo.attach(event.name.value, { body: Buffer.from(event.artifact.base64EncodedValue, 'base64'), contentType: 'image/png' })
136
+ .then(() => {
137
+ this.stage.announce(new AsyncOperationCompleted(
138
+ id,
139
+ this.stage.currentTime()
140
+ ));
141
+ });
69
142
  }
70
143
 
71
- private createStep(activityDetails: ActivityDetails, type: 'task' | 'interaction'): TestStepInternal {
144
+ private createStep(activityDetails: ActivityDetails, type: 'task' | 'interaction' | 'crew'): TestStepInternal {
72
145
  // https://github.com/microsoft/playwright/blob/04f77f231981780704a3a5e2cea93e3c420809a0/packages/playwright-test/src/expect.ts#L200-L206
73
146
  return (this.testInfo as any)._addStep({
74
147
  location: activityDetails.location
@@ -77,7 +150,7 @@ export class PlaywrightStepReporter implements StageCrewMember {
77
150
  category: `serenity-js:${ type }`,
78
151
  title: activityDetails.name.value,
79
152
  canHaveChildren: true,
80
- forceNoParent: false
153
+ forceNoParent: false,
81
154
  }) as TestStepInternal;
82
155
  }
83
156
  }
@@ -1,6 +1,6 @@
1
- import { FullConfig, TestError } from '@playwright/test';
2
- import { Reporter, Suite, TestCase, TestResult } from '@playwright/test/reporter';
3
- import { LogicError, Serenity, serenity as reporterSerenityInstance, StageCrewMember, StageCrewMemberBuilder, Timestamp } from '@serenity-js/core';
1
+ import type { FullConfig, TestError } from '@playwright/test';
2
+ import type { Reporter, Suite, TestCase, TestResult } from '@playwright/test/reporter';
3
+ import { ClassDescription, LogicError, Serenity, serenity as reporterSerenityInstance, StageCrewMember, StageCrewMemberBuilder, Timestamp } from '@serenity-js/core';
4
4
  import { OutputStream } from '@serenity-js/core/lib/adapter';
5
5
  import * as events from '@serenity-js/core/lib/events';
6
6
  import {
@@ -34,25 +34,39 @@ import {
34
34
 
35
35
  import { SERENITY_JS_DOMAIN_EVENTS_ATTACHMENT_CONTENT_TYPE } from './PlaywrightAttachments';
36
36
 
37
- // TODO Split SerenityConfig into ActorsConfig and SerenityReportingConfig
38
- export class SerenityReporterForPlaywrightTestConfig {
37
+ /**
38
+ * Configuration object accepted by `@serenity-js/playwright-test` reporter.
39
+ *
40
+ * See {@apilink SerenityOptions} for usage examples.
41
+ */
42
+ export interface SerenityReporterForPlaywrightTestConfig {
43
+
39
44
  /**
40
45
  * A list of {@apilink StageCrewMemberBuilder|StageCrewMemberBuilders} or {@apilink StageCrewMember|StageCrewMembers}
41
- * to be notified of {@apilink DomainEvent|DomainEvents} that occur during the scenario execution.
46
+ * to be instantiated in Playwright Test reporter process and notified of {@apilink DomainEvent|DomainEvents} that occur during the scenario execution.
47
+ * Note that the `crew` can also be configured using {@apilink ClassDescription|ClassDescriptions}.
48
+ *
49
+ * #### Learn more
50
+ * - {@apilink SerenityOptions}
51
+ * - {@apilink SerenityConfig.crew}
42
52
  */
43
- crew?: Array<StageCrewMember | StageCrewMemberBuilder>;
53
+ crew?: Array<StageCrewMember | StageCrewMemberBuilder | ClassDescription>;
44
54
 
45
55
  /**
46
56
  * An output stream to be injected into {@apilink StageCrewMemberBuilder|StageCrewMemberBuilders}
47
57
  *
48
58
  * Defaults to [`process.stdout`](https://nodejs.org/api/process.html#process_process_stdout).
59
+ *
60
+ * #### Learn more
61
+ * - {@apilink SerenityConfig.outputStream}
49
62
  */
50
63
  outputStream?: OutputStream;
51
64
  }
52
65
 
53
66
  /**
54
- * Receives notifications from Playwright Test and translates them to Serenity/JS
55
- * {@apilink DomainEvent|domain events}, so that they can be used with Serenity/JS reporters.
67
+ * Serenity/JS reporter that receives notifications from Playwright Test and emits them as
68
+ * Serenity/JS {@apilink DomainEvent|domain events} which can be used by
69
+ * Serenity/JS {@apilink StageCrewMember|stage crew members}.
56
70
  */
57
71
  export class SerenityReporterForPlaywrightTest implements Reporter {
58
72
 
@@ -60,7 +74,6 @@ export class SerenityReporterForPlaywrightTest implements Reporter {
60
74
  private sceneIds: Map<string, CorrelationId> = new Map();
61
75
 
62
76
  /**
63
- *
64
77
  * @param config
65
78
  * @param serenity
66
79
  * Instance of {@apilink Serenity}, specific to the Node process running this Serenity reporter.
@@ -1,8 +0,0 @@
1
- import type { PlaywrightTestConfig as BasePlaywrightTestConfig } from '@playwright/test';
2
- import { ClassDescription } from '@serenity-js/core';
3
- export type PlaywrightTestConfig<BaseConfig extends BasePlaywrightTestConfig = BasePlaywrightTestConfig> = Omit<BaseConfig, 'use' | 'reporter'> & {
4
- use?: BaseConfig['use'] & {
5
- crew: Array<ClassDescription>;
6
- };
7
- };
8
- //# sourceMappingURL=PlaywrightTestConfig.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlaywrightTestConfig.d.ts","sourceRoot":"","sources":["../src/PlaywrightTestConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,IAAI,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,oBAAoB,CAAC,UAAU,SAAS,wBAAwB,GAAG,wBAAwB,IAAI,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,UAAU,CAAC,GAAG;IAC9I,GAAG,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,GAAG;QAAE,IAAI,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAA;KAAE,CAAA;CAC9D,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"PlaywrightTestConfig.js","sourceRoot":"","sources":["../src/PlaywrightTestConfig.ts"],"names":[],"mappings":""}
package/lib/api.d.ts DELETED
@@ -1,25 +0,0 @@
1
- import { PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, TestType } from '@playwright/test';
2
- import { Actor, Cast, Duration, Serenity, SerenityConfig, StageCrewMember } from '@serenity-js/core';
3
- export interface SerenityFixtures extends SerenityConfig {
4
- actors: Cast;
5
- crew: StageCrewMember[];
6
- cueTimeout: Duration;
7
- serenity: Serenity;
8
- platform: {
9
- name: string;
10
- version: string;
11
- };
12
- actorCalled: (name: string) => Actor;
13
- defaultActorName: string;
14
- actor: Actor;
15
- }
16
- export type SerenityTestType = TestType<PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
17
- export declare const it: SerenityTestType;
18
- export declare const test: SerenityTestType;
19
- export declare const describe: SerenityTestType['describe'];
20
- export declare const beforeAll: SerenityTestType['beforeAll'];
21
- export declare const beforeEach: SerenityTestType['beforeEach'];
22
- export declare const afterEach: SerenityTestType['afterEach'];
23
- export declare const afterAll: SerenityTestType['afterAll'];
24
- export declare const expect: SerenityTestType['expect'];
25
- //# sourceMappingURL=api.d.ts.map
package/lib/api.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,uBAAuB,EAA0B,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC9J,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAgC,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASnI,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACpD,MAAM,EAAE,IAAI,CAAC;IACb,IAAI,EAAE,eAAe,EAAE,CAAC;IACxB,UAAU,EAAE,QAAQ,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,CAAC;IACrC,gBAAgB,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,KAAK,CAAC;CAChB;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,kBAAkB,GAAG,qBAAqB,GAAG,gBAAgB,EAAE,oBAAoB,GAAG,uBAAuB,CAAC,CAAC;AAEvJ,eAAO,MAAM,EAAE,EAAE,gBAyFf,CAAC;AAEH,eAAO,MAAM,IAAI,EAAE,gBAAqB,CAAC;AACzC,eAAO,MAAM,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAe,CAAC;AAClE,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAgB,CAAC;AACrE,eAAO,MAAM,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAiB,CAAC;AACxE,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAgB,CAAC;AACrE,eAAO,MAAM,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAe,CAAC;AAClE,eAAO,MAAM,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAa,CAAC"}
package/lib/api.js DELETED
@@ -1,97 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.expect = exports.afterAll = exports.afterEach = exports.beforeEach = exports.beforeAll = exports.describe = exports.test = exports.it = void 0;
27
- const test_1 = require("@playwright/test");
28
- const core_1 = require("@serenity-js/core");
29
- const events_1 = require("@serenity-js/core/lib/events");
30
- const model_1 = require("@serenity-js/core/lib/model");
31
- const playwright_1 = require("@serenity-js/playwright");
32
- const os = __importStar(require("os"));
33
- const reporter_1 = require("./reporter");
34
- exports.it = test_1.test.extend({
35
- cueTimeout: core_1.Duration.ofSeconds(5),
36
- crew: [],
37
- // eslint-disable-next-line no-empty-pattern
38
- platform: ({}, use) => {
39
- const platform = os.platform();
40
- // https://nodejs.org/api/process.html#process_process_platform
41
- const name = platform === 'win32'
42
- ? 'Windows'
43
- : (platform === 'darwin' ? 'macOS' : 'Linux');
44
- use({ name, version: os.release() });
45
- },
46
- serenity: async ({ crew, cueTimeout, platform }, use, info) => {
47
- const domainEventBuffer = new reporter_1.DomainEventBuffer();
48
- core_1.serenity.configure({
49
- cueTimeout: cueTimeout,
50
- crew: [
51
- ...crew,
52
- domainEventBuffer,
53
- new reporter_1.PlaywrightStepReporter(info),
54
- ],
55
- });
56
- core_1.serenity.announce(new events_1.SceneTagged(core_1.serenity.currentSceneId(), new model_1.PlatformTag(platform.name, platform.version), core_1.serenity.currentTime()));
57
- await use(core_1.serenity);
58
- const serialisedEvents = [];
59
- for (const event of domainEventBuffer.flush()) {
60
- serialisedEvents.push({
61
- type: event.constructor.name,
62
- value: event.toJSON(),
63
- });
64
- if (event instanceof events_1.SceneTagged) {
65
- exports.test.info().annotations.push({ type: event.tag.type, description: event.tag.name });
66
- }
67
- }
68
- test_1.test.info().attach('serenity-js-events.json', {
69
- contentType: reporter_1.SERENITY_JS_DOMAIN_EVENTS_ATTACHMENT_CONTENT_TYPE,
70
- body: Buffer.from(JSON.stringify(serialisedEvents), 'utf8'),
71
- });
72
- },
73
- actors: async ({ browser }, use) => {
74
- await use(core_1.Cast.whereEveryoneCan(playwright_1.BrowseTheWebWithPlaywright.using(browser)));
75
- },
76
- defaultActorName: 'Serena',
77
- actor: async ({ actorCalled, defaultActorName }, use) => {
78
- await use(actorCalled(defaultActorName));
79
- },
80
- actorCalled: async ({ serenity, actors, browser, browserName }, use) => {
81
- serenity.engage(actors);
82
- const sceneId = serenity.currentSceneId();
83
- const actorCalled = serenity.theActorCalled.bind(serenity);
84
- serenity.announce(new events_1.SceneTagged(sceneId, new model_1.BrowserTag(browserName, browser.version()), serenity.currentTime()));
85
- await use(actorCalled);
86
- serenity.announce(new events_1.SceneFinishes(sceneId, serenity.currentTime()));
87
- await core_1.serenity.waitForNextCue();
88
- },
89
- });
90
- exports.test = exports.it;
91
- exports.describe = exports.it.describe;
92
- exports.beforeAll = exports.it.beforeAll;
93
- exports.beforeEach = exports.it.beforeEach;
94
- exports.afterEach = exports.it.afterEach;
95
- exports.afterAll = exports.it.afterAll;
96
- exports.expect = exports.it.expect;
97
- //# sourceMappingURL=api.js.map
package/lib/api.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
@@ -1,6 +0,0 @@
1
- import type { PlaywrightTestConfig as BasePlaywrightTestConfig } from '@playwright/test';
2
- import { ClassDescription } from '@serenity-js/core';
3
-
4
- export type PlaywrightTestConfig<BaseConfig extends BasePlaywrightTestConfig = BasePlaywrightTestConfig> = Omit<BaseConfig, 'use' | 'reporter'> & {
5
- use?: BaseConfig['use'] & { crew: Array<ClassDescription> }
6
- };