@serenity-js/playwright-test 3.0.0-rc.38 → 3.0.0-rc.40

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 (54) 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.js → api/test-api.js} +43 -16
  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 +55 -12
  33. package/lib/reporter/PlaywrightStepReporter.js.map +1 -1
  34. package/lib/reporter/SerenityReporterForPlaywrightTest.d.ts +20 -7
  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 +6 -5
  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.ts → api/test-api.ts} +63 -128
  45. package/src/index.ts +1 -2
  46. package/src/reporter/PlaywrightStepReporter.ts +90 -18
  47. package/src/reporter/SerenityReporterForPlaywrightTest.ts +21 -8
  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 -213
  52. package/lib/api.d.ts.map +0 -1
  53. package/lib/api.js.map +0 -1
  54. package/src/PlaywrightTestConfig.ts +0 -6
@@ -0,0 +1,130 @@
1
+ import { Actor, Cast, Serenity } from '@serenity-js/core';
2
+
3
+ /**
4
+ * Serenity/JS-specific [Playwright Test fixtures](https://playwright.dev/docs/test-fixtures)
5
+ * injected into your {@apilink it|test scenarios}.
6
+ *
7
+ * ## Example test scenario
8
+ *
9
+ * ```typescript
10
+ * import { Ensure, equals } from '@serenity-js/assertions'
11
+ * import { describe, it, test } from '@serenity-js/playwright-test'
12
+ * import { Photographer, TakePhotosOfFailures } from '@serenity-js/web'
13
+ *
14
+ * describe(`Recording items`, () => {
15
+ *
16
+ * test.use({
17
+ * defaultActorName: 'Serena',
18
+ * crew: [
19
+ * Photographer.whoWill(TakePhotosOfFailures),
20
+ * ],
21
+ * })
22
+ *
23
+ * describe(`Todo List App`, () => {
24
+ *
25
+ * it(`should allow me to add a todo item`, async ({ actor }) => {
26
+ * await actor.attemptsTo(
27
+ * startWithAnEmptyList(),
28
+ *
29
+ * recordItem('Buy some milk'),
30
+ *
31
+ * Ensure.that(itemNames(), equals([
32
+ * 'Buy some milk',
33
+ * ])),
34
+ * )
35
+ * })
36
+ * })
37
+ * })
38
+ * ```
39
+ *
40
+ * ## Learn more
41
+ * - Declaring a Serenity/JS {@apilink it|test scenario}
42
+ * - {@apilink describe|Grouping test scenarios}
43
+ * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/)
44
+ */
45
+ export interface SerenityFixtures {
46
+
47
+ /**
48
+ * Retrieves the root object of the Serenity/JS framework.
49
+ */
50
+ serenity: Serenity;
51
+
52
+ /**
53
+ * Name and version of the operating system that Playwright Test worker process runs on.
54
+ */
55
+ platform: { name: string, version: string };
56
+
57
+ /**
58
+ * A cast of Serenity/JS actors to be used instead of the default cast
59
+ * when instantiating {@apilink SerenityFixtures.actor|actor}
60
+ * and invoking {@apilink SerenityFixtures.actorCalled|actorCalled}.
61
+ *
62
+ * #### Overriding the default cast of Serenity/JS actors
63
+ *
64
+ * ```typescript
65
+ * import { Cast, TakeNotes } from '@serenity-js/core'
66
+ * import { Ensure, equals } from '@serenity-js/assertions'
67
+ * import { BrowseTheWebWithPlaywright } from '@serenity-js/playwright'
68
+ * import { describe, it, test } from '@serenity-js/playwright-test'
69
+ *
70
+ * describe(`Recording items`, () => {
71
+ *
72
+ * test.use({
73
+ * defaultActorName: 'Serena',
74
+ * actors: ({ browser, contextOptions }, use) => {
75
+ * const cast = Cast.whereEveryoneCan(
76
+ * BrowseTheWebWithPlaywright.using(browser, contextOptions),
77
+ * TakeNotes.usingAnEmptyNotepad(),
78
+ * )
79
+ *
80
+ * // Make sure to pass your custom cast to Playwright `use` callback
81
+ * use(cast)
82
+ * },
83
+ * })
84
+ *
85
+ * describe(`Todo List App`, () => {
86
+ *
87
+ * it(`should allow me to add a todo item`, async ({ actor }) => {
88
+ * await actor.attemptsTo(
89
+ * startWithAnEmptyList(),
90
+ *
91
+ * recordItem('Buy some milk'),
92
+ *
93
+ * Ensure.that(itemNames(), equals([
94
+ * 'Buy some milk',
95
+ * ])),
96
+ * )
97
+ * })
98
+ * })
99
+ * })
100
+ * ```
101
+ */
102
+ actors: Cast;
103
+
104
+ /**
105
+ * Uses the provided {@apilink Cast} of {@apilink SerenityFixtures.actors|actors} to instantiate an {@apilink Actor} called `name`
106
+ * and inject it into a {@apilink it|test scenario}.
107
+ *
108
+ * Retrieves an existing actor if one has already been instantiated.
109
+ *
110
+ * #### Learn more
111
+ * - Declaring a Serenity/JS {@apilink it|test scenario}
112
+ * - {@apilink SerenityOptions.actors}
113
+ * - {@apilink SerenityFixtures.actors}
114
+ *
115
+ * @param name
116
+ */
117
+ actorCalled: (name: string) => Actor;
118
+
119
+ /**
120
+ * Default {@apilink SerenityFixtures.actor|actor} injected into a {@apilink it|test scenario}.
121
+ *
122
+ * Using `actor` fixture is equivalent to invoking {@apilink SerenityFixtures.actorCalled|actorCalled} with {@apilink SerenityOptions.defaultActorName|defaultActorName}.
123
+ *
124
+ * #### Learn more
125
+ * - {@apilink SerenityFixtures.actorCalled|actorCalled}
126
+ * - {@apilink SerenityOptions.defaultActorName}
127
+ * - Declaring a Serenity/JS {@apilink it|test scenario}
128
+ */
129
+ actor: Actor;
130
+ }
@@ -0,0 +1,261 @@
1
+ import { PlaywrightTestOptions, PlaywrightWorkerArgs, TestFixture } from '@playwright/test';
2
+ import { Cast, ClassDescription, Duration, StageCrewMember, StageCrewMemberBuilder } from '@serenity-js/core';
3
+ import { PlaywrightOptions } from '@serenity-js/playwright';
4
+
5
+ /**
6
+ * Configuration object accepted by `@serenity-js/playwright-test`.
7
+ *
8
+ * ## Example
9
+ *
10
+ * ```typescript
11
+ * // playwright.config.ts
12
+ * import type { Cast, TakeNotes } from '@serenity-js/core'
13
+ * import type { BrowseTheWebWithPlaywright } from '@serenity-js/playwright'
14
+ * import type { PlaywrightTestConfig } from '@serenity-js/playwright-test'
15
+ * import type { CallAnApi } from '@serenity-js/rest'
16
+ *
17
+ * // Define any custom configuration options, if needed
18
+ * interface MyCustomOptions {
19
+ * apiUrl: string;
20
+ * }
21
+ *
22
+ * const config: PlaywrightTestConfig<MyCustomOptions> = {
23
+ *
24
+ * // Register Serenity/JS reporter for Playwright Test
25
+ * // to enable integration with Serenity/JS stage crew members
26
+ * // and have them instantiated in the Playwright reporter process
27
+ * reporter: [
28
+ * [ '@serenity-js/playwright-test', {
29
+ * // Stage crew members instantiated in the test reporter process
30
+ * crew: [
31
+ * '@serenity-js/serenity-bdd',
32
+ * '@serenity-js/console-reporter',
33
+ * [ '@serenity-js/core:ArtifactArchiver', { outputDirectory: 'target/site/serenity' } ],
34
+ * ]
35
+ * }]
36
+ * ],
37
+ *
38
+ * use: {
39
+ *
40
+ * // Register Serenity/JS stage crew members
41
+ * // and have them instantiated in Playwright Test worker processes
42
+ * crew: [
43
+ * [ '@serenity-js/web:Photographer', { strategy: 'TakePhotosOfFailures' } ]
44
+ * ],
45
+ *
46
+ * // Register a custom cast of Serenity/JS actors
47
+ * // if you don't want to use the default one
48
+ * actors: ({ browser, contextOptions, apiUrl }, use) => {
49
+ * const cast = Cast.whereEveryoneCan(
50
+ * BrowseTheWebWithPlaywright.using(browser, contextOptions),
51
+ * TakeNotes.usingAnEmptyNotepad(),
52
+ * CallAnApi.at(apiUrl),
53
+ * )
54
+ *
55
+ * use(cast)
56
+ * },
57
+ *
58
+ * // Name to be given to an actor injected via `actor` fixture
59
+ * defaultActorName: 'Alice',
60
+ *
61
+ * // Any custom options, as per the MyCustomOptions interface
62
+ * apiUrl: 'https://api.serenity-js.org/v1'
63
+ *
64
+ * // Any other Playwright options
65
+ * baseURL: 'https://todo-app.serenity-js.org/',
66
+ * video: 'on-first-retry',
67
+ * trace: 'on-first-retry',
68
+ * },
69
+ * }
70
+ *
71
+ * export default config
72
+ * ```
73
+ *
74
+ * ## Learn more
75
+ * - {@apilink PlaywrightTestConfig}
76
+ * - {@apilink Cast}
77
+ * - {@apilink SerenityFixtures}
78
+ */
79
+ export interface SerenityOptions {
80
+
81
+ /**
82
+ * Configures the {@apilink Cast} of {@apilink SerenityConfig.actors|actors} to be used when injecting an {@apilink SerenityFixtures.actor|actor}
83
+ * or invoking {@apilink SerenityFixtures.actorCalled|actorCalled} in a {@apilink it|test scenario}.
84
+ *
85
+ * :::info Did you know?
86
+ * When you use `@serenity-js/playwright-test` {@apilink it|test APIs}, Serenity/JS already provides a default cast of actors for you.
87
+ * Each one of the default actors receives {@apilink Ability|abilities} to {@apilink BrowseTheWebWithPlaywright} and {@apilink TakeNotes.usingAnEmptyNotepad}.
88
+ *
89
+ * The default abilities should be sufficient in most web testing scenarios. However, you might want to override this default configuration
90
+ * when you need your actors to {@apilink CallAnApi|interact with REST APIs}, {@apilink ManageALocalServer|manage local servers},
91
+ * start with a notepad that has some {@apilink TakeNotes.using|initial state}, or receive {@apilink Ability|custom abilities}.
92
+ * :::
93
+ *
94
+ * #### Using a custom crew of Serenity/JS actors
95
+ *
96
+ * ```typescript
97
+ * // playwright.config.ts
98
+ * import type { PlaywrightTestConfig } from '@serenity-js/playwright-test'
99
+ * import { Cast, TakeNotes } from '@serenity-js/core'
100
+ * import { BrowseTheWebWithPlaywright } from '@serenity-js/playwright'
101
+ * import { CallAnApi } from '@serenity-js/rest'
102
+ *
103
+ * // Define any custom configuration options, if needed
104
+ * interface MyCustomOptions {
105
+ * apiUrl: string;
106
+ * }
107
+ *
108
+ * // Parameterise PlaywrightTestConfig with MyCustomOptions
109
+ * // to enable type checking of any custom properties
110
+ * const config: PlaywrightTestConfig<MyCustomOptions> = {
111
+ * use: {
112
+ * contextOptions: {
113
+ * defaultNavigationTimeout: 30_000,
114
+ * },
115
+ *
116
+ * // custom properties
117
+ * apiUrl: 'https://api.serenity-js.org/v1',
118
+ *
119
+ * // Custom cast of actors receives `contextOptions`
120
+ * // with the additional Serenity/JS properties (see `PlaywrightOptions`),
121
+ * // as well as any other custom properties you define in the destructuring expression,
122
+ * // such as `apiUrl`.
123
+ * actors: ({ browser, contextOptions, apiUrl }, use) => {
124
+ * const cast = Cast.whereEveryoneCan(
125
+ * BrowseTheWebWithPlaywright.using(browser, contextOptions),
126
+ * TakeNotes.usingAnEmptyNotepad(),
127
+ * CallAnApi.at(apiUrl),
128
+ * )
129
+ *
130
+ * // Make sure to pass your custom cast to Playwright `use` callback
131
+ * use(cast)
132
+ * },
133
+ * },
134
+ * };
135
+ * export default config
136
+ * ```
137
+ *
138
+ * #### Learn more
139
+ * - Declaring a Serenity/JS {@apilink it|test scenario}
140
+ * - {@apilink SerenityFixtures}
141
+ */
142
+ actors: TestFixture<Cast, PlaywrightTestOptions & PlaywrightWorkerArgs>
143
+
144
+ /**
145
+ * Configures the name given to the default Serenity/JS {@apilink SerenityFixtures.actor|actor}
146
+ * injected into a {@apilink it|test scenario}.
147
+ *
148
+ * #### Learn more
149
+ * - Declaring a Serenity/JS {@apilink it|test scenario}
150
+ * - {@apilink SerenityFixtures}
151
+ */
152
+ defaultActorName: string;
153
+
154
+ /**
155
+ * Configures the {@apilink SerenityConfig.crew|stage crew members}
156
+ * to be instantiated in Playwright Test worker processes.
157
+ *
158
+ * :::info Did you know?
159
+ * By default, Serenity/JS registers a {@apilink Photographer}.whoWill({@apilink TakePhotosOfFailures}),
160
+ * so that any test failures are automatically accompanied by a screenshot.
161
+ *
162
+ * If you prefer a different behaviour, you can configure the `crew` with an empty array to disable taking screenshots altogether (`crew: []`),
163
+ * or with a {@apilink Photographer} who uses a different {@apilink PhotoTakingStrategy}, like to {@apilink TakePhotosOfInteractions}.
164
+ * :::
165
+ *
166
+ * #### Example
167
+ *
168
+ * ```typescript
169
+ * // playwright.config.ts
170
+ * import type { PlaywrightTestConfig } from '@serenity-js/playwright-test'
171
+ *
172
+ * const config: PlaywrightTestConfig = {
173
+ * use: {
174
+ * crew: [
175
+ * [ '@serenity-js/web:Photographer', { strategy: 'TakePhotosOfFailures' } ]
176
+ * ],
177
+ * },
178
+ * };
179
+ * export default config
180
+ * ```
181
+ *
182
+ * #### Learn more
183
+ * - {@apilink SerenityConfig.crew}
184
+ */
185
+ crew: Array<ClassDescription | StageCrewMember | StageCrewMemberBuilder>;
186
+
187
+ /**
188
+ * Sets the {@apilink SerenityConfig.cueTimeout|cueTimeout} to a given {@apilink Duration|duration} or a numeric value in milliseconds.
189
+ * Defaults to **5 seconds**.
190
+ *
191
+ * #### Learn more
192
+ * - {@apilink SerenityConfig.cueTimeout}
193
+ * - {@apilink Discardable}
194
+ * - {@apilink Ability}
195
+ */
196
+ cueTimeout: number | Duration;
197
+
198
+ /**
199
+ * Playwright [BrowserContextOptions](https://playwright.dev/docs/api/class-testoptions#test-options-context-options),
200
+ * augmented with several convenience properties to be used with the {@apilink Ability|ability} to {@apilink BrowseTheWebWithPlaywright}.
201
+ *
202
+ * Additional convenience properties include:
203
+ * - {@apilink PlaywrightOptions.defaultNavigationTimeout}
204
+ * - {@apilink PlaywrightOptions.defaultNavigationWaitUntil}
205
+ * - {@apilink PlaywrightOptions.defaultTimeout}
206
+ *
207
+ * #### Using `contextOptions` with the default cast of Serenity/JS actors
208
+ *
209
+ * ```typescript
210
+ * // playwright.config.ts
211
+ * import type { PlaywrightTestConfig } from '@serenity-js/playwright-test'
212
+ *
213
+ * const config: PlaywrightTestConfig = {
214
+ * use: {
215
+ * contextOptions: {
216
+ * defaultNavigationTimeout: 30_000,
217
+ * }
218
+ *
219
+ * // Since `actors` property is not defined,
220
+ * // `contextOptions` will be passed to the default cast of Serenity/JS actors
221
+ * // and injected into the ability to `BrowseTheWebWithPlaywright`
222
+ * // that each actor receives.
223
+ * },
224
+ * };
225
+ * export default config;
226
+ * ```
227
+ *
228
+ * #### Using `contextOptions` with a custom cast of Serenity/JS actors
229
+ *
230
+ * ```typescript
231
+ * // playwright.config.ts
232
+ * import type { PlaywrightTestConfig } from '@serenity-js/playwright-test'
233
+ *
234
+ * const config: PlaywrightTestConfig = {
235
+ * use: {
236
+ * contextOptions: {
237
+ * defaultNavigationTimeout: 30_000,
238
+ * }
239
+ *
240
+ * // Custom cast of actors receives `contextOptions` with the
241
+ * // additional Serenity/JS properties.
242
+ * actors: ({ browser, contextOptions }, use) => {
243
+ * const cast = Cast.whereEveryoneCan(
244
+ * BrowseTheWebWithPlaywright.using(browser, contextOptions),
245
+ * TakeNotes.usingAnEmptyNotepad(),
246
+ * )
247
+ *
248
+ * use(cast)
249
+ * },
250
+ * },
251
+ * };
252
+ * export default config;
253
+ * ```
254
+ *
255
+ * #### Learn more
256
+ * - {@apilink SerenityFixtures}
257
+ * - [Playwright Browser Context options](https://playwright.dev/docs/api/class-testoptions#test-options-context-options)
258
+ * - [Playwright Test fixtures](https://playwright.dev/docs/test-fixtures)
259
+ */
260
+ contextOptions: PlaywrightOptions;
261
+ }
@@ -0,0 +1,12 @@
1
+ import { PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, TestType } from '@playwright/test';
2
+
3
+ import { SerenityFixtures } from './SerenityFixtures';
4
+ import { SerenityOptions } from './SerenityOptions';
5
+
6
+ /* eslint-disable @typescript-eslint/indent */
7
+ export type SerenityTestType =
8
+ TestType<
9
+ PlaywrightTestArgs & PlaywrightTestOptions & Omit<SerenityOptions, 'actors'> & SerenityFixtures,
10
+ PlaywrightWorkerArgs & PlaywrightWorkerOptions
11
+ >;
12
+ /* eslint-enable @typescript-eslint/indent */
@@ -0,0 +1,5 @@
1
+ export * from './PlaywrightTestConfig';
2
+ export * from './SerenityFixtures';
3
+ export * from './SerenityOptions';
4
+ export * from './SerenityTestType';
5
+ export * from './test-api';
@@ -1,115 +1,16 @@
1
- import { PlaywrightTestArgs, PlaywrightTestOptions, PlaywrightWorkerArgs, PlaywrightWorkerOptions, test as base, TestInfo, TestType } from '@playwright/test';
2
- import { Actor, Cast, Duration, Serenity, serenity as serenityInstance, StageCrewMember } from '@serenity-js/core';
1
+ import { test as base, TestInfo } from '@playwright/test';
2
+ import { Cast, Duration, serenity as serenityInstance, TakeNotes } from '@serenity-js/core';
3
3
  import { SceneFinishes, SceneTagged } from '@serenity-js/core/lib/events';
4
4
  import { BrowserTag, PlatformTag } from '@serenity-js/core/lib/model';
5
- import { BrowseTheWebWithPlaywright } from '@serenity-js/playwright';
5
+ import { BrowseTheWebWithPlaywright, PlaywrightPage } from '@serenity-js/playwright';
6
+ import { Photographer, TakePhotosOfFailures } from '@serenity-js/web';
6
7
  import * as os from 'os';
7
- import { JSONValue } from 'tiny-types';
8
+ import { ensure, isFunction, JSONValue, property } from 'tiny-types';
8
9
 
9
- import { DomainEventBuffer, PlaywrightStepReporter, SERENITY_JS_DOMAIN_EVENTS_ATTACHMENT_CONTENT_TYPE } from './reporter';
10
-
11
- /**
12
- * Serenity/JS-specific [Playwright Test fixtures](https://playwright.dev/docs/test-fixtures).
13
- *
14
- * ## Example test scenario
15
- *
16
- * ```typescript
17
- * import { Ensure, equals } from '@serenity-js/assertions'
18
- * import { describe, it, test } from '@serenity-js/playwright-test'
19
- * import { Photographer, TakePhotosOfFailures } from '@serenity-js/web'
20
- *
21
- * describe(`Recording items`, () => {
22
- *
23
- * test.use({
24
- * defaultActorName: 'Serena',
25
- * crew: [
26
- * Photographer.whoWill(TakePhotosOfFailures),
27
- * ],
28
- * })
29
- *
30
- * describe(`Todo List App`, () => {
31
- *
32
- * it(`should allow me to add a todo item`, async ({ actor }) => {
33
- * await actor.attemptsTo(
34
- * startWithAnEmptyList(),
35
- *
36
- * recordItem('Buy some milk'),
37
- *
38
- * Ensure.that(itemNames(), equals([
39
- * 'Buy some milk',
40
- * ])),
41
- * )
42
- * })
43
- * })
44
- * })
45
- * ```
46
- *
47
- * ## Learn more
48
- * - Declaring a test scenario using {@apilink it}
49
- * - Grouping test scenarios using {@apilink describe}
50
- * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/)
51
- */
52
- export interface SerenityFixtures {
53
-
54
- /**
55
- * Configures the {@apilink Cast} of {@apilink SerenityConfig.actors|actors} to be used when injecting an {@apilink SerenityFixtures.actor|actor}
56
- * or invoking {@apilink SerenityFixtures.actorCalled|actorCalled} in a {@apilink it|test scenario}.
57
- *
58
- * #### Learn more
59
- * - Declaring a test scenario using {@apilink it}
60
- */
61
- actors: Cast;
62
-
63
- /**
64
- * Configures the {@apilink SerenityConfig.crew|stage crew}
65
- */
66
- crew: StageCrewMember[];
67
-
68
- /**
69
- * Configures the {@apilink SerenityConfig.cueTimeout|cueTimeout}
70
- */
71
- cueTimeout: Duration;
72
-
73
- /**
74
- * Retrieves the root object of the Serenity/JS framework.
75
- */
76
- serenity: Serenity;
77
-
78
- /**
79
- * Name and version of the operating system the Playwright Test runs on.
80
- */
81
- platform: { name: string, version: string };
82
-
83
- /**
84
- * Uses the provided {@apilink Cast} of {@apilink SerenityFixtures.actors|actors} to instantiate an {@apilink Actor} called `name`
85
- * and inject it into a {@apilink it|test scenario}.
86
- * Retrieves an existing actor if one has already been instantiated.
87
- *
88
- * #### Learn more
89
- * - Declaring a test scenario using {@apilink it}
90
- *
91
- * @param name
92
- */
93
- actorCalled: (name: string) => Actor;
94
-
95
- /**
96
- * Configures the name given to the default {@apilink SerenityFixtures.actor|actor} injected into the {@apilink it|test scenario}.
97
- *
98
- * #### Learn more
99
- * - Declaring a test scenario using {@apilink it}
100
- */
101
- defaultActorName: string;
102
- /**
103
- * Default {@apilink SerenityFixtures.actor|actor} injected into a {@apilink it|test scenario}.
104
- *
105
- * #### Learn more
106
- * - {@apilink SerenityFixtures.actorCalled|actorCalled}
107
- * - Declaring a test scenario using {@apilink it}
108
- */
109
- actor: Actor;
110
- }
111
-
112
- export type SerenityTestType = TestType<PlaywrightTestArgs & PlaywrightTestOptions & SerenityFixtures, PlaywrightWorkerArgs & PlaywrightWorkerOptions>;
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';
113
14
 
114
15
  /**
115
16
  * Declares a single test scenario.
@@ -163,15 +64,38 @@ export type SerenityTestType = TestType<PlaywrightTestArgs & PlaywrightTestOptio
163
64
  * ```
164
65
  *
165
66
  * ## Learn more
166
- * - Grouping test scenarios using {@apilink describe}
67
+ * - {@apilink describe|Grouping test scenarios}
167
68
  * - {@apilink SerenityFixtures}
168
69
  * - [Playwright Test `test` function](https://playwright.dev/docs/api/class-test#test-call)
169
70
  * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/)
170
71
  */
171
- export const it: SerenityTestType = base.extend<SerenityFixtures>({
172
- cueTimeout: Duration.ofSeconds(5),
173
-
174
- crew: [],
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
+ ],
175
99
 
176
100
  // eslint-disable-next-line no-empty-pattern
177
101
  platform: ({}, use) => {
@@ -190,7 +114,7 @@ export const it: SerenityTestType = base.extend<SerenityFixtures>({
190
114
  const domainEventBuffer = new DomainEventBuffer();
191
115
 
192
116
  serenityInstance.configure({
193
- cueTimeout: cueTimeout,
117
+ cueTimeout: asDuration(cueTimeout),
194
118
  crew: [
195
119
  ...crew,
196
120
  domainEventBuffer,
@@ -225,22 +149,12 @@ export const it: SerenityTestType = base.extend<SerenityFixtures>({
225
149
  });
226
150
  },
227
151
 
228
- actors: async ({ browser }, use) => {
229
- await use(Cast.whereEveryoneCan(BrowseTheWebWithPlaywright.using(browser)));
230
- },
231
-
232
- defaultActorName: 'Serena',
233
-
234
- actor: async ({ actorCalled, defaultActorName }, use) => {
235
- await use(actorCalled(defaultActorName));
236
- },
237
-
238
- actorCalled: async ({ serenity, actors, browser, browserName }, use) => {
239
-
240
- serenity.engage(actors);
152
+ actorCalled: async ({ serenity, actors, browser, browserName, contextOptions }, use) => {
241
153
 
242
154
  const sceneId = serenity.currentSceneId();
243
155
 
156
+ serenity.engage(asCast(actors));
157
+
244
158
  const actorCalled = serenity.theActorCalled.bind(serenity);
245
159
 
246
160
  serenity.announce(new SceneTagged(
@@ -257,8 +171,29 @@ export const it: SerenityTestType = base.extend<SerenityFixtures>({
257
171
 
258
172
  await serenityInstance.waitForNextCue();
259
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
+ },
260
185
  });
261
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
+
262
197
  export const test: SerenityTestType = it;
263
198
 
264
199
  /**
@@ -305,7 +240,7 @@ export const test: SerenityTestType = it;
305
240
  * ```
306
241
  *
307
242
  * ## Learn more
308
- * - Declaring a test scenario using {@apilink it}
243
+ * - Declaring a Serenity/JS {@apilink it|test scenario}
309
244
  * - [Playwright Test `describe` function](https://playwright.dev/docs/api/class-test#test-describe-1)
310
245
  * - [Serenity/JS + Playwright Test project template](https://github.com/serenity-js/serenity-js-playwright-test-template/)
311
246
  */
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';