@cronn/playwright-utils 0.5.0 → 0.6.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/dist/index.d.mts +51 -16
- package/dist/index.mjs +128 -1
- package/package.json +17 -18
package/dist/index.d.mts
CHANGED
|
@@ -7,7 +7,7 @@ import { APIRequestContext, APIResponse, ConsoleMessage, Locator, Page, Request,
|
|
|
7
7
|
*
|
|
8
8
|
* Evaluated once when the module is loaded.
|
|
9
9
|
*/
|
|
10
|
-
declare const isCI: boolean;
|
|
10
|
+
export declare const isCI: boolean;
|
|
11
11
|
//#endregion
|
|
12
12
|
//#region src/api/fetch-adapter.d.ts
|
|
13
13
|
type FetchAPI = typeof fetch;
|
|
@@ -21,7 +21,7 @@ type FetchAPI = typeof fetch;
|
|
|
21
21
|
* @param requestContext - Playwright request context to send requests with
|
|
22
22
|
* @returns A function with the signature of the global `fetch`
|
|
23
23
|
*/
|
|
24
|
-
declare function createFetchAdapter(requestContext: APIRequestContext): FetchAPI;
|
|
24
|
+
export declare function createFetchAdapter(requestContext: APIRequestContext): FetchAPI;
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region src/capturing/console-captor.d.ts
|
|
27
27
|
/**
|
|
@@ -57,7 +57,7 @@ type ConsoleMessageLevel = ReturnType<ConsoleMessage["type"]>;
|
|
|
57
57
|
* ]);
|
|
58
58
|
* ```
|
|
59
59
|
*/
|
|
60
|
-
declare class ConsoleCaptor {
|
|
60
|
+
export declare class ConsoleCaptor {
|
|
61
61
|
private readonly page;
|
|
62
62
|
private readonly consoleListener;
|
|
63
63
|
/**
|
|
@@ -171,7 +171,7 @@ declare class ConsoleCaptor {
|
|
|
171
171
|
* );
|
|
172
172
|
* ```
|
|
173
173
|
*/
|
|
174
|
-
declare function captureConsole(page: Page, levelOrFilter?: ConsoleMessageLevel | Array<ConsoleMessageLevel> | ConsoleMessageFilter): ConsoleCaptor;
|
|
174
|
+
export declare function captureConsole(page: Page, levelOrFilter?: ConsoleMessageLevel | Array<ConsoleMessageLevel> | ConsoleMessageFilter): ConsoleCaptor;
|
|
175
175
|
/**
|
|
176
176
|
* Tests whether the given console message has one of the specified log levels.
|
|
177
177
|
*
|
|
@@ -181,7 +181,7 @@ declare function captureConsole(page: Page, levelOrFilter?: ConsoleMessageLevel
|
|
|
181
181
|
* @param level - The log level
|
|
182
182
|
* @returns True if the message has one of the given log levels
|
|
183
183
|
*/
|
|
184
|
-
declare function hasLogLevel(message: ConsoleMessage, ...level: Array<ConsoleMessageLevel>): boolean;
|
|
184
|
+
export declare function hasLogLevel(message: ConsoleMessage, ...level: Array<ConsoleMessageLevel>): boolean;
|
|
185
185
|
//#endregion
|
|
186
186
|
//#region src/api/route-interceptor/filter.d.ts
|
|
187
187
|
/**
|
|
@@ -211,7 +211,7 @@ interface RouteFilter {
|
|
|
211
211
|
* });
|
|
212
212
|
* ```
|
|
213
213
|
*/
|
|
214
|
-
declare function matchPath(pattern: RegExp | string): RouteFilter;
|
|
214
|
+
export declare function matchPath(pattern: RegExp | string): RouteFilter;
|
|
215
215
|
//#endregion
|
|
216
216
|
//#region src/api/route-interceptor/response-handler.d.ts
|
|
217
217
|
/**
|
|
@@ -236,7 +236,7 @@ type ResponseHandler = (response: APIResponse) => Promise<FulfillOptions> | Fulf
|
|
|
236
236
|
* });
|
|
237
237
|
* ```
|
|
238
238
|
*/
|
|
239
|
-
declare function modifyJsonBody<T>(modifier: (body: T) => T): ResponseHandler;
|
|
239
|
+
export declare function modifyJsonBody<T>(modifier: (body: T) => T): ResponseHandler;
|
|
240
240
|
/**
|
|
241
241
|
* Helper to create a {@link ResponseHandler} that modifies the response body as a plaintext string.
|
|
242
242
|
*
|
|
@@ -252,7 +252,7 @@ declare function modifyJsonBody<T>(modifier: (body: T) => T): ResponseHandler;
|
|
|
252
252
|
* });
|
|
253
253
|
* ```
|
|
254
254
|
*/
|
|
255
|
-
declare function modifyTextBody(modifier: (body: string) => string): ResponseHandler;
|
|
255
|
+
export declare function modifyTextBody(modifier: (body: string) => string): ResponseHandler;
|
|
256
256
|
//#endregion
|
|
257
257
|
//#region src/api/route-interceptor/interceptor.d.ts
|
|
258
258
|
type Action<T> = () => Promise<T> | T;
|
|
@@ -260,7 +260,7 @@ type FulfillOptions = Parameters<Route["fulfill"]>[0];
|
|
|
260
260
|
/**
|
|
261
261
|
* Entrypoint to create various network interceptors using the {@link Page#route} API.
|
|
262
262
|
*/
|
|
263
|
-
declare class RouteInterceptor {
|
|
263
|
+
export declare class RouteInterceptor {
|
|
264
264
|
readonly page: Page;
|
|
265
265
|
readonly filter: RouteFilter;
|
|
266
266
|
constructor(page: Page, filter: RouteFilter);
|
|
@@ -398,7 +398,7 @@ declare class ExecutableRouteInterceptor {
|
|
|
398
398
|
* });
|
|
399
399
|
* ```
|
|
400
400
|
*/
|
|
401
|
-
declare function interceptRoute(page: Page, filter: RouteFilter): RouteInterceptor;
|
|
401
|
+
export declare function interceptRoute(page: Page, filter: RouteFilter): RouteInterceptor;
|
|
402
402
|
/**
|
|
403
403
|
* Base class to build re-usable route interceptors.
|
|
404
404
|
*
|
|
@@ -428,7 +428,7 @@ declare function interceptRoute(page: Page, filter: RouteFilter): RouteIntercept
|
|
|
428
428
|
* });
|
|
429
429
|
* ```
|
|
430
430
|
*/
|
|
431
|
-
declare class RouteInterceptorFixture {
|
|
431
|
+
export declare class RouteInterceptorFixture {
|
|
432
432
|
private readonly page;
|
|
433
433
|
constructor(page: Page);
|
|
434
434
|
/**
|
|
@@ -460,7 +460,42 @@ declare class RouteInterceptorFixture {
|
|
|
460
460
|
* @returns The absolute path to the resolved location
|
|
461
461
|
* @throws If no package root can be found
|
|
462
462
|
*/
|
|
463
|
-
declare function resolveFromPackageRoot(...paths: Array<string>): string;
|
|
463
|
+
export declare function resolveFromPackageRoot(...paths: Array<string>): string;
|
|
464
|
+
//#endregion
|
|
465
|
+
//#region src/page-object-model/locator-extensions.d.ts
|
|
466
|
+
type RoleLocators = Record<Role, RoleLocator>;
|
|
467
|
+
interface RoleLocator {
|
|
468
|
+
(options?: RoleLocatorOptions): Locator;
|
|
469
|
+
(name: string | RegExp, options?: RoleLocatorOptions): Locator;
|
|
470
|
+
}
|
|
471
|
+
type RoleLocatorOptions = Omit<GetByRoleOptions, "name">;
|
|
472
|
+
type Role = Parameters<Locator["getByRole"]>[0];
|
|
473
|
+
type GetByRoleOptions = Parameters<Locator["getByRole"]>[1];
|
|
474
|
+
/**
|
|
475
|
+
* Creates a set of locator functions for every ARIA role, so tests don't
|
|
476
|
+
* have to repeat `getByRole` and its role string throughout a page object.
|
|
477
|
+
*
|
|
478
|
+
* Every generated locator applies `exact: true` by default, keeping name
|
|
479
|
+
* matches from accidentally matching unrelated elements with a similar
|
|
480
|
+
* accessible name. This can be overridden per call through `options`, or
|
|
481
|
+
* replaced entirely for every locator by passing a custom `defaultOptions`.
|
|
482
|
+
*
|
|
483
|
+
* The accessible name can be omitted when an element should be located by
|
|
484
|
+
* role alone, in which case `options` can be passed as the first argument.
|
|
485
|
+
*
|
|
486
|
+
* @param locator - The page or locator to scope the role locators to
|
|
487
|
+
* @param defaultOptions - Optional. Options applied to every generated locator, overridden by per-call options; defaults to `{ exact: true }`
|
|
488
|
+
* @returns A `RoleLocators` object with one locator function per ARIA role
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```ts
|
|
492
|
+
* const { button, textbox } = roleLocators(page);
|
|
493
|
+
*
|
|
494
|
+
* await textbox("Email").fill("user@example.com");
|
|
495
|
+
* await button("Submit").click();
|
|
496
|
+
* ```
|
|
497
|
+
*/
|
|
498
|
+
export declare function roleLocators(locator: Pick<Locator, "getByRole">, defaultOptions?: GetByRoleOptions): RoleLocators;
|
|
464
499
|
//#endregion
|
|
465
500
|
//#region src/normalizers/mask-base-url.d.ts
|
|
466
501
|
/**
|
|
@@ -469,7 +504,7 @@ declare function resolveFromPackageRoot(...paths: Array<string>): string;
|
|
|
469
504
|
*
|
|
470
505
|
* @param baseURL - Base URL to mask; if `undefined`, values are left unchanged
|
|
471
506
|
*/
|
|
472
|
-
declare function maskBaseURL<TValue>(baseURL: string | undefined): Normalizer<TValue>;
|
|
507
|
+
export declare function maskBaseURL<TValue>(baseURL: string | undefined): Normalizer<TValue>;
|
|
473
508
|
//#endregion
|
|
474
509
|
//#region src/normalizers/masked-value.d.ts
|
|
475
510
|
/**
|
|
@@ -478,14 +513,14 @@ declare function maskBaseURL<TValue>(baseURL: string | undefined): Normalizer<TV
|
|
|
478
513
|
*
|
|
479
514
|
* @param name - Name of the masked value
|
|
480
515
|
*/
|
|
481
|
-
declare function maskedValue(name: string): string;
|
|
516
|
+
export declare function maskedValue(name: string): string;
|
|
482
517
|
/**
|
|
483
518
|
* Creates a factory for indexed masked placeholders, e.g. `[USER_1]`.
|
|
484
519
|
*
|
|
485
520
|
* @param name - Name of the masked value
|
|
486
521
|
* @returns A function mapping an index to a masked placeholder
|
|
487
522
|
*/
|
|
488
|
-
declare function maskedValueWithIndex(name: string): (index: number) => string;
|
|
523
|
+
export declare function maskedValueWithIndex(name: string): (index: number) => string;
|
|
489
524
|
//#endregion
|
|
490
525
|
//#region src/types/playwright.d.ts
|
|
491
526
|
/**
|
|
@@ -494,4 +529,4 @@ declare function maskedValueWithIndex(name: string): (index: number) => string;
|
|
|
494
529
|
*/
|
|
495
530
|
type PlaywrightTarget = Page | Locator;
|
|
496
531
|
//#endregion
|
|
497
|
-
export {
|
|
532
|
+
export type { ConsoleMessageFilter, ConsoleMessageLevel, HttpMethod, PlaywrightTarget, ResponseHandler, RoleLocators, RouteFilter };
|
package/dist/index.mjs
CHANGED
|
@@ -609,6 +609,133 @@ function resolveFromPackageRoot(...paths) {
|
|
|
609
609
|
return path.resolve(packageDir, ...paths);
|
|
610
610
|
}
|
|
611
611
|
//#endregion
|
|
612
|
+
//#region src/page-object-model/locator-extensions.ts
|
|
613
|
+
const ROLES = [
|
|
614
|
+
"alert",
|
|
615
|
+
"alertdialog",
|
|
616
|
+
"application",
|
|
617
|
+
"article",
|
|
618
|
+
"banner",
|
|
619
|
+
"blockquote",
|
|
620
|
+
"button",
|
|
621
|
+
"caption",
|
|
622
|
+
"cell",
|
|
623
|
+
"checkbox",
|
|
624
|
+
"code",
|
|
625
|
+
"columnheader",
|
|
626
|
+
"combobox",
|
|
627
|
+
"complementary",
|
|
628
|
+
"contentinfo",
|
|
629
|
+
"definition",
|
|
630
|
+
"deletion",
|
|
631
|
+
"dialog",
|
|
632
|
+
"directory",
|
|
633
|
+
"document",
|
|
634
|
+
"emphasis",
|
|
635
|
+
"feed",
|
|
636
|
+
"figure",
|
|
637
|
+
"form",
|
|
638
|
+
"generic",
|
|
639
|
+
"grid",
|
|
640
|
+
"gridcell",
|
|
641
|
+
"group",
|
|
642
|
+
"heading",
|
|
643
|
+
"img",
|
|
644
|
+
"insertion",
|
|
645
|
+
"link",
|
|
646
|
+
"list",
|
|
647
|
+
"listbox",
|
|
648
|
+
"listitem",
|
|
649
|
+
"log",
|
|
650
|
+
"main",
|
|
651
|
+
"marquee",
|
|
652
|
+
"math",
|
|
653
|
+
"meter",
|
|
654
|
+
"menu",
|
|
655
|
+
"menubar",
|
|
656
|
+
"menuitem",
|
|
657
|
+
"menuitemcheckbox",
|
|
658
|
+
"menuitemradio",
|
|
659
|
+
"navigation",
|
|
660
|
+
"none",
|
|
661
|
+
"note",
|
|
662
|
+
"option",
|
|
663
|
+
"paragraph",
|
|
664
|
+
"presentation",
|
|
665
|
+
"progressbar",
|
|
666
|
+
"radio",
|
|
667
|
+
"radiogroup",
|
|
668
|
+
"region",
|
|
669
|
+
"row",
|
|
670
|
+
"rowgroup",
|
|
671
|
+
"rowheader",
|
|
672
|
+
"scrollbar",
|
|
673
|
+
"search",
|
|
674
|
+
"searchbox",
|
|
675
|
+
"separator",
|
|
676
|
+
"slider",
|
|
677
|
+
"spinbutton",
|
|
678
|
+
"status",
|
|
679
|
+
"strong",
|
|
680
|
+
"subscript",
|
|
681
|
+
"superscript",
|
|
682
|
+
"switch",
|
|
683
|
+
"tab",
|
|
684
|
+
"table",
|
|
685
|
+
"tablist",
|
|
686
|
+
"tabpanel",
|
|
687
|
+
"term",
|
|
688
|
+
"textbox",
|
|
689
|
+
"time",
|
|
690
|
+
"timer",
|
|
691
|
+
"toolbar",
|
|
692
|
+
"tooltip",
|
|
693
|
+
"tree",
|
|
694
|
+
"treegrid",
|
|
695
|
+
"treeitem"
|
|
696
|
+
];
|
|
697
|
+
const DEFAULT_OPTIONS = { exact: true };
|
|
698
|
+
/**
|
|
699
|
+
* Creates a set of locator functions for every ARIA role, so tests don't
|
|
700
|
+
* have to repeat `getByRole` and its role string throughout a page object.
|
|
701
|
+
*
|
|
702
|
+
* Every generated locator applies `exact: true` by default, keeping name
|
|
703
|
+
* matches from accidentally matching unrelated elements with a similar
|
|
704
|
+
* accessible name. This can be overridden per call through `options`, or
|
|
705
|
+
* replaced entirely for every locator by passing a custom `defaultOptions`.
|
|
706
|
+
*
|
|
707
|
+
* The accessible name can be omitted when an element should be located by
|
|
708
|
+
* role alone, in which case `options` can be passed as the first argument.
|
|
709
|
+
*
|
|
710
|
+
* @param locator - The page or locator to scope the role locators to
|
|
711
|
+
* @param defaultOptions - Optional. Options applied to every generated locator, overridden by per-call options; defaults to `{ exact: true }`
|
|
712
|
+
* @returns A `RoleLocators` object with one locator function per ARIA role
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```ts
|
|
716
|
+
* const { button, textbox } = roleLocators(page);
|
|
717
|
+
*
|
|
718
|
+
* await textbox("Email").fill("user@example.com");
|
|
719
|
+
* await button("Submit").click();
|
|
720
|
+
* ```
|
|
721
|
+
*/
|
|
722
|
+
function roleLocators(locator, defaultOptions = DEFAULT_OPTIONS) {
|
|
723
|
+
function getByRole(role) {
|
|
724
|
+
return (nameOrOptions, options) => {
|
|
725
|
+
if (typeof nameOrOptions === "string" || nameOrOptions instanceof RegExp) return locator.getByRole(role, {
|
|
726
|
+
name: nameOrOptions,
|
|
727
|
+
...defaultOptions,
|
|
728
|
+
...options
|
|
729
|
+
});
|
|
730
|
+
return locator.getByRole(role, {
|
|
731
|
+
...defaultOptions,
|
|
732
|
+
...nameOrOptions
|
|
733
|
+
});
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
return Object.fromEntries(ROLES.map((role) => [role, getByRole(role)]));
|
|
737
|
+
}
|
|
738
|
+
//#endregion
|
|
612
739
|
//#region src/normalizers/masked-value.ts
|
|
613
740
|
/**
|
|
614
741
|
* Formats a name as a masked placeholder, e.g. `maskedValue("base url")`
|
|
@@ -644,4 +771,4 @@ function identity(value) {
|
|
|
644
771
|
return value;
|
|
645
772
|
}
|
|
646
773
|
//#endregion
|
|
647
|
-
export { ConsoleCaptor, RouteInterceptor, RouteInterceptorFixture, captureConsole, createFetchAdapter, hasLogLevel, interceptRoute, isCI, maskBaseURL, maskedValue, maskedValueWithIndex, matchPath, modifyJsonBody, modifyTextBody, resolveFromPackageRoot };
|
|
774
|
+
export { ConsoleCaptor, RouteInterceptor, RouteInterceptorFixture, captureConsole, createFetchAdapter, hasLogLevel, interceptRoute, isCI, maskBaseURL, maskedValue, maskedValueWithIndex, matchPath, modifyJsonBody, modifyTextBody, resolveFromPackageRoot, roleLocators };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cronn/playwright-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Utilities for writing tests with Playwright",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"playwright",
|
|
@@ -33,30 +33,29 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@arethetypeswrong/core": "0.18.5",
|
|
36
|
-
"@changesets/cli": "3.0.
|
|
37
|
-
"@cronn/element-snapshot": "0.
|
|
38
|
-
"@cronn/playwright-file-snapshots": "2.2.
|
|
39
|
-
"@playwright/test": "1.
|
|
40
|
-
"@types/node": "24.13.
|
|
36
|
+
"@changesets/cli": "3.0.2",
|
|
37
|
+
"@cronn/element-snapshot": "0.30.0",
|
|
38
|
+
"@cronn/playwright-file-snapshots": "2.2.2",
|
|
39
|
+
"@playwright/test": "1.63.0",
|
|
40
|
+
"@types/node": "24.13.4",
|
|
41
41
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
42
|
-
"@vitest/coverage-v8": "
|
|
43
|
-
"eslint": "10.
|
|
42
|
+
"@vitest/coverage-v8": "5.0.0",
|
|
43
|
+
"eslint": "10.10.0",
|
|
44
44
|
"eslint-config-prettier": "10.1.8",
|
|
45
45
|
"eslint-plugin-check-file": "3.3.2",
|
|
46
46
|
"eslint-plugin-unused-imports": "4.4.1",
|
|
47
|
-
"knip": "6.
|
|
48
|
-
"oxc-minify": "0.
|
|
49
|
-
"oxfmt": "0.
|
|
47
|
+
"knip": "6.35.1",
|
|
48
|
+
"oxc-minify": "0.149.0",
|
|
49
|
+
"oxfmt": "0.67.0",
|
|
50
50
|
"publint": "0.3.24",
|
|
51
51
|
"rimraf": "6.1.3",
|
|
52
|
-
"tsdown": "0.
|
|
52
|
+
"tsdown": "0.23.0",
|
|
53
53
|
"turbo": "2.10.12",
|
|
54
54
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
55
|
-
"typescript-eslint": "8.
|
|
56
|
-
"vitepress": "2.0.0-alpha.
|
|
55
|
+
"typescript-eslint": "8.70.0",
|
|
56
|
+
"vitepress": "2.0.0-alpha.20",
|
|
57
57
|
"vitepress-plugin-group-icons": "1.7.6",
|
|
58
|
-
"vitest": "
|
|
59
|
-
"node": "runtime:24.20.0"
|
|
58
|
+
"vitest": "5.0.0"
|
|
60
59
|
},
|
|
61
60
|
"peerDependencies": {
|
|
62
61
|
"@cronn/playwright-file-snapshots": "^2",
|
|
@@ -65,12 +64,12 @@
|
|
|
65
64
|
"devEngines": {
|
|
66
65
|
"packageManager": {
|
|
67
66
|
"name": "pnpm",
|
|
68
|
-
"version": "
|
|
67
|
+
"version": "12.5.1",
|
|
69
68
|
"onFail": "download"
|
|
70
69
|
},
|
|
71
70
|
"runtime": {
|
|
72
71
|
"name": "node",
|
|
73
|
-
"version": "24.
|
|
72
|
+
"version": "24.21.0",
|
|
74
73
|
"onFail": "download"
|
|
75
74
|
}
|
|
76
75
|
},
|