pw-core 1.2.1 → 1.3.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.
- package/README.md +2 -1
- package/dist/cli.js +145 -421
- package/dist/codegen/action-formatter.d.ts +19 -0
- package/dist/codegen/action-formatter.js +160 -0
- package/dist/codegen/action-processor.d.ts +23 -0
- package/dist/codegen/action-processor.js +112 -0
- package/dist/codegen/floating-panel/client.d.ts +14 -1
- package/dist/codegen/floating-panel/client.js +20 -25
- package/dist/codegen/floating-panel/manager.js +16 -22
- package/dist/codegen/generator/action.validator.d.ts +2 -1
- package/dist/codegen/generator/action.validator.js +2 -1
- package/dist/codegen/generator/candidate-scorer.d.ts +7 -0
- package/dist/codegen/generator/candidate-scorer.js +206 -0
- package/dist/codegen/generator/dom-scanner.d.ts +39 -0
- package/dist/codegen/generator/dom-scanner.js +429 -0
- package/dist/codegen/generator/id-stability.d.ts +6 -0
- package/dist/codegen/generator/id-stability.js +38 -0
- package/dist/codegen/generator/index.d.ts +8 -10
- package/dist/codegen/generator/index.js +23 -678
- package/dist/codegen/generator/key-builder.d.ts +13 -0
- package/dist/codegen/generator/key-builder.js +32 -0
- package/dist/codegen/hover-tracker/client.d.ts +5 -0
- package/dist/codegen/hover-tracker/client.js +14 -15
- package/dist/codegen/hover-tracker/manager.js +2 -6
- package/dist/codegen/index.d.ts +9 -32
- package/dist/codegen/index.js +9 -1128
- package/dist/codegen/key-utils.d.ts +16 -0
- package/dist/codegen/key-utils.js +29 -1
- package/dist/codegen/project-finder.d.ts +29 -0
- package/dist/codegen/project-finder.js +283 -0
- package/dist/codegen/registry-matcher.d.ts +27 -0
- package/dist/codegen/registry-matcher.js +254 -0
- package/dist/codegen/registry-store.d.ts +52 -0
- package/dist/codegen/registry-store.js +652 -0
- package/dist/codegen/selector-parser.d.ts +16 -0
- package/dist/codegen/selector-parser.js +121 -0
- package/dist/codegen/types.d.ts +18 -1
- package/dist/codegen/uniqueness.d.ts +3 -0
- package/dist/codegen/uniqueness.js +15 -0
- package/dist/component/table.d.ts +2 -2
- package/dist/component/table.js +7 -6
- package/dist/index.d.ts +3 -0
- package/dist/index.js +19 -0
- package/dist/page/actions/locator-actions.d.ts +6 -10
- package/dist/page/actions/locator-actions.js +24 -23
- package/dist/page/assertions/verify-chain.d.ts +11 -13
- package/dist/page/assertions/verify-chain.js +26 -7
- package/dist/page/assertions/verify-helpers.d.ts +5 -15
- package/dist/page/config.d.ts +25 -25
- package/dist/page/locators/dynamic-locator-resolver.js +22 -9
- package/dist/page/locators/resolver.d.ts +17 -11
- package/dist/page/locators/resolver.js +84 -78
- package/dist/page/registry.d.ts +35 -35
- package/dist/page/registry.js +86 -82
- package/dist/page/typed-page.d.ts +1 -0
- package/dist/page/typed-page.js +22 -12
- package/dist/page/types/proxy-methods.d.ts +11 -19
- package/dist/page/types/validation.d.ts +1 -1
- package/dist/page/utils/formatter.d.ts +3 -3
- package/dist/page/utils/formatter.js +5 -2
- package/package.json +6 -3
package/dist/page/registry.js
CHANGED
|
@@ -7,9 +7,36 @@ exports.createPageRegistry = createPageRegistry;
|
|
|
7
7
|
const test_1 = __importDefault(require("@playwright/test"));
|
|
8
8
|
const typed_page_1 = require("./typed-page");
|
|
9
9
|
const resolver_1 = require("./locators/resolver");
|
|
10
|
-
|
|
10
|
+
// Local runtime key transformation helpers for fixture aliases.
|
|
11
|
+
// Intentionally kept local to preserve runtime isolation (page/ does not depend on codegen/).
|
|
12
|
+
function toUnprefixedPageKey(key) {
|
|
13
|
+
return key.slice(6).charAt(0).toLowerCase() + key.slice(7);
|
|
14
|
+
}
|
|
15
|
+
function toWorkerPageKey(key) {
|
|
16
|
+
return key.startsWith('worker') ? key : `worker${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
17
|
+
}
|
|
18
|
+
function getPageKeyAliases(key) {
|
|
19
|
+
if (key.startsWith('worker')) {
|
|
20
|
+
const unprefixed = toUnprefixedPageKey(key);
|
|
21
|
+
return { pageKey: unprefixed || key, workerKey: key };
|
|
22
|
+
}
|
|
23
|
+
return { pageKey: key, workerKey: toWorkerPageKey(key) };
|
|
24
|
+
}
|
|
25
|
+
function createPageFixture(PageClass) {
|
|
26
|
+
return async ({ page }, use) => {
|
|
27
|
+
await use(new PageClass(page));
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function createWorkerFixture(PageClass) {
|
|
31
|
+
return [
|
|
32
|
+
async ({ workerPage }, use) => {
|
|
33
|
+
await use(new PageClass(workerPage));
|
|
34
|
+
},
|
|
35
|
+
{ scope: 'worker' }
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
function createRegistryFixtures(registry, classes) {
|
|
11
39
|
const fixtures = {
|
|
12
|
-
// Shared worker context and page
|
|
13
40
|
workerContext: [
|
|
14
41
|
async ({ browser }, use) => {
|
|
15
42
|
const context = await browser.newContext();
|
|
@@ -20,82 +47,59 @@ function createPageRegistryWithClasses(registry, classes, base) {
|
|
|
20
47
|
],
|
|
21
48
|
workerPage: [
|
|
22
49
|
async ({ workerContext }, use) => {
|
|
23
|
-
|
|
24
|
-
await use(page);
|
|
50
|
+
await use(await workerContext.newPage());
|
|
25
51
|
},
|
|
26
52
|
{ scope: 'worker' }
|
|
27
53
|
]
|
|
28
54
|
};
|
|
29
55
|
for (const key of Object.keys(registry)) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
await use(instance);
|
|
35
|
-
};
|
|
36
|
-
// Page fixture for un-prefixed key (if key starts with worker)
|
|
37
|
-
if (key.startsWith('worker')) {
|
|
38
|
-
const unPrefixed = key.slice(6).charAt(0).toLowerCase() + key.slice(7);
|
|
39
|
-
if (unPrefixed && !fixtures[unPrefixed]) {
|
|
40
|
-
fixtures[unPrefixed] = async ({ page }, use) => {
|
|
41
|
-
const PageClass = classes[key];
|
|
42
|
-
const instance = new PageClass(page);
|
|
43
|
-
await use(instance);
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
// Worker fixture for worker-prefixed key
|
|
48
|
-
const workerKey = key.startsWith('worker') ? key : `worker${key.charAt(0).toUpperCase()}${key.slice(1)}`;
|
|
49
|
-
fixtures[workerKey] = [
|
|
50
|
-
async ({ workerPage }, use) => {
|
|
51
|
-
const PageClass = classes[key];
|
|
52
|
-
const instance = new PageClass(workerPage);
|
|
53
|
-
await use(instance);
|
|
54
|
-
},
|
|
55
|
-
{ scope: 'worker' }
|
|
56
|
-
];
|
|
56
|
+
const PageClass = classes[key];
|
|
57
|
+
const { pageKey, workerKey } = getPageKeyAliases(key);
|
|
58
|
+
fixtures[pageKey] = createPageFixture(PageClass);
|
|
59
|
+
fixtures[workerKey] = createWorkerFixture(PageClass);
|
|
57
60
|
}
|
|
61
|
+
return fixtures;
|
|
62
|
+
}
|
|
63
|
+
function createPageRegistryWithClasses(registry, classes, base) {
|
|
64
|
+
const fixtures = createRegistryFixtures(registry, classes);
|
|
58
65
|
// Copy worker and non-worker aliases in pages and classes dictionaries
|
|
59
66
|
const extendedClasses = { ...classes };
|
|
60
67
|
for (const key of Object.keys(classes)) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
extendedClasses[unPrefixed] = classes[key];
|
|
65
|
-
}
|
|
68
|
+
const { pageKey, workerKey } = getPageKeyAliases(key);
|
|
69
|
+
if (!extendedClasses[pageKey]) {
|
|
70
|
+
extendedClasses[pageKey] = classes[key];
|
|
66
71
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!extendedClasses[workerKey]) {
|
|
70
|
-
extendedClasses[workerKey] = classes[key];
|
|
71
|
-
}
|
|
72
|
+
if (!extendedClasses[workerKey]) {
|
|
73
|
+
extendedClasses[workerKey] = classes[key];
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
// Playwright compatibility boundary: extend test runner with fixtures and attach registry dictionaries
|
|
77
|
+
const rawRunner = base.extend(fixtures);
|
|
78
|
+
rawRunner.pages = extendedClasses;
|
|
79
|
+
rawRunner.classes = extendedClasses;
|
|
80
|
+
const originalExtend = rawRunner.extend.bind(rawRunner);
|
|
81
|
+
rawRunner.extend = (overrides, customBase = test_1.default) => {
|
|
79
82
|
if (!overrides) {
|
|
80
83
|
return originalExtend();
|
|
81
84
|
}
|
|
82
|
-
const
|
|
85
|
+
const overridesObj = overrides;
|
|
86
|
+
const isPlaywrightFixtures = Object.values(overridesObj).every((val) => (typeof val === 'function' && !val.toString().startsWith('class')) || Array.isArray(val));
|
|
83
87
|
if (isPlaywrightFixtures) {
|
|
84
88
|
const runner = originalExtend(overrides);
|
|
85
89
|
runner.pages = extendedClasses;
|
|
86
90
|
runner.classes = extendedClasses;
|
|
87
|
-
runner.extend =
|
|
91
|
+
runner.extend = rawRunner.extend;
|
|
88
92
|
return runner;
|
|
89
93
|
}
|
|
90
94
|
const newClasses = { ...classes };
|
|
91
|
-
for (const key of Object.keys(
|
|
92
|
-
if (
|
|
93
|
-
newClasses[key] =
|
|
95
|
+
for (const key of Object.keys(overridesObj)) {
|
|
96
|
+
if (overridesObj[key]) {
|
|
97
|
+
newClasses[key] = overridesObj[key];
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
|
-
return createPageRegistryWithClasses(registry, newClasses, customBase);
|
|
100
|
+
return createPageRegistryWithClasses(registry, newClasses, (customBase ?? test_1.default));
|
|
97
101
|
};
|
|
98
|
-
return
|
|
102
|
+
return rawRunner;
|
|
99
103
|
}
|
|
100
104
|
/**
|
|
101
105
|
* Creates a page registry that registers page objects as Playwright fixtures,
|
|
@@ -108,35 +112,35 @@ function createPageRegistryWithClasses(registry, classes, base) {
|
|
|
108
112
|
*
|
|
109
113
|
* // returns the extended test runner directly
|
|
110
114
|
* const test = createPageRegistry({
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
115
|
+
codegenPage: {
|
|
116
|
+
url: '/',
|
|
117
|
+
selectors: {
|
|
118
|
+
'{item}': {
|
|
119
|
+
item: ['why-pw-core', 'why-not-playwright', 'registry', 'typed-page', 'features'],
|
|
120
|
+
selector: '[data-parent-id="{item}"]'
|
|
121
|
+
},
|
|
122
|
+
copyToClipboardBtn: '.page',
|
|
123
|
+
dynamicLocators: 'text="Dynamic Locators" >> nth=0',
|
|
124
|
+
rootrailthumbright: '#rootRailThumbRight',
|
|
125
|
+
'text{item}': {
|
|
126
|
+
item: ['Auto Steps', 'Capabilities >> nth=0', 'Secret Masking'],
|
|
127
|
+
selector: 'text="{item}"'
|
|
128
|
+
},
|
|
129
|
+
tshirts: '.title-title',
|
|
130
|
+
tShirts: 'internal:role=link[name="T-Shirts"s]'
|
|
131
|
+
},
|
|
132
|
+
testIds: {
|
|
133
|
+
qaWorkspaceBtn: 'active-workspace-btn',
|
|
134
|
+
wsOptionApp: 'ws-option-app'
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
blankPage: {
|
|
138
|
+
url: '/',
|
|
139
|
+
selectors: {
|
|
140
|
+
element: '[data-pw-cursor="pointer"]'
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
});
|
|
140
144
|
*
|
|
141
145
|
* // returns page classes only when accessing .pages
|
|
142
146
|
* const pages = createPageRegistry({
|
package/dist/page/typed-page.js
CHANGED
|
@@ -17,12 +17,13 @@ class TypedPageClass {
|
|
|
17
17
|
timeout;
|
|
18
18
|
constructor(context, config, options) {
|
|
19
19
|
this.context = context;
|
|
20
|
-
|
|
20
|
+
const hasPageFn = typeof context.page === 'function';
|
|
21
|
+
this.page = hasPageFn ? context.page() : context;
|
|
21
22
|
this.config = config;
|
|
22
23
|
this.url = config.url;
|
|
23
24
|
this.timeout = options?.timeout;
|
|
24
25
|
(0, resolver_1.defineLocators)(this, this.context, this.config);
|
|
25
|
-
(0, locator_actions_1.defineActionMethods)(this, this.
|
|
26
|
+
(0, locator_actions_1.defineActionMethods)(this, this.resolveTarget.bind(this), this.timeout);
|
|
26
27
|
// Auto-wrap subclass methods with Playwright test.step
|
|
27
28
|
const builtInMethods = new Set([
|
|
28
29
|
'constructor',
|
|
@@ -79,6 +80,9 @@ class TypedPageClass {
|
|
|
79
80
|
proto = Object.getPrototypeOf(proto);
|
|
80
81
|
}
|
|
81
82
|
}
|
|
83
|
+
resolveTarget(target, options) {
|
|
84
|
+
return (0, resolver_1.resolveLocator)(this.context, this.config, target, options);
|
|
85
|
+
}
|
|
82
86
|
/** Navigate to the URL from page config. */
|
|
83
87
|
async goto(options) {
|
|
84
88
|
return (0, page_actions_1.goto)(this.page, this.url, this.constructor.name, options, (0, caller_location_1.getCallerLocation)());
|
|
@@ -104,7 +108,7 @@ class TypedPageClass {
|
|
|
104
108
|
return (0, page_actions_1.waitForURL)(this.page, this.url, this.constructor.name, urlOrOptions, options, (0, caller_location_1.getCallerLocation)());
|
|
105
109
|
}
|
|
106
110
|
resolveLocator(target, options) {
|
|
107
|
-
return
|
|
111
|
+
return this.resolveTarget(target, options);
|
|
108
112
|
}
|
|
109
113
|
/** Resolve a config key to a proxied Locator with step-wrapped methods. */
|
|
110
114
|
locator(target, options) {
|
|
@@ -126,26 +130,32 @@ class TypedPageClass {
|
|
|
126
130
|
options = arg;
|
|
127
131
|
}
|
|
128
132
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
133
|
+
const [firstKey, ...remainingKeys] = keys;
|
|
134
|
+
if (!firstKey) {
|
|
135
|
+
throw new Error('chain requires at least one locator key.');
|
|
136
|
+
}
|
|
137
|
+
let loc = (0, resolver_1.resolveLocator)(this.context, this.config, firstKey, { raw: true });
|
|
138
|
+
for (let i = 0; i < remainingKeys.length; i++) {
|
|
139
|
+
const key = remainingKeys[i];
|
|
140
|
+
const isLast = i === remainingKeys.length - 1;
|
|
141
|
+
loc = (0, resolver_1.resolveLocator)(loc, this.config, key, isLast ? options : { raw: true });
|
|
132
142
|
}
|
|
133
|
-
return loc;
|
|
143
|
+
return remainingKeys.length > 0 ? loc : (0, resolver_1.resolveLocator)(this.context, this.config, firstKey, options);
|
|
134
144
|
}
|
|
135
145
|
/** Chainable assertions on config keys. Supports `.soft` for soft assertions. */
|
|
136
146
|
get verify() {
|
|
137
|
-
const fn = (target, opts) => (0, verify_chain_1.createVerifyChain)(this.
|
|
138
|
-
fn.soft = (target, opts) => (0, verify_chain_1.createVerifyChain)(this.
|
|
147
|
+
const fn = ((target, opts) => (0, verify_chain_1.createVerifyChain)(this.resolveTarget.bind(this), target, opts, false));
|
|
148
|
+
fn.soft = (target, opts) => (0, verify_chain_1.createVerifyChain)(this.resolveTarget.bind(this), target, opts, true);
|
|
139
149
|
return fn;
|
|
140
150
|
}
|
|
141
151
|
async verifyHidden(target, options) {
|
|
142
|
-
return (0, verify_helpers_1.verifyHidden)(this.
|
|
152
|
+
return (0, verify_helpers_1.verifyHidden)(this.resolveTarget.bind(this), target, options, (0, caller_location_1.getCallerLocation)());
|
|
143
153
|
}
|
|
144
154
|
async verifyEnabled(target, options) {
|
|
145
|
-
return (0, verify_helpers_1.verifyEnabled)(this.
|
|
155
|
+
return (0, verify_helpers_1.verifyEnabled)(this.resolveTarget.bind(this), target, options, (0, caller_location_1.getCallerLocation)());
|
|
146
156
|
}
|
|
147
157
|
async verifyDisabled(target, options) {
|
|
148
|
-
return (0, verify_helpers_1.verifyDisabled)(this.
|
|
158
|
+
return (0, verify_helpers_1.verifyDisabled)(this.resolveTarget.bind(this), target, options, (0, caller_location_1.getCallerLocation)());
|
|
149
159
|
}
|
|
150
160
|
expect(target, message) {
|
|
151
161
|
const resolved = typeof target !== 'string' ? target : this.resolveLocator(target);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Locator } from '@playwright/test';
|
|
2
|
-
import type {
|
|
1
|
+
import type { Locator } from '@playwright/test';
|
|
2
|
+
import type { ModifyOptionsForTarget, PageKeys } from '../config';
|
|
3
3
|
export interface ProxyLocatorMethods<T> {
|
|
4
4
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-click Locator.click} */
|
|
5
5
|
click<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['click']>[0]>): Promise<void>;
|
|
@@ -12,15 +12,15 @@ export interface ProxyLocatorMethods<T> {
|
|
|
12
12
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-blur Locator.blur} */
|
|
13
13
|
blur<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['blur']>[0]>): Promise<void>;
|
|
14
14
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-check Locator.check} */
|
|
15
|
-
check<Target extends
|
|
15
|
+
check<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['check']>[0]>): Promise<void>;
|
|
16
16
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-uncheck Locator.uncheck} */
|
|
17
|
-
uncheck<Target extends
|
|
17
|
+
uncheck<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['uncheck']>[0]>): Promise<void>;
|
|
18
18
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-clear Locator.clear} */
|
|
19
|
-
clear<Target extends
|
|
19
|
+
clear<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['clear']>[0]>): Promise<void>;
|
|
20
20
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-wait-for Locator.waitFor} */
|
|
21
21
|
waitFor<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['waitFor']>[0]>): Promise<void>;
|
|
22
22
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-is-checked Locator.isChecked} */
|
|
23
|
-
isChecked<Target extends
|
|
23
|
+
isChecked<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['isChecked']>[0]>): Promise<boolean>;
|
|
24
24
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-is-disabled Locator.isDisabled} */
|
|
25
25
|
isDisabled<Target extends PageKeys<T> | Locator>(target: Target, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['isDisabled']>[0]>): Promise<boolean>;
|
|
26
26
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-is-visible Locator.isVisible} */
|
|
@@ -45,29 +45,21 @@ export interface ProxyLocatorMethods<T> {
|
|
|
45
45
|
height: number;
|
|
46
46
|
} | null>;
|
|
47
47
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-press Locator.press} */
|
|
48
|
-
press<Target extends
|
|
48
|
+
press<Target extends PageKeys<T> | Locator>(target: Target, key: string, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['press']>[1]>): Promise<void>;
|
|
49
49
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-press-sequentially Locator.pressSequentially} */
|
|
50
|
-
pressSequentially<Target extends
|
|
50
|
+
pressSequentially<Target extends PageKeys<T> | Locator>(target: Target, value: string, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['pressSequentially']>[1]>): Promise<void>;
|
|
51
51
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-select-option Locator.selectOption} */
|
|
52
|
-
selectOption<Target extends
|
|
52
|
+
selectOption<Target extends PageKeys<T> | Locator>(target: Target, values: string | string[] | {
|
|
53
53
|
value?: string;
|
|
54
54
|
label?: string;
|
|
55
55
|
index?: number;
|
|
56
56
|
} | null, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['selectOption']>[1]>): Promise<string[]>;
|
|
57
57
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-set-input-files Locator.setInputFiles} */
|
|
58
|
-
setInputFiles<Target extends PageKeys<T> | Locator>(target: Target, files:
|
|
59
|
-
name: string;
|
|
60
|
-
mimeType: string;
|
|
61
|
-
buffer: Buffer;
|
|
62
|
-
} | {
|
|
63
|
-
name: string;
|
|
64
|
-
mimeType: string;
|
|
65
|
-
buffer: Buffer;
|
|
66
|
-
}[], options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['setInputFiles']>[1]>): Promise<void>;
|
|
58
|
+
setInputFiles<Target extends PageKeys<T> | Locator>(target: Target, files: Parameters<Locator['setInputFiles']>[0], options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['setInputFiles']>[1]>): Promise<void>;
|
|
67
59
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-get-attribute Locator.getAttribute} */
|
|
68
60
|
getAttribute<Target extends PageKeys<T> | Locator>(target: Target, name: string, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['getAttribute']>[1]>): Promise<string | null>;
|
|
69
61
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-fill Locator.fill} */
|
|
70
|
-
fill<Target extends
|
|
62
|
+
fill<Target extends PageKeys<T> | Locator>(target: Target, value: string, options?: ModifyOptionsForTarget<T, Target, Parameters<Locator['fill']>[1]> & {
|
|
71
63
|
mask?: boolean;
|
|
72
64
|
}): Promise<void>;
|
|
73
65
|
/** @see {@link https://playwright.dev/docs/api/class-locator#locator-drag-to Locator.dragTo} */
|
|
@@ -10,7 +10,7 @@ export type HasDuplicatePlaceholders<S extends string, Seen extends string = nev
|
|
|
10
10
|
* Returns the subset of `Placeholders` whose names are NOT found as
|
|
11
11
|
* substrings of `TestId`. Evaluates to `never` when all are present.
|
|
12
12
|
*/
|
|
13
|
-
export type MissingInTestId<TestId extends string, Placeholders extends string> = Placeholders extends
|
|
13
|
+
export type MissingInTestId<TestId extends string, Placeholders extends string> = Placeholders extends unknown ? TestId extends `${string}${Placeholders}${string}` ? never : Placeholders : never;
|
|
14
14
|
/**
|
|
15
15
|
* Validates a dynamic entry by mapping each of its properties to their expected types.
|
|
16
16
|
*
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export declare function formatTarget(target:
|
|
2
|
-
export declare function formatStepDescription(methodName: string, target:
|
|
3
|
-
export declare function formatAssertionDescription(target:
|
|
1
|
+
export declare function formatTarget(target: unknown): string;
|
|
2
|
+
export declare function formatStepDescription(methodName: string, target: unknown, args: readonly unknown[]): string;
|
|
3
|
+
export declare function formatAssertionDescription(target: unknown, matcherName: string, isNegated: boolean, args: readonly unknown[]): string;
|
|
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.formatTarget = formatTarget;
|
|
4
4
|
exports.formatStepDescription = formatStepDescription;
|
|
5
5
|
exports.formatAssertionDescription = formatAssertionDescription;
|
|
6
|
+
function isStringifiable(value) {
|
|
7
|
+
return typeof value === 'object' && value !== null && typeof value.toString === 'function';
|
|
8
|
+
}
|
|
6
9
|
function formatTarget(target) {
|
|
7
10
|
if (typeof target === 'string')
|
|
8
11
|
return target;
|
|
9
|
-
if (target
|
|
12
|
+
if (isStringifiable(target)) {
|
|
10
13
|
return target.toString().replace(/^Locator@/, '');
|
|
11
14
|
}
|
|
12
15
|
return 'locator';
|
|
@@ -16,7 +19,7 @@ function formatStepDescription(methodName, target, args) {
|
|
|
16
19
|
if (methodName === 'fill' && args[0] !== undefined) {
|
|
17
20
|
const options = args[1];
|
|
18
21
|
let shouldMask = false;
|
|
19
|
-
if (options && typeof options === 'object' && options.mask !== undefined) {
|
|
22
|
+
if (options && typeof options === 'object' && 'mask' in options && options.mask !== undefined) {
|
|
20
23
|
shouldMask = options.mask === true;
|
|
21
24
|
}
|
|
22
25
|
else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pw-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"workspaces": [
|
|
5
5
|
"examples",
|
|
6
6
|
"create-pw-core"
|
|
@@ -53,14 +53,17 @@
|
|
|
53
53
|
"scripts": {
|
|
54
54
|
"build": "node -e \"const fs = require('fs'); fs.rmSync('dist', {recursive:true,force:true})\" && tsc && npm run build --prefix create-pw-core",
|
|
55
55
|
"prepare": "npm run build",
|
|
56
|
-
"test": "npm run test --workspace=pw-core-demo"
|
|
56
|
+
"test": "npm run test --workspace=pw-core-demo",
|
|
57
|
+
"test:unit": "npm run build && node --test tests/unit/*.test.js",
|
|
58
|
+
"test:types": "tsc --noEmit -p tests/types/tsconfig.json",
|
|
59
|
+
"test:codegen": "npm run build && node scripts/verify-codegen.js"
|
|
57
60
|
},
|
|
58
61
|
"peerDependencies": {
|
|
59
62
|
"@playwright/test": "^1.40.0"
|
|
60
63
|
},
|
|
61
64
|
"devDependencies": {
|
|
62
65
|
"@playwright/test": "^1.61.0",
|
|
63
|
-
"@types/node": "^20.
|
|
66
|
+
"@types/node": "^20.19.43",
|
|
64
67
|
"prettier": "^3.9.4",
|
|
65
68
|
"rimraf": "^6.0.1",
|
|
66
69
|
"typescript": "^5.3.3"
|