@serenity-js/playwright-test 3.36.2 → 3.37.0
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.
- package/CHANGELOG.md +13 -0
- package/README.md +141 -158
- package/lib/api/serenity-fixtures.d.ts +102 -21
- package/lib/api/serenity-fixtures.d.ts.map +1 -1
- package/lib/api/test-api.d.ts +41 -5
- package/lib/api/test-api.d.ts.map +1 -1
- package/lib/api/test-api.js +62 -14
- package/lib/api/test-api.js.map +1 -1
- package/package.json +7 -6
- package/src/api/serenity-fixtures.ts +105 -20
- package/src/api/test-api.ts +81 -29
package/src/api/test-api.ts
CHANGED
|
@@ -13,7 +13,7 @@ import type {
|
|
|
13
13
|
TestType,
|
|
14
14
|
WorkerInfo,
|
|
15
15
|
} from '@playwright/test';
|
|
16
|
-
import { test as playwrightBaseTest } from '@playwright/test';
|
|
16
|
+
import { mergeTests, test as playwrightBaseTest } from '@playwright/test';
|
|
17
17
|
import type { DiffFormatter } from '@serenity-js/core';
|
|
18
18
|
import { AnsiDiffFormatter, Cast, Clock, Duration, Serenity, TakeNotes } from '@serenity-js/core';
|
|
19
19
|
import { SceneFinishes, SceneTagged } from '@serenity-js/core/lib/events';
|
|
@@ -68,20 +68,32 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
68
68
|
{ option: true },
|
|
69
69
|
],
|
|
70
70
|
|
|
71
|
+
axios: async ({ baseURL, extraHTTPHeaders, proxy }, use) => {
|
|
72
|
+
await use({
|
|
73
|
+
baseURL: baseURL,
|
|
74
|
+
headers: extraHTTPHeaders,
|
|
75
|
+
proxy: proxy && proxy?.server
|
|
76
|
+
? asProxyConfig(proxy)
|
|
77
|
+
: undefined,
|
|
78
|
+
})
|
|
79
|
+
},
|
|
80
|
+
|
|
71
81
|
actors: [
|
|
72
82
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
73
|
-
async ({
|
|
74
|
-
await use(Cast.where(actor =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
async ({ axios, extraAbilities, extraContextOptions, page }, use): Promise<void> => {
|
|
84
|
+
await use(Cast.where(actor => {
|
|
85
|
+
|
|
86
|
+
const abilities = Array.isArray(extraAbilities)
|
|
87
|
+
? extraAbilities
|
|
88
|
+
: extraAbilities(actor.name);
|
|
89
|
+
|
|
90
|
+
return actor.whoCan(
|
|
91
|
+
BrowseTheWebWithPlaywright.usingPage(page, extraContextOptions),
|
|
92
|
+
TakeNotes.usingAnEmptyNotepad(),
|
|
93
|
+
CallAnApi.using(axios),
|
|
94
|
+
...abilities,
|
|
95
|
+
);
|
|
96
|
+
}));
|
|
85
97
|
},
|
|
86
98
|
{ option: true },
|
|
87
99
|
],
|
|
@@ -109,7 +121,7 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
109
121
|
|
|
110
122
|
sceneIdFactoryInternal: [
|
|
111
123
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,no-empty-pattern
|
|
112
|
-
async ({
|
|
124
|
+
async ({}, use) => {
|
|
113
125
|
await use(new PlaywrightTestSceneIdFactory());
|
|
114
126
|
},
|
|
115
127
|
{ scope: 'worker', box: true },
|
|
@@ -132,7 +144,7 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
132
144
|
|
|
133
145
|
eventStreamWriterInternal: [
|
|
134
146
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types,no-empty-pattern
|
|
135
|
-
async ({
|
|
147
|
+
async ({}, use, workerInfo) => {
|
|
136
148
|
|
|
137
149
|
const serenityOutputDirectory = path.join(workerInfo.project.outputDir, 'serenity');
|
|
138
150
|
|
|
@@ -225,12 +237,18 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
225
237
|
{ auto: true, box: true, }
|
|
226
238
|
],
|
|
227
239
|
|
|
240
|
+
extraAbilities: [
|
|
241
|
+
[],
|
|
242
|
+
{ option: true },
|
|
243
|
+
],
|
|
244
|
+
|
|
228
245
|
actorCalled: [
|
|
229
246
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
230
247
|
async ({ serenity }, use) => {
|
|
231
248
|
|
|
232
249
|
const actorCalled = (name: string) => {
|
|
233
250
|
const actor = serenity.theActorCalled(name);
|
|
251
|
+
|
|
234
252
|
return actor.whoCan(new PerformActivitiesAsPlaywrightSteps(actor, serenity, it));
|
|
235
253
|
};
|
|
236
254
|
|
|
@@ -247,7 +265,7 @@ export const fixtures: Fixtures<SerenityFixtures & SerenityInternalFixtures, Ser
|
|
|
247
265
|
/**
|
|
248
266
|
* Serenity/JS BDD-style test API created by [`useBase`](https://serenity-js.org/api/playwright-test/function/useBase/).
|
|
249
267
|
*/
|
|
250
|
-
export type TestApi<TestArgs extends
|
|
268
|
+
export type TestApi<TestArgs extends object, WorkerArgs extends object> =
|
|
251
269
|
Pick<TestType<TestArgs, WorkerArgs>, 'describe' | 'beforeAll' | 'beforeEach' | 'afterEach' | 'afterAll' | 'expect'> &
|
|
252
270
|
{
|
|
253
271
|
/**
|
|
@@ -274,7 +292,7 @@ export type TestApi<TestArgs extends Record<string, any>, WorkerArgs extends Rec
|
|
|
274
292
|
*
|
|
275
293
|
* Shorthand for [`useBase`](https://serenity-js.org/api/playwright-test/function/useBase/)
|
|
276
294
|
*/
|
|
277
|
-
useFixtures: <T extends
|
|
295
|
+
useFixtures: <T extends object, W extends object = object>(
|
|
278
296
|
customFixtures: Fixtures<T, W, TestArgs, WorkerArgs>
|
|
279
297
|
) => TestApi<TestArgs & T, WorkerArgs & W>,
|
|
280
298
|
|
|
@@ -282,7 +300,7 @@ export type TestApi<TestArgs extends Record<string, any>, WorkerArgs extends Rec
|
|
|
282
300
|
test: TestType<TestArgs, WorkerArgs>,
|
|
283
301
|
}
|
|
284
302
|
|
|
285
|
-
function createTestApi<BaseTestFixtures extends
|
|
303
|
+
function createTestApi<BaseTestFixtures extends object, BaseWorkerFixtures extends object>(baseTest: TestType<BaseTestFixtures, BaseWorkerFixtures>): TestApi<BaseTestFixtures, BaseWorkerFixtures> {
|
|
286
304
|
return {
|
|
287
305
|
useFixtures<T extends Record<string, any>, W extends Record<string, any> = object>(customFixtures: Fixtures<T, W, BaseTestFixtures, BaseWorkerFixtures>): TestApi<BaseTestFixtures & T, BaseWorkerFixtures & W> {
|
|
288
306
|
return createTestApi(baseTest.extend(customFixtures));
|
|
@@ -426,6 +444,9 @@ export const expect: Expect = api.expect;
|
|
|
426
444
|
|
|
427
445
|
export const useFixtures = api.useFixtures;
|
|
428
446
|
|
|
447
|
+
type MergedT<List> = List extends [ TestType<infer T, any>, ...(infer Rest) ] ? T & MergedT<Rest> : object;
|
|
448
|
+
type MergedW<List> = List extends [ TestType<any, infer W>, ...(infer Rest) ] ? W & MergedW<Rest> : object;
|
|
449
|
+
|
|
429
450
|
/**
|
|
430
451
|
* Creates a Serenity/JS BDD-style test API around the given Playwright [base test](https://playwright.dev/docs/test-fixtures).
|
|
431
452
|
*
|
|
@@ -562,15 +583,45 @@ export const useFixtures = api.useFixtures;
|
|
|
562
583
|
* })
|
|
563
584
|
* ```
|
|
564
585
|
*
|
|
565
|
-
*
|
|
586
|
+
* ## Merging multiple base tests
|
|
587
|
+
*
|
|
588
|
+
* To merge fixtures from multiple files or modules, pass them to `useBase`.
|
|
589
|
+
*
|
|
590
|
+
* ```tsx
|
|
591
|
+
* import { test as componentTest } from '@playwright/experimental-ct-react'
|
|
592
|
+
* import { test as a11yTest } from 'my-a11y-test-utils';
|
|
593
|
+
* import { Ensure, contain } from '@serenity-js/assertions'
|
|
594
|
+
* import { useBase } from '@serenity-js/playwright-test'
|
|
595
|
+
* import { Enter, PageElement, CssClasses } from '@serenity-js/web'
|
|
596
|
+
*
|
|
597
|
+
* import EmailInput from './EmailInput';
|
|
598
|
+
*
|
|
599
|
+
* const { it, describe } = useBase(componentTest, a11yTest).useFixtures<{ emailAddress: string }>({
|
|
600
|
+
* emailAddress: ({ actor }, use) => {
|
|
601
|
+
* use(`${ actor.name }@example.org`)
|
|
602
|
+
* }
|
|
603
|
+
* })
|
|
604
|
+
*
|
|
605
|
+
* describe('EmailInput', () => {
|
|
606
|
+
*
|
|
607
|
+
* it('allows valid email addresses', async ({ actor, mount, emailAddress }) => {
|
|
608
|
+
* const nativeComponent = await mount(<EmailInput/>);
|
|
609
|
+
*
|
|
610
|
+
* const component = PageElement.from(nativeComponent);
|
|
611
|
+
*
|
|
612
|
+
* await actor.attemptsTo(
|
|
613
|
+
* Enter.theValue(emailAddress).into(component),
|
|
614
|
+
* Ensure.that(CssClasses.of(component), contain('valid')),
|
|
615
|
+
* )
|
|
616
|
+
* })
|
|
617
|
+
* })
|
|
618
|
+
* ```
|
|
619
|
+
*
|
|
620
|
+
* @param baseTests
|
|
566
621
|
*/
|
|
567
|
-
export function useBase<
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
> (baseTest: TestType<BaseTestFixtures, BaseWorkerFixtures>): TestApi<BaseTestFixtures & SerenityFixtures, BaseWorkerFixtures & SerenityWorkerFixtures> {
|
|
571
|
-
return createTestApi<BaseTestFixtures, BaseWorkerFixtures>(baseTest).useFixtures(
|
|
572
|
-
fixtures as Fixtures<SerenityFixtures, SerenityWorkerFixtures, BaseTestFixtures, BaseWorkerFixtures>
|
|
573
|
-
);
|
|
622
|
+
export function useBase<List extends any[]>(...baseTests: List): TestApi<MergedT<List> & SerenityFixtures, MergedW<List> & SerenityWorkerFixtures> {
|
|
623
|
+
return createTestApi<MergedT<List>, MergedW<List>>(mergeTests(...baseTests))
|
|
624
|
+
.useFixtures(fixtures as Fixtures<SerenityFixtures, SerenityWorkerFixtures, MergedT<List>, MergedW<List>>);
|
|
574
625
|
}
|
|
575
626
|
|
|
576
627
|
/**
|
|
@@ -602,13 +653,14 @@ function asProxyConfig(proxy: PlaywrightTestOptions['proxy']): {
|
|
|
602
653
|
auth?: { username: string, password: string }
|
|
603
654
|
bypass?: string;
|
|
604
655
|
} {
|
|
656
|
+
const proxyServer = proxy.server.trim();
|
|
605
657
|
|
|
606
658
|
// Playwright defaults to http when proxy.server does not define the protocol
|
|
607
659
|
// See https://playwright.dev/docs/api/class-testoptions#test-options-proxy
|
|
608
|
-
const hasProtocol =
|
|
660
|
+
const hasProtocol = /^[\dA-Za-z]+:\/\//.test(proxyServer);
|
|
609
661
|
const proxyUrl = hasProtocol
|
|
610
|
-
? new URL(
|
|
611
|
-
: new URL(`http://${
|
|
662
|
+
? new URL(proxyServer)
|
|
663
|
+
: new URL(`http://${ proxyServer }`);
|
|
612
664
|
|
|
613
665
|
const host = proxyUrl.hostname;
|
|
614
666
|
const port = proxyUrl.port
|