@ricsam/isolate-playwright 0.1.2 → 0.1.4
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 +170 -45
- package/dist/cjs/index.cjs +431 -530
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/index.mjs +431 -530
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/index.d.ts +49 -18
- package/package.json +2 -1
package/dist/mjs/index.mjs
CHANGED
|
@@ -1,413 +1,389 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/playwright/src/index.ts
|
|
3
3
|
import ivm from "isolated-vm";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"EvalError",
|
|
11
|
-
"TimeoutError"
|
|
12
|
-
];
|
|
13
|
-
function getErrorConstructorName(errorType) {
|
|
14
|
-
return KNOWN_ERROR_TYPES.includes(errorType) ? errorType : "Error";
|
|
15
|
-
}
|
|
16
|
-
function encodeErrorForTransfer(err) {
|
|
17
|
-
const errorType = getErrorConstructorName(err.name);
|
|
18
|
-
return new Error(`[${errorType}]${err.message}`);
|
|
19
|
-
}
|
|
20
|
-
var DECODE_ERROR_JS = `
|
|
21
|
-
function __decodeError(err) {
|
|
22
|
-
if (!(err instanceof Error)) return err;
|
|
23
|
-
const match = err.message.match(/^\\[(TypeError|RangeError|SyntaxError|ReferenceError|URIError|EvalError|TimeoutError|Error)\\](.*)$/);
|
|
24
|
-
if (match) {
|
|
25
|
-
const ErrorType = globalThis[match[1]] || Error;
|
|
26
|
-
return new ErrorType(match[2]);
|
|
4
|
+
function getLocator(page, selectorType, selectorValue, optionsJson) {
|
|
5
|
+
const options = optionsJson ? JSON.parse(optionsJson) : undefined;
|
|
6
|
+
const nthIndex = options?.nth;
|
|
7
|
+
const roleOptions = options ? { ...options } : undefined;
|
|
8
|
+
if (roleOptions) {
|
|
9
|
+
delete roleOptions.nth;
|
|
27
10
|
}
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
`.trim();
|
|
31
|
-
function getLocator(page, selectorType, selectorValue, roleOptionsJson) {
|
|
11
|
+
let locator;
|
|
32
12
|
switch (selectorType) {
|
|
33
13
|
case "css":
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
14
|
+
locator = page.locator(selectorValue);
|
|
15
|
+
break;
|
|
16
|
+
case "role":
|
|
17
|
+
locator = page.getByRole(selectorValue, roleOptions && Object.keys(roleOptions).length > 0 ? roleOptions : undefined);
|
|
18
|
+
break;
|
|
39
19
|
case "text":
|
|
40
|
-
|
|
20
|
+
locator = page.getByText(selectorValue);
|
|
21
|
+
break;
|
|
41
22
|
case "label":
|
|
42
|
-
|
|
23
|
+
locator = page.getByLabel(selectorValue);
|
|
24
|
+
break;
|
|
43
25
|
case "placeholder":
|
|
44
|
-
|
|
26
|
+
locator = page.getByPlaceholder(selectorValue);
|
|
27
|
+
break;
|
|
45
28
|
case "testId":
|
|
46
|
-
|
|
29
|
+
locator = page.getByTestId(selectorValue);
|
|
30
|
+
break;
|
|
47
31
|
default:
|
|
48
|
-
|
|
32
|
+
locator = page.locator(selectorValue);
|
|
33
|
+
}
|
|
34
|
+
if (nthIndex !== undefined) {
|
|
35
|
+
locator = locator.nth(nthIndex);
|
|
49
36
|
}
|
|
37
|
+
return locator;
|
|
50
38
|
}
|
|
51
|
-
async function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
await
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}));
|
|
106
|
-
global.setSync("__Playwright_reload_ref", new ivm.Reference(async () => {
|
|
107
|
-
try {
|
|
108
|
-
await page.reload({ timeout });
|
|
109
|
-
} catch (err) {
|
|
110
|
-
if (err instanceof Error) {
|
|
111
|
-
throw encodeErrorForTransfer(err);
|
|
112
|
-
}
|
|
113
|
-
throw err;
|
|
114
|
-
}
|
|
115
|
-
}));
|
|
116
|
-
global.setSync("__Playwright_url", new ivm.Callback(() => {
|
|
117
|
-
return page.url();
|
|
118
|
-
}));
|
|
119
|
-
global.setSync("__Playwright_title_ref", new ivm.Reference(async () => {
|
|
120
|
-
try {
|
|
121
|
-
return await page.title();
|
|
122
|
-
} catch (err) {
|
|
123
|
-
if (err instanceof Error) {
|
|
124
|
-
throw encodeErrorForTransfer(err);
|
|
125
|
-
}
|
|
126
|
-
throw err;
|
|
127
|
-
}
|
|
128
|
-
}));
|
|
129
|
-
global.setSync("__Playwright_content_ref", new ivm.Reference(async () => {
|
|
130
|
-
try {
|
|
131
|
-
return await page.content();
|
|
132
|
-
} catch (err) {
|
|
133
|
-
if (err instanceof Error) {
|
|
134
|
-
throw encodeErrorForTransfer(err);
|
|
135
|
-
}
|
|
136
|
-
throw err;
|
|
137
|
-
}
|
|
138
|
-
}));
|
|
139
|
-
global.setSync("__Playwright_waitForSelector_ref", new ivm.Reference(async (selector, optionsJson) => {
|
|
140
|
-
try {
|
|
141
|
-
const opts = optionsJson ? JSON.parse(optionsJson) : {};
|
|
142
|
-
await page.waitForSelector(selector, { timeout, ...opts });
|
|
143
|
-
} catch (err) {
|
|
144
|
-
if (err instanceof Error) {
|
|
145
|
-
throw encodeErrorForTransfer(err);
|
|
146
|
-
}
|
|
147
|
-
throw err;
|
|
148
|
-
}
|
|
149
|
-
}));
|
|
150
|
-
global.setSync("__Playwright_waitForTimeout_ref", new ivm.Reference(async (ms) => {
|
|
151
|
-
try {
|
|
152
|
-
await page.waitForTimeout(ms);
|
|
153
|
-
} catch (err) {
|
|
154
|
-
if (err instanceof Error) {
|
|
155
|
-
throw encodeErrorForTransfer(err);
|
|
156
|
-
}
|
|
157
|
-
throw err;
|
|
158
|
-
}
|
|
159
|
-
}));
|
|
160
|
-
global.setSync("__Playwright_waitForLoadState_ref", new ivm.Reference(async (state) => {
|
|
161
|
-
try {
|
|
162
|
-
await page.waitForLoadState(state ?? "load", { timeout });
|
|
163
|
-
} catch (err) {
|
|
164
|
-
if (err instanceof Error) {
|
|
165
|
-
throw encodeErrorForTransfer(err);
|
|
166
|
-
}
|
|
167
|
-
throw err;
|
|
168
|
-
}
|
|
169
|
-
}));
|
|
170
|
-
global.setSync("__Playwright_evaluate_ref", new ivm.Reference(async (script) => {
|
|
171
|
-
try {
|
|
172
|
-
const result = await page.evaluate(script);
|
|
173
|
-
return JSON.stringify(result);
|
|
174
|
-
} catch (err) {
|
|
175
|
-
if (err instanceof Error) {
|
|
176
|
-
throw encodeErrorForTransfer(err);
|
|
177
|
-
}
|
|
178
|
-
throw err;
|
|
179
|
-
}
|
|
180
|
-
}));
|
|
181
|
-
global.setSync("__Playwright_locatorAction_ref", new ivm.Reference(async (selectorType, selectorValue, roleOptionsJson, action, actionArg) => {
|
|
182
|
-
try {
|
|
183
|
-
const locator = getLocator(page, selectorType, selectorValue, roleOptionsJson);
|
|
184
|
-
switch (action) {
|
|
185
|
-
case "click":
|
|
186
|
-
await locator.click({ timeout });
|
|
187
|
-
return null;
|
|
188
|
-
case "dblclick":
|
|
189
|
-
await locator.dblclick({ timeout });
|
|
190
|
-
return null;
|
|
191
|
-
case "fill":
|
|
192
|
-
await locator.fill(actionArg ?? "", { timeout });
|
|
193
|
-
return null;
|
|
194
|
-
case "type":
|
|
195
|
-
await locator.pressSequentially(actionArg ?? "", { timeout });
|
|
196
|
-
return null;
|
|
197
|
-
case "check":
|
|
198
|
-
await locator.check({ timeout });
|
|
199
|
-
return null;
|
|
200
|
-
case "uncheck":
|
|
201
|
-
await locator.uncheck({ timeout });
|
|
202
|
-
return null;
|
|
203
|
-
case "selectOption":
|
|
204
|
-
await locator.selectOption(actionArg ?? "", { timeout });
|
|
205
|
-
return null;
|
|
206
|
-
case "clear":
|
|
207
|
-
await locator.clear({ timeout });
|
|
208
|
-
return null;
|
|
209
|
-
case "press":
|
|
210
|
-
await locator.press(actionArg ?? "", { timeout });
|
|
211
|
-
return null;
|
|
212
|
-
case "hover":
|
|
213
|
-
await locator.hover({ timeout });
|
|
214
|
-
return null;
|
|
215
|
-
case "focus":
|
|
216
|
-
await locator.focus({ timeout });
|
|
217
|
-
return null;
|
|
218
|
-
case "getText":
|
|
219
|
-
return await locator.textContent({ timeout });
|
|
220
|
-
case "getValue":
|
|
221
|
-
return await locator.inputValue({ timeout });
|
|
222
|
-
case "isVisible":
|
|
223
|
-
return await locator.isVisible();
|
|
224
|
-
case "isEnabled":
|
|
225
|
-
return await locator.isEnabled();
|
|
226
|
-
case "isChecked":
|
|
227
|
-
return await locator.isChecked();
|
|
228
|
-
case "count":
|
|
229
|
-
return await locator.count();
|
|
230
|
-
default:
|
|
231
|
-
throw new Error(`Unknown action: ${action}`);
|
|
232
|
-
}
|
|
233
|
-
} catch (err) {
|
|
234
|
-
if (err instanceof Error) {
|
|
235
|
-
throw encodeErrorForTransfer(err);
|
|
236
|
-
}
|
|
237
|
-
throw err;
|
|
238
|
-
}
|
|
239
|
-
}));
|
|
240
|
-
global.setSync("__Playwright_expectVisible_ref", new ivm.Reference(async (selectorType, selectorValue, roleOptionsJson, not) => {
|
|
241
|
-
try {
|
|
242
|
-
const locator = getLocator(page, selectorType, selectorValue, roleOptionsJson);
|
|
39
|
+
async function executeLocatorAction(locator, action, actionArg, timeout) {
|
|
40
|
+
switch (action) {
|
|
41
|
+
case "click":
|
|
42
|
+
await locator.click({ timeout });
|
|
43
|
+
return null;
|
|
44
|
+
case "dblclick":
|
|
45
|
+
await locator.dblclick({ timeout });
|
|
46
|
+
return null;
|
|
47
|
+
case "fill":
|
|
48
|
+
await locator.fill(String(actionArg ?? ""), { timeout });
|
|
49
|
+
return null;
|
|
50
|
+
case "type":
|
|
51
|
+
await locator.pressSequentially(String(actionArg ?? ""), { timeout });
|
|
52
|
+
return null;
|
|
53
|
+
case "check":
|
|
54
|
+
await locator.check({ timeout });
|
|
55
|
+
return null;
|
|
56
|
+
case "uncheck":
|
|
57
|
+
await locator.uncheck({ timeout });
|
|
58
|
+
return null;
|
|
59
|
+
case "selectOption":
|
|
60
|
+
await locator.selectOption(String(actionArg ?? ""), { timeout });
|
|
61
|
+
return null;
|
|
62
|
+
case "clear":
|
|
63
|
+
await locator.clear({ timeout });
|
|
64
|
+
return null;
|
|
65
|
+
case "press":
|
|
66
|
+
await locator.press(String(actionArg ?? ""), { timeout });
|
|
67
|
+
return null;
|
|
68
|
+
case "hover":
|
|
69
|
+
await locator.hover({ timeout });
|
|
70
|
+
return null;
|
|
71
|
+
case "focus":
|
|
72
|
+
await locator.focus({ timeout });
|
|
73
|
+
return null;
|
|
74
|
+
case "getText":
|
|
75
|
+
return await locator.textContent({ timeout });
|
|
76
|
+
case "getValue":
|
|
77
|
+
return await locator.inputValue({ timeout });
|
|
78
|
+
case "isVisible":
|
|
79
|
+
return await locator.isVisible();
|
|
80
|
+
case "isEnabled":
|
|
81
|
+
return await locator.isEnabled();
|
|
82
|
+
case "isChecked":
|
|
83
|
+
return await locator.isChecked();
|
|
84
|
+
case "count":
|
|
85
|
+
return await locator.count();
|
|
86
|
+
default:
|
|
87
|
+
throw new Error(`Unknown action: ${action}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function executeExpectAssertion(locator, matcher, expected, negated, timeout) {
|
|
91
|
+
switch (matcher) {
|
|
92
|
+
case "toBeVisible": {
|
|
243
93
|
const isVisible = await locator.isVisible();
|
|
244
|
-
if (
|
|
245
|
-
if (isVisible)
|
|
246
|
-
throw new Error(
|
|
247
|
-
}
|
|
94
|
+
if (negated) {
|
|
95
|
+
if (isVisible)
|
|
96
|
+
throw new Error("Expected element to not be visible, but it was visible");
|
|
248
97
|
} else {
|
|
249
|
-
if (!isVisible)
|
|
250
|
-
throw new Error(
|
|
251
|
-
}
|
|
98
|
+
if (!isVisible)
|
|
99
|
+
throw new Error("Expected element to be visible, but it was not");
|
|
252
100
|
}
|
|
253
|
-
|
|
254
|
-
if (err instanceof Error) {
|
|
255
|
-
throw encodeErrorForTransfer(err);
|
|
256
|
-
}
|
|
257
|
-
throw err;
|
|
101
|
+
break;
|
|
258
102
|
}
|
|
259
|
-
|
|
260
|
-
global.setSync("__Playwright_expectText_ref", new ivm.Reference(async (selectorType, selectorValue, roleOptionsJson, expected, not) => {
|
|
261
|
-
try {
|
|
262
|
-
const locator = getLocator(page, selectorType, selectorValue, roleOptionsJson);
|
|
103
|
+
case "toContainText": {
|
|
263
104
|
const text = await locator.textContent({ timeout });
|
|
264
|
-
const matches = text?.includes(expected) ?? false;
|
|
265
|
-
if (
|
|
266
|
-
if (matches)
|
|
105
|
+
const matches = text?.includes(String(expected)) ?? false;
|
|
106
|
+
if (negated) {
|
|
107
|
+
if (matches)
|
|
267
108
|
throw new Error(`Expected text to not contain "${expected}", but got "${text}"`);
|
|
268
|
-
}
|
|
269
109
|
} else {
|
|
270
|
-
if (!matches)
|
|
110
|
+
if (!matches)
|
|
271
111
|
throw new Error(`Expected text to contain "${expected}", but got "${text}"`);
|
|
272
|
-
}
|
|
273
112
|
}
|
|
274
|
-
|
|
275
|
-
if (err instanceof Error) {
|
|
276
|
-
throw encodeErrorForTransfer(err);
|
|
277
|
-
}
|
|
278
|
-
throw err;
|
|
113
|
+
break;
|
|
279
114
|
}
|
|
280
|
-
|
|
281
|
-
global.setSync("__Playwright_expectValue_ref", new ivm.Reference(async (selectorType, selectorValue, roleOptionsJson, expected, not) => {
|
|
282
|
-
try {
|
|
283
|
-
const locator = getLocator(page, selectorType, selectorValue, roleOptionsJson);
|
|
115
|
+
case "toHaveValue": {
|
|
284
116
|
const value = await locator.inputValue({ timeout });
|
|
285
|
-
const matches = value === expected;
|
|
286
|
-
if (
|
|
287
|
-
if (matches)
|
|
117
|
+
const matches = value === String(expected);
|
|
118
|
+
if (negated) {
|
|
119
|
+
if (matches)
|
|
288
120
|
throw new Error(`Expected value to not be "${expected}", but it was`);
|
|
289
|
-
}
|
|
290
121
|
} else {
|
|
291
|
-
if (!matches)
|
|
122
|
+
if (!matches)
|
|
292
123
|
throw new Error(`Expected value to be "${expected}", but got "${value}"`);
|
|
293
|
-
}
|
|
294
124
|
}
|
|
295
|
-
|
|
296
|
-
if (err instanceof Error) {
|
|
297
|
-
throw encodeErrorForTransfer(err);
|
|
298
|
-
}
|
|
299
|
-
throw err;
|
|
125
|
+
break;
|
|
300
126
|
}
|
|
301
|
-
|
|
302
|
-
global.setSync("__Playwright_expectEnabled_ref", new ivm.Reference(async (selectorType, selectorValue, roleOptionsJson, not) => {
|
|
303
|
-
try {
|
|
304
|
-
const locator = getLocator(page, selectorType, selectorValue, roleOptionsJson);
|
|
127
|
+
case "toBeEnabled": {
|
|
305
128
|
const isEnabled = await locator.isEnabled();
|
|
306
|
-
if (
|
|
307
|
-
if (isEnabled)
|
|
308
|
-
throw new Error(
|
|
309
|
-
}
|
|
129
|
+
if (negated) {
|
|
130
|
+
if (isEnabled)
|
|
131
|
+
throw new Error("Expected element to be disabled, but it was enabled");
|
|
310
132
|
} else {
|
|
311
|
-
if (!isEnabled)
|
|
312
|
-
throw new Error(
|
|
313
|
-
}
|
|
133
|
+
if (!isEnabled)
|
|
134
|
+
throw new Error("Expected element to be enabled, but it was disabled");
|
|
314
135
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
case "toBeChecked": {
|
|
139
|
+
const isChecked = await locator.isChecked();
|
|
140
|
+
if (negated) {
|
|
141
|
+
if (isChecked)
|
|
142
|
+
throw new Error("Expected element to not be checked, but it was checked");
|
|
143
|
+
} else {
|
|
144
|
+
if (!isChecked)
|
|
145
|
+
throw new Error("Expected element to be checked, but it was not");
|
|
318
146
|
}
|
|
319
|
-
|
|
147
|
+
break;
|
|
320
148
|
}
|
|
321
|
-
|
|
322
|
-
|
|
149
|
+
default:
|
|
150
|
+
throw new Error(`Unknown matcher: ${matcher}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
function createPlaywrightHandler(page, options) {
|
|
154
|
+
const timeout = options?.timeout ?? 30000;
|
|
155
|
+
const baseUrl = options?.baseUrl;
|
|
156
|
+
return async (op) => {
|
|
323
157
|
try {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
158
|
+
switch (op.type) {
|
|
159
|
+
case "goto": {
|
|
160
|
+
const [url, waitUntil] = op.args;
|
|
161
|
+
const targetUrl = baseUrl && !url.startsWith("http") ? `${baseUrl}${url}` : url;
|
|
162
|
+
await page.goto(targetUrl, {
|
|
163
|
+
timeout,
|
|
164
|
+
waitUntil: waitUntil ?? "load"
|
|
165
|
+
});
|
|
166
|
+
return { ok: true };
|
|
329
167
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
168
|
+
case "reload":
|
|
169
|
+
await page.reload({ timeout });
|
|
170
|
+
return { ok: true };
|
|
171
|
+
case "url":
|
|
172
|
+
return { ok: true, value: page.url() };
|
|
173
|
+
case "title":
|
|
174
|
+
return { ok: true, value: await page.title() };
|
|
175
|
+
case "content":
|
|
176
|
+
return { ok: true, value: await page.content() };
|
|
177
|
+
case "waitForSelector": {
|
|
178
|
+
const [selector, optionsJson] = op.args;
|
|
179
|
+
const opts = optionsJson ? JSON.parse(optionsJson) : {};
|
|
180
|
+
await page.waitForSelector(selector, { timeout, ...opts });
|
|
181
|
+
return { ok: true };
|
|
182
|
+
}
|
|
183
|
+
case "waitForTimeout": {
|
|
184
|
+
const [ms] = op.args;
|
|
185
|
+
await page.waitForTimeout(ms);
|
|
186
|
+
return { ok: true };
|
|
187
|
+
}
|
|
188
|
+
case "waitForLoadState": {
|
|
189
|
+
const [state] = op.args;
|
|
190
|
+
await page.waitForLoadState(state ?? "load", { timeout });
|
|
191
|
+
return { ok: true };
|
|
192
|
+
}
|
|
193
|
+
case "evaluate": {
|
|
194
|
+
const [script] = op.args;
|
|
195
|
+
const result = await page.evaluate(script);
|
|
196
|
+
return { ok: true, value: result };
|
|
197
|
+
}
|
|
198
|
+
case "locatorAction": {
|
|
199
|
+
const [selectorType, selectorValue, roleOptions, action, actionArg] = op.args;
|
|
200
|
+
const locator = getLocator(page, selectorType, selectorValue, roleOptions);
|
|
201
|
+
const result = await executeLocatorAction(locator, action, actionArg, timeout);
|
|
202
|
+
return { ok: true, value: result };
|
|
333
203
|
}
|
|
204
|
+
case "expectLocator": {
|
|
205
|
+
const [selectorType, selectorValue, roleOptions, matcher, expected, negated, customTimeout] = op.args;
|
|
206
|
+
const locator = getLocator(page, selectorType, selectorValue, roleOptions);
|
|
207
|
+
const effectiveTimeout = customTimeout ?? timeout;
|
|
208
|
+
await executeExpectAssertion(locator, matcher, expected, negated ?? false, effectiveTimeout);
|
|
209
|
+
return { ok: true };
|
|
210
|
+
}
|
|
211
|
+
case "request": {
|
|
212
|
+
const [url, method, data, headers] = op.args;
|
|
213
|
+
const targetUrl = baseUrl && !url.startsWith("http") ? `${baseUrl}${url}` : url;
|
|
214
|
+
const requestOptions = {
|
|
215
|
+
timeout
|
|
216
|
+
};
|
|
217
|
+
if (headers) {
|
|
218
|
+
requestOptions.headers = headers;
|
|
219
|
+
}
|
|
220
|
+
if (data !== undefined && data !== null) {
|
|
221
|
+
requestOptions.data = data;
|
|
222
|
+
}
|
|
223
|
+
const response = await page.request.fetch(targetUrl, {
|
|
224
|
+
method,
|
|
225
|
+
...requestOptions
|
|
226
|
+
});
|
|
227
|
+
const text = await response.text();
|
|
228
|
+
let json = null;
|
|
229
|
+
try {
|
|
230
|
+
json = JSON.parse(text);
|
|
231
|
+
} catch {}
|
|
232
|
+
return {
|
|
233
|
+
ok: true,
|
|
234
|
+
value: {
|
|
235
|
+
status: response.status(),
|
|
236
|
+
ok: response.ok(),
|
|
237
|
+
headers: response.headers(),
|
|
238
|
+
text,
|
|
239
|
+
json,
|
|
240
|
+
body: null
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
default:
|
|
245
|
+
return { ok: false, error: { name: "Error", message: `Unknown operation: ${op.type}` } };
|
|
334
246
|
}
|
|
335
247
|
} catch (err) {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
throw err;
|
|
248
|
+
const error = err;
|
|
249
|
+
return { ok: false, error: { name: error.name, message: error.message } };
|
|
340
250
|
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
async function setupPlaywright(context, options) {
|
|
254
|
+
const timeout = options.timeout ?? 30000;
|
|
255
|
+
const baseUrl = options.baseUrl;
|
|
256
|
+
const page = "page" in options ? options.page : undefined;
|
|
257
|
+
const handler = "handler" in options ? options.handler : undefined;
|
|
258
|
+
const effectiveHandler = handler ?? (page ? createPlaywrightHandler(page, { timeout, baseUrl }) : undefined);
|
|
259
|
+
if (!effectiveHandler) {
|
|
260
|
+
throw new Error("Either page or handler must be provided to setupPlaywright");
|
|
261
|
+
}
|
|
262
|
+
const browserConsoleLogs = [];
|
|
263
|
+
const networkRequests = [];
|
|
264
|
+
const networkResponses = [];
|
|
265
|
+
const global = context.global;
|
|
266
|
+
let requestHandler;
|
|
267
|
+
let responseHandler;
|
|
268
|
+
let consoleHandler;
|
|
269
|
+
if (page) {
|
|
270
|
+
const onEvent = "onEvent" in options ? options.onEvent : undefined;
|
|
271
|
+
requestHandler = (request) => {
|
|
272
|
+
const info = {
|
|
273
|
+
url: request.url(),
|
|
274
|
+
method: request.method(),
|
|
275
|
+
headers: request.headers(),
|
|
276
|
+
postData: request.postData() ?? undefined,
|
|
277
|
+
resourceType: request.resourceType(),
|
|
278
|
+
timestamp: Date.now()
|
|
279
|
+
};
|
|
280
|
+
networkRequests.push(info);
|
|
281
|
+
if (onEvent) {
|
|
282
|
+
onEvent({
|
|
283
|
+
type: "networkRequest",
|
|
284
|
+
url: info.url,
|
|
285
|
+
method: info.method,
|
|
286
|
+
headers: info.headers,
|
|
287
|
+
postData: info.postData,
|
|
288
|
+
resourceType: info.resourceType,
|
|
289
|
+
timestamp: info.timestamp
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
responseHandler = (response) => {
|
|
294
|
+
const info = {
|
|
295
|
+
url: response.url(),
|
|
296
|
+
status: response.status(),
|
|
297
|
+
statusText: response.statusText(),
|
|
298
|
+
headers: response.headers(),
|
|
299
|
+
timestamp: Date.now()
|
|
300
|
+
};
|
|
301
|
+
networkResponses.push(info);
|
|
302
|
+
if (onEvent) {
|
|
303
|
+
onEvent({
|
|
304
|
+
type: "networkResponse",
|
|
305
|
+
url: info.url,
|
|
306
|
+
status: info.status,
|
|
307
|
+
statusText: info.statusText,
|
|
308
|
+
headers: info.headers,
|
|
309
|
+
timestamp: info.timestamp
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
consoleHandler = (msg) => {
|
|
314
|
+
const entry = {
|
|
315
|
+
level: msg.type(),
|
|
316
|
+
args: msg.args().map((arg) => String(arg)),
|
|
317
|
+
timestamp: Date.now()
|
|
318
|
+
};
|
|
319
|
+
browserConsoleLogs.push(entry);
|
|
320
|
+
if (onEvent) {
|
|
321
|
+
onEvent({
|
|
322
|
+
type: "browserConsoleLog",
|
|
323
|
+
level: entry.level,
|
|
324
|
+
args: entry.args,
|
|
325
|
+
timestamp: entry.timestamp
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
if ("console" in options && options.console) {
|
|
329
|
+
const prefix = `[browser:${entry.level}]`;
|
|
330
|
+
console.log(prefix, ...entry.args);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
page.on("request", requestHandler);
|
|
334
|
+
page.on("response", responseHandler);
|
|
335
|
+
page.on("console", consoleHandler);
|
|
336
|
+
}
|
|
337
|
+
global.setSync("__Playwright_handler_ref", new ivm.Reference(async (opJson) => {
|
|
338
|
+
const op = JSON.parse(opJson);
|
|
339
|
+
const result = await effectiveHandler(op);
|
|
340
|
+
return JSON.stringify(result);
|
|
341
341
|
}));
|
|
342
|
-
context.evalSync(DECODE_ERROR_JS);
|
|
343
342
|
context.evalSync(`
|
|
344
343
|
(function() {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
} catch (err) {
|
|
356
|
-
results.push({ name: t.name, passed: false, error: err.message, duration: Date.now() - start });
|
|
357
|
-
}
|
|
344
|
+
globalThis.__pw_invoke = async function(type, args) {
|
|
345
|
+
const op = JSON.stringify({ type, args });
|
|
346
|
+
const resultJson = __Playwright_handler_ref.applySyncPromise(undefined, [op]);
|
|
347
|
+
const result = JSON.parse(resultJson);
|
|
348
|
+
if (result.ok) {
|
|
349
|
+
return result.value;
|
|
350
|
+
} else {
|
|
351
|
+
const error = new Error(result.error.message);
|
|
352
|
+
error.name = result.error.name;
|
|
353
|
+
throw error;
|
|
358
354
|
}
|
|
359
|
-
const passed = results.filter(r => r.passed).length;
|
|
360
|
-
const failed = results.filter(r => !r.passed).length;
|
|
361
|
-
return JSON.stringify({ passed, failed, total: results.length, results });
|
|
362
355
|
};
|
|
363
|
-
|
|
364
|
-
globalThis.__resetPlaywrightTests = () => { tests.length = 0; };
|
|
365
356
|
})();
|
|
366
357
|
`);
|
|
367
358
|
context.evalSync(`
|
|
368
359
|
(function() {
|
|
369
360
|
globalThis.page = {
|
|
370
361
|
async goto(url, options) {
|
|
371
|
-
|
|
372
|
-
return __Playwright_goto_ref.applySyncPromise(undefined, [url, options?.waitUntil || null]);
|
|
373
|
-
} catch (err) { throw __decodeError(err); }
|
|
362
|
+
return __pw_invoke("goto", [url, options?.waitUntil || null]);
|
|
374
363
|
},
|
|
375
364
|
async reload() {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
365
|
+
return __pw_invoke("reload", []);
|
|
366
|
+
},
|
|
367
|
+
async url() {
|
|
368
|
+
return __pw_invoke("url", []);
|
|
379
369
|
},
|
|
380
|
-
url() { return __Playwright_url(); },
|
|
381
370
|
async title() {
|
|
382
|
-
|
|
383
|
-
return __Playwright_title_ref.applySyncPromise(undefined, []);
|
|
384
|
-
} catch (err) { throw __decodeError(err); }
|
|
371
|
+
return __pw_invoke("title", []);
|
|
385
372
|
},
|
|
386
373
|
async content() {
|
|
387
|
-
|
|
388
|
-
return __Playwright_content_ref.applySyncPromise(undefined, []);
|
|
389
|
-
} catch (err) { throw __decodeError(err); }
|
|
374
|
+
return __pw_invoke("content", []);
|
|
390
375
|
},
|
|
391
376
|
async waitForSelector(selector, options) {
|
|
392
|
-
|
|
393
|
-
return __Playwright_waitForSelector_ref.applySyncPromise(undefined, [selector, options ? JSON.stringify(options) : null]);
|
|
394
|
-
} catch (err) { throw __decodeError(err); }
|
|
377
|
+
return __pw_invoke("waitForSelector", [selector, options ? JSON.stringify(options) : null]);
|
|
395
378
|
},
|
|
396
379
|
async waitForTimeout(ms) {
|
|
397
|
-
|
|
398
|
-
return __Playwright_waitForTimeout_ref.applySyncPromise(undefined, [ms]);
|
|
399
|
-
} catch (err) { throw __decodeError(err); }
|
|
380
|
+
return __pw_invoke("waitForTimeout", [ms]);
|
|
400
381
|
},
|
|
401
382
|
async waitForLoadState(state) {
|
|
402
|
-
|
|
403
|
-
return __Playwright_waitForLoadState_ref.applySyncPromise(undefined, [state]);
|
|
404
|
-
} catch (err) { throw __decodeError(err); }
|
|
383
|
+
return __pw_invoke("waitForLoadState", [state || null]);
|
|
405
384
|
},
|
|
406
385
|
async evaluate(script) {
|
|
407
|
-
|
|
408
|
-
const resultJson = __Playwright_evaluate_ref.applySyncPromise(undefined, [script]);
|
|
409
|
-
return resultJson ? JSON.parse(resultJson) : undefined;
|
|
410
|
-
} catch (err) { throw __decodeError(err); }
|
|
386
|
+
return __pw_invoke("evaluate", [script]);
|
|
411
387
|
},
|
|
412
388
|
locator(selector) { return new Locator("css", selector, null); },
|
|
413
389
|
getByRole(role, options) { return new Locator("role", role, options ? JSON.stringify(options) : null); },
|
|
@@ -415,6 +391,33 @@ async function setupPlaywright(context, options) {
|
|
|
415
391
|
getByLabel(label) { return new Locator("label", label, null); },
|
|
416
392
|
getByPlaceholder(p) { return new Locator("placeholder", p, null); },
|
|
417
393
|
getByTestId(id) { return new Locator("testId", id, null); },
|
|
394
|
+
async click(selector) { return this.locator(selector).click(); },
|
|
395
|
+
async fill(selector, value) { return this.locator(selector).fill(value); },
|
|
396
|
+
request: {
|
|
397
|
+
async fetch(url, options) {
|
|
398
|
+
const result = await __pw_invoke("request", [url, options?.method || "GET", options?.data, options?.headers]);
|
|
399
|
+
return {
|
|
400
|
+
status: () => result.status,
|
|
401
|
+
ok: () => result.ok,
|
|
402
|
+
headers: () => result.headers,
|
|
403
|
+
json: async () => result.json,
|
|
404
|
+
text: async () => result.text,
|
|
405
|
+
body: async () => result.body,
|
|
406
|
+
};
|
|
407
|
+
},
|
|
408
|
+
async get(url, options) {
|
|
409
|
+
return this.fetch(url, { ...options, method: "GET" });
|
|
410
|
+
},
|
|
411
|
+
async post(url, options) {
|
|
412
|
+
return this.fetch(url, { ...options, method: "POST" });
|
|
413
|
+
},
|
|
414
|
+
async put(url, options) {
|
|
415
|
+
return this.fetch(url, { ...options, method: "PUT" });
|
|
416
|
+
},
|
|
417
|
+
async delete(url, options) {
|
|
418
|
+
return this.fetch(url, { ...options, method: "DELETE" });
|
|
419
|
+
},
|
|
420
|
+
},
|
|
418
421
|
};
|
|
419
422
|
})();
|
|
420
423
|
`);
|
|
@@ -431,105 +434,59 @@ async function setupPlaywright(context, options) {
|
|
|
431
434
|
_getInfo() { return [this.#type, this.#value, this.#options]; }
|
|
432
435
|
|
|
433
436
|
async click() {
|
|
434
|
-
|
|
435
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "click", null]);
|
|
436
|
-
} catch (err) { throw __decodeError(err); }
|
|
437
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "click", null]);
|
|
437
438
|
}
|
|
438
|
-
|
|
439
439
|
async dblclick() {
|
|
440
|
-
|
|
441
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "dblclick", null]);
|
|
442
|
-
} catch (err) { throw __decodeError(err); }
|
|
440
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "dblclick", null]);
|
|
443
441
|
}
|
|
444
|
-
|
|
445
442
|
async fill(text) {
|
|
446
|
-
|
|
447
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "fill", text]);
|
|
448
|
-
} catch (err) { throw __decodeError(err); }
|
|
443
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "fill", text]);
|
|
449
444
|
}
|
|
450
|
-
|
|
451
445
|
async type(text) {
|
|
452
|
-
|
|
453
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "type", text]);
|
|
454
|
-
} catch (err) { throw __decodeError(err); }
|
|
446
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "type", text]);
|
|
455
447
|
}
|
|
456
|
-
|
|
457
448
|
async check() {
|
|
458
|
-
|
|
459
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "check", null]);
|
|
460
|
-
} catch (err) { throw __decodeError(err); }
|
|
449
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "check", null]);
|
|
461
450
|
}
|
|
462
|
-
|
|
463
451
|
async uncheck() {
|
|
464
|
-
|
|
465
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "uncheck", null]);
|
|
466
|
-
} catch (err) { throw __decodeError(err); }
|
|
452
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "uncheck", null]);
|
|
467
453
|
}
|
|
468
|
-
|
|
469
454
|
async selectOption(value) {
|
|
470
|
-
|
|
471
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "selectOption", value]);
|
|
472
|
-
} catch (err) { throw __decodeError(err); }
|
|
455
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "selectOption", value]);
|
|
473
456
|
}
|
|
474
|
-
|
|
475
457
|
async clear() {
|
|
476
|
-
|
|
477
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "clear", null]);
|
|
478
|
-
} catch (err) { throw __decodeError(err); }
|
|
458
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "clear", null]);
|
|
479
459
|
}
|
|
480
|
-
|
|
481
460
|
async press(key) {
|
|
482
|
-
|
|
483
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "press", key]);
|
|
484
|
-
} catch (err) { throw __decodeError(err); }
|
|
461
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "press", key]);
|
|
485
462
|
}
|
|
486
|
-
|
|
487
463
|
async hover() {
|
|
488
|
-
|
|
489
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "hover", null]);
|
|
490
|
-
} catch (err) { throw __decodeError(err); }
|
|
464
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "hover", null]);
|
|
491
465
|
}
|
|
492
|
-
|
|
493
466
|
async focus() {
|
|
494
|
-
|
|
495
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "focus", null]);
|
|
496
|
-
} catch (err) { throw __decodeError(err); }
|
|
467
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "focus", null]);
|
|
497
468
|
}
|
|
498
|
-
|
|
499
469
|
async textContent() {
|
|
500
|
-
|
|
501
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "getText", null]);
|
|
502
|
-
} catch (err) { throw __decodeError(err); }
|
|
470
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "getText", null]);
|
|
503
471
|
}
|
|
504
|
-
|
|
505
472
|
async inputValue() {
|
|
506
|
-
|
|
507
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "getValue", null]);
|
|
508
|
-
} catch (err) { throw __decodeError(err); }
|
|
473
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "getValue", null]);
|
|
509
474
|
}
|
|
510
|
-
|
|
511
475
|
async isVisible() {
|
|
512
|
-
|
|
513
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "isVisible", null]);
|
|
514
|
-
} catch (err) { throw __decodeError(err); }
|
|
476
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "isVisible", null]);
|
|
515
477
|
}
|
|
516
|
-
|
|
517
478
|
async isEnabled() {
|
|
518
|
-
|
|
519
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "isEnabled", null]);
|
|
520
|
-
} catch (err) { throw __decodeError(err); }
|
|
479
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "isEnabled", null]);
|
|
521
480
|
}
|
|
522
|
-
|
|
523
481
|
async isChecked() {
|
|
524
|
-
|
|
525
|
-
return __Playwright_locatorAction_ref.applySyncPromise(undefined, [...this._getInfo(), "isChecked", null]);
|
|
526
|
-
} catch (err) { throw __decodeError(err); }
|
|
482
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "isChecked", null]);
|
|
527
483
|
}
|
|
528
|
-
|
|
529
484
|
async count() {
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
485
|
+
return __pw_invoke("locatorAction", [...this._getInfo(), "count", null]);
|
|
486
|
+
}
|
|
487
|
+
nth(index) {
|
|
488
|
+
const existingOpts = this.#options ? JSON.parse(this.#options) : {};
|
|
489
|
+
return new Locator(this.#type, this.#value, JSON.stringify({ ...existingOpts, nth: index }));
|
|
533
490
|
}
|
|
534
491
|
}
|
|
535
492
|
globalThis.Locator = Locator;
|
|
@@ -537,127 +494,84 @@ async function setupPlaywright(context, options) {
|
|
|
537
494
|
`);
|
|
538
495
|
context.evalSync(`
|
|
539
496
|
(function() {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
} catch (err) { throw __decodeError(err); }
|
|
548
|
-
},
|
|
549
|
-
async toContainText(expected) {
|
|
550
|
-
try {
|
|
551
|
-
await __Playwright_expectText_ref.applySyncPromise(undefined, [...info, expected, false]);
|
|
552
|
-
} catch (err) { throw __decodeError(err); }
|
|
553
|
-
},
|
|
554
|
-
async toHaveValue(expected) {
|
|
555
|
-
try {
|
|
556
|
-
await __Playwright_expectValue_ref.applySyncPromise(undefined, [...info, expected, false]);
|
|
557
|
-
} catch (err) { throw __decodeError(err); }
|
|
558
|
-
},
|
|
559
|
-
async toBeEnabled() {
|
|
560
|
-
try {
|
|
561
|
-
await __Playwright_expectEnabled_ref.applySyncPromise(undefined, [...info, false]);
|
|
562
|
-
} catch (err) { throw __decodeError(err); }
|
|
563
|
-
},
|
|
564
|
-
async toBeChecked() {
|
|
565
|
-
try {
|
|
566
|
-
await __Playwright_expectChecked_ref.applySyncPromise(undefined, [...info, false]);
|
|
567
|
-
} catch (err) { throw __decodeError(err); }
|
|
568
|
-
},
|
|
569
|
-
not: {
|
|
570
|
-
async toBeVisible() {
|
|
571
|
-
try {
|
|
572
|
-
await __Playwright_expectVisible_ref.applySyncPromise(undefined, [...info, true]);
|
|
573
|
-
} catch (err) { throw __decodeError(err); }
|
|
574
|
-
},
|
|
575
|
-
async toContainText(expected) {
|
|
576
|
-
try {
|
|
577
|
-
await __Playwright_expectText_ref.applySyncPromise(undefined, [...info, expected, true]);
|
|
578
|
-
} catch (err) { throw __decodeError(err); }
|
|
579
|
-
},
|
|
580
|
-
async toHaveValue(expected) {
|
|
581
|
-
try {
|
|
582
|
-
await __Playwright_expectValue_ref.applySyncPromise(undefined, [...info, expected, true]);
|
|
583
|
-
} catch (err) { throw __decodeError(err); }
|
|
584
|
-
},
|
|
585
|
-
async toBeEnabled() {
|
|
586
|
-
try {
|
|
587
|
-
await __Playwright_expectEnabled_ref.applySyncPromise(undefined, [...info, true]);
|
|
588
|
-
} catch (err) { throw __decodeError(err); }
|
|
589
|
-
},
|
|
590
|
-
async toBeChecked() {
|
|
591
|
-
try {
|
|
592
|
-
await __Playwright_expectChecked_ref.applySyncPromise(undefined, [...info, true]);
|
|
593
|
-
} catch (err) { throw __decodeError(err); }
|
|
594
|
-
},
|
|
595
|
-
},
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
// Fallback: basic matchers for primitives
|
|
599
|
-
return {
|
|
600
|
-
toBe(expected) {
|
|
601
|
-
if (actual !== expected) throw new Error(\`Expected \${JSON.stringify(actual)} to be \${JSON.stringify(expected)}\`);
|
|
497
|
+
// Helper to create locator matchers
|
|
498
|
+
function createLocatorMatchers(locator, baseMatchers) {
|
|
499
|
+
const info = locator._getInfo();
|
|
500
|
+
|
|
501
|
+
const locatorMatchers = {
|
|
502
|
+
async toBeVisible(options) {
|
|
503
|
+
return __pw_invoke("expectLocator", [...info, "toBeVisible", null, false, options?.timeout]);
|
|
602
504
|
},
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
throw new Error(\`Expected \${JSON.stringify(actual)} to equal \${JSON.stringify(expected)}\`);
|
|
606
|
-
}
|
|
505
|
+
async toContainText(expected, options) {
|
|
506
|
+
return __pw_invoke("expectLocator", [...info, "toContainText", expected, false, options?.timeout]);
|
|
607
507
|
},
|
|
608
|
-
|
|
609
|
-
|
|
508
|
+
async toHaveValue(expected, options) {
|
|
509
|
+
return __pw_invoke("expectLocator", [...info, "toHaveValue", expected, false, options?.timeout]);
|
|
610
510
|
},
|
|
611
|
-
|
|
612
|
-
|
|
511
|
+
async toBeEnabled(options) {
|
|
512
|
+
return __pw_invoke("expectLocator", [...info, "toBeEnabled", null, false, options?.timeout]);
|
|
613
513
|
},
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
throw new Error(\`Expected "\${actual}" to contain "\${expected}"\`);
|
|
617
|
-
}
|
|
618
|
-
if (Array.isArray(actual) && !actual.includes(expected)) {
|
|
619
|
-
throw new Error(\`Expected array to contain \${JSON.stringify(expected)}\`);
|
|
620
|
-
}
|
|
514
|
+
async toBeChecked(options) {
|
|
515
|
+
return __pw_invoke("expectLocator", [...info, "toBeChecked", null, false, options?.timeout]);
|
|
621
516
|
},
|
|
622
517
|
not: {
|
|
623
|
-
|
|
624
|
-
|
|
518
|
+
async toBeVisible(options) {
|
|
519
|
+
return __pw_invoke("expectLocator", [...info, "toBeVisible", null, true, options?.timeout]);
|
|
625
520
|
},
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
throw new Error(\`Expected \${JSON.stringify(actual)} to not equal \${JSON.stringify(expected)}\`);
|
|
629
|
-
}
|
|
521
|
+
async toContainText(expected, options) {
|
|
522
|
+
return __pw_invoke("expectLocator", [...info, "toContainText", expected, true, options?.timeout]);
|
|
630
523
|
},
|
|
631
|
-
|
|
632
|
-
|
|
524
|
+
async toHaveValue(expected, options) {
|
|
525
|
+
return __pw_invoke("expectLocator", [...info, "toHaveValue", expected, true, options?.timeout]);
|
|
633
526
|
},
|
|
634
|
-
|
|
635
|
-
|
|
527
|
+
async toBeEnabled(options) {
|
|
528
|
+
return __pw_invoke("expectLocator", [...info, "toBeEnabled", null, true, options?.timeout]);
|
|
636
529
|
},
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
throw new Error(\`Expected "\${actual}" to not contain "\${expected}"\`);
|
|
640
|
-
}
|
|
641
|
-
if (Array.isArray(actual) && actual.includes(expected)) {
|
|
642
|
-
throw new Error(\`Expected array to not contain \${JSON.stringify(expected)}\`);
|
|
643
|
-
}
|
|
530
|
+
async toBeChecked(options) {
|
|
531
|
+
return __pw_invoke("expectLocator", [...info, "toBeChecked", null, true, options?.timeout]);
|
|
644
532
|
},
|
|
645
|
-
}
|
|
533
|
+
}
|
|
646
534
|
};
|
|
647
|
-
|
|
535
|
+
|
|
536
|
+
// Merge locator matchers with base matchers from test-environment
|
|
537
|
+
if (baseMatchers) {
|
|
538
|
+
return {
|
|
539
|
+
...baseMatchers,
|
|
540
|
+
...locatorMatchers,
|
|
541
|
+
not: { ...baseMatchers.not, ...locatorMatchers.not }
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
return locatorMatchers;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Only extend expect if test-environment already defined it
|
|
548
|
+
if (typeof globalThis.expect === 'function') {
|
|
549
|
+
const originalExpect = globalThis.expect;
|
|
550
|
+
globalThis.expect = function(actual) {
|
|
551
|
+
const baseMatchers = originalExpect(actual);
|
|
552
|
+
// If actual is a Locator, add locator-specific matchers
|
|
553
|
+
if (actual && actual.constructor && actual.constructor.name === 'Locator') {
|
|
554
|
+
return createLocatorMatchers(actual, baseMatchers);
|
|
555
|
+
}
|
|
556
|
+
return baseMatchers;
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
// If test-environment not loaded, expect remains undefined
|
|
648
560
|
})();
|
|
649
561
|
`);
|
|
650
562
|
return {
|
|
651
563
|
dispose() {
|
|
652
|
-
page
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
564
|
+
if (page && requestHandler && responseHandler && consoleHandler) {
|
|
565
|
+
page.off("request", requestHandler);
|
|
566
|
+
page.off("response", responseHandler);
|
|
567
|
+
page.off("console", consoleHandler);
|
|
568
|
+
}
|
|
569
|
+
browserConsoleLogs.length = 0;
|
|
656
570
|
networkRequests.length = 0;
|
|
657
571
|
networkResponses.length = 0;
|
|
658
572
|
},
|
|
659
|
-
|
|
660
|
-
return [...
|
|
573
|
+
getBrowserConsoleLogs() {
|
|
574
|
+
return [...browserConsoleLogs];
|
|
661
575
|
},
|
|
662
576
|
getNetworkRequests() {
|
|
663
577
|
return [...networkRequests];
|
|
@@ -666,28 +580,15 @@ async function setupPlaywright(context, options) {
|
|
|
666
580
|
return [...networkResponses];
|
|
667
581
|
},
|
|
668
582
|
clearCollected() {
|
|
669
|
-
|
|
583
|
+
browserConsoleLogs.length = 0;
|
|
670
584
|
networkRequests.length = 0;
|
|
671
585
|
networkResponses.length = 0;
|
|
672
586
|
}
|
|
673
587
|
};
|
|
674
588
|
}
|
|
675
|
-
async function runPlaywrightTests(context) {
|
|
676
|
-
const runTestsRef = context.global.getSync("__runPlaywrightTests", {
|
|
677
|
-
reference: true
|
|
678
|
-
});
|
|
679
|
-
const resultJson = await runTestsRef.apply(undefined, [], {
|
|
680
|
-
result: { promise: true }
|
|
681
|
-
});
|
|
682
|
-
return JSON.parse(resultJson);
|
|
683
|
-
}
|
|
684
|
-
async function resetPlaywrightTests(context) {
|
|
685
|
-
context.evalSync("__resetPlaywrightTests()");
|
|
686
|
-
}
|
|
687
589
|
export {
|
|
688
590
|
setupPlaywright,
|
|
689
|
-
|
|
690
|
-
resetPlaywrightTests
|
|
591
|
+
createPlaywrightHandler
|
|
691
592
|
};
|
|
692
593
|
|
|
693
|
-
//# debugId=
|
|
594
|
+
//# debugId=2B6B9A3D4E225DD464756E2164756E21
|