@rstest/browser 0.11.6 → 0.11.8

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.
Files changed (88) hide show
  1. package/dist/browser-container/container-static/css/index.43daaf6c93.css +1 -0
  2. package/dist/browser-container/container-static/js/260.3739fe815c.js +194 -0
  3. package/dist/browser-container/container-static/js/index.c0f87bfb3e.js +1 -0
  4. package/dist/browser-container/index.html +1 -1
  5. package/dist/browserRsbuild.d.ts +24 -4
  6. package/dist/browserV8Coverage.d.ts +15 -0
  7. package/dist/client/240~1.js +150 -0
  8. package/dist/{augmentExpect.d.ts → client/client/augmentExpect.d.ts} +1 -1
  9. package/dist/client/{browserRpc.d.ts → client/browserRpc.d.ts} +1 -1
  10. package/dist/client/{dispatchTransport.d.ts → client/dispatchTransport.d.ts} +8 -4
  11. package/dist/client/client/index.d.ts +2 -0
  12. package/dist/client/client/runIdentity.d.ts +12 -0
  13. package/dist/client/client/runner.d.ts +4 -0
  14. package/dist/client/client/snapshot.d.ts +27 -0
  15. package/dist/client/client/sourceMapSupport.d.ts +36 -0
  16. package/dist/{browser.js → client/index.js} +3 -102
  17. package/dist/client/protocol.d.ts +225 -0
  18. package/dist/client/rpcProtocol.d.ts +138 -0
  19. package/dist/client/runner.js +675 -0
  20. package/dist/client/sourceMap/sourceMapLoader.d.ts +25 -0
  21. package/dist/containerRpc.d.ts +27 -19
  22. package/dist/headedRunRegistry.d.ts +51 -0
  23. package/dist/headedScheduler.d.ts +10 -10
  24. package/dist/headlessScheduler.d.ts +5 -4
  25. package/dist/headlessTransport.d.ts +4 -2
  26. package/dist/hostPayloads.d.ts +1 -7
  27. package/dist/index.js +840 -330
  28. package/dist/protocol.d.ts +48 -8
  29. package/dist/providers/index.d.ts +21 -0
  30. package/dist/providers/playwright/v8Coverage.d.ts +2 -0
  31. package/dist/rpcProtocol.d.ts +1 -2
  32. package/dist/schedulerSeam.d.ts +5 -0
  33. package/dist/sourceMap/sourceMapLoader.d.ts +12 -1
  34. package/dist/watchRerunPlanner.d.ts +20 -9
  35. package/dist/watchSignals.d.ts +8 -1
  36. package/package.json +11 -11
  37. package/dist/33.js +0 -7
  38. package/dist/browser-container/container-static/css/index.0521ff95b1.css +0 -1
  39. package/dist/browser-container/container-static/js/683.4f821ce8f1.js +0 -194
  40. package/dist/browser-container/container-static/js/index.568aa7cb35.js +0 -1
  41. package/dist/browser.d.ts +0 -2
  42. package/src/augmentExpect.ts +0 -62
  43. package/src/browser.ts +0 -3
  44. package/src/browserExecutor.ts +0 -222
  45. package/src/browserRpcRegistry.ts +0 -57
  46. package/src/browserRsbuild.ts +0 -1927
  47. package/src/client/api.ts +0 -213
  48. package/src/client/browserRpc.ts +0 -86
  49. package/src/client/dispatchTransport.ts +0 -240
  50. package/src/client/entry.ts +0 -807
  51. package/src/client/locator.ts +0 -448
  52. package/src/client/snapshot.ts +0 -113
  53. package/src/client/sourceMapSupport.ts +0 -159
  54. package/src/concurrency.ts +0 -65
  55. package/src/configValidation.ts +0 -263
  56. package/src/containerRpc.ts +0 -206
  57. package/src/dispatchCapabilities.ts +0 -177
  58. package/src/dispatchRouter.ts +0 -82
  59. package/src/env.d.ts +0 -54
  60. package/src/headedScheduler.ts +0 -664
  61. package/src/headedSerialTaskQueue.ts +0 -23
  62. package/src/headlessScheduler.ts +0 -566
  63. package/src/headlessTransport.ts +0 -28
  64. package/src/hostController.ts +0 -1365
  65. package/src/hostPayloads.ts +0 -62
  66. package/src/index.ts +0 -51
  67. package/src/manifest.d.ts +0 -41
  68. package/src/protocol.ts +0 -225
  69. package/src/providers/index.ts +0 -126
  70. package/src/providers/playwright/compileLocator.ts +0 -130
  71. package/src/providers/playwright/dispatchBrowserRpc.ts +0 -372
  72. package/src/providers/playwright/expectUtils.ts +0 -57
  73. package/src/providers/playwright/implementation.ts +0 -35
  74. package/src/providers/playwright/index.ts +0 -1
  75. package/src/providers/playwright/runtime.ts +0 -159
  76. package/src/providers/playwright/textMatcher.ts +0 -10
  77. package/src/rpcProtocol.ts +0 -218
  78. package/src/runSession.ts +0 -110
  79. package/src/schedulerSeam.ts +0 -49
  80. package/src/sessionRegistry.ts +0 -89
  81. package/src/sourceMap/sourceMapLoader.ts +0 -96
  82. package/src/viewportPresets.ts +0 -69
  83. package/src/watchRerunPlanner.ts +0 -88
  84. package/src/watchRuntime.ts +0 -83
  85. package/src/watchSignals.ts +0 -93
  86. /package/dist/{rslib-runtime.js → 612~0.js} +0 -0
  87. /package/dist/client/{api.d.ts → client/api.d.ts} +0 -0
  88. /package/dist/client/{locator.d.ts → client/locator.d.ts} +0 -0
@@ -1,372 +0,0 @@
1
- /**
2
- * Contains adapted logic from Playwright matchers:
3
- * https://github.com/microsoft/playwright/blob/main/packages/playwright/src/matchers/matchers.ts
4
- * Copyright (c) Microsoft Corporation, Apache-2.0.
5
- */
6
- import type { FrameLocator, Locator, Page } from 'playwright';
7
- import {
8
- supportedExpectElementMatchers,
9
- supportedLocatorActions,
10
- } from '../../browserRpcRegistry';
11
- import type {
12
- BrowserLocatorIR,
13
- BrowserLocatorText,
14
- BrowserRpcRequest,
15
- } from '../../rpcProtocol';
16
- import { compilePlaywrightLocator } from './compileLocator';
17
- import { formatExpectError, serializeExpectedText } from './expectUtils';
18
-
19
- // ---------------------------------------------------------------------------
20
- // Iframe lookup
21
- // ---------------------------------------------------------------------------
22
-
23
- const escapeCssAttrValue = (value: string): string => {
24
- // Minimal escaping for use in CSS attribute selectors with single quotes.
25
- // https://www.w3.org/TR/selectors-4/#attribute-representation
26
- return value.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
27
- };
28
-
29
- const getRunnerFrame = async (
30
- containerPage: Page,
31
- testPath: string,
32
- timeoutMs: number,
33
- ): Promise<FrameLocator> => {
34
- const selector = `iframe[data-test-file='${escapeCssAttrValue(testPath)}']`;
35
- const iframe = containerPage.locator(selector);
36
-
37
- const count = await iframe.count();
38
- if (count === 0) {
39
- const known = await containerPage
40
- .locator('iframe[data-test-file]')
41
- .evaluateAll((nodes) =>
42
- nodes.map((n) => (n as HTMLIFrameElement).dataset.testFile),
43
- );
44
- throw new Error(
45
- `Runner iframe not found for testPath: ${JSON.stringify(testPath)}. ` +
46
- `Known iframes: ${JSON.stringify(known)}. ` +
47
- `Timeout: ${timeoutMs}ms`,
48
- );
49
- }
50
-
51
- return containerPage.frameLocator(selector);
52
- };
53
-
54
- // ---------------------------------------------------------------------------
55
- // Table-driven expect matcher dispatch
56
- // ---------------------------------------------------------------------------
57
-
58
- /**
59
- * Calls Playwright's internal `_expect()` and throws on mismatch.
60
- *
61
- * NOTE: `_expect()` is a Playwright semi-internal API used by its own test
62
- * runner to implement all web-first assertions. It is not part of the public
63
- * docs but is stable across minor versions. All Playwright-specific coupling
64
- * is intentionally confined to this provider module.
65
- * See: https://github.com/nicolo-ribaudo/playwright/blob/HEAD/packages/playwright-core/src/client/locator.ts
66
- */
67
- const callExpect = async (
68
- locator: Locator,
69
- expectMethod: string,
70
- options: Record<string, unknown>,
71
- fallbackMessage: string,
72
- ): Promise<null> => {
73
- const result = await (locator as any)._expect(expectMethod, options);
74
- if (result.matches !== !options.isNot) {
75
- throw new Error(formatExpectError(result) || fallbackMessage);
76
- }
77
- return null;
78
- };
79
-
80
- const assertSerializedText = (
81
- value: unknown,
82
- matcherName: string,
83
- ): BrowserLocatorText => {
84
- const t = value as any;
85
- if (!t || (t.type !== 'string' && t.type !== 'regexp')) {
86
- throw new Error(`${matcherName} expects a serialized text matcher`);
87
- }
88
- return t as BrowserLocatorText;
89
- };
90
-
91
- const assertStringArg = (
92
- value: unknown,
93
- matcherName: string,
94
- label: string,
95
- ): string => {
96
- if (typeof value !== 'string' || !value) {
97
- throw new Error(`${matcherName} expects ${label}`);
98
- }
99
- return value;
100
- };
101
-
102
- /** Simple boolean state matchers — no extra args. */
103
- const simpleMatchers: Record<string, string> = {
104
- toBeVisible: 'to.be.visible',
105
- toBeHidden: 'to.be.hidden',
106
- toBeEnabled: 'to.be.enabled',
107
- toBeDisabled: 'to.be.disabled',
108
- toBeAttached: 'to.be.attached',
109
- toBeDetached: 'to.be.detached',
110
- toBeEditable: 'to.be.editable',
111
- toBeFocused: 'to.be.focused',
112
- toBeEmpty: 'to.be.empty',
113
- };
114
-
115
- /** Text matchers that take a single serialized text arg. */
116
- const textMatchers: Record<
117
- string,
118
- {
119
- expectMethod: string;
120
- textOptions?: { matchSubstring?: boolean; normalizeWhiteSpace?: boolean };
121
- }
122
- > = {
123
- toHaveId: { expectMethod: 'to.have.id' },
124
- toHaveText: {
125
- expectMethod: 'to.have.text',
126
- textOptions: { normalizeWhiteSpace: true },
127
- },
128
- toContainText: {
129
- expectMethod: 'to.have.text',
130
- textOptions: { matchSubstring: true, normalizeWhiteSpace: true },
131
- },
132
- toHaveValue: { expectMethod: 'to.have.value' },
133
- toHaveClass: { expectMethod: 'to.have.class' },
134
- };
135
-
136
- /**
137
- * Dispatches an expect matcher call on the given Playwright locator.
138
- * Returns `null` on success, throws on mismatch or invalid args.
139
- */
140
- const dispatchExpectMatcher = (
141
- locator: Locator,
142
- request: BrowserRpcRequest,
143
- isNot: boolean,
144
- timeout: number,
145
- ): Promise<null> => {
146
- const { method, args } = request;
147
-
148
- // --- Simple boolean state matchers ---
149
- const simpleExpect = simpleMatchers[method];
150
- if (simpleExpect) {
151
- return callExpect(
152
- locator,
153
- simpleExpect,
154
- { isNot, timeout },
155
- `Expected element ${method
156
- .replace('toBe', 'to be ')
157
- .replace(/([A-Z])/g, ' $1')
158
- .trim()
159
- .toLowerCase()}`,
160
- );
161
- }
162
-
163
- // --- Text matchers (single serialized text arg) ---
164
- const textDef = textMatchers[method];
165
- if (textDef) {
166
- const expected = assertSerializedText(args[0], method);
167
- return callExpect(
168
- locator,
169
- textDef.expectMethod,
170
- {
171
- isNot,
172
- timeout,
173
- expectedText: serializeExpectedText(expected, textDef.textOptions),
174
- },
175
- `Expected element ${method}`,
176
- );
177
- }
178
-
179
- // --- Matchers with custom arg handling ---
180
- switch (method) {
181
- case 'toBeInViewport': {
182
- const ratio = args[0];
183
- if (ratio !== undefined && typeof ratio !== 'number') {
184
- throw new Error(
185
- `toBeInViewport expects ratio to be a number, got ${typeof ratio}`,
186
- );
187
- }
188
- return callExpect(
189
- locator,
190
- 'to.be.in.viewport',
191
- { isNot, timeout, expectedNumber: ratio },
192
- 'Expected element to be in viewport',
193
- );
194
- }
195
- case 'toBeChecked':
196
- return callExpect(
197
- locator,
198
- 'to.be.checked',
199
- { isNot, timeout, expectedValue: { checked: true } },
200
- 'Expected element to be checked',
201
- );
202
- case 'toBeUnchecked':
203
- return callExpect(
204
- locator,
205
- 'to.be.checked',
206
- { isNot, timeout, expectedValue: { checked: false } },
207
- 'Expected element to be unchecked',
208
- );
209
- case 'toHaveCount': {
210
- const expected = args[0];
211
- if (typeof expected !== 'number') {
212
- throw new Error(`toHaveCount expects a number, got ${typeof expected}`);
213
- }
214
- return callExpect(
215
- locator,
216
- 'to.have.count',
217
- { isNot, timeout, expectedNumber: expected },
218
- `Expected count ${expected}`,
219
- );
220
- }
221
- case 'toHaveAttribute': {
222
- const name = assertStringArg(
223
- args[0],
224
- 'toHaveAttribute',
225
- 'an attribute name',
226
- );
227
- if (args.length < 2) {
228
- return callExpect(
229
- locator,
230
- 'to.have.attribute',
231
- { isNot, timeout, expressionArg: name },
232
- `Expected attribute ${name} to be present`,
233
- );
234
- }
235
- const expected = assertSerializedText(args[1], 'toHaveAttribute');
236
- return callExpect(
237
- locator,
238
- 'to.have.attribute.value',
239
- {
240
- isNot,
241
- timeout,
242
- expressionArg: name,
243
- expectedText: serializeExpectedText(expected),
244
- },
245
- `Expected attribute ${name} to match`,
246
- );
247
- }
248
- case 'toHaveCSS': {
249
- const name = assertStringArg(args[0], 'toHaveCSS', 'a CSS property name');
250
- const expected = assertSerializedText(args[1], 'toHaveCSS');
251
- return callExpect(
252
- locator,
253
- 'to.have.css',
254
- {
255
- isNot,
256
- timeout,
257
- expressionArg: name,
258
- expectedText: serializeExpectedText(expected),
259
- },
260
- `Expected CSS ${name} to match`,
261
- );
262
- }
263
- case 'toHaveJSProperty': {
264
- const name = assertStringArg(
265
- args[0],
266
- 'toHaveJSProperty',
267
- 'a property name',
268
- );
269
- const expectedValue = args[1];
270
- try {
271
- JSON.stringify(expectedValue);
272
- } catch {
273
- throw new Error(
274
- 'toHaveJSProperty expects a JSON-serializable expected value',
275
- );
276
- }
277
- return callExpect(
278
- locator,
279
- 'to.have.property',
280
- { isNot, timeout, expressionArg: name, expectedValue },
281
- `Expected JS property ${name} to match`,
282
- );
283
- }
284
- }
285
-
286
- throw new Error(`Unhandled expect matcher: ${method}`);
287
- };
288
-
289
- // ---------------------------------------------------------------------------
290
- // Config dispatch
291
- // ---------------------------------------------------------------------------
292
-
293
- const dispatchConfigMethod = async (
294
- request: BrowserRpcRequest,
295
- ): Promise<null> => {
296
- switch (request.method) {
297
- case 'setTestIdAttribute': {
298
- const attr = request.args[0];
299
- if (typeof attr !== 'string' || !attr) {
300
- throw new Error(
301
- 'setTestIdAttribute expects a non-empty string argument',
302
- );
303
- }
304
- const playwright = await import('playwright');
305
- playwright.selectors.setTestIdAttribute(attr);
306
- return null;
307
- }
308
- default:
309
- throw new Error(`Unknown config method: ${request.method}`);
310
- }
311
- };
312
-
313
- // ---------------------------------------------------------------------------
314
- // Public entry
315
- // ---------------------------------------------------------------------------
316
-
317
- export async function dispatchPlaywrightBrowserRpc({
318
- containerPage,
319
- runnerPage,
320
- request,
321
- timeoutFallbackMs,
322
- }: {
323
- containerPage?: Page;
324
- runnerPage?: Page;
325
- request: BrowserRpcRequest;
326
- timeoutFallbackMs: number;
327
- }): Promise<unknown> {
328
- // Config operations don't need a locator or runner frame.
329
- if (request.kind === 'config') {
330
- return dispatchConfigMethod(request);
331
- }
332
-
333
- const testPath = request.testPath;
334
- if (!testPath) {
335
- throw new Error('Browser RPC request is missing testPath');
336
- }
337
-
338
- const timeout =
339
- typeof request.timeout === 'number' ? request.timeout : timeoutFallbackMs;
340
-
341
- const locatorRoot = runnerPage
342
- ? runnerPage
343
- : await getRunnerFrame(
344
- containerPage ??
345
- (() => {
346
- throw new Error('Browser container page is not initialized');
347
- })(),
348
- testPath,
349
- timeout,
350
- );
351
- const locator = compilePlaywrightLocator(
352
- locatorRoot,
353
- request.locator as BrowserLocatorIR,
354
- );
355
-
356
- if (request.kind === 'locator') {
357
- if (!supportedLocatorActions.has(request.method)) {
358
- throw new Error(`Locator method not supported: ${request.method}`);
359
- }
360
- const target: any = locator as any;
361
- return await target[request.method](...request.args);
362
- }
363
-
364
- if (request.kind === 'expect') {
365
- if (!supportedExpectElementMatchers.has(request.method)) {
366
- throw new Error(`Expect matcher not supported: ${request.method}`);
367
- }
368
- return dispatchExpectMatcher(locator, request, !!request.isNot, timeout);
369
- }
370
-
371
- throw new Error(`Unknown browser rpc kind: ${request.kind}`);
372
- }
@@ -1,57 +0,0 @@
1
- /**
2
- * Contains adapted logic from Playwright matchers:
3
- * https://github.com/microsoft/playwright/blob/main/packages/playwright/src/matchers/matchers.ts
4
- * Copyright (c) Microsoft Corporation, Apache-2.0.
5
- */
6
- import type { BrowserLocatorText } from '../../rpcProtocol';
7
-
8
- type ExpectedTextValue = {
9
- string?: string;
10
- regexSource?: string;
11
- regexFlags?: string;
12
- matchSubstring?: boolean;
13
- ignoreCase?: boolean;
14
- normalizeWhiteSpace?: boolean;
15
- };
16
-
17
- export const serializeExpectedText = (
18
- text: BrowserLocatorText,
19
- options?: {
20
- matchSubstring?: boolean;
21
- normalizeWhiteSpace?: boolean;
22
- ignoreCase?: boolean;
23
- },
24
- ): ExpectedTextValue[] => {
25
- const base: ExpectedTextValue = {
26
- matchSubstring: options?.matchSubstring,
27
- ignoreCase: options?.ignoreCase,
28
- normalizeWhiteSpace: options?.normalizeWhiteSpace,
29
- };
30
-
31
- if (text.type === 'string') {
32
- return [{ ...base, string: text.value }];
33
- }
34
-
35
- return [
36
- {
37
- ...base,
38
- regexSource: text.source,
39
- regexFlags: text.flags,
40
- },
41
- ];
42
- };
43
-
44
- export const formatExpectError = (result: {
45
- errorMessage?: string;
46
- log?: string[];
47
- }): string => {
48
- const parts: string[] = [];
49
- if (result.errorMessage) {
50
- parts.push(result.errorMessage);
51
- }
52
- if (result.log?.length) {
53
- parts.push('Call log:');
54
- parts.push(...result.log.map((l) => `- ${l}`));
55
- }
56
- return parts.join('\n');
57
- };
@@ -1,35 +0,0 @@
1
- import type { Page } from 'playwright';
2
- import type {
3
- BrowserProviderImplementation,
4
- BrowserProviderRuntime,
5
- } from '../index';
6
- import { dispatchPlaywrightBrowserRpc } from './dispatchBrowserRpc';
7
- import { launchPlaywrightBrowser } from './runtime';
8
-
9
- export const playwrightProviderImplementation: BrowserProviderImplementation = {
10
- name: 'playwright',
11
- async launchRuntime({
12
- browserName,
13
- headless,
14
- providerOptions,
15
- }): Promise<BrowserProviderRuntime> {
16
- return launchPlaywrightBrowser({
17
- browserName,
18
- headless,
19
- providerOptions,
20
- });
21
- },
22
- async dispatchRpc({
23
- containerPage,
24
- runnerPage,
25
- request,
26
- timeoutFallbackMs,
27
- }): Promise<unknown> {
28
- return dispatchPlaywrightBrowserRpc({
29
- containerPage: containerPage as Page | undefined,
30
- runnerPage: runnerPage as Page | undefined,
31
- request,
32
- timeoutFallbackMs,
33
- });
34
- },
35
- };
@@ -1 +0,0 @@
1
- export { playwrightProviderImplementation } from './implementation';
@@ -1,159 +0,0 @@
1
- import type {
2
- BrowserConsoleMessage,
3
- BrowserProviderContext,
4
- BrowserProviderPage,
5
- BrowserProviderRuntime,
6
- } from '../index';
7
-
8
- type PlaywrightPageLike = Omit<
9
- BrowserProviderPage,
10
- 'on' | typeof Symbol.asyncDispose
11
- > & {
12
- on: {
13
- (event: 'popup', listener: (page: PlaywrightPageLike) => void): void;
14
- (
15
- event: 'console',
16
- listener: (message: BrowserConsoleMessage) => void,
17
- ): void;
18
- (event: 'crash' | 'close', listener: () => void): void;
19
- };
20
- };
21
- type PlaywrightContextLike = Omit<
22
- BrowserProviderContext,
23
- 'newPage' | typeof Symbol.asyncDispose
24
- > & {
25
- newPage: () => Promise<PlaywrightPageLike>;
26
- };
27
-
28
- type AsyncDisposableResource<T> = T & {
29
- [Symbol.asyncDispose]: () => Promise<void>;
30
- };
31
-
32
- type PlaywrightBrowserLike = Omit<
33
- BrowserProviderRuntime['browser'],
34
- typeof Symbol.asyncDispose
35
- >;
36
-
37
- const patchedPages = new WeakSet<PlaywrightPageLike>();
38
- const patchedContexts = new WeakSet<PlaywrightContextLike>();
39
-
40
- const withAsyncDispose = <T extends { close: () => Promise<void> }>(
41
- resource: T,
42
- ): AsyncDisposableResource<T> => {
43
- if (typeof Symbol.asyncDispose === 'symbol') {
44
- const existing = Object.getOwnPropertyDescriptor(
45
- resource,
46
- Symbol.asyncDispose,
47
- );
48
- if (!existing) {
49
- Object.defineProperty(resource, Symbol.asyncDispose, {
50
- configurable: true,
51
- value: () => resource.close(),
52
- });
53
- }
54
- }
55
-
56
- return resource as AsyncDisposableResource<T>;
57
- };
58
-
59
- const wrapPage = (page: PlaywrightPageLike): BrowserProviderPage => {
60
- if (patchedPages.has(page)) {
61
- return withAsyncDispose(page) as BrowserProviderPage;
62
- }
63
-
64
- patchedPages.add(page);
65
- const originalOn = page.on.bind(page);
66
- page.on = ((
67
- event: 'popup' | 'console' | 'crash' | 'close',
68
- listener:
69
- | ((page: BrowserProviderPage) => void)
70
- | ((message: BrowserConsoleMessage) => void)
71
- | (() => void),
72
- ) => {
73
- if (event === 'popup') {
74
- originalOn(event, (popup) => {
75
- (listener as (page: BrowserProviderPage) => void)(wrapPage(popup));
76
- });
77
- return;
78
- }
79
-
80
- if (event === 'crash' || event === 'close') {
81
- originalOn(event, listener as () => void);
82
- return;
83
- }
84
-
85
- originalOn(event, listener as (message: BrowserConsoleMessage) => void);
86
- }) as PlaywrightPageLike['on'];
87
-
88
- return withAsyncDispose(page) as BrowserProviderPage;
89
- };
90
-
91
- const wrapContext = (
92
- context: PlaywrightContextLike,
93
- ): BrowserProviderContext => {
94
- if (patchedContexts.has(context)) {
95
- return withAsyncDispose(context) as BrowserProviderContext;
96
- }
97
-
98
- patchedContexts.add(context);
99
- const originalNewPage = context.newPage.bind(context);
100
- context.newPage = async () => wrapPage(await originalNewPage());
101
-
102
- const originalOn = context.on.bind(context);
103
- context.on = (event, listener) => {
104
- originalOn(event, (page) => listener(wrapPage(page)));
105
- };
106
-
107
- return withAsyncDispose(context) as BrowserProviderContext;
108
- };
109
-
110
- export async function launchPlaywrightBrowser({
111
- browserName,
112
- headless,
113
- providerOptions,
114
- }: {
115
- browserName: 'chromium' | 'firefox' | 'webkit';
116
- headless: boolean | undefined;
117
- providerOptions: Record<string, unknown>;
118
- }): Promise<BrowserProviderRuntime> {
119
- const playwright = await import('playwright');
120
- const browserType = playwright[browserName];
121
- const launchOptions = providerOptions.launch as
122
- Record<string, unknown> | undefined;
123
- const launchArgs = Array.isArray(launchOptions?.args)
124
- ? launchOptions.args
125
- : browserName === 'chromium'
126
- ? [
127
- '--disable-popup-blocking',
128
- '--no-first-run',
129
- '--no-default-browser-check',
130
- ]
131
- : undefined;
132
-
133
- const browser = await browserType.launch({
134
- ...launchOptions,
135
- headless,
136
- args: launchArgs,
137
- });
138
-
139
- const wrappedBrowser = withAsyncDispose({
140
- close: async () => browser.close(),
141
- newContext: async ({
142
- providerOptions: contextProviderOptions,
143
- viewport,
144
- }) => {
145
- const contextOptions = contextProviderOptions?.context as
146
- Record<string, unknown> | undefined;
147
- const context = await browser.newContext({
148
- ...contextOptions,
149
- viewport,
150
- });
151
-
152
- return wrapContext(context as unknown as PlaywrightContextLike);
153
- },
154
- } satisfies PlaywrightBrowserLike) as BrowserProviderRuntime['browser'];
155
-
156
- return {
157
- browser: wrappedBrowser,
158
- };
159
- }
@@ -1,10 +0,0 @@
1
- export const reviveBrowserLocatorText = (
2
- text:
3
- | { type: 'string'; value: string }
4
- | { type: 'regexp'; source: string; flags?: string },
5
- ): string | RegExp => {
6
- if (text.type === 'string') {
7
- return text.value;
8
- }
9
- return new RegExp(text.source, text.flags);
10
- };