pw-core 0.0.1

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.
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Table = exports.TableRows = void 0;
4
+ const test_1 = require("@playwright/test");
5
+ /**
6
+ * A custom Array subclass representing a list of table rows.
7
+ * Inherits all standard Array methods while adding type-safe get and getAll capabilities.
8
+ */
9
+ class TableRows extends Array {
10
+ constructor(...items) {
11
+ // Call the base Array constructor
12
+ super(...items);
13
+ // Explicitly set the prototype for correct inheritance in ES6 environment
14
+ Object.setPrototypeOf(this, TableRows.prototype);
15
+ }
16
+ get(key, value) {
17
+ if (arguments.length === 1) {
18
+ // Return the value of the key from the first row
19
+ return this[0] ? this[0][key] : undefined;
20
+ }
21
+ // Return the first matching row
22
+ return this.find(row => row[key] === value);
23
+ }
24
+ getAll(key, value) {
25
+ if (arguments.length === 1) {
26
+ // Return the values of the key from all rows
27
+ return this.map(row => row[key]);
28
+ }
29
+ // Return all matching rows
30
+ return this.filter(row => row[key] === value);
31
+ }
32
+ }
33
+ exports.TableRows = TableRows;
34
+ class Table {
35
+ root;
36
+ constructor(root) {
37
+ this.root = root;
38
+ }
39
+ /**
40
+ * Retrieves all the headers from the table as lowercase strings.
41
+ */
42
+ async getHeaders() {
43
+ return test_1.test.step(`Get headers of table`, async () => {
44
+ const headers = await this.root.locator('th').evaluateAll(ths => ths.map(th => th.textContent?.trim().toLowerCase() || ''));
45
+ return headers;
46
+ });
47
+ }
48
+ /**
49
+ * Retrieves all the rows of the table as typed objects.
50
+ * Dynamically maps table headers to object keys.
51
+ */
52
+ async getRows() {
53
+ return test_1.test.step('Get table rows', async () => {
54
+ const headers = await this.getHeaders();
55
+ const rowsData = await this.root.locator('tbody tr, tr[data-testid="transaction-row"]').evaluateAll((trs, headers) => {
56
+ return trs.map(tr => {
57
+ const cells = Array.from(tr.querySelectorAll('td')).map(td => td.textContent?.trim() || '');
58
+ if (cells.length === 0)
59
+ return null; // Skip header or empty rows
60
+ const rowData = {};
61
+ headers.forEach((header, index) => {
62
+ if (index < cells.length && header) {
63
+ rowData[header] = cells[index];
64
+ }
65
+ });
66
+ return rowData;
67
+ });
68
+ }, headers);
69
+ return rowsData.filter((r) => r !== null);
70
+ });
71
+ }
72
+ /**
73
+ * Retrieves all rows from the table, returned as a custom TableRows collection
74
+ * with type-safe finder helper methods.
75
+ */
76
+ async get() {
77
+ const rows = await this.getRows();
78
+ return new TableRows(...rows);
79
+ }
80
+ /**
81
+ * Gets the total count of data rows in the table.
82
+ */
83
+ async getRowCount() {
84
+ return test_1.test.step('Get table row count', async () => {
85
+ return await this.root.locator('tbody tr, tr[data-testid="transaction-row"]').evaluateAll(trs => {
86
+ return trs.filter(tr => tr.querySelectorAll('td').length > 0).length;
87
+ });
88
+ });
89
+ }
90
+ /**
91
+ * Retrieves the value of a specific cell by row index and column key.
92
+ */
93
+ async getCellValue(rowIndex, column) {
94
+ return test_1.test.step(`Get table cell value at row ${rowIndex}, column "${String(column)}"`, async () => {
95
+ const headers = await this.getHeaders();
96
+ const columnIndex = headers.indexOf(String(column).toLowerCase());
97
+ if (columnIndex === -1) {
98
+ throw new Error(`Column "${String(column)}" not found in table headers: ${headers.join(', ')}`);
99
+ }
100
+ return await this.root.evaluate((tableEl, { rowIndex, columnIndex }) => {
101
+ const trs = Array.from(tableEl.querySelectorAll('tbody tr, tr[data-testid="transaction-row"]'));
102
+ const dataRows = trs.filter(tr => tr.querySelectorAll('td').length > 0);
103
+ if (rowIndex < 0 || rowIndex >= dataRows.length) {
104
+ throw new Error(`Row index ${rowIndex} is out of bounds (0 to ${dataRows.length - 1})`);
105
+ }
106
+ const cell = dataRows[rowIndex].querySelectorAll('td')[columnIndex];
107
+ return cell?.textContent?.trim() ?? '';
108
+ }, { rowIndex, columnIndex });
109
+ });
110
+ }
111
+ }
112
+ exports.Table = Table;
@@ -0,0 +1,15 @@
1
+ import type { Page } from '@playwright/test';
2
+ /** Read a value from the browser's localStorage. Returns null if the key is absent. */
3
+ export declare function getLocalStorage(page: Page, key: string): Promise<string | null>;
4
+ /** Write a value to the browser's localStorage. */
5
+ export declare function setLocalStorage(page: Page, key: string, value: string): Promise<void>;
6
+ /** Read a value from the browser's sessionStorage. Returns null if the key is absent. */
7
+ export declare function getSessionStorage(page: Page, key: string): Promise<string | null>;
8
+ /** Write a value to the browser's sessionStorage. */
9
+ export declare function setSessionStorage(page: Page, key: string, value: string): Promise<void>;
10
+ /**
11
+ * Seeds sessionStorage entries via addInitScript before any navigation.
12
+ * Only runs when authenticated cookies are present (loaded from storageState),
13
+ * so unauthenticated tests that clear storageState are unaffected.
14
+ */
15
+ export declare function seedSessionStorage(page: Page, entries: Record<string, string>): Promise<void>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLocalStorage = getLocalStorage;
4
+ exports.setLocalStorage = setLocalStorage;
5
+ exports.getSessionStorage = getSessionStorage;
6
+ exports.setSessionStorage = setSessionStorage;
7
+ exports.seedSessionStorage = seedSessionStorage;
8
+ /** Read a value from the browser's localStorage. Returns null if the key is absent. */
9
+ async function getLocalStorage(page, key) {
10
+ return page.evaluate((k) => localStorage.getItem(k), key);
11
+ }
12
+ /** Write a value to the browser's localStorage. */
13
+ async function setLocalStorage(page, key, value) {
14
+ await page.evaluate(([k, v]) => localStorage.setItem(k, v), [key, value]);
15
+ }
16
+ /** Read a value from the browser's sessionStorage. Returns null if the key is absent. */
17
+ async function getSessionStorage(page, key) {
18
+ return page.evaluate((k) => sessionStorage.getItem(k), key);
19
+ }
20
+ /** Write a value to the browser's sessionStorage. */
21
+ async function setSessionStorage(page, key, value) {
22
+ await page.evaluate(([k, v]) => sessionStorage.setItem(k, v), [key, value]);
23
+ }
24
+ /**
25
+ * Seeds sessionStorage entries via addInitScript before any navigation.
26
+ * Only runs when authenticated cookies are present (loaded from storageState),
27
+ * so unauthenticated tests that clear storageState are unaffected.
28
+ */
29
+ async function seedSessionStorage(page, entries) {
30
+ const cookies = await page.context().cookies();
31
+ if (cookies.length > 0) {
32
+ const pairs = Object.entries(entries);
33
+ await page.addInitScript((items) => {
34
+ for (const [key, value] of items) {
35
+ sessionStorage.setItem(key, value);
36
+ }
37
+ }, pairs);
38
+ }
39
+ }
@@ -0,0 +1,10 @@
1
+ import { Locator } from '@playwright/test';
2
+ import { AllowedMethodKeys } from '../config';
3
+ export declare function executeAction(prop: AllowedMethodKeys, resolveLocatorFn: (target: any, options?: {
4
+ nth?: number;
5
+ raw?: boolean;
6
+ }) => Locator, timeout: number | undefined, args: any[]): Promise<any>;
7
+ export declare function defineActionMethods(instance: any, resolveLocatorFn: (target: any, options?: {
8
+ nth?: number;
9
+ raw?: boolean;
10
+ }) => Locator, timeout: number | undefined): void;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executeAction = executeAction;
4
+ exports.defineActionMethods = defineActionMethods;
5
+ const test_1 = require("@playwright/test");
6
+ const config_1 = require("../config");
7
+ const formatter_1 = require("../utils/formatter");
8
+ function executeAction(prop, resolveLocatorFn, timeout, args) {
9
+ const [locatorKey, ...methodArgs] = args;
10
+ let optNth = undefined;
11
+ const optionsIndex = (0, config_1.getOptionsArgumentIndex)(prop);
12
+ if (optionsIndex !== -1 && methodArgs.length > optionsIndex) {
13
+ const opts = methodArgs[optionsIndex];
14
+ if (opts && typeof opts === 'object' && 'nth' in opts) {
15
+ optNth = opts.nth;
16
+ }
17
+ }
18
+ const isCount = prop === 'count';
19
+ const locator = resolveLocatorFn(locatorKey, { nth: optNth, raw: isCount });
20
+ const method = locator[prop];
21
+ if (typeof method !== 'function') {
22
+ throw new Error(`Property '${prop}' does not exist on Locator.`);
23
+ }
24
+ if (prop === 'dragTo' && methodArgs.length > 0) {
25
+ methodArgs[0] = resolveLocatorFn(methodArgs[0]);
26
+ }
27
+ if (timeout !== undefined) {
28
+ if (optionsIndex !== -1) {
29
+ while (methodArgs.length < optionsIndex) {
30
+ methodArgs.push(undefined);
31
+ }
32
+ const existingOptions = methodArgs[optionsIndex] || {};
33
+ methodArgs[optionsIndex] = { timeout, ...existingOptions };
34
+ }
35
+ }
36
+ const stepName = (0, formatter_1.formatStepDescription)(prop, locatorKey, methodArgs);
37
+ if (prop === 'fill' && methodArgs.length > 1) {
38
+ const opts = methodArgs[1];
39
+ if (opts && typeof opts === 'object' && 'mask' in opts) {
40
+ const { mask, ...playwrightOpts } = opts;
41
+ methodArgs[1] = playwrightOpts;
42
+ }
43
+ }
44
+ return test_1.test.step(stepName, () => {
45
+ return method.apply(locator, methodArgs);
46
+ });
47
+ }
48
+ function defineActionMethods(instance, resolveLocatorFn, timeout) {
49
+ const locatorMethods = [...config_1.zeroArgMethodsList, ...config_1.oneArgMethodsList];
50
+ for (const prop of locatorMethods) {
51
+ Object.defineProperty(instance, prop, {
52
+ value: (...args) => {
53
+ return executeAction(prop, resolveLocatorFn, timeout, args);
54
+ },
55
+ writable: true,
56
+ configurable: true,
57
+ enumerable: false
58
+ });
59
+ }
60
+ }
@@ -0,0 +1,39 @@
1
+ import { Page, expect as playwrightExpect } from '@playwright/test';
2
+ type GotoOptions = {
3
+ referrer?: string;
4
+ timeout?: number;
5
+ waitUntil?: 'load' | 'domcontentloaded' | 'networkidle' | 'commit';
6
+ };
7
+ type ToHaveURLOptions = Parameters<ReturnType<typeof playwrightExpect<Page>>['toHaveURL']>[1];
8
+ type ToHaveTitleOptions = Parameters<ReturnType<typeof playwrightExpect<Page>>['toHaveTitle']>[1];
9
+ /**
10
+ * Navigate to the page URL defined in the page config.
11
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-goto Page.goto} in a test step.
12
+ */
13
+ export declare function goto(page: Page, url: string | undefined, constructorName: string, options?: GotoOptions): Promise<void>;
14
+ /**
15
+ * Assert the current URL matches the page config URL or a custom pattern.
16
+ * Uses {@link https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-url expect(page).toHaveURL}.
17
+ */
18
+ export declare function verifyURL(page: Page, url: string | undefined, constructorName: string, urlOrOptions?: string | RegExp | ToHaveURLOptions, options?: ToHaveURLOptions): Promise<void>;
19
+ /**
20
+ * Assert the page title matches the expected value.
21
+ * Uses {@link https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-title expect(page).toHaveTitle}.
22
+ */
23
+ export declare function verifyTitle(page: Page, title: string | RegExp, options?: ToHaveTitleOptions): Promise<void>;
24
+ /**
25
+ * Reload the page.
26
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-reload Page.reload} in a test step.
27
+ */
28
+ export declare function reload(page: Page, options?: Parameters<Page['reload']>[0]): Promise<void>;
29
+ /**
30
+ * Wait for the page to reach a load state.
31
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-wait-for-load-state Page.waitForLoadState} in a test step.
32
+ */
33
+ export declare function waitForLoadState(page: Page, state?: Parameters<Page['waitForLoadState']>[0], options?: Parameters<Page['waitForLoadState']>[1]): Promise<void>;
34
+ /**
35
+ * Wait for navigation to a URL. Defaults to the page config URL when no pattern is given.
36
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-wait-for-url Page.waitForURL} in a test step.
37
+ */
38
+ export declare function waitForURL(page: Page, url: string | undefined, constructorName: string, urlOrOptions?: string | RegExp | Parameters<Page['waitForURL']>[1], options?: Parameters<Page['waitForURL']>[1]): Promise<void>;
39
+ export {};
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.goto = goto;
4
+ exports.verifyURL = verifyURL;
5
+ exports.verifyTitle = verifyTitle;
6
+ exports.reload = reload;
7
+ exports.waitForLoadState = waitForLoadState;
8
+ exports.waitForURL = waitForURL;
9
+ const test_1 = require("@playwright/test");
10
+ function resolveUrlPattern(url, constructorName, urlOrOptions, options) {
11
+ let targetUrl;
12
+ let actualOptions = options;
13
+ if (urlOrOptions !== undefined && (typeof urlOrOptions === 'string' || urlOrOptions instanceof RegExp)) {
14
+ if (typeof urlOrOptions === 'string') {
15
+ targetUrl = new RegExp('.*' + urlOrOptions.replace('/#', ''));
16
+ }
17
+ else {
18
+ targetUrl = urlOrOptions;
19
+ }
20
+ }
21
+ else {
22
+ if (!url) {
23
+ throw new Error(`URL is not defined on ${constructorName}`);
24
+ }
25
+ targetUrl = new RegExp('.*' + url.replace('/#', ''));
26
+ if (typeof urlOrOptions === 'object') {
27
+ actualOptions = urlOrOptions;
28
+ }
29
+ }
30
+ return { targetUrl, actualOptions };
31
+ }
32
+ /**
33
+ * Navigate to the page URL defined in the page config.
34
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-goto Page.goto} in a test step.
35
+ */
36
+ async function goto(page, url, constructorName, options) {
37
+ await test_1.test.step(`Goto "${url || ''}"`, async () => {
38
+ if (!url) {
39
+ throw new Error(`URL is not defined on ${constructorName}`);
40
+ }
41
+ await page.goto(url, options);
42
+ });
43
+ }
44
+ /**
45
+ * Assert the current URL matches the page config URL or a custom pattern.
46
+ * Uses {@link https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-url expect(page).toHaveURL}.
47
+ */
48
+ async function verifyURL(page, url, constructorName, urlOrOptions, options) {
49
+ const { targetUrl, actualOptions } = resolveUrlPattern(url, constructorName, urlOrOptions, options);
50
+ const stepName = `Verify URL matches "${targetUrl.toString()}"`;
51
+ await test_1.test.step(stepName, async () => {
52
+ await (0, test_1.expect)(page).toHaveURL(targetUrl, actualOptions);
53
+ });
54
+ }
55
+ /**
56
+ * Assert the page title matches the expected value.
57
+ * Uses {@link https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-title expect(page).toHaveTitle}.
58
+ */
59
+ async function verifyTitle(page, title, options) {
60
+ const stepName = `Verify title matches "${title}"`;
61
+ await test_1.test.step(stepName, async () => {
62
+ await (0, test_1.expect)(page).toHaveTitle(title, options);
63
+ });
64
+ }
65
+ /**
66
+ * Reload the page.
67
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-reload Page.reload} in a test step.
68
+ */
69
+ async function reload(page, options) {
70
+ await test_1.test.step('Reload page', async () => {
71
+ await page.reload(options);
72
+ });
73
+ }
74
+ /**
75
+ * Wait for the page to reach a load state.
76
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-wait-for-load-state Page.waitForLoadState} in a test step.
77
+ */
78
+ async function waitForLoadState(page, state, options) {
79
+ const stepName = `Wait for load state "${state ?? 'load'}"`;
80
+ await test_1.test.step(stepName, async () => {
81
+ await page.waitForLoadState(state, options);
82
+ });
83
+ }
84
+ /**
85
+ * Wait for navigation to a URL. Defaults to the page config URL when no pattern is given.
86
+ * Wraps {@link https://playwright.dev/docs/api/class-page#page-wait-for-url Page.waitForURL} in a test step.
87
+ */
88
+ async function waitForURL(page, url, constructorName, urlOrOptions, options) {
89
+ let targetUrl;
90
+ let actualOptions = options;
91
+ if (urlOrOptions !== undefined && (typeof urlOrOptions === 'string' || urlOrOptions instanceof RegExp)) {
92
+ targetUrl = urlOrOptions;
93
+ }
94
+ else {
95
+ if (!url) {
96
+ throw new Error(`URL is not defined on ${constructorName}`);
97
+ }
98
+ targetUrl = url;
99
+ if (typeof urlOrOptions === 'object') {
100
+ actualOptions = urlOrOptions;
101
+ }
102
+ }
103
+ const stepName = `Wait for URL "${targetUrl.toString()}"`;
104
+ await test_1.test.step(stepName, async () => {
105
+ await page.waitForURL(targetUrl, actualOptions);
106
+ });
107
+ }
@@ -0,0 +1,2 @@
1
+ import { Locator, expect as playwrightExpect } from '@playwright/test';
2
+ export declare function typedExpect(resolved: Locator, message?: string): ReturnType<typeof playwrightExpect<Locator>>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.typedExpect = typedExpect;
4
+ const test_1 = require("@playwright/test");
5
+ function typedExpect(resolved, message) {
6
+ return (0, test_1.expect)(resolved, message);
7
+ }
@@ -0,0 +1,63 @@
1
+ import { Locator, expect as playwrightExpect } from '@playwright/test';
2
+ import { ChainedKeys, PageKeys } from '../config';
3
+ export type VerifyOptions = {
4
+ timeout?: number;
5
+ nth?: number;
6
+ message?: string;
7
+ };
8
+ type PlaywrightLocatorMatchers = ReturnType<typeof playwrightExpect<Locator>>;
9
+ type ModifyMatcherArgs<Args extends any[]> = Args extends [] ? [options?: {
10
+ nth?: number;
11
+ message?: string;
12
+ }] : Args extends [any, any?] ? [Args[0], (Exclude<Args[1], undefined> & {
13
+ nth?: number;
14
+ message?: string;
15
+ })?] : Args extends [any?] ? Exclude<Args[0], undefined> extends object ? [(Exclude<Args[0], undefined> & {
16
+ nth?: number;
17
+ message?: string;
18
+ })?] : [Exclude<Args[0], undefined>, options?: {
19
+ nth?: number;
20
+ message?: string;
21
+ }] : [options?: {
22
+ nth?: number;
23
+ message?: string;
24
+ }];
25
+ type DynamicallyModifiedMatchers<T> = {
26
+ [K in keyof PlaywrightLocatorMatchers]: K extends 'not' ? Omit<VerifyMatchers<T>, 'not'> : PlaywrightLocatorMatchers[K] extends (...args: infer Args) => any ? (...args: ModifyMatcherArgs<Args>) => Promise<void> : PlaywrightLocatorMatchers[K];
27
+ };
28
+ export type VerifyMatchers<T> = DynamicallyModifiedMatchers<T> & PromiseLike<void> & {
29
+ (options?: Parameters<PlaywrightLocatorMatchers['toBeVisible']>[0] & {
30
+ nth?: number;
31
+ message?: string;
32
+ }): Promise<void>;
33
+ };
34
+ export type VerifyFn<T> = (target: PageKeys<T> | ChainedKeys<T> | Locator, options?: VerifyOptions) => VerifyMatchers<T>;
35
+ export type AssertionsMethod<T> = {
36
+ verify: VerifyFn<T> & {
37
+ soft: VerifyFn<T>;
38
+ };
39
+ verifyHidden(target: PageKeys<T> | ChainedKeys<T> | Locator, options?: Parameters<ReturnType<typeof playwrightExpect<Locator>>['toBeHidden']>[0] & {
40
+ nth?: number;
41
+ message?: string;
42
+ }): Promise<void>;
43
+ verifyEnabled(target: PageKeys<T> | ChainedKeys<T> | Locator, options?: Parameters<ReturnType<typeof playwrightExpect<Locator>>['toBeEnabled']>[0] & {
44
+ nth?: number;
45
+ message?: string;
46
+ }): Promise<void>;
47
+ verifyDisabled(target: PageKeys<T> | ChainedKeys<T> | Locator, options?: Parameters<ReturnType<typeof playwrightExpect<Locator>>['toBeDisabled']>[0] & {
48
+ nth?: number;
49
+ message?: string;
50
+ }): Promise<void>;
51
+ expect(target: PageKeys<T> | ChainedKeys<T> | Locator, message?: string): ReturnType<typeof playwrightExpect<Locator>>;
52
+ locator(target: PageKeys<T> | ChainedKeys<T> | Locator, options?: Parameters<Locator['filter']>[0] & {
53
+ nth?: number;
54
+ }): Locator;
55
+ };
56
+ export declare function createVerifyChain<T extends {
57
+ testIds?: Record<string, string>;
58
+ selectors?: Record<string, string>;
59
+ }>(resolveLocator: (target: any, options?: {
60
+ nth?: number;
61
+ raw?: boolean;
62
+ }) => Locator, target: PageKeys<T> | ChainedKeys<T> | Locator, verifyOptions: VerifyOptions | undefined, isSoft: boolean): VerifyMatchers<T>;
63
+ export {};
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createVerifyChain = createVerifyChain;
4
+ const test_1 = require("@playwright/test");
5
+ const formatter_1 = require("../utils/formatter");
6
+ function createVerifyChain(resolveLocator, target, verifyOptions, isSoft) {
7
+ const defaultNth = verifyOptions?.nth;
8
+ const defaultMessage = verifyOptions?.message;
9
+ const expectFn = isSoft ? test_1.expect.soft : test_1.expect;
10
+ const createMatcher = (isNegated) => {
11
+ const baseFn = async (options) => {
12
+ const nth = options?.nth !== undefined ? options.nth : defaultNth;
13
+ const stepName = options?.message ?? defaultMessage ?? (0, formatter_1.formatAssertionDescription)(target, 'toBeVisible', isNegated, [options]);
14
+ await test_1.test.step(stepName, async () => {
15
+ const locator = resolveLocator(target, { nth });
16
+ const expectation = expectFn(locator, stepName);
17
+ const match = isNegated ? expectation.not : expectation;
18
+ await match.toBeVisible(options);
19
+ });
20
+ };
21
+ return new Proxy(baseFn, {
22
+ get(targetObj, prop) {
23
+ if (typeof prop === 'symbol') {
24
+ return targetObj[prop];
25
+ }
26
+ if (prop === 'not') {
27
+ if (isNegated)
28
+ return undefined;
29
+ return createMatcher(true);
30
+ }
31
+ if (prop === 'then') {
32
+ return (onfulfilled, onrejected) => {
33
+ return baseFn().then(onfulfilled, onrejected);
34
+ };
35
+ }
36
+ const skippedProps = new Set(['then', 'catch', 'finally', 'bind', 'call', 'apply', 'toString', 'valueOf', 'toLocaleString']);
37
+ if (skippedProps.has(prop)) {
38
+ return targetObj[prop];
39
+ }
40
+ return async (...args) => {
41
+ const lastArg = args[args.length - 1];
42
+ const lastIsOptions = lastArg !== null && typeof lastArg === 'object' && !(lastArg instanceof RegExp) && !Array.isArray(lastArg);
43
+ const valueArgs = lastIsOptions ? args.slice(0, args.length - 1) : args;
44
+ const options = lastIsOptions ? lastArg : undefined;
45
+ const nth = (options && 'nth' in options) ? options.nth : defaultNth;
46
+ const isHaveCount = prop === 'toHaveCount';
47
+ const stepName = options?.message ?? defaultMessage ?? (0, formatter_1.formatAssertionDescription)(target, String(prop), isNegated, valueArgs);
48
+ await test_1.test.step(stepName, async () => {
49
+ const locator = resolveLocator(target, { nth, raw: isHaveCount });
50
+ const expectation = expectFn(locator, stepName);
51
+ const match = isNegated ? expectation.not : expectation;
52
+ await match[prop](...args);
53
+ });
54
+ };
55
+ }
56
+ });
57
+ };
58
+ return createMatcher(false);
59
+ }
@@ -0,0 +1,22 @@
1
+ import { Locator, expect as playwrightExpect } from '@playwright/test';
2
+ export declare function verifyHidden(resolveLocator: (target: any, options?: {
3
+ nth?: number;
4
+ raw?: boolean;
5
+ }) => Locator, target: any, options?: Parameters<ReturnType<typeof playwrightExpect<Locator>>['toBeHidden']>[0] & {
6
+ nth?: number;
7
+ message?: string;
8
+ }): Promise<void>;
9
+ export declare function verifyEnabled(resolveLocator: (target: any, options?: {
10
+ nth?: number;
11
+ raw?: boolean;
12
+ }) => Locator, target: any, options?: Parameters<ReturnType<typeof playwrightExpect<Locator>>['toBeEnabled']>[0] & {
13
+ nth?: number;
14
+ message?: string;
15
+ }): Promise<void>;
16
+ export declare function verifyDisabled(resolveLocator: (target: any, options?: {
17
+ nth?: number;
18
+ raw?: boolean;
19
+ }) => Locator, target: any, options?: Parameters<ReturnType<typeof playwrightExpect<Locator>>['toBeDisabled']>[0] & {
20
+ nth?: number;
21
+ message?: string;
22
+ }): Promise<void>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyHidden = verifyHidden;
4
+ exports.verifyEnabled = verifyEnabled;
5
+ exports.verifyDisabled = verifyDisabled;
6
+ const test_1 = require("@playwright/test");
7
+ const formatter_1 = require("../utils/formatter");
8
+ async function verifyHidden(resolveLocator, target, options) {
9
+ const stepName = options?.message ?? (0, formatter_1.formatAssertionDescription)(target, 'toBeHidden', false, [options]);
10
+ await test_1.test.step(stepName, async () => {
11
+ const locator = resolveLocator(target, { nth: options?.nth });
12
+ await (0, test_1.expect)(locator, stepName).toBeHidden(options);
13
+ });
14
+ }
15
+ async function verifyEnabled(resolveLocator, target, options) {
16
+ const stepName = options?.message ?? (0, formatter_1.formatAssertionDescription)(target, 'toBeEnabled', false, [options]);
17
+ await test_1.test.step(stepName, async () => {
18
+ const locator = resolveLocator(target, { nth: options?.nth });
19
+ await (0, test_1.expect)(locator, stepName).toBeEnabled(options);
20
+ });
21
+ }
22
+ async function verifyDisabled(resolveLocator, target, options) {
23
+ const stepName = options?.message ?? (0, formatter_1.formatAssertionDescription)(target, 'toBeDisabled', false, [options]);
24
+ await test_1.test.step(stepName, async () => {
25
+ const locator = resolveLocator(target, { nth: options?.nth });
26
+ await (0, test_1.expect)(locator, stepName).toBeDisabled(options);
27
+ });
28
+ }
@@ -0,0 +1,31 @@
1
+ import { Locator, Page } from '@playwright/test';
2
+ export { ProxyLocatorMethods } from './types/proxy-methods';
3
+ export declare const zeroArgMethodsList: readonly ["click", "dblclick", "hover", "focus", "blur", "check", "uncheck", "clear", "waitFor", "isChecked", "isDisabled", "isVisible", "textContent", "innerText", "allInnerTexts", "allTextContents", "count", "scrollIntoViewIfNeeded", "boundingBox"];
4
+ export declare const oneArgMethodsList: readonly ["fill", "press", "pressSequentially", "selectOption", "setInputFiles", "getAttribute", "dragTo"];
5
+ export type AllowedZeroArgMethods = typeof zeroArgMethodsList[number];
6
+ export type AllowedOneArgMethods = typeof oneArgMethodsList[number];
7
+ export type AllowedMethodKeys = AllowedZeroArgMethods | AllowedOneArgMethods;
8
+ export type PageKeys<T> = (T extends {
9
+ testIds?: infer I;
10
+ } ? keyof I & string : never) | (T extends {
11
+ selectors?: infer S;
12
+ } ? keyof S & string : never);
13
+ export type TypedLocators<T> = {
14
+ [K in PageKeys<T>]: Locator;
15
+ };
16
+ export type ChainedKeys<T> = `${PageKeys<T>}.${PageKeys<T>}`;
17
+ export type TargetKey<T> = PageKeys<T> | ChainedKeys<T> | Locator;
18
+ export type ValidateTarget<K, T> = K extends Locator ? Locator : K extends (PageKeys<T> | ChainedKeys<T>) ? K : never;
19
+ export declare function getOptionsArgumentIndex(methodName: AllowedMethodKeys): number;
20
+ export type PageConfig<T = any> = {
21
+ url?: string;
22
+ testIds?: Record<string, string>;
23
+ selectors?: T extends {
24
+ testIds: infer I;
25
+ selectors: infer S;
26
+ } ? {
27
+ [K in keyof S]: K extends keyof I ? `Duplicate key: ${K & string} already exists in testIds` : S[K];
28
+ } : Record<string, string>;
29
+ Class?: new (page: Page, config?: any) => any;
30
+ };
31
+ export declare function createPageConfig<T extends PageConfig<T>>(config: T): T;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oneArgMethodsList = exports.zeroArgMethodsList = void 0;
4
+ exports.getOptionsArgumentIndex = getOptionsArgumentIndex;
5
+ exports.createPageConfig = createPageConfig;
6
+ exports.zeroArgMethodsList = [
7
+ 'click', 'dblclick', 'hover', 'focus', 'blur', 'check', 'uncheck', 'clear',
8
+ 'waitFor', 'isChecked', 'isDisabled',
9
+ 'isVisible', 'textContent', 'innerText',
10
+ 'allInnerTexts', 'allTextContents', 'count',
11
+ 'scrollIntoViewIfNeeded', 'boundingBox'
12
+ ];
13
+ exports.oneArgMethodsList = [
14
+ 'fill', 'press', 'pressSequentially', 'selectOption', 'setInputFiles',
15
+ 'getAttribute', 'dragTo'
16
+ ];
17
+ function getOptionsArgumentIndex(methodName) {
18
+ if (exports.zeroArgMethodsList.includes(methodName))
19
+ return 0;
20
+ if (exports.oneArgMethodsList.includes(methodName))
21
+ return 1;
22
+ return -1;
23
+ }
24
+ function createPageConfig(config) {
25
+ return config;
26
+ }
@@ -0,0 +1,10 @@
1
+ export * from './config';
2
+ export * from './utils/formatter';
3
+ export * from './assertions/verify-chain';
4
+ export * from './assertions/verify-helpers';
5
+ export * from './assertions/expect';
6
+ export * from './actions/page-actions';
7
+ export * from './actions/locator-actions';
8
+ export * from './locators/resolver';
9
+ export * from './typed-page';
10
+ export * from './registry';