mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-22 02:00:12 +01:00
Add form submission debugging to login page
This commit is contained in:
parent
90234ee58b
commit
29fd18839f
517 changed files with 154163 additions and 1 deletions
202
node_modules/playwright/LICENSE
generated
vendored
Normal file
202
node_modules/playwright/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Portions Copyright (c) Microsoft Corporation.
|
||||
Portions Copyright 2017 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
5
node_modules/playwright/NOTICE
generated
vendored
Normal file
5
node_modules/playwright/NOTICE
generated
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
Playwright
|
||||
Copyright (c) Microsoft Corporation
|
||||
|
||||
This software contains code derived from the Puppeteer project (https://github.com/puppeteer/puppeteer),
|
||||
available under the Apache 2.0 license (https://github.com/puppeteer/puppeteer/blob/master/LICENSE).
|
||||
168
node_modules/playwright/README.md
generated
vendored
Normal file
168
node_modules/playwright/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
# 🎭 Playwright
|
||||
|
||||
[](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[](https://webkit.org/)<!-- GEN:stop --> [](https://aka.ms/playwright/discord)
|
||||
|
||||
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
|
||||
|
||||
Playwright is a framework for Web Testing and Automation. It allows testing [Chromium](https://www.chromium.org/Home), [Firefox](https://www.mozilla.org/en-US/firefox/new/) and [WebKit](https://webkit.org/) with a single API. Playwright is built to enable cross-browser web automation that is **ever-green**, **capable**, **reliable** and **fast**.
|
||||
|
||||
| | Linux | macOS | Windows |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| Chromium <!-- GEN:chromium-version -->141.0.7390.37<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| WebKit <!-- GEN:webkit-version -->26.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Firefox <!-- GEN:firefox-version -->142.0.1<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details.
|
||||
|
||||
Looking for Playwright for [Python](https://playwright.dev/python/docs/intro), [.NET](https://playwright.dev/dotnet/docs/intro), or [Java](https://playwright.dev/java/docs/intro)?
|
||||
|
||||
## Installation
|
||||
|
||||
Playwright has its own test runner for end-to-end tests, we call it Playwright Test.
|
||||
|
||||
### Using init command
|
||||
|
||||
The easiest way to get started with Playwright Test is to run the init command.
|
||||
|
||||
```Shell
|
||||
# Run from your project's root directory
|
||||
npm init playwright@latest
|
||||
# Or create a new project
|
||||
npm init playwright@latest new-project
|
||||
```
|
||||
|
||||
This will create a configuration file, optionally add examples, a GitHub Action workflow and a first test example.spec.ts. You can now jump directly to writing assertions section.
|
||||
|
||||
### Manually
|
||||
|
||||
Add dependency and install browsers.
|
||||
|
||||
```Shell
|
||||
npm i -D @playwright/test
|
||||
# install supported browsers
|
||||
npx playwright install
|
||||
```
|
||||
|
||||
You can optionally install only selected browsers, see [install browsers](https://playwright.dev/docs/cli#install-browsers) for more details. Or you can install no browsers at all and use existing [browser channels](https://playwright.dev/docs/browsers).
|
||||
|
||||
* [Getting started](https://playwright.dev/docs/intro)
|
||||
* [API reference](https://playwright.dev/docs/api/class-playwright)
|
||||
|
||||
## Capabilities
|
||||
|
||||
### Resilient • No flaky tests
|
||||
|
||||
**Auto-wait**. Playwright waits for elements to be actionable prior to performing actions. It also has a rich set of introspection events. The combination of the two eliminates the need for artificial timeouts - a primary cause of flaky tests.
|
||||
|
||||
**Web-first assertions**. Playwright assertions are created specifically for the dynamic web. Checks are automatically retried until the necessary conditions are met.
|
||||
|
||||
**Tracing**. Configure test retry strategy, capture execution trace, videos and screenshots to eliminate flakes.
|
||||
|
||||
### No trade-offs • No limits
|
||||
|
||||
Browsers run web content belonging to different origins in different processes. Playwright is aligned with the architecture of the modern browsers and runs tests out-of-process. This makes Playwright free of the typical in-process test runner limitations.
|
||||
|
||||
**Multiple everything**. Test scenarios that span multiple tabs, multiple origins and multiple users. Create scenarios with different contexts for different users and run them against your server, all in one test.
|
||||
|
||||
**Trusted events**. Hover elements, interact with dynamic controls and produce trusted events. Playwright uses real browser input pipeline indistinguishable from the real user.
|
||||
|
||||
Test frames, pierce Shadow DOM. Playwright selectors pierce shadow DOM and allow entering frames seamlessly.
|
||||
|
||||
### Full isolation • Fast execution
|
||||
|
||||
**Browser contexts**. Playwright creates a browser context for each test. Browser context is equivalent to a brand new browser profile. This delivers full test isolation with zero overhead. Creating a new browser context only takes a handful of milliseconds.
|
||||
|
||||
**Log in once**. Save the authentication state of the context and reuse it in all the tests. This bypasses repetitive log-in operations in each test, yet delivers full isolation of independent tests.
|
||||
|
||||
### Powerful Tooling
|
||||
|
||||
**[Codegen](https://playwright.dev/docs/codegen)**. Generate tests by recording your actions. Save them into any language.
|
||||
|
||||
**[Playwright inspector](https://playwright.dev/docs/inspector)**. Inspect page, generate selectors, step through the test execution, see click points and explore execution logs.
|
||||
|
||||
**[Trace Viewer](https://playwright.dev/docs/trace-viewer)**. Capture all the information to investigate the test failure. Playwright trace contains test execution screencast, live DOM snapshots, action explorer, test source and many more.
|
||||
|
||||
Looking for Playwright for [TypeScript](https://playwright.dev/docs/intro), [JavaScript](https://playwright.dev/docs/intro), [Python](https://playwright.dev/python/docs/intro), [.NET](https://playwright.dev/dotnet/docs/intro), or [Java](https://playwright.dev/java/docs/intro)?
|
||||
|
||||
## Examples
|
||||
|
||||
To learn how to run these Playwright Test examples, check out our [getting started docs](https://playwright.dev/docs/intro).
|
||||
|
||||
#### Page screenshot
|
||||
|
||||
This code snippet navigates to Playwright homepage and saves a screenshot.
|
||||
|
||||
```TypeScript
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('Page Screenshot', async ({ page }) => {
|
||||
await page.goto('https://playwright.dev/');
|
||||
await page.screenshot({ path: `example.png` });
|
||||
});
|
||||
```
|
||||
|
||||
#### Mobile and geolocation
|
||||
|
||||
This snippet emulates Mobile Safari on a device at given geolocation, navigates to maps.google.com, performs the action and takes a screenshot.
|
||||
|
||||
```TypeScript
|
||||
import { test, devices } from '@playwright/test';
|
||||
|
||||
test.use({
|
||||
...devices['iPhone 13 Pro'],
|
||||
locale: 'en-US',
|
||||
geolocation: { longitude: 12.492507, latitude: 41.889938 },
|
||||
permissions: ['geolocation'],
|
||||
})
|
||||
|
||||
test('Mobile and geolocation', async ({ page }) => {
|
||||
await page.goto('https://maps.google.com');
|
||||
await page.getByText('Your location').click();
|
||||
await page.waitForRequest(/.*preview\/pwa/);
|
||||
await page.screenshot({ path: 'colosseum-iphone.png' });
|
||||
});
|
||||
```
|
||||
|
||||
#### Evaluate in browser context
|
||||
|
||||
This code snippet navigates to example.com, and executes a script in the page context.
|
||||
|
||||
```TypeScript
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('Evaluate in browser context', async ({ page }) => {
|
||||
await page.goto('https://www.example.com/');
|
||||
const dimensions = await page.evaluate(() => {
|
||||
return {
|
||||
width: document.documentElement.clientWidth,
|
||||
height: document.documentElement.clientHeight,
|
||||
deviceScaleFactor: window.devicePixelRatio
|
||||
}
|
||||
});
|
||||
console.log(dimensions);
|
||||
});
|
||||
```
|
||||
|
||||
#### Intercept network requests
|
||||
|
||||
This code snippet sets up request routing for a page to log all network requests.
|
||||
|
||||
```TypeScript
|
||||
import { test } from '@playwright/test';
|
||||
|
||||
test('Intercept network requests', async ({ page }) => {
|
||||
// Log and continue all network requests
|
||||
await page.route('**', route => {
|
||||
console.log(route.request().url());
|
||||
route.continue();
|
||||
});
|
||||
await page.goto('http://todomvc.com');
|
||||
});
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
* [Documentation](https://playwright.dev)
|
||||
* [API reference](https://playwright.dev/docs/api/class-playwright/)
|
||||
* [Contribution guide](CONTRIBUTING.md)
|
||||
* [Changelog](https://github.com/microsoft/playwright/releases)
|
||||
6277
node_modules/playwright/ThirdPartyNotices.txt
generated
vendored
Normal file
6277
node_modules/playwright/ThirdPartyNotices.txt
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
19
node_modules/playwright/cli.js
generated
vendored
Executable file
19
node_modules/playwright/cli.js
generated
vendored
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const { program } = require('./lib/program');
|
||||
program.parse(process.argv);
|
||||
17
node_modules/playwright/index.d.ts
generated
vendored
Normal file
17
node_modules/playwright/index.d.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from 'playwright-core';
|
||||
17
node_modules/playwright/index.js
generated
vendored
Normal file
17
node_modules/playwright/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
module.exports = require('playwright-core');
|
||||
18
node_modules/playwright/index.mjs
generated
vendored
Normal file
18
node_modules/playwright/index.mjs
generated
vendored
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export * from 'playwright-core';
|
||||
import playwright from 'playwright-core';
|
||||
export default playwright;
|
||||
42
node_modules/playwright/jsx-runtime.js
generated
vendored
Normal file
42
node_modules/playwright/jsx-runtime.js
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
function jsx(type, props, key) {
|
||||
return {
|
||||
__pw_type: 'jsx',
|
||||
type,
|
||||
props,
|
||||
key,
|
||||
};
|
||||
}
|
||||
|
||||
function jsxs(type, props, key) {
|
||||
return {
|
||||
__pw_type: 'jsx',
|
||||
type,
|
||||
props,
|
||||
key,
|
||||
};
|
||||
}
|
||||
|
||||
// this is used in <></> notation
|
||||
const Fragment = { __pw_jsx_fragment: true };
|
||||
|
||||
module.exports = {
|
||||
Fragment,
|
||||
jsx,
|
||||
jsxs,
|
||||
};
|
||||
21
node_modules/playwright/jsx-runtime.mjs
generated
vendored
Normal file
21
node_modules/playwright/jsx-runtime.mjs
generated
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import jsxRuntime from './jsx-runtime.js';
|
||||
|
||||
export const jsx = jsxRuntime.jsx;
|
||||
export const jsxs = jsxRuntime.jsxs;
|
||||
export const Fragment = jsxRuntime.Fragment;
|
||||
263
node_modules/playwright/lib/agents/generateAgents.js
generated
vendored
Normal file
263
node_modules/playwright/lib/agents/generateAgents.js
generated
vendored
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var generateAgents_exports = {};
|
||||
__export(generateAgents_exports, {
|
||||
initClaudeCodeRepo: () => initClaudeCodeRepo,
|
||||
initOpencodeRepo: () => initOpencodeRepo,
|
||||
initVSCodeRepo: () => initVSCodeRepo
|
||||
});
|
||||
module.exports = __toCommonJS(generateAgents_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
class AgentParser {
|
||||
static async parseFile(filePath) {
|
||||
const rawMarkdown = await import_fs.default.promises.readFile(filePath, "utf-8");
|
||||
const { header, content } = this.extractYamlAndContent(rawMarkdown);
|
||||
const { instructions, examples } = this.extractInstructionsAndExamples(content);
|
||||
return { header, instructions, examples };
|
||||
}
|
||||
static extractYamlAndContent(markdown) {
|
||||
const lines = markdown.split("\n");
|
||||
if (lines[0] !== "---")
|
||||
throw new Error("Markdown file must start with YAML front matter (---)");
|
||||
let yamlEndIndex = -1;
|
||||
for (let i = 1; i < lines.length; i++) {
|
||||
if (lines[i] === "---") {
|
||||
yamlEndIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (yamlEndIndex === -1)
|
||||
throw new Error("YAML front matter must be closed with ---");
|
||||
const yamlLines = lines.slice(1, yamlEndIndex);
|
||||
const yamlRaw = yamlLines.join("\n");
|
||||
const contentLines = lines.slice(yamlEndIndex + 1);
|
||||
const content = contentLines.join("\n");
|
||||
let header;
|
||||
try {
|
||||
header = import_utilsBundle.yaml.parse(yamlRaw);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to parse YAML header: ${error.message}`);
|
||||
}
|
||||
if (!header.name)
|
||||
throw new Error('YAML header must contain a "name" field');
|
||||
if (!header.description)
|
||||
throw new Error('YAML header must contain a "description" field');
|
||||
return { header, content };
|
||||
}
|
||||
static extractInstructionsAndExamples(content) {
|
||||
const examples = [];
|
||||
const instructions = content.split("<example>")[0].trim();
|
||||
const exampleRegex = /<example>([\s\S]*?)<\/example>/g;
|
||||
let match;
|
||||
while ((match = exampleRegex.exec(content)) !== null) {
|
||||
const example = match[1].trim();
|
||||
examples.push(example.replace(/[\n]/g, " ").replace(/ +/g, " "));
|
||||
}
|
||||
return { instructions, examples };
|
||||
}
|
||||
}
|
||||
const claudeToolMap = /* @__PURE__ */ new Map([
|
||||
["ls", ["Glob"]],
|
||||
["grep", ["Grep"]],
|
||||
["read", ["Read"]],
|
||||
["edit", ["Edit", "MultiEdit"]],
|
||||
["write", ["Write"]]
|
||||
]);
|
||||
const commonMcpServers = {
|
||||
playwrightTest: {
|
||||
type: "local",
|
||||
command: "npx",
|
||||
args: ["playwright", "run-test-mcp-server"]
|
||||
}
|
||||
};
|
||||
function saveAsClaudeCode(agent) {
|
||||
function asClaudeTool(tool) {
|
||||
const [first, second] = tool.split("/");
|
||||
if (!second)
|
||||
return (claudeToolMap.get(first) || [first]).join(", ");
|
||||
return `mcp__${first}__${second}`;
|
||||
}
|
||||
const lines = [];
|
||||
lines.push(`---`);
|
||||
lines.push(`name: playwright-test-${agent.header.name}`);
|
||||
lines.push(`description: ${agent.header.description}. Examples: ${agent.examples.map((example) => `<example>${example}</example>`).join("")}`);
|
||||
lines.push(`tools: ${agent.header.tools.map((tool) => asClaudeTool(tool)).join(", ")}`);
|
||||
lines.push(`model: ${agent.header.model}`);
|
||||
lines.push(`color: ${agent.header.color}`);
|
||||
lines.push(`---`);
|
||||
lines.push("");
|
||||
lines.push(agent.instructions);
|
||||
return lines.join("\n");
|
||||
}
|
||||
const opencodeToolMap = /* @__PURE__ */ new Map([
|
||||
["ls", ["ls", "glob"]],
|
||||
["grep", ["grep"]],
|
||||
["read", ["read"]],
|
||||
["edit", ["edit"]],
|
||||
["write", ["write"]]
|
||||
]);
|
||||
function saveAsOpencodeJson(agents) {
|
||||
function asOpencodeTool(tools, tool) {
|
||||
const [first, second] = tool.split("/");
|
||||
if (!second) {
|
||||
for (const tool2 of opencodeToolMap.get(first) || [first])
|
||||
tools[tool2] = true;
|
||||
} else {
|
||||
tools[`${first}*${second}`] = true;
|
||||
}
|
||||
}
|
||||
const result = {};
|
||||
result["$schema"] = "https://opencode.ai/config.json";
|
||||
result["mcp"] = {};
|
||||
result["tools"] = {
|
||||
"playwright*": false
|
||||
};
|
||||
result["agent"] = {};
|
||||
for (const agent of agents) {
|
||||
const tools = {};
|
||||
result["agent"]["playwright-test-" + agent.header.name] = {
|
||||
description: agent.header.description,
|
||||
mode: "subagent",
|
||||
prompt: `{file:.opencode/prompts/playwright-test-${agent.header.name}.md}`,
|
||||
tools
|
||||
};
|
||||
for (const tool of agent.header.tools)
|
||||
asOpencodeTool(tools, tool);
|
||||
}
|
||||
const server = commonMcpServers.playwrightTest;
|
||||
result["mcp"]["playwright-test"] = {
|
||||
type: server.type,
|
||||
command: [server.command, ...server.args],
|
||||
enabled: true
|
||||
};
|
||||
return JSON.stringify(result, null, 2);
|
||||
}
|
||||
async function loadAgents() {
|
||||
const files = await import_fs.default.promises.readdir(__dirname);
|
||||
return Promise.all(files.filter((file) => file.endsWith(".md")).map((file) => AgentParser.parseFile(import_path.default.join(__dirname, file))));
|
||||
}
|
||||
async function writeFile(filePath, content) {
|
||||
console.log(`Writing file: ${filePath}`);
|
||||
await import_fs.default.promises.writeFile(filePath, content, "utf-8");
|
||||
}
|
||||
async function initClaudeCodeRepo() {
|
||||
const agents = await loadAgents();
|
||||
await import_fs.default.promises.mkdir(".claude/agents", { recursive: true });
|
||||
for (const agent of agents)
|
||||
await writeFile(`.claude/agents/playwright-test-${agent.header.name}.md`, saveAsClaudeCode(agent));
|
||||
await writeFile(".mcp.json", JSON.stringify({
|
||||
mcpServers: {
|
||||
"playwright-test": {
|
||||
command: commonMcpServers.playwrightTest.command,
|
||||
args: commonMcpServers.playwrightTest.args
|
||||
}
|
||||
}
|
||||
}, null, 2));
|
||||
}
|
||||
const vscodeToolMap = /* @__PURE__ */ new Map([
|
||||
["ls", ["search/listDirectory", "search/fileSearch"]],
|
||||
["grep", ["search/textSearch"]],
|
||||
["read", ["search/readFile"]],
|
||||
["edit", ["edit/editFiles"]],
|
||||
["write", ["edit/createFile", "edit/createDirectory"]]
|
||||
]);
|
||||
const vscodeToolsOrder = ["edit/createFile", "edit/createDirectory", "edit/editFiles", "search/fileSearch", "search/textSearch", "search/listDirectory", "search/readFile"];
|
||||
const vscodeMcpName = "playwright-test";
|
||||
function saveAsVSCodeChatmode(agent) {
|
||||
function asVscodeTool(tool) {
|
||||
const [first, second] = tool.split("/");
|
||||
if (second)
|
||||
return `${vscodeMcpName}/${second}`;
|
||||
return vscodeToolMap.get(first) || first;
|
||||
}
|
||||
const tools = agent.header.tools.map(asVscodeTool).flat().sort((a, b) => {
|
||||
const indexA = vscodeToolsOrder.indexOf(a);
|
||||
const indexB = vscodeToolsOrder.indexOf(b);
|
||||
if (indexA === -1 && indexB === -1)
|
||||
return a.localeCompare(b);
|
||||
if (indexA === -1)
|
||||
return 1;
|
||||
if (indexB === -1)
|
||||
return -1;
|
||||
return indexA - indexB;
|
||||
}).map((tool) => `'${tool}'`).join(", ");
|
||||
const lines = [];
|
||||
lines.push(`---`);
|
||||
lines.push(`description: ${agent.header.description}.`);
|
||||
lines.push(`tools: [${tools}]`);
|
||||
lines.push(`---`);
|
||||
lines.push("");
|
||||
lines.push(agent.instructions);
|
||||
for (const example of agent.examples)
|
||||
lines.push(`<example>${example}</example>`);
|
||||
return lines.join("\n");
|
||||
}
|
||||
async function initVSCodeRepo() {
|
||||
const agents = await loadAgents();
|
||||
await import_fs.default.promises.mkdir(".github/chatmodes", { recursive: true });
|
||||
for (const agent of agents)
|
||||
await writeFile(`.github/chatmodes/${agent.header.name === "planner" ? " " : ""}\u{1F3AD} ${agent.header.name}.chatmode.md`, saveAsVSCodeChatmode(agent));
|
||||
await import_fs.default.promises.mkdir(".vscode", { recursive: true });
|
||||
const mcpJsonPath = ".vscode/mcp.json";
|
||||
let mcpJson = {
|
||||
servers: {},
|
||||
inputs: []
|
||||
};
|
||||
try {
|
||||
mcpJson = JSON.parse(import_fs.default.readFileSync(mcpJsonPath, "utf8"));
|
||||
} catch {
|
||||
}
|
||||
if (!mcpJson.servers)
|
||||
mcpJson.servers = {};
|
||||
mcpJson.servers["playwright-test"] = {
|
||||
type: "stdio",
|
||||
command: commonMcpServers.playwrightTest.command,
|
||||
args: commonMcpServers.playwrightTest.args
|
||||
};
|
||||
await writeFile(mcpJsonPath, JSON.stringify(mcpJson, null, 2));
|
||||
}
|
||||
async function initOpencodeRepo() {
|
||||
const agents = await loadAgents();
|
||||
await import_fs.default.promises.mkdir(".opencode/prompts", { recursive: true });
|
||||
for (const agent of agents) {
|
||||
const prompt = [agent.instructions];
|
||||
prompt.push("");
|
||||
prompt.push(...agent.examples.map((example) => `<example>${example}</example>`));
|
||||
await writeFile(`.opencode/prompts/playwright-test-${agent.header.name}.md`, prompt.join("\n"));
|
||||
}
|
||||
await writeFile("opencode.json", saveAsOpencodeJson(agents));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
initClaudeCodeRepo,
|
||||
initOpencodeRepo,
|
||||
initVSCodeRepo
|
||||
});
|
||||
102
node_modules/playwright/lib/agents/generator.md
generated
vendored
Normal file
102
node_modules/playwright/lib/agents/generator.md
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
---
|
||||
name: generator
|
||||
description: Use this agent when you need to create automated browser tests using Playwright
|
||||
model: sonnet
|
||||
color: blue
|
||||
tools:
|
||||
- ls
|
||||
- grep
|
||||
- read
|
||||
- playwright-test/browser_click
|
||||
- playwright-test/browser_drag
|
||||
- playwright-test/browser_evaluate
|
||||
- playwright-test/browser_file_upload
|
||||
- playwright-test/browser_handle_dialog
|
||||
- playwright-test/browser_hover
|
||||
- playwright-test/browser_navigate
|
||||
- playwright-test/browser_press_key
|
||||
- playwright-test/browser_select_option
|
||||
- playwright-test/browser_snapshot
|
||||
- playwright-test/browser_type
|
||||
- playwright-test/browser_verify_element_visible
|
||||
- playwright-test/browser_verify_list_visible
|
||||
- playwright-test/browser_verify_text_visible
|
||||
- playwright-test/browser_verify_value
|
||||
- playwright-test/browser_wait_for
|
||||
- playwright-test/generator_read_log
|
||||
- playwright-test/generator_setup_page
|
||||
- playwright-test/generator_write_test
|
||||
---
|
||||
|
||||
You are a Playwright Test Generator, an expert in browser automation and end-to-end testing.
|
||||
Your specialty is creating robust, reliable Playwright tests that accurately simulate user interactions and validate
|
||||
application behavior.
|
||||
|
||||
# For each test you generate
|
||||
- Obtain the test plan with all the steps and verification specification
|
||||
- Run the `generator_setup_page` tool to set up page for the scenario
|
||||
- For each step and verification in the scenario, do the following:
|
||||
- Use Playwright tool to manually execute it in real-time.
|
||||
- Use the step description as the intent for each Playwright tool call.
|
||||
- Retrieve generator log via `generator_read_log`
|
||||
- Immediately after reading the test log, invoke `generator_write_test` with the generated source code
|
||||
- File should contain single test
|
||||
- File name must be fs-friendly scenario name
|
||||
- Test must be placed in a describe matching the top-level test plan item
|
||||
- Test title must match the scenario name
|
||||
- Includes a comment with the step text before each step execution. Do not duplicate comments if step requires
|
||||
multiple actions.
|
||||
- Always use best practices from the log when generating tests.
|
||||
|
||||
<example-generation>
|
||||
For following plan:
|
||||
|
||||
```markdown file=specs/plan.md
|
||||
### 1. Adding New Todos
|
||||
**Seed:** `tests/seed.spec.ts`
|
||||
|
||||
#### 1.1 Add Valid Todo
|
||||
**Steps:**
|
||||
1. Click in the "What needs to be done?" input field
|
||||
|
||||
#### 1.2 Add Multiple Todos
|
||||
...
|
||||
```
|
||||
|
||||
Following file is generated:
|
||||
|
||||
```ts file=add-valid-todo.spec.ts
|
||||
// spec: specs/plan.md
|
||||
// seed: tests/seed.spec.ts
|
||||
|
||||
test.describe('Adding New Todos', () => {
|
||||
test('Add Valid Todo', async { page } => {
|
||||
// 1. Click in the "What needs to be done?" input field
|
||||
await page.click(...);
|
||||
|
||||
...
|
||||
});
|
||||
});
|
||||
```
|
||||
</example-generation>
|
||||
|
||||
<example>
|
||||
Context: User wants to test a login flow on their web application.
|
||||
user: 'I need a test that logs into my app at localhost:3000 with username admin@test.com and password 123456, then
|
||||
verifies the dashboard page loads'
|
||||
assistant: 'I'll use the generator agent to create and validate this login test for you'
|
||||
<commentary>
|
||||
The user needs a specific browser automation test created, which is exactly what the generator agent
|
||||
is designed for.
|
||||
</commentary>
|
||||
</example>
|
||||
<example>
|
||||
Context: User has built a new checkout flow and wants to ensure it works correctly.
|
||||
user: 'Can you create a test that adds items to cart, proceeds to checkout, fills in payment details, and confirms the
|
||||
order?'
|
||||
assistant: 'I'll use the generator agent to build a comprehensive checkout flow test'
|
||||
<commentary>
|
||||
This is a complex user journey that needs to be automated and tested, perfect for the generator
|
||||
agent.
|
||||
</commentary>
|
||||
</example>
|
||||
78
node_modules/playwright/lib/agents/healer.md
generated
vendored
Normal file
78
node_modules/playwright/lib/agents/healer.md
generated
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
---
|
||||
name: healer
|
||||
description: Use this agent when you need to debug and fix failing Playwright tests
|
||||
color: red
|
||||
model: sonnet
|
||||
tools:
|
||||
- ls
|
||||
- grep
|
||||
- read
|
||||
- write
|
||||
- edit
|
||||
- playwright-test/browser_console_messages
|
||||
- playwright-test/browser_evaluate
|
||||
- playwright-test/browser_generate_locator
|
||||
- playwright-test/browser_network_requests
|
||||
- playwright-test/browser_snapshot
|
||||
- playwright-test/test_debug
|
||||
- playwright-test/test_list
|
||||
- playwright-test/test_run
|
||||
---
|
||||
|
||||
You are the Playwright Test Healer, an expert test automation engineer specializing in debugging and
|
||||
resolving Playwright test failures. Your mission is to systematically identify, diagnose, and fix
|
||||
broken Playwright tests using a methodical approach.
|
||||
|
||||
Your workflow:
|
||||
1. **Initial Execution**: Run all tests using playwright_test_run_test tool to identify failing tests
|
||||
2. **Debug failed tests**: For each failing test run playwright_test_debug_test.
|
||||
3. **Error Investigation**: When the test pauses on errors, use available Playwright MCP tools to:
|
||||
- Examine the error details
|
||||
- Capture page snapshot to understand the context
|
||||
- Analyze selectors, timing issues, or assertion failures
|
||||
4. **Root Cause Analysis**: Determine the underlying cause of the failure by examining:
|
||||
- Element selectors that may have changed
|
||||
- Timing and synchronization issues
|
||||
- Data dependencies or test environment problems
|
||||
- Application changes that broke test assumptions
|
||||
5. **Code Remediation**: Edit the test code to address identified issues, focusing on:
|
||||
- Updating selectors to match current application state
|
||||
- Fixing assertions and expected values
|
||||
- Improving test reliability and maintainability
|
||||
- For inherently dynamic data, utilize regular expressions to produce resilient locators
|
||||
6. **Verification**: Restart the test after each fix to validate the changes
|
||||
7. **Iteration**: Repeat the investigation and fixing process until the test passes cleanly
|
||||
|
||||
Key principles:
|
||||
- Be systematic and thorough in your debugging approach
|
||||
- Document your findings and reasoning for each fix
|
||||
- Prefer robust, maintainable solutions over quick hacks
|
||||
- Use Playwright best practices for reliable test automation
|
||||
- If multiple errors exist, fix them one at a time and retest
|
||||
- Provide clear explanations of what was broken and how you fixed it
|
||||
- You will continue this process until the test runs successfully without any failures or errors.
|
||||
- If the error persists and you have high level of confidence that the test is correct, mark this test as test.fixme()
|
||||
so that it is skipped during the execution. Add a comment before the failing step explaining what is happening instead
|
||||
of the expected behavior.
|
||||
- Do not ask user questions, you are not interactive tool, do the most reasonable thing possible to pass the test.
|
||||
- Never wait for networkidle or use other discouraged or deprecated apis
|
||||
|
||||
<example>
|
||||
Context: A developer has a failing Playwright test that needs to be debugged and fixed.
|
||||
user: 'The login test is failing, can you fix it?'
|
||||
assistant: 'I'll use the healer agent to debug and fix the failing login test.'
|
||||
<commentary>
|
||||
The user has identified a specific failing test that needs debugging and fixing, which is exactly what the
|
||||
healer agent is designed for.
|
||||
</commentary>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
Context: After running a test suite, several tests are reported as failing.
|
||||
user: 'Test user-registration.spec.ts is broken after the recent changes'
|
||||
assistant: 'Let me use the healer agent to investigate and fix the user-registration test.'
|
||||
<commentary>
|
||||
A specific test file is failing and needs debugging, which requires the systematic approach of the
|
||||
playwright-test-healer agent.
|
||||
</commentary>
|
||||
</example>
|
||||
135
node_modules/playwright/lib/agents/planner.md
generated
vendored
Normal file
135
node_modules/playwright/lib/agents/planner.md
generated
vendored
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
---
|
||||
name: planner
|
||||
description: Use this agent when you need to create comprehensive test plan for a web application or website
|
||||
model: sonnet
|
||||
color: green
|
||||
tools:
|
||||
- ls
|
||||
- grep
|
||||
- read
|
||||
- write
|
||||
- playwright-test/browser_click
|
||||
- playwright-test/browser_close
|
||||
- playwright-test/browser_console_messages
|
||||
- playwright-test/browser_drag
|
||||
- playwright-test/browser_evaluate
|
||||
- playwright-test/browser_file_upload
|
||||
- playwright-test/browser_handle_dialog
|
||||
- playwright-test/browser_hover
|
||||
- playwright-test/browser_navigate
|
||||
- playwright-test/browser_navigate_back
|
||||
- playwright-test/browser_network_requests
|
||||
- playwright-test/browser_press_key
|
||||
- playwright-test/browser_select_option
|
||||
- playwright-test/browser_snapshot
|
||||
- playwright-test/browser_take_screenshot
|
||||
- playwright-test/browser_type
|
||||
- playwright-test/browser_wait_for
|
||||
- playwright-test/planner_setup_page
|
||||
---
|
||||
|
||||
You are an expert web test planner with extensive experience in quality assurance, user experience testing, and test
|
||||
scenario design. Your expertise includes functional testing, edge case identification, and comprehensive test coverage
|
||||
planning.
|
||||
|
||||
You will:
|
||||
|
||||
1. **Navigate and Explore**
|
||||
- Invoke the `planner_setup_page` tool once to set up page before using any other tools
|
||||
- Explore the browser snapshot
|
||||
- Do not take screenshots unless absolutely necessary
|
||||
- Use browser_* tools to navigate and discover interface
|
||||
- Thoroughly explore the interface, identifying all interactive elements, forms, navigation paths, and functionality
|
||||
|
||||
2. **Analyze User Flows**
|
||||
- Map out the primary user journeys and identify critical paths through the application
|
||||
- Consider different user types and their typical behaviors
|
||||
|
||||
3. **Design Comprehensive Scenarios**
|
||||
|
||||
Create detailed test scenarios that cover:
|
||||
- Happy path scenarios (normal user behavior)
|
||||
- Edge cases and boundary conditions
|
||||
- Error handling and validation
|
||||
|
||||
4. **Structure Test Plans**
|
||||
|
||||
Each scenario must include:
|
||||
- Clear, descriptive title
|
||||
- Detailed step-by-step instructions
|
||||
- Expected outcomes where appropriate
|
||||
- Assumptions about starting state (always assume blank/fresh state)
|
||||
- Success criteria and failure conditions
|
||||
|
||||
5. **Create Documentation**
|
||||
|
||||
Save your test plan as requested:
|
||||
- Executive summary of the tested page/application
|
||||
- Individual scenarios as separate sections
|
||||
- Each scenario formatted with numbered steps
|
||||
- Clear expected results for verification
|
||||
|
||||
<example-spec>
|
||||
# TodoMVC Application - Comprehensive Test Plan
|
||||
|
||||
## Application Overview
|
||||
|
||||
The TodoMVC application is a React-based todo list manager that provides core task management functionality. The
|
||||
application features:
|
||||
|
||||
- **Task Management**: Add, edit, complete, and delete individual todos
|
||||
- **Bulk Operations**: Mark all todos as complete/incomplete and clear all completed todos
|
||||
- **Filtering**: View todos by All, Active, or Completed status
|
||||
- **URL Routing**: Support for direct navigation to filtered views via URLs
|
||||
- **Counter Display**: Real-time count of active (incomplete) todos
|
||||
- **Persistence**: State maintained during session (browser refresh behavior not tested)
|
||||
|
||||
## Test Scenarios
|
||||
|
||||
### 1. Adding New Todos
|
||||
|
||||
**Seed:** `tests/seed.spec.ts`
|
||||
|
||||
#### 1.1 Add Valid Todo
|
||||
**Steps:**
|
||||
1. Click in the "What needs to be done?" input field
|
||||
2. Type "Buy groceries"
|
||||
3. Press Enter key
|
||||
|
||||
**Expected Results:**
|
||||
- Todo appears in the list with unchecked checkbox
|
||||
- Counter shows "1 item left"
|
||||
- Input field is cleared and ready for next entry
|
||||
- Todo list controls become visible (Mark all as complete checkbox)
|
||||
|
||||
#### 1.2
|
||||
...
|
||||
</example-spec>
|
||||
|
||||
**Quality Standards**:
|
||||
- Write steps that are specific enough for any tester to follow
|
||||
- Include negative testing scenarios
|
||||
- Ensure scenarios are independent and can be run in any order
|
||||
|
||||
**Output Format**: Always save the complete test plan as a markdown file with clear headings, numbered steps, and
|
||||
professional formatting suitable for sharing with development and QA teams.
|
||||
|
||||
<example>
|
||||
Context: User wants to test a new e-commerce checkout flow.
|
||||
user: 'I need test scenarios for our new checkout process at https://mystore.com/checkout'
|
||||
assistant: 'I'll use the planner agent to navigate to your checkout page and create comprehensive test
|
||||
scenarios.'
|
||||
<commentary>
|
||||
The user needs test planning for a specific web page, so use the planner agent to explore and create
|
||||
test scenarios.
|
||||
</commentary>
|
||||
</example>
|
||||
<example>
|
||||
Context: User has deployed a new feature and wants thorough testing coverage.
|
||||
user: 'Can you help me test our new user dashboard at https://app.example.com/dashboard?'
|
||||
assistant: 'I'll launch the planner agent to explore your dashboard and develop detailed test
|
||||
scenarios.'
|
||||
<commentary>
|
||||
This requires web exploration and test scenario creation, perfect for the planner agent.
|
||||
</commentary>
|
||||
</example>
|
||||
274
node_modules/playwright/lib/common/config.js
generated
vendored
Normal file
274
node_modules/playwright/lib/common/config.js
generated
vendored
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var config_exports = {};
|
||||
__export(config_exports, {
|
||||
FullConfigInternal: () => FullConfigInternal,
|
||||
FullProjectInternal: () => FullProjectInternal,
|
||||
builtInReporters: () => builtInReporters,
|
||||
defaultGrep: () => defaultGrep,
|
||||
defaultReporter: () => defaultReporter,
|
||||
defaultTimeout: () => defaultTimeout,
|
||||
getProjectId: () => getProjectId,
|
||||
takeFirst: () => takeFirst,
|
||||
toReporters: () => toReporters
|
||||
});
|
||||
module.exports = __toCommonJS(config_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_util = require("../util");
|
||||
const defaultTimeout = 3e4;
|
||||
class FullConfigInternal {
|
||||
constructor(location, userConfig, configCLIOverrides, metadata) {
|
||||
this.projects = [];
|
||||
this.cliArgs = [];
|
||||
this.cliListOnly = false;
|
||||
this.preOnlyTestFilters = [];
|
||||
this.postShardTestFilters = [];
|
||||
this.defineConfigWasUsed = false;
|
||||
this.globalSetups = [];
|
||||
this.globalTeardowns = [];
|
||||
if (configCLIOverrides.projects && userConfig.projects)
|
||||
throw new Error(`Cannot use --browser option when configuration file defines projects. Specify browserName in the projects instead.`);
|
||||
const { resolvedConfigFile, configDir } = location;
|
||||
const packageJsonPath = (0, import_util.getPackageJsonPath)(configDir);
|
||||
const packageJsonDir = packageJsonPath ? import_path.default.dirname(packageJsonPath) : process.cwd();
|
||||
this.configDir = configDir;
|
||||
this.configCLIOverrides = configCLIOverrides;
|
||||
const privateConfiguration = userConfig["@playwright/test"];
|
||||
this.plugins = (privateConfiguration?.plugins || []).map((p) => ({ factory: p }));
|
||||
this.singleTSConfigPath = pathResolve(configDir, userConfig.tsconfig);
|
||||
this.captureGitInfo = userConfig.captureGitInfo;
|
||||
this.failOnFlakyTests = takeFirst(configCLIOverrides.failOnFlakyTests, userConfig.failOnFlakyTests, false);
|
||||
this.globalSetups = (Array.isArray(userConfig.globalSetup) ? userConfig.globalSetup : [userConfig.globalSetup]).map((s) => resolveScript(s, configDir)).filter((script) => script !== void 0);
|
||||
this.globalTeardowns = (Array.isArray(userConfig.globalTeardown) ? userConfig.globalTeardown : [userConfig.globalTeardown]).map((s) => resolveScript(s, configDir)).filter((script) => script !== void 0);
|
||||
userConfig.metadata = userConfig.metadata || {};
|
||||
this.config = {
|
||||
configFile: resolvedConfigFile,
|
||||
rootDir: pathResolve(configDir, userConfig.testDir) || configDir,
|
||||
forbidOnly: takeFirst(configCLIOverrides.forbidOnly, userConfig.forbidOnly, false),
|
||||
fullyParallel: takeFirst(configCLIOverrides.fullyParallel, userConfig.fullyParallel, false),
|
||||
globalSetup: this.globalSetups[0] ?? null,
|
||||
globalTeardown: this.globalTeardowns[0] ?? null,
|
||||
globalTimeout: takeFirst(configCLIOverrides.debug ? 0 : void 0, configCLIOverrides.globalTimeout, userConfig.globalTimeout, 0),
|
||||
grep: takeFirst(userConfig.grep, defaultGrep),
|
||||
grepInvert: takeFirst(userConfig.grepInvert, null),
|
||||
maxFailures: takeFirst(configCLIOverrides.debug ? 1 : void 0, configCLIOverrides.maxFailures, userConfig.maxFailures, 0),
|
||||
metadata: metadata ?? userConfig.metadata,
|
||||
preserveOutput: takeFirst(userConfig.preserveOutput, "always"),
|
||||
reporter: takeFirst(configCLIOverrides.reporter, resolveReporters(userConfig.reporter, configDir), [[defaultReporter]]),
|
||||
reportSlowTests: takeFirst(userConfig.reportSlowTests, {
|
||||
max: 5,
|
||||
threshold: 3e5
|
||||
/* 5 minutes */
|
||||
}),
|
||||
quiet: takeFirst(configCLIOverrides.quiet, userConfig.quiet, false),
|
||||
projects: [],
|
||||
shard: takeFirst(configCLIOverrides.shard, userConfig.shard, null),
|
||||
updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, "missing"),
|
||||
updateSourceMethod: takeFirst(configCLIOverrides.updateSourceMethod, userConfig.updateSourceMethod, "patch"),
|
||||
version: require("../../package.json").version,
|
||||
workers: resolveWorkers(takeFirst(configCLIOverrides.debug ? 1 : void 0, configCLIOverrides.workers, userConfig.workers, "50%")),
|
||||
webServer: null
|
||||
};
|
||||
for (const key in userConfig) {
|
||||
if (key.startsWith("@"))
|
||||
this.config[key] = userConfig[key];
|
||||
}
|
||||
this.config[configInternalSymbol] = this;
|
||||
const webServers = takeFirst(userConfig.webServer, null);
|
||||
if (Array.isArray(webServers)) {
|
||||
this.config.webServer = null;
|
||||
this.webServers = webServers;
|
||||
} else if (webServers) {
|
||||
this.config.webServer = webServers;
|
||||
this.webServers = [webServers];
|
||||
} else {
|
||||
this.webServers = [];
|
||||
}
|
||||
const projectConfigs = configCLIOverrides.projects || userConfig.projects || [{ ...userConfig, workers: void 0 }];
|
||||
this.projects = projectConfigs.map((p) => new FullProjectInternal(configDir, userConfig, this, p, this.configCLIOverrides, packageJsonDir));
|
||||
resolveProjectDependencies(this.projects);
|
||||
this._assignUniqueProjectIds(this.projects);
|
||||
this.config.projects = this.projects.map((p) => p.project);
|
||||
}
|
||||
_assignUniqueProjectIds(projects) {
|
||||
const usedNames = /* @__PURE__ */ new Set();
|
||||
for (const p of projects) {
|
||||
const name = p.project.name || "";
|
||||
for (let i = 0; i < projects.length; ++i) {
|
||||
const candidate = name + (i ? i : "");
|
||||
if (usedNames.has(candidate))
|
||||
continue;
|
||||
p.id = candidate;
|
||||
p.project.__projectId = p.id;
|
||||
usedNames.add(candidate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class FullProjectInternal {
|
||||
constructor(configDir, config, fullConfig, projectConfig, configCLIOverrides, packageJsonDir) {
|
||||
this.id = "";
|
||||
this.deps = [];
|
||||
this.fullConfig = fullConfig;
|
||||
const testDir = takeFirst(pathResolve(configDir, projectConfig.testDir), pathResolve(configDir, config.testDir), fullConfig.configDir);
|
||||
this.snapshotPathTemplate = takeFirst(projectConfig.snapshotPathTemplate, config.snapshotPathTemplate);
|
||||
this.project = {
|
||||
grep: takeFirst(projectConfig.grep, config.grep, defaultGrep),
|
||||
grepInvert: takeFirst(projectConfig.grepInvert, config.grepInvert, null),
|
||||
outputDir: takeFirst(configCLIOverrides.outputDir, pathResolve(configDir, projectConfig.outputDir), pathResolve(configDir, config.outputDir), import_path.default.join(packageJsonDir, "test-results")),
|
||||
// Note: we either apply the cli override for repeatEach or not, depending on whether the
|
||||
// project is top-level vs dependency. See collectProjectsAndTestFiles in loadUtils.
|
||||
repeatEach: takeFirst(projectConfig.repeatEach, config.repeatEach, 1),
|
||||
retries: takeFirst(configCLIOverrides.retries, projectConfig.retries, config.retries, 0),
|
||||
metadata: takeFirst(projectConfig.metadata, config.metadata, {}),
|
||||
name: takeFirst(projectConfig.name, config.name, ""),
|
||||
testDir,
|
||||
snapshotDir: takeFirst(pathResolve(configDir, projectConfig.snapshotDir), pathResolve(configDir, config.snapshotDir), testDir),
|
||||
testIgnore: takeFirst(projectConfig.testIgnore, config.testIgnore, []),
|
||||
testMatch: takeFirst(projectConfig.testMatch, config.testMatch, "**/*.@(spec|test).?(c|m)[jt]s?(x)"),
|
||||
timeout: takeFirst(configCLIOverrides.debug ? 0 : void 0, configCLIOverrides.timeout, projectConfig.timeout, config.timeout, defaultTimeout),
|
||||
use: (0, import_util.mergeObjects)(config.use, projectConfig.use, configCLIOverrides.use),
|
||||
dependencies: projectConfig.dependencies || [],
|
||||
teardown: projectConfig.teardown
|
||||
};
|
||||
this.fullyParallel = takeFirst(configCLIOverrides.fullyParallel, projectConfig.fullyParallel, config.fullyParallel, void 0);
|
||||
this.expect = takeFirst(projectConfig.expect, config.expect, {});
|
||||
if (this.expect.toHaveScreenshot?.stylePath) {
|
||||
const stylePaths = Array.isArray(this.expect.toHaveScreenshot.stylePath) ? this.expect.toHaveScreenshot.stylePath : [this.expect.toHaveScreenshot.stylePath];
|
||||
this.expect.toHaveScreenshot.stylePath = stylePaths.map((stylePath) => import_path.default.resolve(configDir, stylePath));
|
||||
}
|
||||
this.respectGitIgnore = takeFirst(projectConfig.respectGitIgnore, config.respectGitIgnore, !projectConfig.testDir && !config.testDir);
|
||||
this.ignoreSnapshots = takeFirst(configCLIOverrides.ignoreSnapshots, projectConfig.ignoreSnapshots, config.ignoreSnapshots, false);
|
||||
this.workers = projectConfig.workers ? resolveWorkers(projectConfig.workers) : void 0;
|
||||
if (configCLIOverrides.debug && this.workers)
|
||||
this.workers = 1;
|
||||
}
|
||||
}
|
||||
function takeFirst(...args) {
|
||||
for (const arg of args) {
|
||||
if (arg !== void 0)
|
||||
return arg;
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
function pathResolve(baseDir, relative) {
|
||||
if (!relative)
|
||||
return void 0;
|
||||
return import_path.default.resolve(baseDir, relative);
|
||||
}
|
||||
function resolveReporters(reporters, rootDir) {
|
||||
return toReporters(reporters)?.map(([id, arg]) => {
|
||||
if (builtInReporters.includes(id))
|
||||
return [id, arg];
|
||||
return [require.resolve(id, { paths: [rootDir] }), arg];
|
||||
});
|
||||
}
|
||||
function resolveWorkers(workers) {
|
||||
if (typeof workers === "string") {
|
||||
if (workers.endsWith("%")) {
|
||||
const cpus = import_os.default.cpus().length;
|
||||
return Math.max(1, Math.floor(cpus * (parseInt(workers, 10) / 100)));
|
||||
}
|
||||
const parsedWorkers = parseInt(workers, 10);
|
||||
if (isNaN(parsedWorkers))
|
||||
throw new Error(`Workers ${workers} must be a number or percentage.`);
|
||||
return parsedWorkers;
|
||||
}
|
||||
return workers;
|
||||
}
|
||||
function resolveProjectDependencies(projects) {
|
||||
const teardownSet = /* @__PURE__ */ new Set();
|
||||
for (const project of projects) {
|
||||
for (const dependencyName of project.project.dependencies) {
|
||||
const dependencies = projects.filter((p) => p.project.name === dependencyName);
|
||||
if (!dependencies.length)
|
||||
throw new Error(`Project '${project.project.name}' depends on unknown project '${dependencyName}'`);
|
||||
if (dependencies.length > 1)
|
||||
throw new Error(`Project dependencies should have unique names, reading ${dependencyName}`);
|
||||
project.deps.push(...dependencies);
|
||||
}
|
||||
if (project.project.teardown) {
|
||||
const teardowns = projects.filter((p) => p.project.name === project.project.teardown);
|
||||
if (!teardowns.length)
|
||||
throw new Error(`Project '${project.project.name}' has unknown teardown project '${project.project.teardown}'`);
|
||||
if (teardowns.length > 1)
|
||||
throw new Error(`Project teardowns should have unique names, reading ${project.project.teardown}`);
|
||||
const teardown = teardowns[0];
|
||||
project.teardown = teardown;
|
||||
teardownSet.add(teardown);
|
||||
}
|
||||
}
|
||||
for (const teardown of teardownSet) {
|
||||
if (teardown.deps.length)
|
||||
throw new Error(`Teardown project ${teardown.project.name} must not have dependencies`);
|
||||
}
|
||||
for (const project of projects) {
|
||||
for (const dep of project.deps) {
|
||||
if (teardownSet.has(dep))
|
||||
throw new Error(`Project ${project.project.name} must not depend on a teardown project ${dep.project.name}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
function toReporters(reporters) {
|
||||
if (!reporters)
|
||||
return;
|
||||
if (typeof reporters === "string")
|
||||
return [[reporters]];
|
||||
return reporters;
|
||||
}
|
||||
const builtInReporters = ["list", "line", "dot", "json", "junit", "null", "github", "html", "blob"];
|
||||
function resolveScript(id, rootDir) {
|
||||
if (!id)
|
||||
return void 0;
|
||||
const localPath = import_path.default.resolve(rootDir, id);
|
||||
if (import_fs.default.existsSync(localPath))
|
||||
return localPath;
|
||||
return require.resolve(id, { paths: [rootDir] });
|
||||
}
|
||||
const defaultGrep = /.*/;
|
||||
const defaultReporter = process.env.CI ? "dot" : "list";
|
||||
const configInternalSymbol = Symbol("configInternalSymbol");
|
||||
function getProjectId(project) {
|
||||
return project.__projectId;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FullConfigInternal,
|
||||
FullProjectInternal,
|
||||
builtInReporters,
|
||||
defaultGrep,
|
||||
defaultReporter,
|
||||
defaultTimeout,
|
||||
getProjectId,
|
||||
takeFirst,
|
||||
toReporters
|
||||
});
|
||||
344
node_modules/playwright/lib/common/configLoader.js
generated
vendored
Normal file
344
node_modules/playwright/lib/common/configLoader.js
generated
vendored
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var configLoader_exports = {};
|
||||
__export(configLoader_exports, {
|
||||
defineConfig: () => defineConfig,
|
||||
deserializeConfig: () => deserializeConfig,
|
||||
loadConfig: () => loadConfig,
|
||||
loadConfigFromFile: () => loadConfigFromFile,
|
||||
loadEmptyConfigForMergeReports: () => loadEmptyConfigForMergeReports,
|
||||
resolveConfigLocation: () => resolveConfigLocation
|
||||
});
|
||||
module.exports = __toCommonJS(configLoader_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_transform = require("../transform/transform");
|
||||
var import_util = require("../util");
|
||||
var import_config = require("./config");
|
||||
var import_esmLoaderHost = require("./esmLoaderHost");
|
||||
var import_compilationCache = require("../transform/compilationCache");
|
||||
const kDefineConfigWasUsed = Symbol("defineConfigWasUsed");
|
||||
const defineConfig = (...configs) => {
|
||||
let result = configs[0];
|
||||
for (let i = 1; i < configs.length; ++i) {
|
||||
const config = configs[i];
|
||||
const prevProjects = result.projects;
|
||||
result = {
|
||||
...result,
|
||||
...config,
|
||||
expect: {
|
||||
...result.expect,
|
||||
...config.expect
|
||||
},
|
||||
use: {
|
||||
...result.use,
|
||||
...config.use
|
||||
},
|
||||
build: {
|
||||
...result.build,
|
||||
...config.build
|
||||
},
|
||||
webServer: [
|
||||
...Array.isArray(result.webServer) ? result.webServer : result.webServer ? [result.webServer] : [],
|
||||
...Array.isArray(config.webServer) ? config.webServer : config.webServer ? [config.webServer] : []
|
||||
]
|
||||
};
|
||||
if (!result.projects && !config.projects)
|
||||
continue;
|
||||
const projectOverrides = /* @__PURE__ */ new Map();
|
||||
for (const project of config.projects || [])
|
||||
projectOverrides.set(project.name, project);
|
||||
const projects = [];
|
||||
for (const project of prevProjects || []) {
|
||||
const projectOverride = projectOverrides.get(project.name);
|
||||
if (projectOverride) {
|
||||
projects.push({
|
||||
...project,
|
||||
...projectOverride,
|
||||
use: {
|
||||
...project.use,
|
||||
...projectOverride.use
|
||||
}
|
||||
});
|
||||
projectOverrides.delete(project.name);
|
||||
} else {
|
||||
projects.push(project);
|
||||
}
|
||||
}
|
||||
projects.push(...projectOverrides.values());
|
||||
result.projects = projects;
|
||||
}
|
||||
result[kDefineConfigWasUsed] = true;
|
||||
return result;
|
||||
};
|
||||
async function deserializeConfig(data) {
|
||||
if (data.compilationCache)
|
||||
(0, import_compilationCache.addToCompilationCache)(data.compilationCache);
|
||||
return await loadConfig(data.location, data.configCLIOverrides, void 0, data.metadata ? JSON.parse(data.metadata) : void 0);
|
||||
}
|
||||
async function loadUserConfig(location) {
|
||||
let object = location.resolvedConfigFile ? await (0, import_transform.requireOrImport)(location.resolvedConfigFile) : {};
|
||||
if (object && typeof object === "object" && "default" in object)
|
||||
object = object["default"];
|
||||
return object;
|
||||
}
|
||||
async function loadConfig(location, overrides, ignoreProjectDependencies = false, metadata) {
|
||||
if (!(0, import_esmLoaderHost.registerESMLoader)()) {
|
||||
if (location.resolvedConfigFile && (0, import_util.fileIsModule)(location.resolvedConfigFile))
|
||||
throw (0, import_util.errorWithFile)(location.resolvedConfigFile, `Playwright requires Node.js 18.19 or higher to load esm modules. Please update your version of Node.js.`);
|
||||
}
|
||||
(0, import_transform.setSingleTSConfig)(overrides?.tsconfig);
|
||||
await (0, import_esmLoaderHost.configureESMLoader)();
|
||||
const userConfig = await loadUserConfig(location);
|
||||
validateConfig(location.resolvedConfigFile || "<default config>", userConfig);
|
||||
const fullConfig = new import_config.FullConfigInternal(location, userConfig, overrides || {}, metadata);
|
||||
fullConfig.defineConfigWasUsed = !!userConfig[kDefineConfigWasUsed];
|
||||
if (ignoreProjectDependencies) {
|
||||
for (const project of fullConfig.projects) {
|
||||
project.deps = [];
|
||||
project.teardown = void 0;
|
||||
}
|
||||
}
|
||||
const babelPlugins = userConfig["@playwright/test"]?.babelPlugins || [];
|
||||
const external = userConfig.build?.external || [];
|
||||
(0, import_transform.setTransformConfig)({ babelPlugins, external });
|
||||
if (!overrides?.tsconfig)
|
||||
(0, import_transform.setSingleTSConfig)(fullConfig?.singleTSConfigPath);
|
||||
await (0, import_esmLoaderHost.configureESMLoaderTransformConfig)();
|
||||
return fullConfig;
|
||||
}
|
||||
function validateConfig(file, config) {
|
||||
if (typeof config !== "object" || !config)
|
||||
throw (0, import_util.errorWithFile)(file, `Configuration file must export a single object`);
|
||||
validateProject(file, config, "config");
|
||||
if ("forbidOnly" in config && config.forbidOnly !== void 0) {
|
||||
if (typeof config.forbidOnly !== "boolean")
|
||||
throw (0, import_util.errorWithFile)(file, `config.forbidOnly must be a boolean`);
|
||||
}
|
||||
if ("globalSetup" in config && config.globalSetup !== void 0) {
|
||||
if (Array.isArray(config.globalSetup)) {
|
||||
config.globalSetup.forEach((item, index) => {
|
||||
if (typeof item !== "string")
|
||||
throw (0, import_util.errorWithFile)(file, `config.globalSetup[${index}] must be a string`);
|
||||
});
|
||||
} else if (typeof config.globalSetup !== "string") {
|
||||
throw (0, import_util.errorWithFile)(file, `config.globalSetup must be a string`);
|
||||
}
|
||||
}
|
||||
if ("globalTeardown" in config && config.globalTeardown !== void 0) {
|
||||
if (Array.isArray(config.globalTeardown)) {
|
||||
config.globalTeardown.forEach((item, index) => {
|
||||
if (typeof item !== "string")
|
||||
throw (0, import_util.errorWithFile)(file, `config.globalTeardown[${index}] must be a string`);
|
||||
});
|
||||
} else if (typeof config.globalTeardown !== "string") {
|
||||
throw (0, import_util.errorWithFile)(file, `config.globalTeardown must be a string`);
|
||||
}
|
||||
}
|
||||
if ("globalTimeout" in config && config.globalTimeout !== void 0) {
|
||||
if (typeof config.globalTimeout !== "number" || config.globalTimeout < 0)
|
||||
throw (0, import_util.errorWithFile)(file, `config.globalTimeout must be a non-negative number`);
|
||||
}
|
||||
if ("grep" in config && config.grep !== void 0) {
|
||||
if (Array.isArray(config.grep)) {
|
||||
config.grep.forEach((item, index) => {
|
||||
if (!(0, import_utils.isRegExp)(item))
|
||||
throw (0, import_util.errorWithFile)(file, `config.grep[${index}] must be a RegExp`);
|
||||
});
|
||||
} else if (!(0, import_utils.isRegExp)(config.grep)) {
|
||||
throw (0, import_util.errorWithFile)(file, `config.grep must be a RegExp`);
|
||||
}
|
||||
}
|
||||
if ("grepInvert" in config && config.grepInvert !== void 0) {
|
||||
if (Array.isArray(config.grepInvert)) {
|
||||
config.grepInvert.forEach((item, index) => {
|
||||
if (!(0, import_utils.isRegExp)(item))
|
||||
throw (0, import_util.errorWithFile)(file, `config.grepInvert[${index}] must be a RegExp`);
|
||||
});
|
||||
} else if (!(0, import_utils.isRegExp)(config.grepInvert)) {
|
||||
throw (0, import_util.errorWithFile)(file, `config.grepInvert must be a RegExp`);
|
||||
}
|
||||
}
|
||||
if ("maxFailures" in config && config.maxFailures !== void 0) {
|
||||
if (typeof config.maxFailures !== "number" || config.maxFailures < 0)
|
||||
throw (0, import_util.errorWithFile)(file, `config.maxFailures must be a non-negative number`);
|
||||
}
|
||||
if ("preserveOutput" in config && config.preserveOutput !== void 0) {
|
||||
if (typeof config.preserveOutput !== "string" || !["always", "never", "failures-only"].includes(config.preserveOutput))
|
||||
throw (0, import_util.errorWithFile)(file, `config.preserveOutput must be one of "always", "never" or "failures-only"`);
|
||||
}
|
||||
if ("projects" in config && config.projects !== void 0) {
|
||||
if (!Array.isArray(config.projects))
|
||||
throw (0, import_util.errorWithFile)(file, `config.projects must be an array`);
|
||||
config.projects.forEach((project, index) => {
|
||||
validateProject(file, project, `config.projects[${index}]`);
|
||||
});
|
||||
}
|
||||
if ("quiet" in config && config.quiet !== void 0) {
|
||||
if (typeof config.quiet !== "boolean")
|
||||
throw (0, import_util.errorWithFile)(file, `config.quiet must be a boolean`);
|
||||
}
|
||||
if ("reporter" in config && config.reporter !== void 0) {
|
||||
if (Array.isArray(config.reporter)) {
|
||||
config.reporter.forEach((item, index) => {
|
||||
if (!Array.isArray(item) || item.length <= 0 || item.length > 2 || typeof item[0] !== "string")
|
||||
throw (0, import_util.errorWithFile)(file, `config.reporter[${index}] must be a tuple [name, optionalArgument]`);
|
||||
});
|
||||
} else if (typeof config.reporter !== "string") {
|
||||
throw (0, import_util.errorWithFile)(file, `config.reporter must be a string`);
|
||||
}
|
||||
}
|
||||
if ("reportSlowTests" in config && config.reportSlowTests !== void 0 && config.reportSlowTests !== null) {
|
||||
if (!config.reportSlowTests || typeof config.reportSlowTests !== "object")
|
||||
throw (0, import_util.errorWithFile)(file, `config.reportSlowTests must be an object`);
|
||||
if (!("max" in config.reportSlowTests) || typeof config.reportSlowTests.max !== "number" || config.reportSlowTests.max < 0)
|
||||
throw (0, import_util.errorWithFile)(file, `config.reportSlowTests.max must be a non-negative number`);
|
||||
if (!("threshold" in config.reportSlowTests) || typeof config.reportSlowTests.threshold !== "number" || config.reportSlowTests.threshold < 0)
|
||||
throw (0, import_util.errorWithFile)(file, `config.reportSlowTests.threshold must be a non-negative number`);
|
||||
}
|
||||
if ("shard" in config && config.shard !== void 0 && config.shard !== null) {
|
||||
if (!config.shard || typeof config.shard !== "object")
|
||||
throw (0, import_util.errorWithFile)(file, `config.shard must be an object`);
|
||||
if (!("total" in config.shard) || typeof config.shard.total !== "number" || config.shard.total < 1)
|
||||
throw (0, import_util.errorWithFile)(file, `config.shard.total must be a positive number`);
|
||||
if (!("current" in config.shard) || typeof config.shard.current !== "number" || config.shard.current < 1 || config.shard.current > config.shard.total)
|
||||
throw (0, import_util.errorWithFile)(file, `config.shard.current must be a positive number, not greater than config.shard.total`);
|
||||
}
|
||||
if ("updateSnapshots" in config && config.updateSnapshots !== void 0) {
|
||||
if (typeof config.updateSnapshots !== "string" || !["all", "changed", "missing", "none"].includes(config.updateSnapshots))
|
||||
throw (0, import_util.errorWithFile)(file, `config.updateSnapshots must be one of "all", "changed", "missing" or "none"`);
|
||||
}
|
||||
if ("tsconfig" in config && config.tsconfig !== void 0) {
|
||||
if (typeof config.tsconfig !== "string")
|
||||
throw (0, import_util.errorWithFile)(file, `config.tsconfig must be a string`);
|
||||
if (!import_fs.default.existsSync(import_path.default.resolve(file, "..", config.tsconfig)))
|
||||
throw (0, import_util.errorWithFile)(file, `config.tsconfig does not exist`);
|
||||
}
|
||||
}
|
||||
function validateProject(file, project, title) {
|
||||
if (typeof project !== "object" || !project)
|
||||
throw (0, import_util.errorWithFile)(file, `${title} must be an object`);
|
||||
if ("name" in project && project.name !== void 0) {
|
||||
if (typeof project.name !== "string")
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.name must be a string`);
|
||||
}
|
||||
if ("outputDir" in project && project.outputDir !== void 0) {
|
||||
if (typeof project.outputDir !== "string")
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.outputDir must be a string`);
|
||||
}
|
||||
if ("repeatEach" in project && project.repeatEach !== void 0) {
|
||||
if (typeof project.repeatEach !== "number" || project.repeatEach < 0)
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.repeatEach must be a non-negative number`);
|
||||
}
|
||||
if ("retries" in project && project.retries !== void 0) {
|
||||
if (typeof project.retries !== "number" || project.retries < 0)
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.retries must be a non-negative number`);
|
||||
}
|
||||
if ("testDir" in project && project.testDir !== void 0) {
|
||||
if (typeof project.testDir !== "string")
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.testDir must be a string`);
|
||||
}
|
||||
for (const prop of ["testIgnore", "testMatch"]) {
|
||||
if (prop in project && project[prop] !== void 0) {
|
||||
const value = project[prop];
|
||||
if (Array.isArray(value)) {
|
||||
value.forEach((item, index) => {
|
||||
if (typeof item !== "string" && !(0, import_utils.isRegExp)(item))
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.${prop}[${index}] must be a string or a RegExp`);
|
||||
});
|
||||
} else if (typeof value !== "string" && !(0, import_utils.isRegExp)(value)) {
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.${prop} must be a string or a RegExp`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ("timeout" in project && project.timeout !== void 0) {
|
||||
if (typeof project.timeout !== "number" || project.timeout < 0)
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.timeout must be a non-negative number`);
|
||||
}
|
||||
if ("use" in project && project.use !== void 0) {
|
||||
if (!project.use || typeof project.use !== "object")
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.use must be an object`);
|
||||
}
|
||||
if ("ignoreSnapshots" in project && project.ignoreSnapshots !== void 0) {
|
||||
if (typeof project.ignoreSnapshots !== "boolean")
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.ignoreSnapshots must be a boolean`);
|
||||
}
|
||||
if ("workers" in project && project.workers !== void 0) {
|
||||
if (typeof project.workers === "number" && project.workers <= 0)
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.workers must be a positive number`);
|
||||
else if (typeof project.workers === "string" && !project.workers.endsWith("%"))
|
||||
throw (0, import_util.errorWithFile)(file, `${title}.workers must be a number or percentage`);
|
||||
}
|
||||
}
|
||||
function resolveConfigLocation(configFile) {
|
||||
const configFileOrDirectory = configFile ? import_path.default.resolve(process.cwd(), configFile) : process.cwd();
|
||||
const resolvedConfigFile = resolveConfigFile(configFileOrDirectory);
|
||||
return {
|
||||
resolvedConfigFile,
|
||||
configDir: resolvedConfigFile ? import_path.default.dirname(resolvedConfigFile) : configFileOrDirectory
|
||||
};
|
||||
}
|
||||
function resolveConfigFile(configFileOrDirectory) {
|
||||
const resolveConfig = (configFile) => {
|
||||
if (import_fs.default.existsSync(configFile))
|
||||
return configFile;
|
||||
};
|
||||
const resolveConfigFileFromDirectory = (directory) => {
|
||||
for (const ext of [".ts", ".js", ".mts", ".mjs", ".cts", ".cjs"]) {
|
||||
const configFile = resolveConfig(import_path.default.resolve(directory, "playwright.config" + ext));
|
||||
if (configFile)
|
||||
return configFile;
|
||||
}
|
||||
};
|
||||
if (!import_fs.default.existsSync(configFileOrDirectory))
|
||||
throw new Error(`${configFileOrDirectory} does not exist`);
|
||||
if (import_fs.default.statSync(configFileOrDirectory).isDirectory()) {
|
||||
const configFile = resolveConfigFileFromDirectory(configFileOrDirectory);
|
||||
if (configFile)
|
||||
return configFile;
|
||||
return void 0;
|
||||
}
|
||||
return configFileOrDirectory;
|
||||
}
|
||||
async function loadConfigFromFile(configFile, overrides, ignoreDeps) {
|
||||
return await loadConfig(resolveConfigLocation(configFile), overrides, ignoreDeps);
|
||||
}
|
||||
async function loadEmptyConfigForMergeReports() {
|
||||
return await loadConfig({ configDir: process.cwd() });
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
defineConfig,
|
||||
deserializeConfig,
|
||||
loadConfig,
|
||||
loadConfigFromFile,
|
||||
loadEmptyConfigForMergeReports,
|
||||
resolveConfigLocation
|
||||
});
|
||||
102
node_modules/playwright/lib/common/esmLoaderHost.js
generated
vendored
Normal file
102
node_modules/playwright/lib/common/esmLoaderHost.js
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var esmLoaderHost_exports = {};
|
||||
__export(esmLoaderHost_exports, {
|
||||
configureESMLoader: () => configureESMLoader,
|
||||
configureESMLoaderTransformConfig: () => configureESMLoaderTransformConfig,
|
||||
incorporateCompilationCache: () => incorporateCompilationCache,
|
||||
registerESMLoader: () => registerESMLoader,
|
||||
startCollectingFileDeps: () => startCollectingFileDeps,
|
||||
stopCollectingFileDeps: () => stopCollectingFileDeps
|
||||
});
|
||||
module.exports = __toCommonJS(esmLoaderHost_exports);
|
||||
var import_url = __toESM(require("url"));
|
||||
var import_compilationCache = require("../transform/compilationCache");
|
||||
var import_portTransport = require("../transform/portTransport");
|
||||
var import_transform = require("../transform/transform");
|
||||
let loaderChannel;
|
||||
function registerESMLoader() {
|
||||
if (process.env.PW_DISABLE_TS_ESM)
|
||||
return true;
|
||||
if (loaderChannel)
|
||||
return true;
|
||||
const register = require("node:module").register;
|
||||
if (!register)
|
||||
return false;
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
register(import_url.default.pathToFileURL(require.resolve("../transform/esmLoader")), {
|
||||
data: { port: port2 },
|
||||
transferList: [port2]
|
||||
});
|
||||
loaderChannel = createPortTransport(port1);
|
||||
return true;
|
||||
}
|
||||
function createPortTransport(port) {
|
||||
return new import_portTransport.PortTransport(port, async (method, params) => {
|
||||
if (method === "pushToCompilationCache")
|
||||
(0, import_compilationCache.addToCompilationCache)(params.cache);
|
||||
});
|
||||
}
|
||||
async function startCollectingFileDeps() {
|
||||
if (!loaderChannel)
|
||||
return;
|
||||
await loaderChannel.send("startCollectingFileDeps", {});
|
||||
}
|
||||
async function stopCollectingFileDeps(file) {
|
||||
if (!loaderChannel)
|
||||
return;
|
||||
await loaderChannel.send("stopCollectingFileDeps", { file });
|
||||
}
|
||||
async function incorporateCompilationCache() {
|
||||
if (!loaderChannel)
|
||||
return;
|
||||
const result = await loaderChannel.send("getCompilationCache", {});
|
||||
(0, import_compilationCache.addToCompilationCache)(result.cache);
|
||||
}
|
||||
async function configureESMLoader() {
|
||||
if (!loaderChannel)
|
||||
return;
|
||||
await loaderChannel.send("setSingleTSConfig", { tsconfig: (0, import_transform.singleTSConfig)() });
|
||||
await loaderChannel.send("addToCompilationCache", { cache: (0, import_compilationCache.serializeCompilationCache)() });
|
||||
}
|
||||
async function configureESMLoaderTransformConfig() {
|
||||
if (!loaderChannel)
|
||||
return;
|
||||
await loaderChannel.send("setSingleTSConfig", { tsconfig: (0, import_transform.singleTSConfig)() });
|
||||
await loaderChannel.send("setTransformConfig", { config: (0, import_transform.transformConfig)() });
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
configureESMLoader,
|
||||
configureESMLoaderTransformConfig,
|
||||
incorporateCompilationCache,
|
||||
registerESMLoader,
|
||||
startCollectingFileDeps,
|
||||
stopCollectingFileDeps
|
||||
});
|
||||
52
node_modules/playwright/lib/common/expectBundle.js
generated
vendored
Normal file
52
node_modules/playwright/lib/common/expectBundle.js
generated
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var expectBundle_exports = {};
|
||||
__export(expectBundle_exports, {
|
||||
DIM_COLOR: () => DIM_COLOR,
|
||||
EXPECTED_COLOR: () => EXPECTED_COLOR,
|
||||
INVERTED_COLOR: () => INVERTED_COLOR,
|
||||
RECEIVED_COLOR: () => RECEIVED_COLOR,
|
||||
asymmetricMatchers: () => asymmetricMatchers,
|
||||
expect: () => expect,
|
||||
matcherUtils: () => matcherUtils,
|
||||
mock: () => mock,
|
||||
printReceived: () => printReceived
|
||||
});
|
||||
module.exports = __toCommonJS(expectBundle_exports);
|
||||
const expect = require("./expectBundleImpl").expect;
|
||||
const mock = require("./expectBundleImpl").mock;
|
||||
const asymmetricMatchers = require("./expectBundleImpl").asymmetricMatchers;
|
||||
const matcherUtils = require("./expectBundleImpl").matcherUtils;
|
||||
const EXPECTED_COLOR = require("./expectBundleImpl").EXPECTED_COLOR;
|
||||
const INVERTED_COLOR = require("./expectBundleImpl").INVERTED_COLOR;
|
||||
const RECEIVED_COLOR = require("./expectBundleImpl").RECEIVED_COLOR;
|
||||
const DIM_COLOR = require("./expectBundleImpl").DIM_COLOR;
|
||||
const printReceived = require("./expectBundleImpl").printReceived;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
DIM_COLOR,
|
||||
EXPECTED_COLOR,
|
||||
INVERTED_COLOR,
|
||||
RECEIVED_COLOR,
|
||||
asymmetricMatchers,
|
||||
expect,
|
||||
matcherUtils,
|
||||
mock,
|
||||
printReceived
|
||||
});
|
||||
389
node_modules/playwright/lib/common/expectBundleImpl.js
generated
vendored
Normal file
389
node_modules/playwright/lib/common/expectBundleImpl.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
302
node_modules/playwright/lib/common/fixtures.js
generated
vendored
Normal file
302
node_modules/playwright/lib/common/fixtures.js
generated
vendored
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var fixtures_exports = {};
|
||||
__export(fixtures_exports, {
|
||||
FixturePool: () => FixturePool,
|
||||
fixtureParameterNames: () => fixtureParameterNames,
|
||||
formatPotentiallyInternalLocation: () => formatPotentiallyInternalLocation,
|
||||
inheritFixtureNames: () => inheritFixtureNames
|
||||
});
|
||||
module.exports = __toCommonJS(fixtures_exports);
|
||||
var import_crypto = __toESM(require("crypto"));
|
||||
var import_util = require("../util");
|
||||
const kScopeOrder = ["test", "worker"];
|
||||
function isFixtureTuple(value) {
|
||||
return Array.isArray(value) && typeof value[1] === "object";
|
||||
}
|
||||
function isFixtureOption(value) {
|
||||
return isFixtureTuple(value) && !!value[1].option;
|
||||
}
|
||||
class FixturePool {
|
||||
constructor(fixturesList, onLoadError, parentPool, disallowWorkerFixtures, optionOverrides) {
|
||||
this._registrations = new Map(parentPool ? parentPool._registrations : []);
|
||||
this._onLoadError = onLoadError;
|
||||
const allOverrides = optionOverrides?.overrides ?? {};
|
||||
const overrideKeys = new Set(Object.keys(allOverrides));
|
||||
for (const list of fixturesList) {
|
||||
this._appendFixtureList(list, !!disallowWorkerFixtures, false);
|
||||
const selectedOverrides = {};
|
||||
for (const [key, value] of Object.entries(list.fixtures)) {
|
||||
if (isFixtureOption(value) && overrideKeys.has(key))
|
||||
selectedOverrides[key] = [allOverrides[key], value[1]];
|
||||
}
|
||||
if (Object.entries(selectedOverrides).length)
|
||||
this._appendFixtureList({ fixtures: selectedOverrides, location: optionOverrides.location }, !!disallowWorkerFixtures, true);
|
||||
}
|
||||
this.digest = this.validate();
|
||||
}
|
||||
_appendFixtureList(list, disallowWorkerFixtures, isOptionsOverride) {
|
||||
const { fixtures, location } = list;
|
||||
for (const entry of Object.entries(fixtures)) {
|
||||
const name = entry[0];
|
||||
let value = entry[1];
|
||||
let options;
|
||||
if (isFixtureTuple(value)) {
|
||||
options = {
|
||||
auto: value[1].auto ?? false,
|
||||
scope: value[1].scope || "test",
|
||||
option: !!value[1].option,
|
||||
timeout: value[1].timeout,
|
||||
customTitle: value[1].title,
|
||||
box: value[1].box
|
||||
};
|
||||
value = value[0];
|
||||
}
|
||||
let fn = value;
|
||||
const previous = this._registrations.get(name);
|
||||
if (previous && options) {
|
||||
if (previous.scope !== options.scope) {
|
||||
this._addLoadError(`Fixture "${name}" has already been registered as a { scope: '${previous.scope}' } fixture defined in ${(0, import_util.formatLocation)(previous.location)}.`, location);
|
||||
continue;
|
||||
}
|
||||
if (previous.auto !== options.auto) {
|
||||
this._addLoadError(`Fixture "${name}" has already been registered as a { auto: '${previous.scope}' } fixture defined in ${(0, import_util.formatLocation)(previous.location)}.`, location);
|
||||
continue;
|
||||
}
|
||||
} else if (previous) {
|
||||
options = { auto: previous.auto, scope: previous.scope, option: previous.option, timeout: previous.timeout, customTitle: previous.customTitle };
|
||||
} else if (!options) {
|
||||
options = { auto: false, scope: "test", option: false, timeout: void 0 };
|
||||
}
|
||||
if (!kScopeOrder.includes(options.scope)) {
|
||||
this._addLoadError(`Fixture "${name}" has unknown { scope: '${options.scope}' }.`, location);
|
||||
continue;
|
||||
}
|
||||
if (options.scope === "worker" && disallowWorkerFixtures) {
|
||||
this._addLoadError(`Cannot use({ ${name} }) in a describe group, because it forces a new worker.
|
||||
Make it top-level in the test file or put in the configuration file.`, location);
|
||||
continue;
|
||||
}
|
||||
if (fn === void 0 && options.option && previous) {
|
||||
let original = previous;
|
||||
while (!original.optionOverride && original.super)
|
||||
original = original.super;
|
||||
fn = original.fn;
|
||||
}
|
||||
const deps = fixtureParameterNames(fn, location, (e) => this._onLoadError(e));
|
||||
const registration = { id: "", name, location, scope: options.scope, fn, auto: options.auto, option: options.option, timeout: options.timeout, customTitle: options.customTitle, box: options.box, deps, super: previous, optionOverride: isOptionsOverride };
|
||||
registrationId(registration);
|
||||
this._registrations.set(name, registration);
|
||||
}
|
||||
}
|
||||
validate() {
|
||||
const markers = /* @__PURE__ */ new Map();
|
||||
const stack = [];
|
||||
let hasDependencyErrors = false;
|
||||
const addDependencyError = (message, location) => {
|
||||
hasDependencyErrors = true;
|
||||
this._addLoadError(message, location);
|
||||
};
|
||||
const visit = (registration, boxedOnly) => {
|
||||
markers.set(registration, "visiting");
|
||||
stack.push(registration);
|
||||
for (const name of registration.deps) {
|
||||
const dep = this.resolve(name, registration);
|
||||
if (!dep) {
|
||||
if (name === registration.name)
|
||||
addDependencyError(`Fixture "${registration.name}" references itself, but does not have a base implementation.`, registration.location);
|
||||
else
|
||||
addDependencyError(`Fixture "${registration.name}" has unknown parameter "${name}".`, registration.location);
|
||||
continue;
|
||||
}
|
||||
if (kScopeOrder.indexOf(registration.scope) > kScopeOrder.indexOf(dep.scope)) {
|
||||
addDependencyError(`${registration.scope} fixture "${registration.name}" cannot depend on a ${dep.scope} fixture "${name}" defined in ${formatPotentiallyInternalLocation(dep.location)}.`, registration.location);
|
||||
continue;
|
||||
}
|
||||
if (!markers.has(dep)) {
|
||||
visit(dep, boxedOnly);
|
||||
} else if (markers.get(dep) === "visiting") {
|
||||
const index = stack.indexOf(dep);
|
||||
const allRegs = stack.slice(index, stack.length);
|
||||
const filteredRegs = allRegs.filter((r) => !r.box);
|
||||
const regs = boxedOnly ? filteredRegs : allRegs;
|
||||
const names2 = regs.map((r) => `"${r.name}"`);
|
||||
addDependencyError(`Fixtures ${names2.join(" -> ")} -> "${dep.name}" form a dependency cycle: ${regs.map((r) => formatPotentiallyInternalLocation(r.location)).join(" -> ")} -> ${formatPotentiallyInternalLocation(dep.location)}`, dep.location);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
markers.set(registration, "visited");
|
||||
stack.pop();
|
||||
};
|
||||
const names = Array.from(this._registrations.keys()).sort();
|
||||
for (const name of names) {
|
||||
const registration = this._registrations.get(name);
|
||||
if (!registration.box)
|
||||
visit(registration, true);
|
||||
}
|
||||
if (!hasDependencyErrors) {
|
||||
for (const name of names) {
|
||||
const registration = this._registrations.get(name);
|
||||
if (registration.box)
|
||||
visit(registration, false);
|
||||
}
|
||||
}
|
||||
const hash = import_crypto.default.createHash("sha1");
|
||||
for (const name of names) {
|
||||
const registration = this._registrations.get(name);
|
||||
if (registration.scope === "worker")
|
||||
hash.update(registration.id + ";");
|
||||
}
|
||||
return hash.digest("hex");
|
||||
}
|
||||
validateFunction(fn, prefix, location) {
|
||||
for (const name of fixtureParameterNames(fn, location, (e) => this._onLoadError(e))) {
|
||||
const registration = this._registrations.get(name);
|
||||
if (!registration)
|
||||
this._addLoadError(`${prefix} has unknown parameter "${name}".`, location);
|
||||
}
|
||||
}
|
||||
resolve(name, forFixture) {
|
||||
if (name === forFixture?.name)
|
||||
return forFixture.super;
|
||||
return this._registrations.get(name);
|
||||
}
|
||||
autoFixtures() {
|
||||
return [...this._registrations.values()].filter((r) => r.auto !== false);
|
||||
}
|
||||
_addLoadError(message, location) {
|
||||
this._onLoadError({ message, location });
|
||||
}
|
||||
}
|
||||
const signatureSymbol = Symbol("signature");
|
||||
function formatPotentiallyInternalLocation(location) {
|
||||
const isUserFixture = location && (0, import_util.filterStackFile)(location.file);
|
||||
return isUserFixture ? (0, import_util.formatLocation)(location) : "<builtin>";
|
||||
}
|
||||
function fixtureParameterNames(fn, location, onError) {
|
||||
if (typeof fn !== "function")
|
||||
return [];
|
||||
if (!fn[signatureSymbol])
|
||||
fn[signatureSymbol] = innerFixtureParameterNames(fn, location, onError);
|
||||
return fn[signatureSymbol];
|
||||
}
|
||||
function inheritFixtureNames(from, to) {
|
||||
to[signatureSymbol] = from[signatureSymbol];
|
||||
}
|
||||
function innerFixtureParameterNames(fn, location, onError) {
|
||||
const text = filterOutComments(fn.toString());
|
||||
const match = text.match(/(?:async)?(?:\s+function)?[^(]*\(([^)]*)/);
|
||||
if (!match)
|
||||
return [];
|
||||
const trimmedParams = match[1].trim();
|
||||
if (!trimmedParams)
|
||||
return [];
|
||||
const [firstParam] = splitByComma(trimmedParams);
|
||||
if (firstParam[0] !== "{" || firstParam[firstParam.length - 1] !== "}") {
|
||||
onError({ message: "First argument must use the object destructuring pattern: " + firstParam, location });
|
||||
return [];
|
||||
}
|
||||
const props = splitByComma(firstParam.substring(1, firstParam.length - 1)).map((prop) => {
|
||||
const colon = prop.indexOf(":");
|
||||
return colon === -1 ? prop.trim() : prop.substring(0, colon).trim();
|
||||
});
|
||||
const restProperty = props.find((prop) => prop.startsWith("..."));
|
||||
if (restProperty) {
|
||||
onError({ message: `Rest property "${restProperty}" is not supported. List all used fixtures explicitly, separated by comma.`, location });
|
||||
return [];
|
||||
}
|
||||
return props;
|
||||
}
|
||||
function filterOutComments(s) {
|
||||
const result = [];
|
||||
let commentState = "none";
|
||||
for (let i = 0; i < s.length; ++i) {
|
||||
if (commentState === "singleline") {
|
||||
if (s[i] === "\n")
|
||||
commentState = "none";
|
||||
} else if (commentState === "multiline") {
|
||||
if (s[i - 1] === "*" && s[i] === "/")
|
||||
commentState = "none";
|
||||
} else if (commentState === "none") {
|
||||
if (s[i] === "/" && s[i + 1] === "/") {
|
||||
commentState = "singleline";
|
||||
} else if (s[i] === "/" && s[i + 1] === "*") {
|
||||
commentState = "multiline";
|
||||
i += 2;
|
||||
} else {
|
||||
result.push(s[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.join("");
|
||||
}
|
||||
function splitByComma(s) {
|
||||
const result = [];
|
||||
const stack = [];
|
||||
let start = 0;
|
||||
for (let i = 0; i < s.length; i++) {
|
||||
if (s[i] === "{" || s[i] === "[") {
|
||||
stack.push(s[i] === "{" ? "}" : "]");
|
||||
} else if (s[i] === stack[stack.length - 1]) {
|
||||
stack.pop();
|
||||
} else if (!stack.length && s[i] === ",") {
|
||||
const token = s.substring(start, i).trim();
|
||||
if (token)
|
||||
result.push(token);
|
||||
start = i + 1;
|
||||
}
|
||||
}
|
||||
const lastToken = s.substring(start).trim();
|
||||
if (lastToken)
|
||||
result.push(lastToken);
|
||||
return result;
|
||||
}
|
||||
const registrationIdMap = /* @__PURE__ */ new Map();
|
||||
let lastId = 0;
|
||||
function registrationId(registration) {
|
||||
if (registration.id)
|
||||
return registration.id;
|
||||
const key = registration.name + "@@@" + (registration.super ? registrationId(registration.super) : "");
|
||||
let map = registrationIdMap.get(key);
|
||||
if (!map) {
|
||||
map = /* @__PURE__ */ new Map();
|
||||
registrationIdMap.set(key, map);
|
||||
}
|
||||
if (!map.has(registration.fn))
|
||||
map.set(registration.fn, String(lastId++));
|
||||
registration.id = map.get(registration.fn);
|
||||
return registration.id;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
FixturePool,
|
||||
fixtureParameterNames,
|
||||
formatPotentiallyInternalLocation,
|
||||
inheritFixtureNames
|
||||
});
|
||||
58
node_modules/playwright/lib/common/globals.js
generated
vendored
Normal file
58
node_modules/playwright/lib/common/globals.js
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var globals_exports = {};
|
||||
__export(globals_exports, {
|
||||
currentTestInfo: () => currentTestInfo,
|
||||
currentlyLoadingFileSuite: () => currentlyLoadingFileSuite,
|
||||
isWorkerProcess: () => isWorkerProcess,
|
||||
setCurrentTestInfo: () => setCurrentTestInfo,
|
||||
setCurrentlyLoadingFileSuite: () => setCurrentlyLoadingFileSuite,
|
||||
setIsWorkerProcess: () => setIsWorkerProcess
|
||||
});
|
||||
module.exports = __toCommonJS(globals_exports);
|
||||
let currentTestInfoValue = null;
|
||||
function setCurrentTestInfo(testInfo) {
|
||||
currentTestInfoValue = testInfo;
|
||||
}
|
||||
function currentTestInfo() {
|
||||
return currentTestInfoValue;
|
||||
}
|
||||
let currentFileSuite;
|
||||
function setCurrentlyLoadingFileSuite(suite) {
|
||||
currentFileSuite = suite;
|
||||
}
|
||||
function currentlyLoadingFileSuite() {
|
||||
return currentFileSuite;
|
||||
}
|
||||
let _isWorkerProcess = false;
|
||||
function setIsWorkerProcess() {
|
||||
_isWorkerProcess = true;
|
||||
}
|
||||
function isWorkerProcess() {
|
||||
return _isWorkerProcess;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
currentTestInfo,
|
||||
currentlyLoadingFileSuite,
|
||||
isWorkerProcess,
|
||||
setCurrentTestInfo,
|
||||
setCurrentlyLoadingFileSuite,
|
||||
setIsWorkerProcess
|
||||
});
|
||||
60
node_modules/playwright/lib/common/ipc.js
generated
vendored
Normal file
60
node_modules/playwright/lib/common/ipc.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var ipc_exports = {};
|
||||
__export(ipc_exports, {
|
||||
serializeConfig: () => serializeConfig,
|
||||
stdioChunkToParams: () => stdioChunkToParams
|
||||
});
|
||||
module.exports = __toCommonJS(ipc_exports);
|
||||
var import_util = __toESM(require("util"));
|
||||
var import_compilationCache = require("../transform/compilationCache");
|
||||
function serializeConfig(config, passCompilationCache) {
|
||||
const result = {
|
||||
location: { configDir: config.configDir, resolvedConfigFile: config.config.configFile },
|
||||
configCLIOverrides: config.configCLIOverrides,
|
||||
compilationCache: passCompilationCache ? (0, import_compilationCache.serializeCompilationCache)() : void 0
|
||||
};
|
||||
try {
|
||||
result.metadata = JSON.stringify(config.config.metadata);
|
||||
} catch (error) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function stdioChunkToParams(chunk) {
|
||||
if (chunk instanceof Uint8Array)
|
||||
return { buffer: Buffer.from(chunk).toString("base64") };
|
||||
if (typeof chunk !== "string")
|
||||
return { text: import_util.default.inspect(chunk) };
|
||||
return { text: chunk };
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
serializeConfig,
|
||||
stdioChunkToParams
|
||||
});
|
||||
85
node_modules/playwright/lib/common/poolBuilder.js
generated
vendored
Normal file
85
node_modules/playwright/lib/common/poolBuilder.js
generated
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var poolBuilder_exports = {};
|
||||
__export(poolBuilder_exports, {
|
||||
PoolBuilder: () => PoolBuilder
|
||||
});
|
||||
module.exports = __toCommonJS(poolBuilder_exports);
|
||||
var import_fixtures = require("./fixtures");
|
||||
var import_util = require("../util");
|
||||
class PoolBuilder {
|
||||
constructor(type, project) {
|
||||
this._testTypePools = /* @__PURE__ */ new Map();
|
||||
this._type = type;
|
||||
this._project = project;
|
||||
}
|
||||
static createForLoader() {
|
||||
return new PoolBuilder("loader");
|
||||
}
|
||||
static createForWorker(project) {
|
||||
return new PoolBuilder("worker", project);
|
||||
}
|
||||
buildPools(suite, testErrors) {
|
||||
suite.forEachTest((test) => {
|
||||
const pool = this._buildPoolForTest(test, testErrors);
|
||||
if (this._type === "loader")
|
||||
test._poolDigest = pool.digest;
|
||||
if (this._type === "worker")
|
||||
test._pool = pool;
|
||||
});
|
||||
}
|
||||
_buildPoolForTest(test, testErrors) {
|
||||
let pool = this._buildTestTypePool(test._testType, testErrors);
|
||||
const parents = [];
|
||||
for (let parent = test.parent; parent; parent = parent.parent)
|
||||
parents.push(parent);
|
||||
parents.reverse();
|
||||
for (const parent of parents) {
|
||||
if (parent._use.length)
|
||||
pool = new import_fixtures.FixturePool(parent._use, (e) => this._handleLoadError(e, testErrors), pool, parent._type === "describe");
|
||||
for (const hook of parent._hooks)
|
||||
pool.validateFunction(hook.fn, hook.type + " hook", hook.location);
|
||||
for (const modifier of parent._modifiers)
|
||||
pool.validateFunction(modifier.fn, modifier.type + " modifier", modifier.location);
|
||||
}
|
||||
pool.validateFunction(test.fn, "Test", test.location);
|
||||
return pool;
|
||||
}
|
||||
_buildTestTypePool(testType, testErrors) {
|
||||
if (!this._testTypePools.has(testType)) {
|
||||
const optionOverrides = {
|
||||
overrides: this._project?.project?.use ?? {},
|
||||
location: { file: `project#${this._project?.id}`, line: 1, column: 1 }
|
||||
};
|
||||
const pool = new import_fixtures.FixturePool(testType.fixtures, (e) => this._handleLoadError(e, testErrors), void 0, void 0, optionOverrides);
|
||||
this._testTypePools.set(testType, pool);
|
||||
}
|
||||
return this._testTypePools.get(testType);
|
||||
}
|
||||
_handleLoadError(e, testErrors) {
|
||||
if (testErrors)
|
||||
testErrors.push(e);
|
||||
else
|
||||
throw new Error(`${(0, import_util.formatLocation)(e.location)}: ${e.message}`);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
PoolBuilder
|
||||
});
|
||||
104
node_modules/playwright/lib/common/process.js
generated
vendored
Normal file
104
node_modules/playwright/lib/common/process.js
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var process_exports = {};
|
||||
__export(process_exports, {
|
||||
ProcessRunner: () => ProcessRunner
|
||||
});
|
||||
module.exports = __toCommonJS(process_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_util = require("../util");
|
||||
class ProcessRunner {
|
||||
async gracefullyClose() {
|
||||
}
|
||||
dispatchEvent(method, params) {
|
||||
const response = { method, params };
|
||||
sendMessageToParent({ method: "__dispatch__", params: response });
|
||||
}
|
||||
}
|
||||
let gracefullyCloseCalled = false;
|
||||
let forceExitInitiated = false;
|
||||
sendMessageToParent({ method: "ready" });
|
||||
process.on("disconnect", () => gracefullyCloseAndExit(true));
|
||||
process.on("SIGINT", () => {
|
||||
});
|
||||
process.on("SIGTERM", () => {
|
||||
});
|
||||
let processRunner;
|
||||
let processName;
|
||||
const startingEnv = { ...process.env };
|
||||
process.on("message", async (message) => {
|
||||
if (message.method === "__init__") {
|
||||
const { processParams, runnerParams, runnerScript } = message.params;
|
||||
void (0, import_utils.startProfiling)();
|
||||
(0, import_utils.setTimeOrigin)(processParams.timeOrigin);
|
||||
const { create } = require(runnerScript);
|
||||
processRunner = create(runnerParams);
|
||||
processName = processParams.processName;
|
||||
return;
|
||||
}
|
||||
if (message.method === "__stop__") {
|
||||
const keys = /* @__PURE__ */ new Set([...Object.keys(process.env), ...Object.keys(startingEnv)]);
|
||||
const producedEnv = [...keys].filter((key) => startingEnv[key] !== process.env[key]).map((key) => [key, process.env[key] ?? null]);
|
||||
sendMessageToParent({ method: "__env_produced__", params: producedEnv });
|
||||
await gracefullyCloseAndExit(false);
|
||||
return;
|
||||
}
|
||||
if (message.method === "__dispatch__") {
|
||||
const { id, method, params } = message.params;
|
||||
try {
|
||||
const result = await processRunner[method](params);
|
||||
const response = { id, result };
|
||||
sendMessageToParent({ method: "__dispatch__", params: response });
|
||||
} catch (e) {
|
||||
const response = { id, error: (0, import_util.serializeError)(e) };
|
||||
sendMessageToParent({ method: "__dispatch__", params: response });
|
||||
}
|
||||
}
|
||||
});
|
||||
const kForceExitTimeout = +(process.env.PWTEST_FORCE_EXIT_TIMEOUT || 3e4);
|
||||
async function gracefullyCloseAndExit(forceExit) {
|
||||
if (forceExit && !forceExitInitiated) {
|
||||
forceExitInitiated = true;
|
||||
setTimeout(() => process.exit(0), kForceExitTimeout);
|
||||
}
|
||||
if (!gracefullyCloseCalled) {
|
||||
gracefullyCloseCalled = true;
|
||||
await processRunner?.gracefullyClose().catch(() => {
|
||||
});
|
||||
if (processName)
|
||||
await (0, import_utils.stopProfiling)(processName).catch(() => {
|
||||
});
|
||||
process.exit(0);
|
||||
}
|
||||
}
|
||||
function sendMessageToParent(message) {
|
||||
try {
|
||||
process.send(message);
|
||||
} catch (e) {
|
||||
try {
|
||||
JSON.stringify(message);
|
||||
} catch {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ProcessRunner
|
||||
});
|
||||
140
node_modules/playwright/lib/common/suiteUtils.js
generated
vendored
Normal file
140
node_modules/playwright/lib/common/suiteUtils.js
generated
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var suiteUtils_exports = {};
|
||||
__export(suiteUtils_exports, {
|
||||
applyRepeatEachIndex: () => applyRepeatEachIndex,
|
||||
bindFileSuiteToProject: () => bindFileSuiteToProject,
|
||||
filterByFocusedLine: () => filterByFocusedLine,
|
||||
filterOnly: () => filterOnly,
|
||||
filterSuite: () => filterSuite,
|
||||
filterTestsRemoveEmptySuites: () => filterTestsRemoveEmptySuites
|
||||
});
|
||||
module.exports = __toCommonJS(suiteUtils_exports);
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_util = require("../util");
|
||||
function filterSuite(suite, suiteFilter, testFilter) {
|
||||
for (const child of suite.suites) {
|
||||
if (!suiteFilter(child))
|
||||
filterSuite(child, suiteFilter, testFilter);
|
||||
}
|
||||
const filteredTests = suite.tests.filter(testFilter);
|
||||
const entries = /* @__PURE__ */ new Set([...suite.suites, ...filteredTests]);
|
||||
suite._entries = suite._entries.filter((e) => entries.has(e));
|
||||
}
|
||||
function filterTestsRemoveEmptySuites(suite, filter) {
|
||||
const filteredSuites = suite.suites.filter((child) => filterTestsRemoveEmptySuites(child, filter));
|
||||
const filteredTests = suite.tests.filter(filter);
|
||||
const entries = /* @__PURE__ */ new Set([...filteredSuites, ...filteredTests]);
|
||||
suite._entries = suite._entries.filter((e) => entries.has(e));
|
||||
return !!suite._entries.length;
|
||||
}
|
||||
function bindFileSuiteToProject(project, suite) {
|
||||
const relativeFile = import_path.default.relative(project.project.testDir, suite.location.file);
|
||||
const fileId = (0, import_utils.calculateSha1)((0, import_utils.toPosixPath)(relativeFile)).slice(0, 20);
|
||||
const result = suite._deepClone();
|
||||
result._fileId = fileId;
|
||||
result.forEachTest((test, suite2) => {
|
||||
suite2._fileId = fileId;
|
||||
const [file, ...titles] = test.titlePath();
|
||||
const testIdExpression = `[project=${project.id}]${(0, import_utils.toPosixPath)(file)}${titles.join("")}`;
|
||||
const testId = fileId + "-" + (0, import_utils.calculateSha1)(testIdExpression).slice(0, 20);
|
||||
test.id = testId;
|
||||
test._projectId = project.id;
|
||||
let inheritedRetries;
|
||||
let inheritedTimeout;
|
||||
for (let parentSuite = suite2; parentSuite; parentSuite = parentSuite.parent) {
|
||||
if (parentSuite._staticAnnotations.length)
|
||||
test.annotations.unshift(...parentSuite._staticAnnotations);
|
||||
if (inheritedRetries === void 0 && parentSuite._retries !== void 0)
|
||||
inheritedRetries = parentSuite._retries;
|
||||
if (inheritedTimeout === void 0 && parentSuite._timeout !== void 0)
|
||||
inheritedTimeout = parentSuite._timeout;
|
||||
}
|
||||
test.retries = inheritedRetries ?? project.project.retries;
|
||||
test.timeout = inheritedTimeout ?? project.project.timeout;
|
||||
if (test.annotations.some((a) => a.type === "skip" || a.type === "fixme"))
|
||||
test.expectedStatus = "skipped";
|
||||
if (test._poolDigest)
|
||||
test._workerHash = `${project.id}-${test._poolDigest}-0`;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
function applyRepeatEachIndex(project, fileSuite, repeatEachIndex) {
|
||||
fileSuite.forEachTest((test, suite) => {
|
||||
if (repeatEachIndex) {
|
||||
const [file, ...titles] = test.titlePath();
|
||||
const testIdExpression = `[project=${project.id}]${(0, import_utils.toPosixPath)(file)}${titles.join("")} (repeat:${repeatEachIndex})`;
|
||||
const testId = suite._fileId + "-" + (0, import_utils.calculateSha1)(testIdExpression).slice(0, 20);
|
||||
test.id = testId;
|
||||
test.repeatEachIndex = repeatEachIndex;
|
||||
if (test._poolDigest)
|
||||
test._workerHash = `${project.id}-${test._poolDigest}-${repeatEachIndex}`;
|
||||
}
|
||||
});
|
||||
}
|
||||
function filterOnly(suite) {
|
||||
if (!suite._getOnlyItems().length)
|
||||
return;
|
||||
const suiteFilter = (suite2) => suite2._only;
|
||||
const testFilter = (test) => test._only;
|
||||
return filterSuiteWithOnlySemantics(suite, suiteFilter, testFilter);
|
||||
}
|
||||
function filterSuiteWithOnlySemantics(suite, suiteFilter, testFilter) {
|
||||
const onlySuites = suite.suites.filter((child) => filterSuiteWithOnlySemantics(child, suiteFilter, testFilter) || suiteFilter(child));
|
||||
const onlyTests = suite.tests.filter(testFilter);
|
||||
const onlyEntries = /* @__PURE__ */ new Set([...onlySuites, ...onlyTests]);
|
||||
if (onlyEntries.size) {
|
||||
suite._entries = suite._entries.filter((e) => onlyEntries.has(e));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function filterByFocusedLine(suite, focusedTestFileLines) {
|
||||
if (!focusedTestFileLines.length)
|
||||
return;
|
||||
const matchers = focusedTestFileLines.map(createFileMatcherFromFilter);
|
||||
const testFileLineMatches = (testFileName, testLine, testColumn) => matchers.some((m) => m(testFileName, testLine, testColumn));
|
||||
const suiteFilter = (suite2) => !!suite2.location && testFileLineMatches(suite2.location.file, suite2.location.line, suite2.location.column);
|
||||
const testFilter = (test) => testFileLineMatches(test.location.file, test.location.line, test.location.column);
|
||||
return filterSuite(suite, suiteFilter, testFilter);
|
||||
}
|
||||
function createFileMatcherFromFilter(filter) {
|
||||
const fileMatcher = (0, import_util.createFileMatcher)(filter.re || filter.exact || "");
|
||||
return (testFileName, testLine, testColumn) => fileMatcher(testFileName) && (filter.line === testLine || filter.line === null) && (filter.column === testColumn || filter.column === null);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
applyRepeatEachIndex,
|
||||
bindFileSuiteToProject,
|
||||
filterByFocusedLine,
|
||||
filterOnly,
|
||||
filterSuite,
|
||||
filterTestsRemoveEmptySuites
|
||||
});
|
||||
321
node_modules/playwright/lib/common/test.js
generated
vendored
Normal file
321
node_modules/playwright/lib/common/test.js
generated
vendored
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var test_exports = {};
|
||||
__export(test_exports, {
|
||||
Suite: () => Suite,
|
||||
TestCase: () => TestCase
|
||||
});
|
||||
module.exports = __toCommonJS(test_exports);
|
||||
var import_testType = require("./testType");
|
||||
var import_teleReceiver = require("../isomorphic/teleReceiver");
|
||||
class Base {
|
||||
constructor(title) {
|
||||
this._only = false;
|
||||
this._requireFile = "";
|
||||
this.title = title;
|
||||
}
|
||||
}
|
||||
class Suite extends Base {
|
||||
constructor(title, type) {
|
||||
super(title);
|
||||
this._use = [];
|
||||
this._entries = [];
|
||||
this._hooks = [];
|
||||
// Annotations known statically before running the test, e.g. `test.describe.skip()` or `test.describe({ annotation }, body)`.
|
||||
this._staticAnnotations = [];
|
||||
// Explicitly declared tags that are not a part of the title.
|
||||
this._tags = [];
|
||||
this._modifiers = [];
|
||||
this._parallelMode = "none";
|
||||
this._type = type;
|
||||
}
|
||||
get type() {
|
||||
return this._type;
|
||||
}
|
||||
entries() {
|
||||
return this._entries;
|
||||
}
|
||||
get suites() {
|
||||
return this._entries.filter((entry) => entry instanceof Suite);
|
||||
}
|
||||
get tests() {
|
||||
return this._entries.filter((entry) => entry instanceof TestCase);
|
||||
}
|
||||
_addTest(test) {
|
||||
test.parent = this;
|
||||
this._entries.push(test);
|
||||
}
|
||||
_addSuite(suite) {
|
||||
suite.parent = this;
|
||||
this._entries.push(suite);
|
||||
}
|
||||
_prependSuite(suite) {
|
||||
suite.parent = this;
|
||||
this._entries.unshift(suite);
|
||||
}
|
||||
allTests() {
|
||||
const result = [];
|
||||
const visit = (suite) => {
|
||||
for (const entry of suite._entries) {
|
||||
if (entry instanceof Suite)
|
||||
visit(entry);
|
||||
else
|
||||
result.push(entry);
|
||||
}
|
||||
};
|
||||
visit(this);
|
||||
return result;
|
||||
}
|
||||
_hasTests() {
|
||||
let result = false;
|
||||
const visit = (suite) => {
|
||||
for (const entry of suite._entries) {
|
||||
if (result)
|
||||
return;
|
||||
if (entry instanceof Suite)
|
||||
visit(entry);
|
||||
else
|
||||
result = true;
|
||||
}
|
||||
};
|
||||
visit(this);
|
||||
return result;
|
||||
}
|
||||
titlePath() {
|
||||
const titlePath = this.parent ? this.parent.titlePath() : [];
|
||||
if (this.title || this._type !== "describe")
|
||||
titlePath.push(this.title);
|
||||
return titlePath;
|
||||
}
|
||||
_collectGrepTitlePath(path) {
|
||||
if (this.parent)
|
||||
this.parent._collectGrepTitlePath(path);
|
||||
if (this.title || this._type !== "describe")
|
||||
path.push(this.title);
|
||||
path.push(...this._tags);
|
||||
}
|
||||
_getOnlyItems() {
|
||||
const items = [];
|
||||
if (this._only)
|
||||
items.push(this);
|
||||
for (const suite of this.suites)
|
||||
items.push(...suite._getOnlyItems());
|
||||
items.push(...this.tests.filter((test) => test._only));
|
||||
return items;
|
||||
}
|
||||
_deepClone() {
|
||||
const suite = this._clone();
|
||||
for (const entry of this._entries) {
|
||||
if (entry instanceof Suite)
|
||||
suite._addSuite(entry._deepClone());
|
||||
else
|
||||
suite._addTest(entry._clone());
|
||||
}
|
||||
return suite;
|
||||
}
|
||||
_deepSerialize() {
|
||||
const suite = this._serialize();
|
||||
suite.entries = [];
|
||||
for (const entry of this._entries) {
|
||||
if (entry instanceof Suite)
|
||||
suite.entries.push(entry._deepSerialize());
|
||||
else
|
||||
suite.entries.push(entry._serialize());
|
||||
}
|
||||
return suite;
|
||||
}
|
||||
static _deepParse(data) {
|
||||
const suite = Suite._parse(data);
|
||||
for (const entry of data.entries) {
|
||||
if (entry.kind === "suite")
|
||||
suite._addSuite(Suite._deepParse(entry));
|
||||
else
|
||||
suite._addTest(TestCase._parse(entry));
|
||||
}
|
||||
return suite;
|
||||
}
|
||||
forEachTest(visitor) {
|
||||
for (const entry of this._entries) {
|
||||
if (entry instanceof Suite)
|
||||
entry.forEachTest(visitor);
|
||||
else
|
||||
visitor(entry, this);
|
||||
}
|
||||
}
|
||||
_serialize() {
|
||||
return {
|
||||
kind: "suite",
|
||||
title: this.title,
|
||||
type: this._type,
|
||||
location: this.location,
|
||||
only: this._only,
|
||||
requireFile: this._requireFile,
|
||||
timeout: this._timeout,
|
||||
retries: this._retries,
|
||||
staticAnnotations: this._staticAnnotations.slice(),
|
||||
tags: this._tags.slice(),
|
||||
modifiers: this._modifiers.slice(),
|
||||
parallelMode: this._parallelMode,
|
||||
hooks: this._hooks.map((h) => ({ type: h.type, location: h.location, title: h.title })),
|
||||
fileId: this._fileId
|
||||
};
|
||||
}
|
||||
static _parse(data) {
|
||||
const suite = new Suite(data.title, data.type);
|
||||
suite.location = data.location;
|
||||
suite._only = data.only;
|
||||
suite._requireFile = data.requireFile;
|
||||
suite._timeout = data.timeout;
|
||||
suite._retries = data.retries;
|
||||
suite._staticAnnotations = data.staticAnnotations;
|
||||
suite._tags = data.tags;
|
||||
suite._modifiers = data.modifiers;
|
||||
suite._parallelMode = data.parallelMode;
|
||||
suite._hooks = data.hooks.map((h) => ({ type: h.type, location: h.location, title: h.title, fn: () => {
|
||||
} }));
|
||||
suite._fileId = data.fileId;
|
||||
return suite;
|
||||
}
|
||||
_clone() {
|
||||
const data = this._serialize();
|
||||
const suite = Suite._parse(data);
|
||||
suite._use = this._use.slice();
|
||||
suite._hooks = this._hooks.slice();
|
||||
suite._fullProject = this._fullProject;
|
||||
return suite;
|
||||
}
|
||||
project() {
|
||||
return this._fullProject?.project || this.parent?.project();
|
||||
}
|
||||
}
|
||||
class TestCase extends Base {
|
||||
constructor(title, fn, testType, location) {
|
||||
super(title);
|
||||
this.results = [];
|
||||
this.type = "test";
|
||||
this.expectedStatus = "passed";
|
||||
this.timeout = 0;
|
||||
this.annotations = [];
|
||||
this.retries = 0;
|
||||
this.repeatEachIndex = 0;
|
||||
this.id = "";
|
||||
this._poolDigest = "";
|
||||
this._workerHash = "";
|
||||
this._projectId = "";
|
||||
// Explicitly declared tags that are not a part of the title.
|
||||
this._tags = [];
|
||||
this.fn = fn;
|
||||
this._testType = testType;
|
||||
this.location = location;
|
||||
}
|
||||
titlePath() {
|
||||
const titlePath = this.parent ? this.parent.titlePath() : [];
|
||||
titlePath.push(this.title);
|
||||
return titlePath;
|
||||
}
|
||||
outcome() {
|
||||
return (0, import_teleReceiver.computeTestCaseOutcome)(this);
|
||||
}
|
||||
ok() {
|
||||
const status = this.outcome();
|
||||
return status === "expected" || status === "flaky" || status === "skipped";
|
||||
}
|
||||
get tags() {
|
||||
const titleTags = this._grepBaseTitlePath().join(" ").match(/@[\S]+/g) || [];
|
||||
return [
|
||||
...titleTags,
|
||||
...this._tags
|
||||
];
|
||||
}
|
||||
_serialize() {
|
||||
return {
|
||||
kind: "test",
|
||||
id: this.id,
|
||||
title: this.title,
|
||||
retries: this.retries,
|
||||
timeout: this.timeout,
|
||||
expectedStatus: this.expectedStatus,
|
||||
location: this.location,
|
||||
only: this._only,
|
||||
requireFile: this._requireFile,
|
||||
poolDigest: this._poolDigest,
|
||||
workerHash: this._workerHash,
|
||||
annotations: this.annotations.slice(),
|
||||
tags: this._tags.slice(),
|
||||
projectId: this._projectId
|
||||
};
|
||||
}
|
||||
static _parse(data) {
|
||||
const test = new TestCase(data.title, () => {
|
||||
}, import_testType.rootTestType, data.location);
|
||||
test.id = data.id;
|
||||
test.retries = data.retries;
|
||||
test.timeout = data.timeout;
|
||||
test.expectedStatus = data.expectedStatus;
|
||||
test._only = data.only;
|
||||
test._requireFile = data.requireFile;
|
||||
test._poolDigest = data.poolDigest;
|
||||
test._workerHash = data.workerHash;
|
||||
test.annotations = data.annotations;
|
||||
test._tags = data.tags;
|
||||
test._projectId = data.projectId;
|
||||
return test;
|
||||
}
|
||||
_clone() {
|
||||
const data = this._serialize();
|
||||
const test = TestCase._parse(data);
|
||||
test._testType = this._testType;
|
||||
test.fn = this.fn;
|
||||
return test;
|
||||
}
|
||||
_appendTestResult() {
|
||||
const result = {
|
||||
retry: this.results.length,
|
||||
parallelIndex: -1,
|
||||
workerIndex: -1,
|
||||
duration: 0,
|
||||
startTime: /* @__PURE__ */ new Date(),
|
||||
stdout: [],
|
||||
stderr: [],
|
||||
attachments: [],
|
||||
status: "skipped",
|
||||
steps: [],
|
||||
errors: [],
|
||||
annotations: []
|
||||
};
|
||||
this.results.push(result);
|
||||
return result;
|
||||
}
|
||||
_grepBaseTitlePath() {
|
||||
const path = [];
|
||||
this.parent._collectGrepTitlePath(path);
|
||||
path.push(this.title);
|
||||
return path;
|
||||
}
|
||||
_grepTitleWithTags() {
|
||||
const path = this._grepBaseTitlePath();
|
||||
path.push(...this._tags);
|
||||
return path.join(" ");
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Suite,
|
||||
TestCase
|
||||
});
|
||||
100
node_modules/playwright/lib/common/testLoader.js
generated
vendored
Normal file
100
node_modules/playwright/lib/common/testLoader.js
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var testLoader_exports = {};
|
||||
__export(testLoader_exports, {
|
||||
defaultTimeout: () => defaultTimeout,
|
||||
loadTestFile: () => loadTestFile
|
||||
});
|
||||
module.exports = __toCommonJS(testLoader_exports);
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_util = __toESM(require("util"));
|
||||
var esmLoaderHost = __toESM(require("./esmLoaderHost"));
|
||||
var import_globals = require("./globals");
|
||||
var import_test = require("./test");
|
||||
var import_compilationCache = require("../transform/compilationCache");
|
||||
var import_transform = require("../transform/transform");
|
||||
var import_util2 = require("../util");
|
||||
const defaultTimeout = 3e4;
|
||||
const cachedFileSuites = /* @__PURE__ */ new Map();
|
||||
async function loadTestFile(file, rootDir, testErrors) {
|
||||
if (cachedFileSuites.has(file))
|
||||
return cachedFileSuites.get(file);
|
||||
const suite = new import_test.Suite(import_path.default.relative(rootDir, file) || import_path.default.basename(file), "file");
|
||||
suite._requireFile = file;
|
||||
suite.location = { file, line: 0, column: 0 };
|
||||
(0, import_globals.setCurrentlyLoadingFileSuite)(suite);
|
||||
if (!(0, import_globals.isWorkerProcess)()) {
|
||||
(0, import_compilationCache.startCollectingFileDeps)();
|
||||
await esmLoaderHost.startCollectingFileDeps();
|
||||
}
|
||||
try {
|
||||
await (0, import_transform.requireOrImport)(file);
|
||||
cachedFileSuites.set(file, suite);
|
||||
} catch (e) {
|
||||
if (!testErrors)
|
||||
throw e;
|
||||
testErrors.push(serializeLoadError(file, e));
|
||||
} finally {
|
||||
(0, import_globals.setCurrentlyLoadingFileSuite)(void 0);
|
||||
if (!(0, import_globals.isWorkerProcess)()) {
|
||||
(0, import_compilationCache.stopCollectingFileDeps)(file);
|
||||
await esmLoaderHost.stopCollectingFileDeps(file);
|
||||
}
|
||||
}
|
||||
{
|
||||
const files = /* @__PURE__ */ new Set();
|
||||
suite.allTests().map((t) => files.add(t.location.file));
|
||||
if (files.size === 1) {
|
||||
const mappedFile = files.values().next().value;
|
||||
if (suite.location.file !== mappedFile) {
|
||||
if (import_path.default.extname(mappedFile) !== import_path.default.extname(suite.location.file))
|
||||
suite.location.file = mappedFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
return suite;
|
||||
}
|
||||
function serializeLoadError(file, error) {
|
||||
if (error instanceof Error) {
|
||||
const result = (0, import_util2.filterStackTrace)(error);
|
||||
const loc = error.loc;
|
||||
result.location = loc ? {
|
||||
file,
|
||||
line: loc.line || 0,
|
||||
column: loc.column || 0
|
||||
} : void 0;
|
||||
return result;
|
||||
}
|
||||
return { value: import_util.default.inspect(error) };
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
defaultTimeout,
|
||||
loadTestFile
|
||||
});
|
||||
307
node_modules/playwright/lib/common/testType.js
generated
vendored
Normal file
307
node_modules/playwright/lib/common/testType.js
generated
vendored
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var testType_exports = {};
|
||||
__export(testType_exports, {
|
||||
TestTypeImpl: () => TestTypeImpl,
|
||||
mergeTests: () => mergeTests,
|
||||
rootTestType: () => rootTestType
|
||||
});
|
||||
module.exports = __toCommonJS(testType_exports);
|
||||
var import_playwright_core = require("playwright-core");
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_globals = require("./globals");
|
||||
var import_test = require("./test");
|
||||
var import_expect = require("../matchers/expect");
|
||||
var import_transform = require("../transform/transform");
|
||||
const testTypeSymbol = Symbol("testType");
|
||||
class TestTypeImpl {
|
||||
constructor(fixtures) {
|
||||
this.fixtures = fixtures;
|
||||
const test = (0, import_transform.wrapFunctionWithLocation)(this._createTest.bind(this, "default"));
|
||||
test[testTypeSymbol] = this;
|
||||
test.expect = import_expect.expect;
|
||||
test.only = (0, import_transform.wrapFunctionWithLocation)(this._createTest.bind(this, "only"));
|
||||
test.describe = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "default"));
|
||||
test.describe.only = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "only"));
|
||||
test.describe.configure = (0, import_transform.wrapFunctionWithLocation)(this._configure.bind(this));
|
||||
test.describe.fixme = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "fixme"));
|
||||
test.describe.parallel = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "parallel"));
|
||||
test.describe.parallel.only = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "parallel.only"));
|
||||
test.describe.serial = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "serial"));
|
||||
test.describe.serial.only = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "serial.only"));
|
||||
test.describe.skip = (0, import_transform.wrapFunctionWithLocation)(this._describe.bind(this, "skip"));
|
||||
test.beforeEach = (0, import_transform.wrapFunctionWithLocation)(this._hook.bind(this, "beforeEach"));
|
||||
test.afterEach = (0, import_transform.wrapFunctionWithLocation)(this._hook.bind(this, "afterEach"));
|
||||
test.beforeAll = (0, import_transform.wrapFunctionWithLocation)(this._hook.bind(this, "beforeAll"));
|
||||
test.afterAll = (0, import_transform.wrapFunctionWithLocation)(this._hook.bind(this, "afterAll"));
|
||||
test.skip = (0, import_transform.wrapFunctionWithLocation)(this._modifier.bind(this, "skip"));
|
||||
test.fixme = (0, import_transform.wrapFunctionWithLocation)(this._modifier.bind(this, "fixme"));
|
||||
test.fail = (0, import_transform.wrapFunctionWithLocation)(this._modifier.bind(this, "fail"));
|
||||
test.fail.only = (0, import_transform.wrapFunctionWithLocation)(this._createTest.bind(this, "fail.only"));
|
||||
test.slow = (0, import_transform.wrapFunctionWithLocation)(this._modifier.bind(this, "slow"));
|
||||
test.setTimeout = (0, import_transform.wrapFunctionWithLocation)(this._setTimeout.bind(this));
|
||||
test.step = this._step.bind(this, "pass");
|
||||
test.step.skip = this._step.bind(this, "skip");
|
||||
test.use = (0, import_transform.wrapFunctionWithLocation)(this._use.bind(this));
|
||||
test.extend = (0, import_transform.wrapFunctionWithLocation)(this._extend.bind(this));
|
||||
test.info = () => {
|
||||
const result = (0, import_globals.currentTestInfo)();
|
||||
if (!result)
|
||||
throw new Error("test.info() can only be called while test is running");
|
||||
return result;
|
||||
};
|
||||
this.test = test;
|
||||
}
|
||||
_currentSuite(location, title) {
|
||||
const suite = (0, import_globals.currentlyLoadingFileSuite)();
|
||||
if (!suite) {
|
||||
throw new Error([
|
||||
`Playwright Test did not expect ${title} to be called here.`,
|
||||
`Most common reasons include:`,
|
||||
`- You are calling ${title} in a configuration file.`,
|
||||
`- You are calling ${title} in a file that is imported by the configuration file.`,
|
||||
`- You have two different versions of @playwright/test. This usually happens`,
|
||||
` when one of the dependencies in your package.json depends on @playwright/test.`
|
||||
].join("\n"));
|
||||
}
|
||||
return suite;
|
||||
}
|
||||
_createTest(type, location, title, fnOrDetails, fn) {
|
||||
throwIfRunningInsideJest();
|
||||
const suite = this._currentSuite(location, "test()");
|
||||
if (!suite)
|
||||
return;
|
||||
let details;
|
||||
let body;
|
||||
if (typeof fnOrDetails === "function") {
|
||||
body = fnOrDetails;
|
||||
details = {};
|
||||
} else {
|
||||
body = fn;
|
||||
details = fnOrDetails;
|
||||
}
|
||||
const validatedDetails = validateTestDetails(details, location);
|
||||
const test = new import_test.TestCase(title, body, this, location);
|
||||
test._requireFile = suite._requireFile;
|
||||
test.annotations.push(...validatedDetails.annotations);
|
||||
test._tags.push(...validatedDetails.tags);
|
||||
suite._addTest(test);
|
||||
if (type === "only" || type === "fail.only")
|
||||
test._only = true;
|
||||
if (type === "skip" || type === "fixme" || type === "fail")
|
||||
test.annotations.push({ type, location });
|
||||
else if (type === "fail.only")
|
||||
test.annotations.push({ type: "fail", location });
|
||||
}
|
||||
_describe(type, location, titleOrFn, fnOrDetails, fn) {
|
||||
throwIfRunningInsideJest();
|
||||
const suite = this._currentSuite(location, "test.describe()");
|
||||
if (!suite)
|
||||
return;
|
||||
let title;
|
||||
let body;
|
||||
let details;
|
||||
if (typeof titleOrFn === "function") {
|
||||
title = "";
|
||||
details = {};
|
||||
body = titleOrFn;
|
||||
} else if (typeof fnOrDetails === "function") {
|
||||
title = titleOrFn;
|
||||
details = {};
|
||||
body = fnOrDetails;
|
||||
} else {
|
||||
title = titleOrFn;
|
||||
details = fnOrDetails;
|
||||
body = fn;
|
||||
}
|
||||
const validatedDetails = validateTestDetails(details, location);
|
||||
const child = new import_test.Suite(title, "describe");
|
||||
child._requireFile = suite._requireFile;
|
||||
child.location = location;
|
||||
child._staticAnnotations.push(...validatedDetails.annotations);
|
||||
child._tags.push(...validatedDetails.tags);
|
||||
suite._addSuite(child);
|
||||
if (type === "only" || type === "serial.only" || type === "parallel.only")
|
||||
child._only = true;
|
||||
if (type === "serial" || type === "serial.only")
|
||||
child._parallelMode = "serial";
|
||||
if (type === "parallel" || type === "parallel.only")
|
||||
child._parallelMode = "parallel";
|
||||
if (type === "skip" || type === "fixme")
|
||||
child._staticAnnotations.push({ type, location });
|
||||
for (let parent = suite; parent; parent = parent.parent) {
|
||||
if (parent._parallelMode === "serial" && child._parallelMode === "parallel")
|
||||
throw new Error("describe.parallel cannot be nested inside describe.serial");
|
||||
if (parent._parallelMode === "default" && child._parallelMode === "parallel")
|
||||
throw new Error("describe.parallel cannot be nested inside describe with default mode");
|
||||
}
|
||||
(0, import_globals.setCurrentlyLoadingFileSuite)(child);
|
||||
body();
|
||||
(0, import_globals.setCurrentlyLoadingFileSuite)(suite);
|
||||
}
|
||||
_hook(name, location, title, fn) {
|
||||
const suite = this._currentSuite(location, `test.${name}()`);
|
||||
if (!suite)
|
||||
return;
|
||||
if (typeof title === "function") {
|
||||
fn = title;
|
||||
title = `${name} hook`;
|
||||
}
|
||||
suite._hooks.push({ type: name, fn, title, location });
|
||||
}
|
||||
_configure(location, options) {
|
||||
throwIfRunningInsideJest();
|
||||
const suite = this._currentSuite(location, `test.describe.configure()`);
|
||||
if (!suite)
|
||||
return;
|
||||
if (options.timeout !== void 0)
|
||||
suite._timeout = options.timeout;
|
||||
if (options.retries !== void 0)
|
||||
suite._retries = options.retries;
|
||||
if (options.mode !== void 0) {
|
||||
if (suite._parallelMode !== "none")
|
||||
throw new Error(`"${suite._parallelMode}" mode is already assigned for the enclosing scope.`);
|
||||
suite._parallelMode = options.mode;
|
||||
for (let parent = suite.parent; parent; parent = parent.parent) {
|
||||
if (parent._parallelMode === "serial" && suite._parallelMode === "parallel")
|
||||
throw new Error("describe with parallel mode cannot be nested inside describe with serial mode");
|
||||
if (parent._parallelMode === "default" && suite._parallelMode === "parallel")
|
||||
throw new Error("describe with parallel mode cannot be nested inside describe with default mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
_modifier(type, location, ...modifierArgs) {
|
||||
const suite = (0, import_globals.currentlyLoadingFileSuite)();
|
||||
if (suite) {
|
||||
if (typeof modifierArgs[0] === "string" && typeof modifierArgs[1] === "function" && (type === "skip" || type === "fixme" || type === "fail")) {
|
||||
this._createTest(type, location, modifierArgs[0], modifierArgs[1]);
|
||||
return;
|
||||
}
|
||||
if (typeof modifierArgs[0] === "string" && typeof modifierArgs[1] === "object" && typeof modifierArgs[2] === "function" && (type === "skip" || type === "fixme" || type === "fail")) {
|
||||
this._createTest(type, location, modifierArgs[0], modifierArgs[1], modifierArgs[2]);
|
||||
return;
|
||||
}
|
||||
if (typeof modifierArgs[0] === "function") {
|
||||
suite._modifiers.push({ type, fn: modifierArgs[0], location, description: modifierArgs[1] });
|
||||
} else {
|
||||
if (modifierArgs.length >= 1 && !modifierArgs[0])
|
||||
return;
|
||||
const description = modifierArgs[1];
|
||||
suite._staticAnnotations.push({ type, description, location });
|
||||
}
|
||||
return;
|
||||
}
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo)
|
||||
throw new Error(`test.${type}() can only be called inside test, describe block or fixture`);
|
||||
if (typeof modifierArgs[0] === "function")
|
||||
throw new Error(`test.${type}() with a function can only be called inside describe block`);
|
||||
testInfo._modifier(type, location, modifierArgs);
|
||||
}
|
||||
_setTimeout(location, timeout) {
|
||||
const suite = (0, import_globals.currentlyLoadingFileSuite)();
|
||||
if (suite) {
|
||||
suite._timeout = timeout;
|
||||
return;
|
||||
}
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo)
|
||||
throw new Error(`test.setTimeout() can only be called from a test`);
|
||||
testInfo.setTimeout(timeout);
|
||||
}
|
||||
_use(location, fixtures) {
|
||||
const suite = this._currentSuite(location, `test.use()`);
|
||||
if (!suite)
|
||||
return;
|
||||
suite._use.push({ fixtures, location });
|
||||
}
|
||||
async _step(expectation, title, body, options = {}) {
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo)
|
||||
throw new Error(`test.step() can only be called from a test`);
|
||||
const step = testInfo._addStep({ category: "test.step", title, location: options.location, box: options.box });
|
||||
return await (0, import_utils.currentZone)().with("stepZone", step).run(async () => {
|
||||
try {
|
||||
let result = void 0;
|
||||
result = await (0, import_utils.raceAgainstDeadline)(async () => {
|
||||
try {
|
||||
return await step.info._runStepBody(expectation === "skip", body, step.location);
|
||||
} catch (e) {
|
||||
if (result?.timedOut)
|
||||
testInfo._failWithError(e);
|
||||
throw e;
|
||||
}
|
||||
}, options.timeout ? (0, import_utils.monotonicTime)() + options.timeout : 0);
|
||||
if (result.timedOut)
|
||||
throw new import_playwright_core.errors.TimeoutError(`Step timeout of ${options.timeout}ms exceeded.`);
|
||||
step.complete({});
|
||||
return result.result;
|
||||
} catch (error) {
|
||||
step.complete({ error });
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
}
|
||||
_extend(location, fixtures) {
|
||||
if (fixtures[testTypeSymbol])
|
||||
throw new Error(`test.extend() accepts fixtures object, not a test object.
|
||||
Did you mean to call mergeTests()?`);
|
||||
const fixturesWithLocation = { fixtures, location };
|
||||
return new TestTypeImpl([...this.fixtures, fixturesWithLocation]).test;
|
||||
}
|
||||
}
|
||||
function throwIfRunningInsideJest() {
|
||||
if (process.env.JEST_WORKER_ID) {
|
||||
const packageManagerCommand = (0, import_utils.getPackageManagerExecCommand)();
|
||||
throw new Error(
|
||||
`Playwright Test needs to be invoked via '${packageManagerCommand} playwright test' and excluded from Jest test runs.
|
||||
Creating one directory for Playwright tests and one for Jest is the recommended way of doing it.
|
||||
See https://playwright.dev/docs/intro for more information about Playwright Test.`
|
||||
);
|
||||
}
|
||||
}
|
||||
function validateTestDetails(details, location) {
|
||||
const originalAnnotations = Array.isArray(details.annotation) ? details.annotation : details.annotation ? [details.annotation] : [];
|
||||
const annotations = originalAnnotations.map((annotation) => ({ ...annotation, location }));
|
||||
const tags = Array.isArray(details.tag) ? details.tag : details.tag ? [details.tag] : [];
|
||||
for (const tag of tags) {
|
||||
if (tag[0] !== "@")
|
||||
throw new Error(`Tag must start with "@" symbol, got "${tag}" instead.`);
|
||||
}
|
||||
return { annotations, tags };
|
||||
}
|
||||
const rootTestType = new TestTypeImpl([]);
|
||||
function mergeTests(...tests) {
|
||||
let result = rootTestType;
|
||||
for (const t of tests) {
|
||||
const testTypeImpl = t[testTypeSymbol];
|
||||
if (!testTypeImpl)
|
||||
throw new Error(`mergeTests() accepts "test" functions as parameters.
|
||||
Did you mean to call test.extend() with fixtures instead?`);
|
||||
const newFixtures = testTypeImpl.fixtures.filter((theirs) => !result.fixtures.find((ours) => ours.fixtures === theirs.fixtures));
|
||||
result = new TestTypeImpl([...result.fixtures, ...newFixtures]);
|
||||
}
|
||||
return result.test;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TestTypeImpl,
|
||||
mergeTests,
|
||||
rootTestType
|
||||
});
|
||||
67
node_modules/playwright/lib/fsWatcher.js
generated
vendored
Normal file
67
node_modules/playwright/lib/fsWatcher.js
generated
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var fsWatcher_exports = {};
|
||||
__export(fsWatcher_exports, {
|
||||
Watcher: () => Watcher
|
||||
});
|
||||
module.exports = __toCommonJS(fsWatcher_exports);
|
||||
var import_utilsBundle = require("./utilsBundle");
|
||||
class Watcher {
|
||||
constructor(onChange) {
|
||||
this._watchedPaths = [];
|
||||
this._ignoredFolders = [];
|
||||
this._collector = [];
|
||||
this._onChange = onChange;
|
||||
}
|
||||
async update(watchedPaths, ignoredFolders, reportPending) {
|
||||
if (JSON.stringify([this._watchedPaths, this._ignoredFolders]) === JSON.stringify([watchedPaths, ignoredFolders]))
|
||||
return;
|
||||
if (reportPending)
|
||||
this._reportEventsIfAny();
|
||||
this._watchedPaths = watchedPaths;
|
||||
this._ignoredFolders = ignoredFolders;
|
||||
void this._fsWatcher?.close();
|
||||
this._fsWatcher = void 0;
|
||||
this._collector.length = 0;
|
||||
clearTimeout(this._throttleTimer);
|
||||
this._throttleTimer = void 0;
|
||||
if (!this._watchedPaths.length)
|
||||
return;
|
||||
const ignored = [...this._ignoredFolders, "**/node_modules/**"];
|
||||
this._fsWatcher = import_utilsBundle.chokidar.watch(watchedPaths, { ignoreInitial: true, ignored }).on("all", async (event, file) => {
|
||||
if (this._throttleTimer)
|
||||
clearTimeout(this._throttleTimer);
|
||||
this._collector.push({ event, file });
|
||||
this._throttleTimer = setTimeout(() => this._reportEventsIfAny(), 250);
|
||||
});
|
||||
await new Promise((resolve, reject) => this._fsWatcher.once("ready", resolve).once("error", reject));
|
||||
}
|
||||
async close() {
|
||||
await this._fsWatcher?.close();
|
||||
}
|
||||
_reportEventsIfAny() {
|
||||
if (this._collector.length)
|
||||
this._onChange(this._collector.slice());
|
||||
this._collector.length = 0;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Watcher
|
||||
});
|
||||
682
node_modules/playwright/lib/index.js
generated
vendored
Normal file
682
node_modules/playwright/lib/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,682 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var index_exports = {};
|
||||
__export(index_exports, {
|
||||
_baseTest: () => _baseTest,
|
||||
defineConfig: () => import_configLoader.defineConfig,
|
||||
expect: () => import_expect.expect,
|
||||
mergeExpects: () => import_expect2.mergeExpects,
|
||||
mergeTests: () => import_testType2.mergeTests,
|
||||
test: () => test
|
||||
});
|
||||
module.exports = __toCommonJS(index_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var playwrightLibrary = __toESM(require("playwright-core"));
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_globals = require("./common/globals");
|
||||
var import_testType = require("./common/testType");
|
||||
var import_browserBackend = require("./mcp/test/browserBackend");
|
||||
var import_expect = require("./matchers/expect");
|
||||
var import_configLoader = require("./common/configLoader");
|
||||
var import_testType2 = require("./common/testType");
|
||||
var import_expect2 = require("./matchers/expect");
|
||||
const _baseTest = import_testType.rootTestType.test;
|
||||
(0, import_utils.setBoxedStackPrefixes)([import_path.default.dirname(require.resolve("../package.json"))]);
|
||||
if (process["__pw_initiator__"]) {
|
||||
const originalStackTraceLimit = Error.stackTraceLimit;
|
||||
Error.stackTraceLimit = 200;
|
||||
try {
|
||||
throw new Error("Requiring @playwright/test second time, \nFirst:\n" + process["__pw_initiator__"] + "\n\nSecond: ");
|
||||
} finally {
|
||||
Error.stackTraceLimit = originalStackTraceLimit;
|
||||
}
|
||||
} else {
|
||||
process["__pw_initiator__"] = new Error().stack;
|
||||
}
|
||||
const playwrightFixtures = {
|
||||
defaultBrowserType: ["chromium", { scope: "worker", option: true, box: true }],
|
||||
browserName: [({ defaultBrowserType }, use) => use(defaultBrowserType), { scope: "worker", option: true, box: true }],
|
||||
playwright: [async ({}, use) => {
|
||||
await use(require("playwright-core"));
|
||||
}, { scope: "worker", box: true }],
|
||||
headless: [({ launchOptions }, use) => use(launchOptions.headless ?? true), { scope: "worker", option: true, box: true }],
|
||||
channel: [({ launchOptions }, use) => use(launchOptions.channel), { scope: "worker", option: true, box: true }],
|
||||
launchOptions: [{}, { scope: "worker", option: true, box: true }],
|
||||
connectOptions: [async ({ _optionConnectOptions }, use) => {
|
||||
await use(connectOptionsFromEnv() || _optionConnectOptions);
|
||||
}, { scope: "worker", option: true, box: true }],
|
||||
screenshot: ["off", { scope: "worker", option: true, box: true }],
|
||||
video: ["off", { scope: "worker", option: true, box: true }],
|
||||
trace: ["off", { scope: "worker", option: true, box: true }],
|
||||
_browserOptions: [async ({ playwright, headless, channel, launchOptions }, use) => {
|
||||
const options = {
|
||||
handleSIGINT: false,
|
||||
...launchOptions,
|
||||
tracesDir: tracing().tracesDir()
|
||||
};
|
||||
if (headless !== void 0)
|
||||
options.headless = headless;
|
||||
if (channel !== void 0)
|
||||
options.channel = channel;
|
||||
playwright._defaultLaunchOptions = options;
|
||||
await use(options);
|
||||
playwright._defaultLaunchOptions = void 0;
|
||||
}, { scope: "worker", auto: true, box: true }],
|
||||
browser: [async ({ playwright, browserName, _browserOptions, connectOptions }, use, testInfo) => {
|
||||
if (!["chromium", "firefox", "webkit", "_bidiChromium", "_bidiFirefox"].includes(browserName))
|
||||
throw new Error(`Unexpected browserName "${browserName}", must be one of "chromium", "firefox" or "webkit"`);
|
||||
if (connectOptions) {
|
||||
const browser2 = await playwright[browserName].connect({
|
||||
...connectOptions,
|
||||
exposeNetwork: connectOptions.exposeNetwork ?? connectOptions._exposeNetwork,
|
||||
headers: {
|
||||
// HTTP headers are ASCII only (not UTF-8).
|
||||
"x-playwright-launch-options": (0, import_utils.jsonStringifyForceASCII)(_browserOptions),
|
||||
...connectOptions.headers
|
||||
}
|
||||
});
|
||||
await use(browser2);
|
||||
await browser2.close({ reason: "Test ended." });
|
||||
return;
|
||||
}
|
||||
const browser = await playwright[browserName].launch();
|
||||
await use(browser);
|
||||
await browser.close({ reason: "Test ended." });
|
||||
}, { scope: "worker", timeout: 0 }],
|
||||
acceptDownloads: [({ contextOptions }, use) => use(contextOptions.acceptDownloads ?? true), { option: true, box: true }],
|
||||
bypassCSP: [({ contextOptions }, use) => use(contextOptions.bypassCSP ?? false), { option: true, box: true }],
|
||||
colorScheme: [({ contextOptions }, use) => use(contextOptions.colorScheme === void 0 ? "light" : contextOptions.colorScheme), { option: true, box: true }],
|
||||
deviceScaleFactor: [({ contextOptions }, use) => use(contextOptions.deviceScaleFactor), { option: true, box: true }],
|
||||
extraHTTPHeaders: [({ contextOptions }, use) => use(contextOptions.extraHTTPHeaders), { option: true, box: true }],
|
||||
geolocation: [({ contextOptions }, use) => use(contextOptions.geolocation), { option: true, box: true }],
|
||||
hasTouch: [({ contextOptions }, use) => use(contextOptions.hasTouch ?? false), { option: true, box: true }],
|
||||
httpCredentials: [({ contextOptions }, use) => use(contextOptions.httpCredentials), { option: true, box: true }],
|
||||
ignoreHTTPSErrors: [({ contextOptions }, use) => use(contextOptions.ignoreHTTPSErrors ?? false), { option: true, box: true }],
|
||||
isMobile: [({ contextOptions }, use) => use(contextOptions.isMobile ?? false), { option: true, box: true }],
|
||||
javaScriptEnabled: [({ contextOptions }, use) => use(contextOptions.javaScriptEnabled ?? true), { option: true, box: true }],
|
||||
locale: [({ contextOptions }, use) => use(contextOptions.locale ?? "en-US"), { option: true, box: true }],
|
||||
offline: [({ contextOptions }, use) => use(contextOptions.offline ?? false), { option: true, box: true }],
|
||||
permissions: [({ contextOptions }, use) => use(contextOptions.permissions), { option: true, box: true }],
|
||||
proxy: [({ contextOptions }, use) => use(contextOptions.proxy), { option: true, box: true }],
|
||||
storageState: [({ contextOptions }, use) => use(contextOptions.storageState), { option: true, box: true }],
|
||||
clientCertificates: [({ contextOptions }, use) => use(contextOptions.clientCertificates), { option: true, box: true }],
|
||||
timezoneId: [({ contextOptions }, use) => use(contextOptions.timezoneId), { option: true, box: true }],
|
||||
userAgent: [({ contextOptions }, use) => use(contextOptions.userAgent), { option: true, box: true }],
|
||||
viewport: [({ contextOptions }, use) => use(contextOptions.viewport === void 0 ? { width: 1280, height: 720 } : contextOptions.viewport), { option: true, box: true }],
|
||||
actionTimeout: [0, { option: true, box: true }],
|
||||
testIdAttribute: ["data-testid", { option: true, box: true }],
|
||||
navigationTimeout: [0, { option: true, box: true }],
|
||||
baseURL: [async ({}, use) => {
|
||||
await use(process.env.PLAYWRIGHT_TEST_BASE_URL);
|
||||
}, { option: true, box: true }],
|
||||
serviceWorkers: [({ contextOptions }, use) => use(contextOptions.serviceWorkers ?? "allow"), { option: true, box: true }],
|
||||
contextOptions: [{}, { option: true, box: true }],
|
||||
_combinedContextOptions: [async ({
|
||||
acceptDownloads,
|
||||
bypassCSP,
|
||||
clientCertificates,
|
||||
colorScheme,
|
||||
deviceScaleFactor,
|
||||
extraHTTPHeaders,
|
||||
hasTouch,
|
||||
geolocation,
|
||||
httpCredentials,
|
||||
ignoreHTTPSErrors,
|
||||
isMobile,
|
||||
javaScriptEnabled,
|
||||
locale,
|
||||
offline,
|
||||
permissions,
|
||||
proxy,
|
||||
storageState,
|
||||
viewport,
|
||||
timezoneId,
|
||||
userAgent,
|
||||
baseURL,
|
||||
contextOptions,
|
||||
serviceWorkers
|
||||
}, use) => {
|
||||
const options = {};
|
||||
if (acceptDownloads !== void 0)
|
||||
options.acceptDownloads = acceptDownloads;
|
||||
if (bypassCSP !== void 0)
|
||||
options.bypassCSP = bypassCSP;
|
||||
if (colorScheme !== void 0)
|
||||
options.colorScheme = colorScheme;
|
||||
if (deviceScaleFactor !== void 0)
|
||||
options.deviceScaleFactor = deviceScaleFactor;
|
||||
if (extraHTTPHeaders !== void 0)
|
||||
options.extraHTTPHeaders = extraHTTPHeaders;
|
||||
if (geolocation !== void 0)
|
||||
options.geolocation = geolocation;
|
||||
if (hasTouch !== void 0)
|
||||
options.hasTouch = hasTouch;
|
||||
if (httpCredentials !== void 0)
|
||||
options.httpCredentials = httpCredentials;
|
||||
if (ignoreHTTPSErrors !== void 0)
|
||||
options.ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||
if (isMobile !== void 0)
|
||||
options.isMobile = isMobile;
|
||||
if (javaScriptEnabled !== void 0)
|
||||
options.javaScriptEnabled = javaScriptEnabled;
|
||||
if (locale !== void 0)
|
||||
options.locale = locale;
|
||||
if (offline !== void 0)
|
||||
options.offline = offline;
|
||||
if (permissions !== void 0)
|
||||
options.permissions = permissions;
|
||||
if (proxy !== void 0)
|
||||
options.proxy = proxy;
|
||||
if (storageState !== void 0)
|
||||
options.storageState = storageState;
|
||||
if (clientCertificates?.length)
|
||||
options.clientCertificates = resolveClientCerticates(clientCertificates);
|
||||
if (timezoneId !== void 0)
|
||||
options.timezoneId = timezoneId;
|
||||
if (userAgent !== void 0)
|
||||
options.userAgent = userAgent;
|
||||
if (viewport !== void 0)
|
||||
options.viewport = viewport;
|
||||
if (baseURL !== void 0)
|
||||
options.baseURL = baseURL;
|
||||
if (serviceWorkers !== void 0)
|
||||
options.serviceWorkers = serviceWorkers;
|
||||
await use({
|
||||
...contextOptions,
|
||||
...options
|
||||
});
|
||||
}, { box: true }],
|
||||
_setupContextOptions: [async ({ playwright, _combinedContextOptions, actionTimeout, navigationTimeout, testIdAttribute }, use, testInfo) => {
|
||||
if (testIdAttribute)
|
||||
playwrightLibrary.selectors.setTestIdAttribute(testIdAttribute);
|
||||
testInfo.snapshotSuffix = process.platform;
|
||||
if ((0, import_utils.debugMode)() === "inspector")
|
||||
testInfo._setDebugMode();
|
||||
playwright._defaultContextOptions = _combinedContextOptions;
|
||||
playwright._defaultContextTimeout = testInfo._pauseOnError() ? 5e3 : actionTimeout || 0;
|
||||
playwright._defaultContextNavigationTimeout = navigationTimeout || 0;
|
||||
await use();
|
||||
playwright._defaultContextOptions = void 0;
|
||||
playwright._defaultContextTimeout = void 0;
|
||||
playwright._defaultContextNavigationTimeout = void 0;
|
||||
}, { auto: "all-hooks-included", title: "context configuration", box: true }],
|
||||
_setupArtifacts: [async ({ playwright, screenshot }, use, testInfo) => {
|
||||
testInfo.setTimeout(testInfo.project.timeout);
|
||||
const artifactsRecorder = new ArtifactsRecorder(playwright, tracing().artifactsDir(), screenshot);
|
||||
await artifactsRecorder.willStartTest(testInfo);
|
||||
const tracingGroupSteps = [];
|
||||
const csiListener = {
|
||||
onApiCallBegin: (data, channel) => {
|
||||
const testInfo2 = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo2 || data.apiName.includes("setTestIdAttribute") || data.apiName === "tracing.groupEnd")
|
||||
return;
|
||||
const zone = (0, import_utils.currentZone)().data("stepZone");
|
||||
const isExpectCall = data.apiName === "locator._expect" || data.apiName === "frame._expect" || data.apiName === "page._expectScreenshot";
|
||||
if (zone && zone.category === "expect" && isExpectCall) {
|
||||
if (zone.apiName)
|
||||
data.apiName = zone.apiName;
|
||||
if (zone.title)
|
||||
data.title = zone.title;
|
||||
data.stepId = zone.stepId;
|
||||
return;
|
||||
}
|
||||
const step = testInfo2._addStep({
|
||||
location: data.frames[0],
|
||||
category: "pw:api",
|
||||
title: renderTitle(channel.type, channel.method, channel.params, data.title),
|
||||
apiName: data.apiName,
|
||||
params: channel.params,
|
||||
group: (0, import_utils.getActionGroup)({ type: channel.type, method: channel.method })
|
||||
}, tracingGroupSteps[tracingGroupSteps.length - 1]);
|
||||
data.userData = step;
|
||||
data.stepId = step.stepId;
|
||||
if (data.apiName === "tracing.group")
|
||||
tracingGroupSteps.push(step);
|
||||
},
|
||||
onApiCallEnd: (data) => {
|
||||
if (data.apiName === "tracing.group")
|
||||
return;
|
||||
if (data.apiName === "tracing.groupEnd") {
|
||||
const step2 = tracingGroupSteps.pop();
|
||||
step2?.complete({ error: data.error });
|
||||
return;
|
||||
}
|
||||
const step = data.userData;
|
||||
step?.complete({ error: data.error });
|
||||
},
|
||||
onWillPause: ({ keepTestTimeout }) => {
|
||||
if (!keepTestTimeout)
|
||||
(0, import_globals.currentTestInfo)()?._setDebugMode();
|
||||
},
|
||||
runAfterCreateBrowserContext: async (context) => {
|
||||
await artifactsRecorder?.didCreateBrowserContext(context);
|
||||
const testInfo2 = (0, import_globals.currentTestInfo)();
|
||||
if (testInfo2)
|
||||
attachConnectedHeaderIfNeeded(testInfo2, context.browser());
|
||||
},
|
||||
runAfterCreateRequestContext: async (context) => {
|
||||
await artifactsRecorder?.didCreateRequestContext(context);
|
||||
},
|
||||
runBeforeCloseBrowserContext: async (context) => {
|
||||
await artifactsRecorder?.willCloseBrowserContext(context);
|
||||
},
|
||||
runBeforeCloseRequestContext: async (context) => {
|
||||
await artifactsRecorder?.willCloseRequestContext(context);
|
||||
}
|
||||
};
|
||||
const clientInstrumentation = playwright._instrumentation;
|
||||
clientInstrumentation.addListener(csiListener);
|
||||
await use();
|
||||
clientInstrumentation.removeListener(csiListener);
|
||||
await artifactsRecorder.didFinishTest();
|
||||
}, { auto: "all-hooks-included", title: "trace recording", box: true, timeout: 0 }],
|
||||
_contextFactory: [async ({
|
||||
browser,
|
||||
video,
|
||||
_reuseContext,
|
||||
_combinedContextOptions
|
||||
/** mitigate dep-via-auto lack of traceability */
|
||||
}, use, testInfo) => {
|
||||
const testInfoImpl = testInfo;
|
||||
const videoMode = normalizeVideoMode(video);
|
||||
const captureVideo = shouldCaptureVideo(videoMode, testInfo) && !_reuseContext;
|
||||
const contexts = /* @__PURE__ */ new Map();
|
||||
let counter = 0;
|
||||
await use(async (options) => {
|
||||
const hook = testInfoImpl._currentHookType();
|
||||
if (hook === "beforeAll" || hook === "afterAll") {
|
||||
throw new Error([
|
||||
`"context" and "page" fixtures are not supported in "${hook}" since they are created on a per-test basis.`,
|
||||
`If you would like to reuse a single page between tests, create context manually with browser.newContext(). See https://aka.ms/playwright/reuse-page for details.`,
|
||||
`If you would like to configure your page before each test, do that in beforeEach hook instead.`
|
||||
].join("\n"));
|
||||
}
|
||||
const videoOptions = captureVideo ? {
|
||||
recordVideo: {
|
||||
dir: tracing().artifactsDir(),
|
||||
size: typeof video === "string" ? void 0 : video.size
|
||||
}
|
||||
} : {};
|
||||
const context = await browser.newContext({ ...videoOptions, ...options });
|
||||
if (process.env.PW_CLOCK === "frozen") {
|
||||
await context._wrapApiCall(async () => {
|
||||
await context.clock.install({ time: 0 });
|
||||
await context.clock.pauseAt(1e3);
|
||||
}, { internal: true });
|
||||
} else if (process.env.PW_CLOCK === "realtime") {
|
||||
await context._wrapApiCall(async () => {
|
||||
await context.clock.install({ time: 0 });
|
||||
}, { internal: true });
|
||||
}
|
||||
let closed = false;
|
||||
const close = async () => {
|
||||
if (closed)
|
||||
return;
|
||||
closed = true;
|
||||
const closeReason = testInfo.status === "timedOut" ? "Test timeout of " + testInfo.timeout + "ms exceeded." : "Test ended.";
|
||||
await context.close({ reason: closeReason });
|
||||
const testFailed = testInfo.status !== testInfo.expectedStatus;
|
||||
const preserveVideo = captureVideo && (videoMode === "on" || testFailed && videoMode === "retain-on-failure" || videoMode === "on-first-retry" && testInfo.retry === 1);
|
||||
if (preserveVideo) {
|
||||
const { pagesWithVideo: pagesForVideo } = contexts.get(context);
|
||||
const videos = pagesForVideo.map((p) => p.video()).filter((video2) => !!video2);
|
||||
await Promise.all(videos.map(async (v) => {
|
||||
try {
|
||||
const savedPath = testInfo.outputPath(`video${counter ? "-" + counter : ""}.webm`);
|
||||
++counter;
|
||||
await v.saveAs(savedPath);
|
||||
testInfo.attachments.push({ name: "video", path: savedPath, contentType: "video/webm" });
|
||||
} catch (e) {
|
||||
}
|
||||
}));
|
||||
}
|
||||
};
|
||||
const contextData = { close, pagesWithVideo: [] };
|
||||
if (captureVideo)
|
||||
context.on("page", (page) => contextData.pagesWithVideo.push(page));
|
||||
contexts.set(context, contextData);
|
||||
return { context, close };
|
||||
});
|
||||
await Promise.all([...contexts.values()].map((data) => data.close()));
|
||||
}, { scope: "test", title: "context", box: true }],
|
||||
_optionContextReuseMode: ["none", { scope: "worker", option: true, box: true }],
|
||||
_optionConnectOptions: [void 0, { scope: "worker", option: true, box: true }],
|
||||
_reuseContext: [async ({ video, _optionContextReuseMode }, use) => {
|
||||
let mode = _optionContextReuseMode;
|
||||
if (process.env.PW_TEST_REUSE_CONTEXT)
|
||||
mode = "when-possible";
|
||||
const reuse = mode === "when-possible" && normalizeVideoMode(video) === "off";
|
||||
await use(reuse);
|
||||
}, { scope: "worker", title: "context", box: true }],
|
||||
context: async ({ browser, _reuseContext, _contextFactory }, use, testInfo) => {
|
||||
const browserImpl = browser;
|
||||
attachConnectedHeaderIfNeeded(testInfo, browserImpl);
|
||||
if (!_reuseContext) {
|
||||
const { context: context2, close } = await _contextFactory();
|
||||
testInfo._onDidFinishTestFunctions.unshift(() => (0, import_browserBackend.runBrowserBackendAtEnd)(context2, testInfo.errors[0]?.message));
|
||||
await use(context2);
|
||||
await close();
|
||||
return;
|
||||
}
|
||||
const context = await browserImpl._wrapApiCall(() => browserImpl._newContextForReuse(), { internal: true });
|
||||
testInfo._onDidFinishTestFunctions.unshift(() => (0, import_browserBackend.runBrowserBackendAtEnd)(context, testInfo.errors[0]?.message));
|
||||
await use(context);
|
||||
const closeReason = testInfo.status === "timedOut" ? "Test timeout of " + testInfo.timeout + "ms exceeded." : "Test ended.";
|
||||
await browserImpl._wrapApiCall(() => browserImpl._disconnectFromReusedContext(closeReason), { internal: true });
|
||||
},
|
||||
page: async ({ context, _reuseContext }, use) => {
|
||||
if (!_reuseContext) {
|
||||
await use(await context.newPage());
|
||||
return;
|
||||
}
|
||||
let [page] = context.pages();
|
||||
if (!page)
|
||||
page = await context.newPage();
|
||||
await use(page);
|
||||
},
|
||||
request: async ({ playwright }, use) => {
|
||||
const request = await playwright.request.newContext();
|
||||
await use(request);
|
||||
const hook = test.info()._currentHookType();
|
||||
if (hook === "beforeAll") {
|
||||
await request.dispose({ reason: [
|
||||
`Fixture { request } from beforeAll cannot be reused in a test.`,
|
||||
` - Recommended fix: use a separate { request } in the test.`,
|
||||
` - Alternatively, manually create APIRequestContext in beforeAll and dispose it in afterAll.`,
|
||||
`See https://playwright.dev/docs/api-testing#sending-api-requests-from-ui-tests for more details.`
|
||||
].join("\n") });
|
||||
} else {
|
||||
await request.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
function normalizeVideoMode(video) {
|
||||
if (!video)
|
||||
return "off";
|
||||
let videoMode = typeof video === "string" ? video : video.mode;
|
||||
if (videoMode === "retry-with-video")
|
||||
videoMode = "on-first-retry";
|
||||
return videoMode;
|
||||
}
|
||||
function shouldCaptureVideo(videoMode, testInfo) {
|
||||
return videoMode === "on" || videoMode === "retain-on-failure" || videoMode === "on-first-retry" && testInfo.retry === 1;
|
||||
}
|
||||
function normalizeScreenshotMode(screenshot) {
|
||||
if (!screenshot)
|
||||
return "off";
|
||||
return typeof screenshot === "string" ? screenshot : screenshot.mode;
|
||||
}
|
||||
function attachConnectedHeaderIfNeeded(testInfo, browser) {
|
||||
const connectHeaders = browser?._connection.headers;
|
||||
if (!connectHeaders)
|
||||
return;
|
||||
for (const header of connectHeaders) {
|
||||
if (header.name !== "x-playwright-attachment")
|
||||
continue;
|
||||
const [name, value] = header.value.split("=");
|
||||
if (!name || !value)
|
||||
continue;
|
||||
if (testInfo.attachments.some((attachment) => attachment.name === name))
|
||||
continue;
|
||||
testInfo.attachments.push({ name, contentType: "text/plain", body: Buffer.from(value) });
|
||||
}
|
||||
}
|
||||
function resolveFileToConfig(file) {
|
||||
const config = test.info().config.configFile;
|
||||
if (!config || !file)
|
||||
return file;
|
||||
if (import_path.default.isAbsolute(file))
|
||||
return file;
|
||||
return import_path.default.resolve(import_path.default.dirname(config), file);
|
||||
}
|
||||
function resolveClientCerticates(clientCertificates) {
|
||||
for (const cert of clientCertificates) {
|
||||
cert.certPath = resolveFileToConfig(cert.certPath);
|
||||
cert.keyPath = resolveFileToConfig(cert.keyPath);
|
||||
cert.pfxPath = resolveFileToConfig(cert.pfxPath);
|
||||
}
|
||||
return clientCertificates;
|
||||
}
|
||||
const kTracingStarted = Symbol("kTracingStarted");
|
||||
function connectOptionsFromEnv() {
|
||||
const wsEndpoint = process.env.PW_TEST_CONNECT_WS_ENDPOINT;
|
||||
if (!wsEndpoint)
|
||||
return void 0;
|
||||
const headers = process.env.PW_TEST_CONNECT_HEADERS ? JSON.parse(process.env.PW_TEST_CONNECT_HEADERS) : void 0;
|
||||
return {
|
||||
wsEndpoint,
|
||||
headers,
|
||||
exposeNetwork: process.env.PW_TEST_CONNECT_EXPOSE_NETWORK
|
||||
};
|
||||
}
|
||||
class SnapshotRecorder {
|
||||
constructor(_artifactsRecorder, _mode, _name, _contentType, _extension, _doSnapshot) {
|
||||
this._artifactsRecorder = _artifactsRecorder;
|
||||
this._mode = _mode;
|
||||
this._name = _name;
|
||||
this._contentType = _contentType;
|
||||
this._extension = _extension;
|
||||
this._doSnapshot = _doSnapshot;
|
||||
this._ordinal = 0;
|
||||
this._temporary = [];
|
||||
}
|
||||
fixOrdinal() {
|
||||
this._ordinal = this.testInfo.attachments.filter((a) => a.name === this._name).length;
|
||||
}
|
||||
shouldCaptureUponFinish() {
|
||||
return this._mode === "on" || this._mode === "only-on-failure" && this.testInfo._isFailure() || this._mode === "on-first-failure" && this.testInfo._isFailure() && this.testInfo.retry === 0;
|
||||
}
|
||||
async maybeCapture() {
|
||||
if (!this.shouldCaptureUponFinish())
|
||||
return;
|
||||
await Promise.all(this._artifactsRecorder._playwright._allPages().map((page) => this._snapshotPage(page, false)));
|
||||
}
|
||||
async persistTemporary() {
|
||||
if (this.shouldCaptureUponFinish()) {
|
||||
await Promise.all(this._temporary.map(async (file) => {
|
||||
try {
|
||||
const path2 = this._createAttachmentPath();
|
||||
await import_fs.default.promises.rename(file, path2);
|
||||
this._attach(path2);
|
||||
} catch {
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
async captureTemporary(context) {
|
||||
if (this._mode === "on" || this._mode === "only-on-failure" || this._mode === "on-first-failure" && this.testInfo.retry === 0)
|
||||
await Promise.all(context.pages().map((page) => this._snapshotPage(page, true)));
|
||||
}
|
||||
_attach(screenshotPath) {
|
||||
this.testInfo.attachments.push({ name: this._name, path: screenshotPath, contentType: this._contentType });
|
||||
}
|
||||
_createAttachmentPath() {
|
||||
const testFailed = this.testInfo._isFailure();
|
||||
const index = this._ordinal + 1;
|
||||
++this._ordinal;
|
||||
const path2 = this.testInfo.outputPath(`test-${testFailed ? "failed" : "finished"}-${index}${this._extension}`);
|
||||
return path2;
|
||||
}
|
||||
_createTemporaryArtifact(...name) {
|
||||
const file = import_path.default.join(this._artifactsRecorder._artifactsDir, ...name);
|
||||
return file;
|
||||
}
|
||||
async _snapshotPage(page, temporary) {
|
||||
if (page[this.testInfo._uniqueSymbol])
|
||||
return;
|
||||
page[this.testInfo._uniqueSymbol] = true;
|
||||
try {
|
||||
const path2 = temporary ? this._createTemporaryArtifact((0, import_utils.createGuid)() + this._extension) : this._createAttachmentPath();
|
||||
await this._doSnapshot(page, path2);
|
||||
if (temporary)
|
||||
this._temporary.push(path2);
|
||||
else
|
||||
this._attach(path2);
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
get testInfo() {
|
||||
return this._artifactsRecorder._testInfo;
|
||||
}
|
||||
}
|
||||
class ArtifactsRecorder {
|
||||
constructor(playwright, artifactsDir, screenshot) {
|
||||
this._playwright = playwright;
|
||||
this._artifactsDir = artifactsDir;
|
||||
const screenshotOptions = typeof screenshot === "string" ? void 0 : screenshot;
|
||||
this._startedCollectingArtifacts = Symbol("startedCollectingArtifacts");
|
||||
this._screenshotRecorder = new SnapshotRecorder(this, normalizeScreenshotMode(screenshot), "screenshot", "image/png", ".png", async (page, path2) => {
|
||||
await page._wrapApiCall(async () => {
|
||||
await page.screenshot({ ...screenshotOptions, timeout: 5e3, path: path2, caret: "initial" });
|
||||
}, { internal: true });
|
||||
});
|
||||
}
|
||||
async willStartTest(testInfo) {
|
||||
this._testInfo = testInfo;
|
||||
testInfo._onDidFinishTestFunctions.push(() => this.didFinishTestFunction());
|
||||
this._screenshotRecorder.fixOrdinal();
|
||||
await Promise.all(this._playwright._allContexts().map((context) => this.didCreateBrowserContext(context)));
|
||||
const existingApiRequests = Array.from(this._playwright.request._contexts);
|
||||
await Promise.all(existingApiRequests.map((c) => this.didCreateRequestContext(c)));
|
||||
}
|
||||
async didCreateBrowserContext(context) {
|
||||
await this._startTraceChunkOnContextCreation(context, context.tracing);
|
||||
}
|
||||
async willCloseBrowserContext(context) {
|
||||
await this._stopTracing(context, context.tracing);
|
||||
await this._screenshotRecorder.captureTemporary(context);
|
||||
await this._takePageSnapshot(context);
|
||||
}
|
||||
async _takePageSnapshot(context) {
|
||||
if (process.env.PLAYWRIGHT_NO_COPY_PROMPT)
|
||||
return;
|
||||
if (this._testInfo.errors.length === 0)
|
||||
return;
|
||||
if (this._pageSnapshot)
|
||||
return;
|
||||
const page = context.pages()[0];
|
||||
if (!page)
|
||||
return;
|
||||
try {
|
||||
await page._wrapApiCall(async () => {
|
||||
this._pageSnapshot = await page._snapshotForAI({ timeout: 5e3 });
|
||||
}, { internal: true });
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
async didCreateRequestContext(context) {
|
||||
await this._startTraceChunkOnContextCreation(context, context._tracing);
|
||||
}
|
||||
async willCloseRequestContext(context) {
|
||||
await this._stopTracing(context, context._tracing);
|
||||
}
|
||||
async didFinishTestFunction() {
|
||||
await this._screenshotRecorder.maybeCapture();
|
||||
}
|
||||
async didFinishTest() {
|
||||
await this.didFinishTestFunction();
|
||||
const leftoverContexts = this._playwright._allContexts();
|
||||
const leftoverApiRequests = Array.from(this._playwright.request._contexts);
|
||||
await Promise.all(leftoverContexts.map(async (context2) => {
|
||||
await this._stopTracing(context2, context2.tracing);
|
||||
}).concat(leftoverApiRequests.map(async (context2) => {
|
||||
await this._stopTracing(context2, context2._tracing);
|
||||
})));
|
||||
await this._screenshotRecorder.persistTemporary();
|
||||
const context = leftoverContexts[0];
|
||||
if (context)
|
||||
await this._takePageSnapshot(context);
|
||||
if (this._pageSnapshot && this._testInfo.errors.length > 0 && !this._testInfo.attachments.some((a) => a.name === "error-context")) {
|
||||
const lines = [
|
||||
"# Page snapshot",
|
||||
"",
|
||||
"```yaml",
|
||||
this._pageSnapshot,
|
||||
"```"
|
||||
];
|
||||
const filePath = this._testInfo.outputPath("error-context.md");
|
||||
await import_fs.default.promises.writeFile(filePath, lines.join("\n"), "utf8");
|
||||
this._testInfo._attach({
|
||||
name: "error-context",
|
||||
contentType: "text/markdown",
|
||||
path: filePath
|
||||
}, void 0);
|
||||
}
|
||||
}
|
||||
async _startTraceChunkOnContextCreation(channelOwner, tracing2) {
|
||||
await channelOwner._wrapApiCall(async () => {
|
||||
const options = this._testInfo._tracing.traceOptions();
|
||||
if (options) {
|
||||
const title = this._testInfo._tracing.traceTitle();
|
||||
const name = this._testInfo._tracing.generateNextTraceRecordingName();
|
||||
if (!tracing2[kTracingStarted]) {
|
||||
await tracing2.start({ ...options, title, name });
|
||||
tracing2[kTracingStarted] = true;
|
||||
} else {
|
||||
await tracing2.startChunk({ title, name });
|
||||
}
|
||||
} else {
|
||||
if (tracing2[kTracingStarted]) {
|
||||
tracing2[kTracingStarted] = false;
|
||||
await tracing2.stop();
|
||||
}
|
||||
}
|
||||
}, { internal: true });
|
||||
}
|
||||
async _stopTracing(channelOwner, tracing2) {
|
||||
await channelOwner._wrapApiCall(async () => {
|
||||
if (tracing2[this._startedCollectingArtifacts])
|
||||
return;
|
||||
tracing2[this._startedCollectingArtifacts] = true;
|
||||
if (this._testInfo._tracing.traceOptions() && tracing2[kTracingStarted])
|
||||
await tracing2.stopChunk({ path: this._testInfo._tracing.maybeGenerateNextTraceRecordingPath() });
|
||||
}, { internal: true });
|
||||
}
|
||||
}
|
||||
function renderTitle(type, method, params, title) {
|
||||
const prefix = (0, import_utils.renderTitleForCall)({ title, type, method, params });
|
||||
let selector;
|
||||
if (params?.["selector"] && typeof params.selector === "string")
|
||||
selector = (0, import_utils.asLocatorDescription)("javascript", params.selector);
|
||||
return prefix + (selector ? ` ${selector}` : "");
|
||||
}
|
||||
function tracing() {
|
||||
return test.info()._tracing;
|
||||
}
|
||||
const test = _baseTest.extend(playwrightFixtures);
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
_baseTest,
|
||||
defineConfig,
|
||||
expect,
|
||||
mergeExpects,
|
||||
mergeTests,
|
||||
test
|
||||
});
|
||||
42
node_modules/playwright/lib/internalsForTest.js
generated
vendored
Normal file
42
node_modules/playwright/lib/internalsForTest.js
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var internalsForTest_exports = {};
|
||||
__export(internalsForTest_exports, {
|
||||
fileDependencies: () => fileDependencies
|
||||
});
|
||||
module.exports = __toCommonJS(internalsForTest_exports);
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_compilationCache = require("./transform/compilationCache");
|
||||
function fileDependencies() {
|
||||
return Object.fromEntries([...(0, import_compilationCache.fileDependenciesForTest)().entries()].map((entry) => [import_path.default.basename(entry[0]), [...entry[1]].map((f) => import_path.default.basename(f)).sort()]));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
fileDependencies
|
||||
});
|
||||
77
node_modules/playwright/lib/isomorphic/events.js
generated
vendored
Normal file
77
node_modules/playwright/lib/isomorphic/events.js
generated
vendored
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var events_exports = {};
|
||||
__export(events_exports, {
|
||||
Disposable: () => Disposable,
|
||||
EventEmitter: () => EventEmitter
|
||||
});
|
||||
module.exports = __toCommonJS(events_exports);
|
||||
var Disposable;
|
||||
((Disposable2) => {
|
||||
function disposeAll(disposables) {
|
||||
for (const disposable of disposables.splice(0))
|
||||
disposable.dispose();
|
||||
}
|
||||
Disposable2.disposeAll = disposeAll;
|
||||
})(Disposable || (Disposable = {}));
|
||||
class EventEmitter {
|
||||
constructor() {
|
||||
this._listeners = /* @__PURE__ */ new Set();
|
||||
this.event = (listener, disposables) => {
|
||||
this._listeners.add(listener);
|
||||
let disposed = false;
|
||||
const self = this;
|
||||
const result = {
|
||||
dispose() {
|
||||
if (!disposed) {
|
||||
disposed = true;
|
||||
self._listeners.delete(listener);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (disposables)
|
||||
disposables.push(result);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
fire(event) {
|
||||
const dispatch = !this._deliveryQueue;
|
||||
if (!this._deliveryQueue)
|
||||
this._deliveryQueue = [];
|
||||
for (const listener of this._listeners)
|
||||
this._deliveryQueue.push({ listener, event });
|
||||
if (!dispatch)
|
||||
return;
|
||||
for (let index = 0; index < this._deliveryQueue.length; index++) {
|
||||
const { listener, event: event2 } = this._deliveryQueue[index];
|
||||
listener.call(null, event2);
|
||||
}
|
||||
this._deliveryQueue = void 0;
|
||||
}
|
||||
dispose() {
|
||||
this._listeners.clear();
|
||||
if (this._deliveryQueue)
|
||||
this._deliveryQueue = [];
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Disposable,
|
||||
EventEmitter
|
||||
});
|
||||
30
node_modules/playwright/lib/isomorphic/folders.js
generated
vendored
Normal file
30
node_modules/playwright/lib/isomorphic/folders.js
generated
vendored
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var folders_exports = {};
|
||||
__export(folders_exports, {
|
||||
artifactsFolderName: () => artifactsFolderName
|
||||
});
|
||||
module.exports = __toCommonJS(folders_exports);
|
||||
function artifactsFolderName(workerIndex) {
|
||||
return `.playwright-artifacts-${workerIndex}`;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
artifactsFolderName
|
||||
});
|
||||
69
node_modules/playwright/lib/isomorphic/stringInternPool.js
generated
vendored
Normal file
69
node_modules/playwright/lib/isomorphic/stringInternPool.js
generated
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var stringInternPool_exports = {};
|
||||
__export(stringInternPool_exports, {
|
||||
JsonStringInternalizer: () => JsonStringInternalizer,
|
||||
StringInternPool: () => StringInternPool
|
||||
});
|
||||
module.exports = __toCommonJS(stringInternPool_exports);
|
||||
class StringInternPool {
|
||||
constructor() {
|
||||
this._stringCache = /* @__PURE__ */ new Map();
|
||||
}
|
||||
internString(s) {
|
||||
let result = this._stringCache.get(s);
|
||||
if (!result) {
|
||||
this._stringCache.set(s, s);
|
||||
result = s;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
class JsonStringInternalizer {
|
||||
constructor(pool) {
|
||||
this._pool = pool;
|
||||
}
|
||||
traverse(value) {
|
||||
if (typeof value !== "object")
|
||||
return;
|
||||
if (Array.isArray(value)) {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (typeof value[i] === "string")
|
||||
value[i] = this.intern(value[i]);
|
||||
else
|
||||
this.traverse(value[i]);
|
||||
}
|
||||
} else {
|
||||
for (const name in value) {
|
||||
if (typeof value[name] === "string")
|
||||
value[name] = this.intern(value[name]);
|
||||
else
|
||||
this.traverse(value[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
intern(value) {
|
||||
return this._pool.internString(value);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
JsonStringInternalizer,
|
||||
StringInternPool
|
||||
});
|
||||
507
node_modules/playwright/lib/isomorphic/teleReceiver.js
generated
vendored
Normal file
507
node_modules/playwright/lib/isomorphic/teleReceiver.js
generated
vendored
Normal file
|
|
@ -0,0 +1,507 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var teleReceiver_exports = {};
|
||||
__export(teleReceiver_exports, {
|
||||
TeleReporterReceiver: () => TeleReporterReceiver,
|
||||
TeleSuite: () => TeleSuite,
|
||||
TeleTestCase: () => TeleTestCase,
|
||||
TeleTestResult: () => TeleTestResult,
|
||||
baseFullConfig: () => baseFullConfig,
|
||||
computeTestCaseOutcome: () => computeTestCaseOutcome,
|
||||
parseRegexPatterns: () => parseRegexPatterns,
|
||||
serializeRegexPatterns: () => serializeRegexPatterns
|
||||
});
|
||||
module.exports = __toCommonJS(teleReceiver_exports);
|
||||
class TeleReporterReceiver {
|
||||
constructor(reporter, options = {}) {
|
||||
this.isListing = false;
|
||||
this._tests = /* @__PURE__ */ new Map();
|
||||
this._rootSuite = new TeleSuite("", "root");
|
||||
this._options = options;
|
||||
this._reporter = reporter;
|
||||
}
|
||||
reset() {
|
||||
this._rootSuite._entries = [];
|
||||
this._tests.clear();
|
||||
}
|
||||
dispatch(message) {
|
||||
const { method, params } = message;
|
||||
if (method === "onConfigure") {
|
||||
this._onConfigure(params.config);
|
||||
return;
|
||||
}
|
||||
if (method === "onProject") {
|
||||
this._onProject(params.project);
|
||||
return;
|
||||
}
|
||||
if (method === "onBegin") {
|
||||
this._onBegin();
|
||||
return;
|
||||
}
|
||||
if (method === "onTestBegin") {
|
||||
this._onTestBegin(params.testId, params.result);
|
||||
return;
|
||||
}
|
||||
if (method === "onTestEnd") {
|
||||
this._onTestEnd(params.test, params.result);
|
||||
return;
|
||||
}
|
||||
if (method === "onStepBegin") {
|
||||
this._onStepBegin(params.testId, params.resultId, params.step);
|
||||
return;
|
||||
}
|
||||
if (method === "onAttach") {
|
||||
this._onAttach(params.testId, params.resultId, params.attachments);
|
||||
return;
|
||||
}
|
||||
if (method === "onStepEnd") {
|
||||
this._onStepEnd(params.testId, params.resultId, params.step);
|
||||
return;
|
||||
}
|
||||
if (method === "onError") {
|
||||
this._onError(params.error);
|
||||
return;
|
||||
}
|
||||
if (method === "onStdIO") {
|
||||
this._onStdIO(params.type, params.testId, params.resultId, params.data, params.isBase64);
|
||||
return;
|
||||
}
|
||||
if (method === "onEnd")
|
||||
return this._onEnd(params.result);
|
||||
if (method === "onExit")
|
||||
return this._onExit();
|
||||
}
|
||||
_onConfigure(config) {
|
||||
this._rootDir = config.rootDir;
|
||||
this._config = this._parseConfig(config);
|
||||
this._reporter.onConfigure?.(this._config);
|
||||
}
|
||||
_onProject(project) {
|
||||
let projectSuite = this._options.mergeProjects ? this._rootSuite.suites.find((suite) => suite.project().name === project.name) : void 0;
|
||||
if (!projectSuite) {
|
||||
projectSuite = new TeleSuite(project.name, "project");
|
||||
this._rootSuite._addSuite(projectSuite);
|
||||
}
|
||||
projectSuite._project = this._parseProject(project);
|
||||
for (const suite of project.suites)
|
||||
this._mergeSuiteInto(suite, projectSuite);
|
||||
}
|
||||
_onBegin() {
|
||||
this._reporter.onBegin?.(this._rootSuite);
|
||||
}
|
||||
_onTestBegin(testId, payload) {
|
||||
const test = this._tests.get(testId);
|
||||
if (this._options.clearPreviousResultsWhenTestBegins)
|
||||
test.results = [];
|
||||
const testResult = test._createTestResult(payload.id);
|
||||
testResult.retry = payload.retry;
|
||||
testResult.workerIndex = payload.workerIndex;
|
||||
testResult.parallelIndex = payload.parallelIndex;
|
||||
testResult.setStartTimeNumber(payload.startTime);
|
||||
this._reporter.onTestBegin?.(test, testResult);
|
||||
}
|
||||
_onTestEnd(testEndPayload, payload) {
|
||||
const test = this._tests.get(testEndPayload.testId);
|
||||
test.timeout = testEndPayload.timeout;
|
||||
test.expectedStatus = testEndPayload.expectedStatus;
|
||||
const result = test.results.find((r) => r._id === payload.id);
|
||||
result.duration = payload.duration;
|
||||
result.status = payload.status;
|
||||
result.errors = payload.errors;
|
||||
result.error = result.errors?.[0];
|
||||
if (!!payload.attachments)
|
||||
result.attachments = this._parseAttachments(payload.attachments);
|
||||
if (payload.annotations) {
|
||||
this._absoluteAnnotationLocationsInplace(payload.annotations);
|
||||
result.annotations = payload.annotations;
|
||||
test.annotations = payload.annotations;
|
||||
}
|
||||
this._reporter.onTestEnd?.(test, result);
|
||||
result._stepMap = /* @__PURE__ */ new Map();
|
||||
}
|
||||
_onStepBegin(testId, resultId, payload) {
|
||||
const test = this._tests.get(testId);
|
||||
const result = test.results.find((r) => r._id === resultId);
|
||||
const parentStep = payload.parentStepId ? result._stepMap.get(payload.parentStepId) : void 0;
|
||||
const location = this._absoluteLocation(payload.location);
|
||||
const step = new TeleTestStep(payload, parentStep, location, result);
|
||||
if (parentStep)
|
||||
parentStep.steps.push(step);
|
||||
else
|
||||
result.steps.push(step);
|
||||
result._stepMap.set(payload.id, step);
|
||||
this._reporter.onStepBegin?.(test, result, step);
|
||||
}
|
||||
_onStepEnd(testId, resultId, payload) {
|
||||
const test = this._tests.get(testId);
|
||||
const result = test.results.find((r) => r._id === resultId);
|
||||
const step = result._stepMap.get(payload.id);
|
||||
step._endPayload = payload;
|
||||
step.duration = payload.duration;
|
||||
step.error = payload.error;
|
||||
this._reporter.onStepEnd?.(test, result, step);
|
||||
}
|
||||
_onAttach(testId, resultId, attachments) {
|
||||
const test = this._tests.get(testId);
|
||||
const result = test.results.find((r) => r._id === resultId);
|
||||
result.attachments.push(...attachments.map((a) => ({
|
||||
name: a.name,
|
||||
contentType: a.contentType,
|
||||
path: a.path,
|
||||
body: a.base64 && globalThis.Buffer ? Buffer.from(a.base64, "base64") : void 0
|
||||
})));
|
||||
}
|
||||
_onError(error) {
|
||||
this._reporter.onError?.(error);
|
||||
}
|
||||
_onStdIO(type, testId, resultId, data, isBase64) {
|
||||
const chunk = isBase64 ? globalThis.Buffer ? Buffer.from(data, "base64") : atob(data) : data;
|
||||
const test = testId ? this._tests.get(testId) : void 0;
|
||||
const result = test && resultId ? test.results.find((r) => r._id === resultId) : void 0;
|
||||
if (type === "stdout") {
|
||||
result?.stdout.push(chunk);
|
||||
this._reporter.onStdOut?.(chunk, test, result);
|
||||
} else {
|
||||
result?.stderr.push(chunk);
|
||||
this._reporter.onStdErr?.(chunk, test, result);
|
||||
}
|
||||
}
|
||||
async _onEnd(result) {
|
||||
await this._reporter.onEnd?.({
|
||||
status: result.status,
|
||||
startTime: new Date(result.startTime),
|
||||
duration: result.duration
|
||||
});
|
||||
}
|
||||
_onExit() {
|
||||
return this._reporter.onExit?.();
|
||||
}
|
||||
_parseConfig(config) {
|
||||
const result = { ...baseFullConfig, ...config };
|
||||
if (this._options.configOverrides) {
|
||||
result.configFile = this._options.configOverrides.configFile;
|
||||
result.reportSlowTests = this._options.configOverrides.reportSlowTests;
|
||||
result.quiet = this._options.configOverrides.quiet;
|
||||
result.reporter = [...this._options.configOverrides.reporter];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
_parseProject(project) {
|
||||
return {
|
||||
metadata: project.metadata,
|
||||
name: project.name,
|
||||
outputDir: this._absolutePath(project.outputDir),
|
||||
repeatEach: project.repeatEach,
|
||||
retries: project.retries,
|
||||
testDir: this._absolutePath(project.testDir),
|
||||
testIgnore: parseRegexPatterns(project.testIgnore),
|
||||
testMatch: parseRegexPatterns(project.testMatch),
|
||||
timeout: project.timeout,
|
||||
grep: parseRegexPatterns(project.grep),
|
||||
grepInvert: parseRegexPatterns(project.grepInvert),
|
||||
dependencies: project.dependencies,
|
||||
teardown: project.teardown,
|
||||
snapshotDir: this._absolutePath(project.snapshotDir),
|
||||
use: project.use
|
||||
};
|
||||
}
|
||||
_parseAttachments(attachments) {
|
||||
return attachments.map((a) => {
|
||||
return {
|
||||
...a,
|
||||
body: a.base64 && globalThis.Buffer ? Buffer.from(a.base64, "base64") : void 0
|
||||
};
|
||||
});
|
||||
}
|
||||
_mergeSuiteInto(jsonSuite, parent) {
|
||||
let targetSuite = parent.suites.find((s) => s.title === jsonSuite.title);
|
||||
if (!targetSuite) {
|
||||
targetSuite = new TeleSuite(jsonSuite.title, parent.type === "project" ? "file" : "describe");
|
||||
parent._addSuite(targetSuite);
|
||||
}
|
||||
targetSuite.location = this._absoluteLocation(jsonSuite.location);
|
||||
jsonSuite.entries.forEach((e) => {
|
||||
if ("testId" in e)
|
||||
this._mergeTestInto(e, targetSuite);
|
||||
else
|
||||
this._mergeSuiteInto(e, targetSuite);
|
||||
});
|
||||
}
|
||||
_mergeTestInto(jsonTest, parent) {
|
||||
let targetTest = this._options.mergeTestCases ? parent.tests.find((s) => s.title === jsonTest.title && s.repeatEachIndex === jsonTest.repeatEachIndex) : void 0;
|
||||
if (!targetTest) {
|
||||
targetTest = new TeleTestCase(jsonTest.testId, jsonTest.title, this._absoluteLocation(jsonTest.location), jsonTest.repeatEachIndex);
|
||||
parent._addTest(targetTest);
|
||||
this._tests.set(targetTest.id, targetTest);
|
||||
}
|
||||
this._updateTest(jsonTest, targetTest);
|
||||
}
|
||||
_updateTest(payload, test) {
|
||||
test.id = payload.testId;
|
||||
test.location = this._absoluteLocation(payload.location);
|
||||
test.retries = payload.retries;
|
||||
test.tags = payload.tags ?? [];
|
||||
test.annotations = payload.annotations ?? [];
|
||||
this._absoluteAnnotationLocationsInplace(test.annotations);
|
||||
return test;
|
||||
}
|
||||
_absoluteAnnotationLocationsInplace(annotations) {
|
||||
for (const annotation of annotations) {
|
||||
if (annotation.location)
|
||||
annotation.location = this._absoluteLocation(annotation.location);
|
||||
}
|
||||
}
|
||||
_absoluteLocation(location) {
|
||||
if (!location)
|
||||
return location;
|
||||
return {
|
||||
...location,
|
||||
file: this._absolutePath(location.file)
|
||||
};
|
||||
}
|
||||
_absolutePath(relativePath) {
|
||||
if (relativePath === void 0)
|
||||
return;
|
||||
return this._options.resolvePath ? this._options.resolvePath(this._rootDir, relativePath) : this._rootDir + "/" + relativePath;
|
||||
}
|
||||
}
|
||||
class TeleSuite {
|
||||
constructor(title, type) {
|
||||
this._entries = [];
|
||||
this._requireFile = "";
|
||||
this._parallelMode = "none";
|
||||
this.title = title;
|
||||
this._type = type;
|
||||
}
|
||||
get type() {
|
||||
return this._type;
|
||||
}
|
||||
get suites() {
|
||||
return this._entries.filter((e) => e.type !== "test");
|
||||
}
|
||||
get tests() {
|
||||
return this._entries.filter((e) => e.type === "test");
|
||||
}
|
||||
entries() {
|
||||
return this._entries;
|
||||
}
|
||||
allTests() {
|
||||
const result = [];
|
||||
const visit = (suite) => {
|
||||
for (const entry of suite.entries()) {
|
||||
if (entry.type === "test")
|
||||
result.push(entry);
|
||||
else
|
||||
visit(entry);
|
||||
}
|
||||
};
|
||||
visit(this);
|
||||
return result;
|
||||
}
|
||||
titlePath() {
|
||||
const titlePath = this.parent ? this.parent.titlePath() : [];
|
||||
if (this.title || this._type !== "describe")
|
||||
titlePath.push(this.title);
|
||||
return titlePath;
|
||||
}
|
||||
project() {
|
||||
return this._project ?? this.parent?.project();
|
||||
}
|
||||
_addTest(test) {
|
||||
test.parent = this;
|
||||
this._entries.push(test);
|
||||
}
|
||||
_addSuite(suite) {
|
||||
suite.parent = this;
|
||||
this._entries.push(suite);
|
||||
}
|
||||
}
|
||||
class TeleTestCase {
|
||||
constructor(id, title, location, repeatEachIndex) {
|
||||
this.fn = () => {
|
||||
};
|
||||
this.results = [];
|
||||
this.type = "test";
|
||||
this.expectedStatus = "passed";
|
||||
this.timeout = 0;
|
||||
this.annotations = [];
|
||||
this.retries = 0;
|
||||
this.tags = [];
|
||||
this.repeatEachIndex = 0;
|
||||
this.id = id;
|
||||
this.title = title;
|
||||
this.location = location;
|
||||
this.repeatEachIndex = repeatEachIndex;
|
||||
}
|
||||
titlePath() {
|
||||
const titlePath = this.parent ? this.parent.titlePath() : [];
|
||||
titlePath.push(this.title);
|
||||
return titlePath;
|
||||
}
|
||||
outcome() {
|
||||
return computeTestCaseOutcome(this);
|
||||
}
|
||||
ok() {
|
||||
const status = this.outcome();
|
||||
return status === "expected" || status === "flaky" || status === "skipped";
|
||||
}
|
||||
_createTestResult(id) {
|
||||
const result = new TeleTestResult(this.results.length, id);
|
||||
this.results.push(result);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
class TeleTestStep {
|
||||
constructor(payload, parentStep, location, result) {
|
||||
this.duration = -1;
|
||||
this.steps = [];
|
||||
this._startTime = 0;
|
||||
this.title = payload.title;
|
||||
this.category = payload.category;
|
||||
this.location = location;
|
||||
this.parent = parentStep;
|
||||
this._startTime = payload.startTime;
|
||||
this._result = result;
|
||||
}
|
||||
titlePath() {
|
||||
const parentPath = this.parent?.titlePath() || [];
|
||||
return [...parentPath, this.title];
|
||||
}
|
||||
get startTime() {
|
||||
return new Date(this._startTime);
|
||||
}
|
||||
set startTime(value) {
|
||||
this._startTime = +value;
|
||||
}
|
||||
get attachments() {
|
||||
return this._endPayload?.attachments?.map((index) => this._result.attachments[index]) ?? [];
|
||||
}
|
||||
get annotations() {
|
||||
return this._endPayload?.annotations ?? [];
|
||||
}
|
||||
}
|
||||
class TeleTestResult {
|
||||
constructor(retry, id) {
|
||||
this.parallelIndex = -1;
|
||||
this.workerIndex = -1;
|
||||
this.duration = -1;
|
||||
this.stdout = [];
|
||||
this.stderr = [];
|
||||
this.attachments = [];
|
||||
this.annotations = [];
|
||||
this.status = "skipped";
|
||||
this.steps = [];
|
||||
this.errors = [];
|
||||
this._stepMap = /* @__PURE__ */ new Map();
|
||||
this._startTime = 0;
|
||||
this.retry = retry;
|
||||
this._id = id;
|
||||
}
|
||||
setStartTimeNumber(startTime) {
|
||||
this._startTime = startTime;
|
||||
}
|
||||
get startTime() {
|
||||
return new Date(this._startTime);
|
||||
}
|
||||
set startTime(value) {
|
||||
this._startTime = +value;
|
||||
}
|
||||
}
|
||||
const baseFullConfig = {
|
||||
forbidOnly: false,
|
||||
fullyParallel: false,
|
||||
globalSetup: null,
|
||||
globalTeardown: null,
|
||||
globalTimeout: 0,
|
||||
grep: /.*/,
|
||||
grepInvert: null,
|
||||
maxFailures: 0,
|
||||
metadata: {},
|
||||
preserveOutput: "always",
|
||||
projects: [],
|
||||
reporter: [[process.env.CI ? "dot" : "list"]],
|
||||
reportSlowTests: {
|
||||
max: 5,
|
||||
threshold: 3e5
|
||||
/* 5 minutes */
|
||||
},
|
||||
configFile: "",
|
||||
rootDir: "",
|
||||
quiet: false,
|
||||
shard: null,
|
||||
updateSnapshots: "missing",
|
||||
updateSourceMethod: "patch",
|
||||
version: "",
|
||||
workers: 0,
|
||||
webServer: null
|
||||
};
|
||||
function serializeRegexPatterns(patterns) {
|
||||
if (!Array.isArray(patterns))
|
||||
patterns = [patterns];
|
||||
return patterns.map((s) => {
|
||||
if (typeof s === "string")
|
||||
return { s };
|
||||
return { r: { source: s.source, flags: s.flags } };
|
||||
});
|
||||
}
|
||||
function parseRegexPatterns(patterns) {
|
||||
return patterns.map((p) => {
|
||||
if (p.s !== void 0)
|
||||
return p.s;
|
||||
return new RegExp(p.r.source, p.r.flags);
|
||||
});
|
||||
}
|
||||
function computeTestCaseOutcome(test) {
|
||||
let skipped = 0;
|
||||
let didNotRun = 0;
|
||||
let expected = 0;
|
||||
let interrupted = 0;
|
||||
let unexpected = 0;
|
||||
for (const result of test.results) {
|
||||
if (result.status === "interrupted") {
|
||||
++interrupted;
|
||||
} else if (result.status === "skipped" && test.expectedStatus === "skipped") {
|
||||
++skipped;
|
||||
} else if (result.status === "skipped") {
|
||||
++didNotRun;
|
||||
} else if (result.status === test.expectedStatus) {
|
||||
++expected;
|
||||
} else {
|
||||
++unexpected;
|
||||
}
|
||||
}
|
||||
if (expected === 0 && unexpected === 0)
|
||||
return "skipped";
|
||||
if (unexpected === 0)
|
||||
return "expected";
|
||||
if (expected === 0 && skipped === 0)
|
||||
return "unexpected";
|
||||
return "flaky";
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TeleReporterReceiver,
|
||||
TeleSuite,
|
||||
TeleTestCase,
|
||||
TeleTestResult,
|
||||
baseFullConfig,
|
||||
computeTestCaseOutcome,
|
||||
parseRegexPatterns,
|
||||
serializeRegexPatterns
|
||||
});
|
||||
137
node_modules/playwright/lib/isomorphic/teleSuiteUpdater.js
generated
vendored
Normal file
137
node_modules/playwright/lib/isomorphic/teleSuiteUpdater.js
generated
vendored
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var teleSuiteUpdater_exports = {};
|
||||
__export(teleSuiteUpdater_exports, {
|
||||
TeleSuiteUpdater: () => TeleSuiteUpdater
|
||||
});
|
||||
module.exports = __toCommonJS(teleSuiteUpdater_exports);
|
||||
var import_teleReceiver = require("./teleReceiver");
|
||||
var import_testTree = require("./testTree");
|
||||
class TeleSuiteUpdater {
|
||||
constructor(options) {
|
||||
this.loadErrors = [];
|
||||
this.progress = {
|
||||
total: 0,
|
||||
passed: 0,
|
||||
failed: 0,
|
||||
skipped: 0
|
||||
};
|
||||
this._lastRunTestCount = 0;
|
||||
this._receiver = new import_teleReceiver.TeleReporterReceiver(this._createReporter(), {
|
||||
mergeProjects: true,
|
||||
mergeTestCases: true,
|
||||
resolvePath: (rootDir, relativePath) => rootDir + options.pathSeparator + relativePath,
|
||||
clearPreviousResultsWhenTestBegins: true
|
||||
});
|
||||
this._options = options;
|
||||
}
|
||||
_createReporter() {
|
||||
return {
|
||||
version: () => "v2",
|
||||
onConfigure: (c) => {
|
||||
this.config = c;
|
||||
this._lastRunReceiver = new import_teleReceiver.TeleReporterReceiver({
|
||||
version: () => "v2",
|
||||
onBegin: (suite) => {
|
||||
this._lastRunTestCount = suite.allTests().length;
|
||||
this._lastRunReceiver = void 0;
|
||||
}
|
||||
}, {
|
||||
mergeProjects: true,
|
||||
mergeTestCases: false,
|
||||
resolvePath: (rootDir, relativePath) => rootDir + this._options.pathSeparator + relativePath
|
||||
});
|
||||
},
|
||||
onBegin: (suite) => {
|
||||
if (!this.rootSuite)
|
||||
this.rootSuite = suite;
|
||||
if (this._testResultsSnapshot) {
|
||||
for (const test of this.rootSuite.allTests())
|
||||
test.results = this._testResultsSnapshot?.get(test.id) || test.results;
|
||||
this._testResultsSnapshot = void 0;
|
||||
}
|
||||
this.progress.total = this._lastRunTestCount;
|
||||
this.progress.passed = 0;
|
||||
this.progress.failed = 0;
|
||||
this.progress.skipped = 0;
|
||||
this._options.onUpdate(true);
|
||||
},
|
||||
onEnd: () => {
|
||||
this._options.onUpdate(true);
|
||||
},
|
||||
onTestBegin: (test, testResult) => {
|
||||
testResult[import_testTree.statusEx] = "running";
|
||||
this._options.onUpdate();
|
||||
},
|
||||
onTestEnd: (test, testResult) => {
|
||||
if (test.outcome() === "skipped")
|
||||
++this.progress.skipped;
|
||||
else if (test.outcome() === "unexpected")
|
||||
++this.progress.failed;
|
||||
else
|
||||
++this.progress.passed;
|
||||
testResult[import_testTree.statusEx] = testResult.status;
|
||||
this._options.onUpdate();
|
||||
},
|
||||
onError: (error) => this._handleOnError(error),
|
||||
printsToStdio: () => false
|
||||
};
|
||||
}
|
||||
processGlobalReport(report) {
|
||||
const receiver = new import_teleReceiver.TeleReporterReceiver({
|
||||
version: () => "v2",
|
||||
onConfigure: (c) => {
|
||||
this.config = c;
|
||||
},
|
||||
onError: (error) => this._handleOnError(error)
|
||||
});
|
||||
for (const message of report)
|
||||
void receiver.dispatch(message);
|
||||
}
|
||||
processListReport(report) {
|
||||
const tests = this.rootSuite?.allTests() || [];
|
||||
this._testResultsSnapshot = new Map(tests.map((test) => [test.id, test.results]));
|
||||
this._receiver.reset();
|
||||
for (const message of report)
|
||||
void this._receiver.dispatch(message);
|
||||
}
|
||||
processTestReportEvent(message) {
|
||||
this._lastRunReceiver?.dispatch(message)?.catch(() => {
|
||||
});
|
||||
this._receiver.dispatch(message)?.catch(() => {
|
||||
});
|
||||
}
|
||||
_handleOnError(error) {
|
||||
this.loadErrors.push(error);
|
||||
this._options.onError?.(error);
|
||||
this._options.onUpdate();
|
||||
}
|
||||
asModel() {
|
||||
return {
|
||||
rootSuite: this.rootSuite || new import_teleReceiver.TeleSuite("", "root"),
|
||||
config: this.config,
|
||||
loadErrors: this.loadErrors,
|
||||
progress: this.progress
|
||||
};
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TeleSuiteUpdater
|
||||
});
|
||||
211
node_modules/playwright/lib/isomorphic/testServerConnection.js
generated
vendored
Normal file
211
node_modules/playwright/lib/isomorphic/testServerConnection.js
generated
vendored
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var testServerConnection_exports = {};
|
||||
__export(testServerConnection_exports, {
|
||||
TestServerConnection: () => TestServerConnection,
|
||||
WebSocketTestServerTransport: () => WebSocketTestServerTransport
|
||||
});
|
||||
module.exports = __toCommonJS(testServerConnection_exports);
|
||||
var events = __toESM(require("./events"));
|
||||
class WebSocketTestServerTransport {
|
||||
constructor(url) {
|
||||
this._ws = new WebSocket(url);
|
||||
}
|
||||
onmessage(listener) {
|
||||
this._ws.addEventListener("message", (event) => listener(event.data.toString()));
|
||||
}
|
||||
onopen(listener) {
|
||||
this._ws.addEventListener("open", listener);
|
||||
}
|
||||
onerror(listener) {
|
||||
this._ws.addEventListener("error", listener);
|
||||
}
|
||||
onclose(listener) {
|
||||
this._ws.addEventListener("close", listener);
|
||||
}
|
||||
send(data) {
|
||||
this._ws.send(data);
|
||||
}
|
||||
close() {
|
||||
this._ws.close();
|
||||
}
|
||||
}
|
||||
class TestServerConnection {
|
||||
constructor(transport) {
|
||||
this._onCloseEmitter = new events.EventEmitter();
|
||||
this._onReportEmitter = new events.EventEmitter();
|
||||
this._onStdioEmitter = new events.EventEmitter();
|
||||
this._onTestFilesChangedEmitter = new events.EventEmitter();
|
||||
this._onLoadTraceRequestedEmitter = new events.EventEmitter();
|
||||
this._lastId = 0;
|
||||
this._callbacks = /* @__PURE__ */ new Map();
|
||||
this._isClosed = false;
|
||||
this.onClose = this._onCloseEmitter.event;
|
||||
this.onReport = this._onReportEmitter.event;
|
||||
this.onStdio = this._onStdioEmitter.event;
|
||||
this.onTestFilesChanged = this._onTestFilesChangedEmitter.event;
|
||||
this.onLoadTraceRequested = this._onLoadTraceRequestedEmitter.event;
|
||||
this._transport = transport;
|
||||
this._transport.onmessage((data) => {
|
||||
const message = JSON.parse(data);
|
||||
const { id, result, error, method, params } = message;
|
||||
if (id) {
|
||||
const callback = this._callbacks.get(id);
|
||||
if (!callback)
|
||||
return;
|
||||
this._callbacks.delete(id);
|
||||
if (error)
|
||||
callback.reject(new Error(error));
|
||||
else
|
||||
callback.resolve(result);
|
||||
} else {
|
||||
this._dispatchEvent(method, params);
|
||||
}
|
||||
});
|
||||
const pingInterval = setInterval(() => this._sendMessage("ping").catch(() => {
|
||||
}), 3e4);
|
||||
this._connectedPromise = new Promise((f, r) => {
|
||||
this._transport.onopen(f);
|
||||
this._transport.onerror(r);
|
||||
});
|
||||
this._transport.onclose(() => {
|
||||
this._isClosed = true;
|
||||
this._onCloseEmitter.fire();
|
||||
clearInterval(pingInterval);
|
||||
});
|
||||
}
|
||||
isClosed() {
|
||||
return this._isClosed;
|
||||
}
|
||||
async _sendMessage(method, params) {
|
||||
const logForTest = globalThis.__logForTest;
|
||||
logForTest?.({ method, params });
|
||||
await this._connectedPromise;
|
||||
const id = ++this._lastId;
|
||||
const message = { id, method, params };
|
||||
this._transport.send(JSON.stringify(message));
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, { resolve, reject });
|
||||
});
|
||||
}
|
||||
_sendMessageNoReply(method, params) {
|
||||
this._sendMessage(method, params).catch(() => {
|
||||
});
|
||||
}
|
||||
_dispatchEvent(method, params) {
|
||||
if (method === "report")
|
||||
this._onReportEmitter.fire(params);
|
||||
else if (method === "stdio")
|
||||
this._onStdioEmitter.fire(params);
|
||||
else if (method === "testFilesChanged")
|
||||
this._onTestFilesChangedEmitter.fire(params);
|
||||
else if (method === "loadTraceRequested")
|
||||
this._onLoadTraceRequestedEmitter.fire(params);
|
||||
}
|
||||
async initialize(params) {
|
||||
await this._sendMessage("initialize", params);
|
||||
}
|
||||
async ping(params) {
|
||||
await this._sendMessage("ping", params);
|
||||
}
|
||||
async pingNoReply(params) {
|
||||
this._sendMessageNoReply("ping", params);
|
||||
}
|
||||
async watch(params) {
|
||||
await this._sendMessage("watch", params);
|
||||
}
|
||||
watchNoReply(params) {
|
||||
this._sendMessageNoReply("watch", params);
|
||||
}
|
||||
async open(params) {
|
||||
await this._sendMessage("open", params);
|
||||
}
|
||||
openNoReply(params) {
|
||||
this._sendMessageNoReply("open", params);
|
||||
}
|
||||
async resizeTerminal(params) {
|
||||
await this._sendMessage("resizeTerminal", params);
|
||||
}
|
||||
resizeTerminalNoReply(params) {
|
||||
this._sendMessageNoReply("resizeTerminal", params);
|
||||
}
|
||||
async checkBrowsers(params) {
|
||||
return await this._sendMessage("checkBrowsers", params);
|
||||
}
|
||||
async installBrowsers(params) {
|
||||
await this._sendMessage("installBrowsers", params);
|
||||
}
|
||||
async runGlobalSetup(params) {
|
||||
return await this._sendMessage("runGlobalSetup", params);
|
||||
}
|
||||
async runGlobalTeardown(params) {
|
||||
return await this._sendMessage("runGlobalTeardown", params);
|
||||
}
|
||||
async startDevServer(params) {
|
||||
return await this._sendMessage("startDevServer", params);
|
||||
}
|
||||
async stopDevServer(params) {
|
||||
return await this._sendMessage("stopDevServer", params);
|
||||
}
|
||||
async clearCache(params) {
|
||||
return await this._sendMessage("clearCache", params);
|
||||
}
|
||||
async listFiles(params) {
|
||||
return await this._sendMessage("listFiles", params);
|
||||
}
|
||||
async listTests(params) {
|
||||
return await this._sendMessage("listTests", params);
|
||||
}
|
||||
async runTests(params) {
|
||||
return await this._sendMessage("runTests", params);
|
||||
}
|
||||
async findRelatedTestFiles(params) {
|
||||
return await this._sendMessage("findRelatedTestFiles", params);
|
||||
}
|
||||
async stopTests(params) {
|
||||
await this._sendMessage("stopTests", params);
|
||||
}
|
||||
stopTestsNoReply(params) {
|
||||
this._sendMessageNoReply("stopTests", params);
|
||||
}
|
||||
async closeGracefully(params) {
|
||||
await this._sendMessage("closeGracefully", params);
|
||||
}
|
||||
close() {
|
||||
try {
|
||||
this._transport.close();
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TestServerConnection,
|
||||
WebSocketTestServerTransport
|
||||
});
|
||||
16
node_modules/playwright/lib/isomorphic/testServerInterface.js
generated
vendored
Normal file
16
node_modules/playwright/lib/isomorphic/testServerInterface.js
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var testServerInterface_exports = {};
|
||||
module.exports = __toCommonJS(testServerInterface_exports);
|
||||
334
node_modules/playwright/lib/isomorphic/testTree.js
generated
vendored
Normal file
334
node_modules/playwright/lib/isomorphic/testTree.js
generated
vendored
Normal file
|
|
@ -0,0 +1,334 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var testTree_exports = {};
|
||||
__export(testTree_exports, {
|
||||
TestTree: () => TestTree,
|
||||
collectTestIds: () => collectTestIds,
|
||||
sortAndPropagateStatus: () => sortAndPropagateStatus,
|
||||
statusEx: () => statusEx
|
||||
});
|
||||
module.exports = __toCommonJS(testTree_exports);
|
||||
class TestTree {
|
||||
constructor(rootFolder, rootSuite, loadErrors, projectFilters, pathSeparator, hideFiles) {
|
||||
this._treeItemById = /* @__PURE__ */ new Map();
|
||||
this._treeItemByTestId = /* @__PURE__ */ new Map();
|
||||
const filterProjects = projectFilters && [...projectFilters.values()].some(Boolean);
|
||||
this.pathSeparator = pathSeparator;
|
||||
this.rootItem = {
|
||||
kind: "group",
|
||||
subKind: "folder",
|
||||
id: rootFolder,
|
||||
title: "",
|
||||
location: { file: "", line: 0, column: 0 },
|
||||
duration: 0,
|
||||
parent: void 0,
|
||||
children: [],
|
||||
status: "none",
|
||||
hasLoadErrors: false
|
||||
};
|
||||
this._treeItemById.set(rootFolder, this.rootItem);
|
||||
const visitSuite = (project, parentSuite, parentGroup, mode) => {
|
||||
for (const suite of mode === "tests" ? [] : parentSuite.suites) {
|
||||
if (!suite.title) {
|
||||
visitSuite(project, suite, parentGroup, "all");
|
||||
continue;
|
||||
}
|
||||
let group = parentGroup.children.find((item) => item.kind === "group" && item.title === suite.title);
|
||||
if (!group) {
|
||||
group = {
|
||||
kind: "group",
|
||||
subKind: "describe",
|
||||
id: "suite:" + parentSuite.titlePath().join("") + "" + suite.title,
|
||||
// account for anonymous suites
|
||||
title: suite.title,
|
||||
location: suite.location,
|
||||
duration: 0,
|
||||
parent: parentGroup,
|
||||
children: [],
|
||||
status: "none",
|
||||
hasLoadErrors: false
|
||||
};
|
||||
this._addChild(parentGroup, group);
|
||||
}
|
||||
visitSuite(project, suite, group, "all");
|
||||
}
|
||||
for (const test of mode === "suites" ? [] : parentSuite.tests) {
|
||||
const title = test.title;
|
||||
let testCaseItem = parentGroup.children.find((t) => t.kind !== "group" && t.title === title);
|
||||
if (!testCaseItem) {
|
||||
testCaseItem = {
|
||||
kind: "case",
|
||||
id: "test:" + test.titlePath().join(""),
|
||||
title,
|
||||
parent: parentGroup,
|
||||
children: [],
|
||||
tests: [],
|
||||
location: test.location,
|
||||
duration: 0,
|
||||
status: "none",
|
||||
project: void 0,
|
||||
test: void 0,
|
||||
tags: test.tags
|
||||
};
|
||||
this._addChild(parentGroup, testCaseItem);
|
||||
}
|
||||
const result = test.results[0];
|
||||
let status = "none";
|
||||
if (result?.[statusEx] === "scheduled")
|
||||
status = "scheduled";
|
||||
else if (result?.[statusEx] === "running")
|
||||
status = "running";
|
||||
else if (result?.status === "skipped")
|
||||
status = "skipped";
|
||||
else if (result?.status === "interrupted")
|
||||
status = "none";
|
||||
else if (result && test.outcome() !== "expected")
|
||||
status = "failed";
|
||||
else if (result && test.outcome() === "expected")
|
||||
status = "passed";
|
||||
testCaseItem.tests.push(test);
|
||||
const testItem = {
|
||||
kind: "test",
|
||||
id: test.id,
|
||||
title: project.name,
|
||||
location: test.location,
|
||||
test,
|
||||
parent: testCaseItem,
|
||||
children: [],
|
||||
status,
|
||||
duration: test.results.length ? Math.max(0, test.results[0].duration) : 0,
|
||||
project
|
||||
};
|
||||
this._addChild(testCaseItem, testItem);
|
||||
this._treeItemByTestId.set(test.id, testItem);
|
||||
testCaseItem.duration = testCaseItem.children.reduce((a, b) => a + b.duration, 0);
|
||||
}
|
||||
};
|
||||
for (const projectSuite of rootSuite?.suites || []) {
|
||||
if (filterProjects && !projectFilters.get(projectSuite.title))
|
||||
continue;
|
||||
for (const fileSuite of projectSuite.suites) {
|
||||
if (hideFiles) {
|
||||
visitSuite(projectSuite.project(), fileSuite, this.rootItem, "suites");
|
||||
if (fileSuite.tests.length) {
|
||||
const defaultDescribeItem = this._defaultDescribeItem();
|
||||
visitSuite(projectSuite.project(), fileSuite, defaultDescribeItem, "tests");
|
||||
}
|
||||
} else {
|
||||
const fileItem = this._fileItem(fileSuite.location.file.split(pathSeparator), true);
|
||||
visitSuite(projectSuite.project(), fileSuite, fileItem, "all");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const loadError of loadErrors) {
|
||||
if (!loadError.location)
|
||||
continue;
|
||||
const fileItem = this._fileItem(loadError.location.file.split(pathSeparator), true);
|
||||
fileItem.hasLoadErrors = true;
|
||||
}
|
||||
}
|
||||
_addChild(parent, child) {
|
||||
parent.children.push(child);
|
||||
child.parent = parent;
|
||||
this._treeItemById.set(child.id, child);
|
||||
}
|
||||
filterTree(filterText, statusFilters, runningTestIds) {
|
||||
const tokens = filterText.trim().toLowerCase().split(" ");
|
||||
const filtersStatuses = [...statusFilters.values()].some(Boolean);
|
||||
const filter = (testCase) => {
|
||||
const titleWithTags = [...testCase.tests[0].titlePath(), ...testCase.tests[0].tags].join(" ").toLowerCase();
|
||||
if (!tokens.every((token) => titleWithTags.includes(token)) && !testCase.tests.some((t) => runningTestIds?.has(t.id)))
|
||||
return false;
|
||||
testCase.children = testCase.children.filter((test) => {
|
||||
return !filtersStatuses || runningTestIds?.has(test.test.id) || statusFilters.get(test.status);
|
||||
});
|
||||
testCase.tests = testCase.children.map((c) => c.test);
|
||||
return !!testCase.children.length;
|
||||
};
|
||||
const visit = (treeItem) => {
|
||||
const newChildren = [];
|
||||
for (const child of treeItem.children) {
|
||||
if (child.kind === "case") {
|
||||
if (filter(child))
|
||||
newChildren.push(child);
|
||||
} else {
|
||||
visit(child);
|
||||
if (child.children.length || child.hasLoadErrors)
|
||||
newChildren.push(child);
|
||||
}
|
||||
}
|
||||
treeItem.children = newChildren;
|
||||
};
|
||||
visit(this.rootItem);
|
||||
}
|
||||
_fileItem(filePath, isFile) {
|
||||
if (filePath.length === 0)
|
||||
return this.rootItem;
|
||||
const fileName = filePath.join(this.pathSeparator);
|
||||
const existingFileItem = this._treeItemById.get(fileName);
|
||||
if (existingFileItem)
|
||||
return existingFileItem;
|
||||
const parentFileItem = this._fileItem(filePath.slice(0, filePath.length - 1), false);
|
||||
const fileItem = {
|
||||
kind: "group",
|
||||
subKind: isFile ? "file" : "folder",
|
||||
id: fileName,
|
||||
title: filePath[filePath.length - 1],
|
||||
location: { file: fileName, line: 0, column: 0 },
|
||||
duration: 0,
|
||||
parent: parentFileItem,
|
||||
children: [],
|
||||
status: "none",
|
||||
hasLoadErrors: false
|
||||
};
|
||||
this._addChild(parentFileItem, fileItem);
|
||||
return fileItem;
|
||||
}
|
||||
_defaultDescribeItem() {
|
||||
let defaultDescribeItem = this._treeItemById.get("<anonymous>");
|
||||
if (!defaultDescribeItem) {
|
||||
defaultDescribeItem = {
|
||||
kind: "group",
|
||||
subKind: "describe",
|
||||
id: "<anonymous>",
|
||||
title: "<anonymous>",
|
||||
location: { file: "", line: 0, column: 0 },
|
||||
duration: 0,
|
||||
parent: this.rootItem,
|
||||
children: [],
|
||||
status: "none",
|
||||
hasLoadErrors: false
|
||||
};
|
||||
this._addChild(this.rootItem, defaultDescribeItem);
|
||||
}
|
||||
return defaultDescribeItem;
|
||||
}
|
||||
sortAndPropagateStatus() {
|
||||
sortAndPropagateStatus(this.rootItem);
|
||||
}
|
||||
flattenForSingleProject() {
|
||||
const visit = (treeItem) => {
|
||||
if (treeItem.kind === "case" && treeItem.children.length === 1) {
|
||||
treeItem.project = treeItem.children[0].project;
|
||||
treeItem.test = treeItem.children[0].test;
|
||||
treeItem.children = [];
|
||||
this._treeItemByTestId.set(treeItem.test.id, treeItem);
|
||||
} else {
|
||||
treeItem.children.forEach(visit);
|
||||
}
|
||||
};
|
||||
visit(this.rootItem);
|
||||
}
|
||||
shortenRoot() {
|
||||
let shortRoot = this.rootItem;
|
||||
while (shortRoot.children.length === 1 && shortRoot.children[0].kind === "group" && shortRoot.children[0].subKind === "folder")
|
||||
shortRoot = shortRoot.children[0];
|
||||
shortRoot.location = this.rootItem.location;
|
||||
this.rootItem = shortRoot;
|
||||
}
|
||||
testIds() {
|
||||
const result = /* @__PURE__ */ new Set();
|
||||
const visit = (treeItem) => {
|
||||
if (treeItem.kind === "case")
|
||||
treeItem.tests.forEach((t) => result.add(t.id));
|
||||
treeItem.children.forEach(visit);
|
||||
};
|
||||
visit(this.rootItem);
|
||||
return result;
|
||||
}
|
||||
fileNames() {
|
||||
const result = /* @__PURE__ */ new Set();
|
||||
const visit = (treeItem) => {
|
||||
if (treeItem.kind === "group" && treeItem.subKind === "file")
|
||||
result.add(treeItem.id);
|
||||
else
|
||||
treeItem.children.forEach(visit);
|
||||
};
|
||||
visit(this.rootItem);
|
||||
return [...result];
|
||||
}
|
||||
flatTreeItems() {
|
||||
const result = [];
|
||||
const visit = (treeItem) => {
|
||||
result.push(treeItem);
|
||||
treeItem.children.forEach(visit);
|
||||
};
|
||||
visit(this.rootItem);
|
||||
return result;
|
||||
}
|
||||
treeItemById(id) {
|
||||
return this._treeItemById.get(id);
|
||||
}
|
||||
collectTestIds(treeItem) {
|
||||
return treeItem ? collectTestIds(treeItem) : /* @__PURE__ */ new Set();
|
||||
}
|
||||
}
|
||||
function sortAndPropagateStatus(treeItem) {
|
||||
for (const child of treeItem.children)
|
||||
sortAndPropagateStatus(child);
|
||||
if (treeItem.kind === "group") {
|
||||
treeItem.children.sort((a, b) => {
|
||||
const fc = a.location.file.localeCompare(b.location.file);
|
||||
return fc || a.location.line - b.location.line;
|
||||
});
|
||||
}
|
||||
let allPassed = treeItem.children.length > 0;
|
||||
let allSkipped = treeItem.children.length > 0;
|
||||
let hasFailed = false;
|
||||
let hasRunning = false;
|
||||
let hasScheduled = false;
|
||||
for (const child of treeItem.children) {
|
||||
allSkipped = allSkipped && child.status === "skipped";
|
||||
allPassed = allPassed && (child.status === "passed" || child.status === "skipped");
|
||||
hasFailed = hasFailed || child.status === "failed";
|
||||
hasRunning = hasRunning || child.status === "running";
|
||||
hasScheduled = hasScheduled || child.status === "scheduled";
|
||||
}
|
||||
if (hasRunning)
|
||||
treeItem.status = "running";
|
||||
else if (hasScheduled)
|
||||
treeItem.status = "scheduled";
|
||||
else if (hasFailed)
|
||||
treeItem.status = "failed";
|
||||
else if (allSkipped)
|
||||
treeItem.status = "skipped";
|
||||
else if (allPassed)
|
||||
treeItem.status = "passed";
|
||||
}
|
||||
function collectTestIds(treeItem) {
|
||||
const testIds = /* @__PURE__ */ new Set();
|
||||
const visit = (treeItem2) => {
|
||||
if (treeItem2.kind === "case")
|
||||
treeItem2.tests.map((t) => t.id).forEach((id) => testIds.add(id));
|
||||
else if (treeItem2.kind === "test")
|
||||
testIds.add(treeItem2.id);
|
||||
else
|
||||
treeItem2.children?.forEach(visit);
|
||||
};
|
||||
visit(treeItem);
|
||||
return testIds;
|
||||
}
|
||||
const statusEx = Symbol("statusEx");
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
TestTree,
|
||||
collectTestIds,
|
||||
sortAndPropagateStatus,
|
||||
statusEx
|
||||
});
|
||||
16
node_modules/playwright/lib/isomorphic/types.d.js
generated
vendored
Normal file
16
node_modules/playwright/lib/isomorphic/types.d.js
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var types_d_exports = {};
|
||||
module.exports = __toCommonJS(types_d_exports);
|
||||
59
node_modules/playwright/lib/loader/loaderMain.js
generated
vendored
Normal file
59
node_modules/playwright/lib/loader/loaderMain.js
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var loaderMain_exports = {};
|
||||
__export(loaderMain_exports, {
|
||||
LoaderMain: () => LoaderMain,
|
||||
create: () => create
|
||||
});
|
||||
module.exports = __toCommonJS(loaderMain_exports);
|
||||
var import_configLoader = require("../common/configLoader");
|
||||
var import_esmLoaderHost = require("../common/esmLoaderHost");
|
||||
var import_poolBuilder = require("../common/poolBuilder");
|
||||
var import_process = require("../common/process");
|
||||
var import_testLoader = require("../common/testLoader");
|
||||
var import_compilationCache = require("../transform/compilationCache");
|
||||
class LoaderMain extends import_process.ProcessRunner {
|
||||
constructor(serializedConfig) {
|
||||
super();
|
||||
this._poolBuilder = import_poolBuilder.PoolBuilder.createForLoader();
|
||||
this._serializedConfig = serializedConfig;
|
||||
}
|
||||
_config() {
|
||||
if (!this._configPromise)
|
||||
this._configPromise = (0, import_configLoader.deserializeConfig)(this._serializedConfig);
|
||||
return this._configPromise;
|
||||
}
|
||||
async loadTestFile(params) {
|
||||
const testErrors = [];
|
||||
const config = await this._config();
|
||||
const fileSuite = await (0, import_testLoader.loadTestFile)(params.file, config.config.rootDir, testErrors);
|
||||
this._poolBuilder.buildPools(fileSuite);
|
||||
return { fileSuite: fileSuite._deepSerialize(), testErrors };
|
||||
}
|
||||
async getCompilationCacheFromLoader() {
|
||||
await (0, import_esmLoaderHost.incorporateCompilationCache)();
|
||||
return (0, import_compilationCache.serializeCompilationCache)();
|
||||
}
|
||||
}
|
||||
const create = (config) => new LoaderMain(config);
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
LoaderMain,
|
||||
create
|
||||
});
|
||||
325
node_modules/playwright/lib/matchers/expect.js
generated
vendored
Normal file
325
node_modules/playwright/lib/matchers/expect.js
generated
vendored
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var expect_exports = {};
|
||||
__export(expect_exports, {
|
||||
expect: () => expect,
|
||||
mergeExpects: () => mergeExpects,
|
||||
printReceivedStringContainExpectedResult: () => printReceivedStringContainExpectedResult,
|
||||
printReceivedStringContainExpectedSubstring: () => printReceivedStringContainExpectedSubstring
|
||||
});
|
||||
module.exports = __toCommonJS(expect_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
var import_matchers = require("./matchers");
|
||||
var import_toMatchAriaSnapshot = require("./toMatchAriaSnapshot");
|
||||
var import_toMatchSnapshot = require("./toMatchSnapshot");
|
||||
var import_expectBundle = require("../common/expectBundle");
|
||||
var import_globals = require("../common/globals");
|
||||
var import_util = require("../util");
|
||||
var import_testInfo = require("../worker/testInfo");
|
||||
const printSubstring = (val) => val.replace(/"|\\/g, "\\$&");
|
||||
const printReceivedStringContainExpectedSubstring = (received, start, length) => (0, import_expectBundle.RECEIVED_COLOR)(
|
||||
'"' + printSubstring(received.slice(0, start)) + (0, import_expectBundle.INVERTED_COLOR)(printSubstring(received.slice(start, start + length))) + printSubstring(received.slice(start + length)) + '"'
|
||||
);
|
||||
const printReceivedStringContainExpectedResult = (received, result) => result === null ? (0, import_expectBundle.printReceived)(received) : printReceivedStringContainExpectedSubstring(
|
||||
received,
|
||||
result.index,
|
||||
result[0].length
|
||||
);
|
||||
function createMatchers(actual, info, prefix) {
|
||||
return new Proxy((0, import_expectBundle.expect)(actual), new ExpectMetaInfoProxyHandler(info, prefix));
|
||||
}
|
||||
const userMatchersSymbol = Symbol("userMatchers");
|
||||
function qualifiedMatcherName(qualifier, matcherName) {
|
||||
return qualifier.join(":") + "$" + matcherName;
|
||||
}
|
||||
function createExpect(info, prefix, userMatchers) {
|
||||
const expectInstance = new Proxy(import_expectBundle.expect, {
|
||||
apply: function(target, thisArg, argumentsList) {
|
||||
const [actual, messageOrOptions] = argumentsList;
|
||||
const message = (0, import_utils.isString)(messageOrOptions) ? messageOrOptions : messageOrOptions?.message || info.message;
|
||||
const newInfo = { ...info, message };
|
||||
if (newInfo.poll) {
|
||||
if (typeof actual !== "function")
|
||||
throw new Error("`expect.poll()` accepts only function as a first argument");
|
||||
newInfo.poll.generator = actual;
|
||||
}
|
||||
return createMatchers(actual, newInfo, prefix);
|
||||
},
|
||||
get: function(target, property) {
|
||||
if (property === "configure")
|
||||
return configure;
|
||||
if (property === "extend") {
|
||||
return (matchers) => {
|
||||
const qualifier = [...prefix, (0, import_utils.createGuid)()];
|
||||
const wrappedMatchers = {};
|
||||
for (const [name, matcher] of Object.entries(matchers)) {
|
||||
wrappedMatchers[name] = wrapPlaywrightMatcherToPassNiceThis(matcher);
|
||||
const key = qualifiedMatcherName(qualifier, name);
|
||||
wrappedMatchers[key] = wrappedMatchers[name];
|
||||
Object.defineProperty(wrappedMatchers[key], "name", { value: name });
|
||||
}
|
||||
import_expectBundle.expect.extend(wrappedMatchers);
|
||||
return createExpect(info, qualifier, { ...userMatchers, ...matchers });
|
||||
};
|
||||
}
|
||||
if (property === "soft") {
|
||||
return (actual, messageOrOptions) => {
|
||||
return configure({ soft: true })(actual, messageOrOptions);
|
||||
};
|
||||
}
|
||||
if (property === userMatchersSymbol)
|
||||
return userMatchers;
|
||||
if (property === "poll") {
|
||||
return (actual, messageOrOptions) => {
|
||||
const poll = (0, import_utils.isString)(messageOrOptions) ? {} : messageOrOptions || {};
|
||||
return configure({ _poll: poll })(actual, messageOrOptions);
|
||||
};
|
||||
}
|
||||
return import_expectBundle.expect[property];
|
||||
}
|
||||
});
|
||||
const configure = (configuration) => {
|
||||
const newInfo = { ...info };
|
||||
if ("message" in configuration)
|
||||
newInfo.message = configuration.message;
|
||||
if ("timeout" in configuration)
|
||||
newInfo.timeout = configuration.timeout;
|
||||
if ("soft" in configuration)
|
||||
newInfo.isSoft = configuration.soft;
|
||||
if ("_poll" in configuration) {
|
||||
newInfo.poll = configuration._poll ? { ...info.poll, generator: () => {
|
||||
} } : void 0;
|
||||
if (typeof configuration._poll === "object") {
|
||||
newInfo.poll.timeout = configuration._poll.timeout ?? newInfo.poll.timeout;
|
||||
newInfo.poll.intervals = configuration._poll.intervals ?? newInfo.poll.intervals;
|
||||
}
|
||||
}
|
||||
return createExpect(newInfo, prefix, userMatchers);
|
||||
};
|
||||
return expectInstance;
|
||||
}
|
||||
let matcherCallContext;
|
||||
function setMatcherCallContext(context) {
|
||||
matcherCallContext = context;
|
||||
}
|
||||
function takeMatcherCallContext() {
|
||||
try {
|
||||
return matcherCallContext;
|
||||
} finally {
|
||||
matcherCallContext = void 0;
|
||||
}
|
||||
}
|
||||
const defaultExpectTimeout = 5e3;
|
||||
function wrapPlaywrightMatcherToPassNiceThis(matcher) {
|
||||
return function(...args) {
|
||||
const { isNot, promise, utils } = this;
|
||||
const context = takeMatcherCallContext();
|
||||
const timeout = context?.expectInfo.timeout ?? context?.testInfo?._projectInternal?.expect?.timeout ?? defaultExpectTimeout;
|
||||
const newThis = {
|
||||
isNot,
|
||||
promise,
|
||||
utils,
|
||||
timeout,
|
||||
_stepInfo: context?.step
|
||||
};
|
||||
newThis.equals = throwUnsupportedExpectMatcherError;
|
||||
return matcher.call(newThis, ...args);
|
||||
};
|
||||
}
|
||||
function throwUnsupportedExpectMatcherError() {
|
||||
throw new Error("It looks like you are using custom expect matchers that are not compatible with Playwright. See https://aka.ms/playwright/expect-compatibility");
|
||||
}
|
||||
import_expectBundle.expect.setState({ expand: false });
|
||||
const customAsyncMatchers = {
|
||||
toBeAttached: import_matchers.toBeAttached,
|
||||
toBeChecked: import_matchers.toBeChecked,
|
||||
toBeDisabled: import_matchers.toBeDisabled,
|
||||
toBeEditable: import_matchers.toBeEditable,
|
||||
toBeEmpty: import_matchers.toBeEmpty,
|
||||
toBeEnabled: import_matchers.toBeEnabled,
|
||||
toBeFocused: import_matchers.toBeFocused,
|
||||
toBeHidden: import_matchers.toBeHidden,
|
||||
toBeInViewport: import_matchers.toBeInViewport,
|
||||
toBeOK: import_matchers.toBeOK,
|
||||
toBeVisible: import_matchers.toBeVisible,
|
||||
toContainText: import_matchers.toContainText,
|
||||
toContainClass: import_matchers.toContainClass,
|
||||
toHaveAccessibleDescription: import_matchers.toHaveAccessibleDescription,
|
||||
toHaveAccessibleName: import_matchers.toHaveAccessibleName,
|
||||
toHaveAccessibleErrorMessage: import_matchers.toHaveAccessibleErrorMessage,
|
||||
toHaveAttribute: import_matchers.toHaveAttribute,
|
||||
toHaveClass: import_matchers.toHaveClass,
|
||||
toHaveCount: import_matchers.toHaveCount,
|
||||
toHaveCSS: import_matchers.toHaveCSS,
|
||||
toHaveId: import_matchers.toHaveId,
|
||||
toHaveJSProperty: import_matchers.toHaveJSProperty,
|
||||
toHaveRole: import_matchers.toHaveRole,
|
||||
toHaveText: import_matchers.toHaveText,
|
||||
toHaveTitle: import_matchers.toHaveTitle,
|
||||
toHaveURL: import_matchers.toHaveURL,
|
||||
toHaveValue: import_matchers.toHaveValue,
|
||||
toHaveValues: import_matchers.toHaveValues,
|
||||
toHaveScreenshot: import_toMatchSnapshot.toHaveScreenshot,
|
||||
toMatchAriaSnapshot: import_toMatchAriaSnapshot.toMatchAriaSnapshot,
|
||||
toPass: import_matchers.toPass
|
||||
};
|
||||
const customMatchers = {
|
||||
...customAsyncMatchers,
|
||||
toMatchSnapshot: import_toMatchSnapshot.toMatchSnapshot
|
||||
};
|
||||
class ExpectMetaInfoProxyHandler {
|
||||
constructor(info, prefix) {
|
||||
this._info = { ...info };
|
||||
this._prefix = prefix;
|
||||
}
|
||||
get(target, matcherName, receiver) {
|
||||
let matcher = Reflect.get(target, matcherName, receiver);
|
||||
if (typeof matcherName !== "string")
|
||||
return matcher;
|
||||
let resolvedMatcherName = matcherName;
|
||||
for (let i = this._prefix.length; i > 0; i--) {
|
||||
const qualifiedName = qualifiedMatcherName(this._prefix.slice(0, i), matcherName);
|
||||
if (Reflect.has(target, qualifiedName)) {
|
||||
matcher = Reflect.get(target, qualifiedName, receiver);
|
||||
resolvedMatcherName = qualifiedName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matcher === void 0)
|
||||
throw new Error(`expect: Property '${matcherName}' not found.`);
|
||||
if (typeof matcher !== "function") {
|
||||
if (matcherName === "not")
|
||||
this._info.isNot = !this._info.isNot;
|
||||
return new Proxy(matcher, this);
|
||||
}
|
||||
if (this._info.poll) {
|
||||
if (customAsyncMatchers[matcherName] || matcherName === "resolves" || matcherName === "rejects")
|
||||
throw new Error(`\`expect.poll()\` does not support "${matcherName}" matcher.`);
|
||||
matcher = (...args) => pollMatcher(resolvedMatcherName, this._info, this._prefix, ...args);
|
||||
}
|
||||
return (...args) => {
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
setMatcherCallContext({ expectInfo: this._info, testInfo });
|
||||
if (!testInfo)
|
||||
return matcher.call(target, ...args);
|
||||
const customMessage = this._info.message || "";
|
||||
const argsSuffix = computeArgsSuffix(matcherName, args);
|
||||
const defaultTitle = `${this._info.poll ? "poll " : ""}${this._info.isSoft ? "soft " : ""}${this._info.isNot ? "not " : ""}${matcherName}${argsSuffix}`;
|
||||
const title = customMessage || `Expect ${(0, import_utils.escapeWithQuotes)(defaultTitle, '"')}`;
|
||||
const apiName = `expect${this._info.poll ? ".poll " : ""}${this._info.isSoft ? ".soft " : ""}${this._info.isNot ? ".not" : ""}.${matcherName}${argsSuffix}`;
|
||||
const stackFrames = (0, import_util.filteredStackTrace)((0, import_utils.captureRawStack)());
|
||||
const stepInfo = {
|
||||
category: "expect",
|
||||
apiName,
|
||||
title,
|
||||
params: args[0] ? { expected: args[0] } : void 0,
|
||||
infectParentStepsWithError: this._info.isSoft
|
||||
};
|
||||
const step = testInfo._addStep(stepInfo);
|
||||
const reportStepError = (e) => {
|
||||
const jestError = (0, import_matcherHint.isJestError)(e) ? e : null;
|
||||
const expectError = jestError ? new import_matcherHint.ExpectError(jestError, customMessage, stackFrames) : void 0;
|
||||
if (jestError?.matcherResult.suggestedRebaseline) {
|
||||
step.complete({ suggestedRebaseline: jestError?.matcherResult.suggestedRebaseline });
|
||||
return;
|
||||
}
|
||||
const error = expectError ?? e;
|
||||
step.complete({ error });
|
||||
if (this._info.isSoft)
|
||||
testInfo._failWithError(error);
|
||||
else
|
||||
throw error;
|
||||
};
|
||||
const finalizer = () => {
|
||||
step.complete({});
|
||||
};
|
||||
try {
|
||||
setMatcherCallContext({ expectInfo: this._info, testInfo, step: step.info });
|
||||
const callback = () => matcher.call(target, ...args);
|
||||
const result = (0, import_utils.currentZone)().with("stepZone", step).run(callback);
|
||||
if (result instanceof Promise)
|
||||
return result.then(finalizer).catch(reportStepError);
|
||||
finalizer();
|
||||
return result;
|
||||
} catch (e) {
|
||||
void reportStepError(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
async function pollMatcher(qualifiedMatcherName2, info, prefix, ...args) {
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
const poll = info.poll;
|
||||
const timeout = poll.timeout ?? info.timeout ?? testInfo?._projectInternal?.expect?.timeout ?? defaultExpectTimeout;
|
||||
const { deadline, timeoutMessage } = testInfo ? testInfo._deadlineForMatcher(timeout) : import_testInfo.TestInfoImpl._defaultDeadlineForMatcher(timeout);
|
||||
const result = await (0, import_utils.pollAgainstDeadline)(async () => {
|
||||
if (testInfo && (0, import_globals.currentTestInfo)() !== testInfo)
|
||||
return { continuePolling: false, result: void 0 };
|
||||
const innerInfo = {
|
||||
...info,
|
||||
isSoft: false,
|
||||
// soft is outside of poll, not inside
|
||||
poll: void 0
|
||||
};
|
||||
const value = await poll.generator();
|
||||
try {
|
||||
let matchers = createMatchers(value, innerInfo, prefix);
|
||||
if (info.isNot)
|
||||
matchers = matchers.not;
|
||||
matchers[qualifiedMatcherName2](...args);
|
||||
return { continuePolling: false, result: void 0 };
|
||||
} catch (error) {
|
||||
return { continuePolling: true, result: error };
|
||||
}
|
||||
}, deadline, poll.intervals ?? [100, 250, 500, 1e3]);
|
||||
if (result.timedOut) {
|
||||
const message = result.result ? [
|
||||
result.result.message,
|
||||
"",
|
||||
`Call Log:`,
|
||||
`- ${timeoutMessage}`
|
||||
].join("\n") : timeoutMessage;
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
function computeArgsSuffix(matcherName, args) {
|
||||
let value = "";
|
||||
if (matcherName === "toHaveScreenshot")
|
||||
value = (0, import_toMatchSnapshot.toHaveScreenshotStepTitle)(...args);
|
||||
return value ? `(${value})` : "";
|
||||
}
|
||||
const expect = createExpect({}, [], {}).extend(customMatchers);
|
||||
function mergeExpects(...expects) {
|
||||
let merged = expect;
|
||||
for (const e of expects) {
|
||||
const internals = e[userMatchersSymbol];
|
||||
if (!internals)
|
||||
continue;
|
||||
merged = merged.extend(internals);
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
expect,
|
||||
mergeExpects,
|
||||
printReceivedStringContainExpectedResult,
|
||||
printReceivedStringContainExpectedSubstring
|
||||
});
|
||||
87
node_modules/playwright/lib/matchers/matcherHint.js
generated
vendored
Normal file
87
node_modules/playwright/lib/matchers/matcherHint.js
generated
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var matcherHint_exports = {};
|
||||
__export(matcherHint_exports, {
|
||||
ExpectError: () => ExpectError,
|
||||
callLogText: () => callLogText,
|
||||
formatMatcherMessage: () => formatMatcherMessage,
|
||||
isJestError: () => isJestError
|
||||
});
|
||||
module.exports = __toCommonJS(matcherHint_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_expectBundle = require("../common/expectBundle");
|
||||
function formatMatcherMessage(state, details) {
|
||||
const receiver = details.receiver ?? (details.locator ? "locator" : "page");
|
||||
let message = (0, import_expectBundle.DIM_COLOR)("expect(") + (0, import_expectBundle.RECEIVED_COLOR)(receiver) + (0, import_expectBundle.DIM_COLOR)(")" + (state.promise ? "." + state.promise : "") + (state.isNot ? ".not" : "") + ".") + details.matcherName + (0, import_expectBundle.DIM_COLOR)("(") + (0, import_expectBundle.EXPECTED_COLOR)(details.expectation) + (0, import_expectBundle.DIM_COLOR)(")") + " failed\n\n";
|
||||
const diffLines = details.printedDiff?.split("\n");
|
||||
if (diffLines?.length === 2) {
|
||||
details.printedExpected = diffLines[0];
|
||||
details.printedReceived = diffLines[1];
|
||||
details.printedDiff = void 0;
|
||||
}
|
||||
const align = !details.errorMessage && details.printedExpected?.startsWith("Expected:") && (!details.printedReceived || details.printedReceived.startsWith("Received:"));
|
||||
if (details.locator)
|
||||
message += `Locator: ${align ? " " : ""}${String(details.locator)}
|
||||
`;
|
||||
if (details.printedExpected)
|
||||
message += details.printedExpected + "\n";
|
||||
if (details.printedReceived)
|
||||
message += details.printedReceived + "\n";
|
||||
if (details.timedOut && details.timeout)
|
||||
message += `Timeout: ${align ? " " : ""}${details.timeout}ms
|
||||
`;
|
||||
if (details.printedDiff)
|
||||
message += details.printedDiff + "\n";
|
||||
if (details.errorMessage) {
|
||||
message += details.errorMessage;
|
||||
if (!details.errorMessage.endsWith("\n"))
|
||||
message += "\n";
|
||||
}
|
||||
message += callLogText(details.log);
|
||||
return message;
|
||||
}
|
||||
class ExpectError extends Error {
|
||||
constructor(jestError, customMessage, stackFrames) {
|
||||
super("");
|
||||
this.name = jestError.name;
|
||||
this.message = jestError.message;
|
||||
this.matcherResult = jestError.matcherResult;
|
||||
if (customMessage)
|
||||
this.message = customMessage + "\n\n" + this.message;
|
||||
this.stack = this.name + ": " + this.message + "\n" + (0, import_utils.stringifyStackFrames)(stackFrames).join("\n");
|
||||
}
|
||||
}
|
||||
function isJestError(e) {
|
||||
return e instanceof Error && "matcherResult" in e;
|
||||
}
|
||||
const callLogText = (log) => {
|
||||
if (!log || !log.some((l) => !!l))
|
||||
return "";
|
||||
return `
|
||||
Call log:
|
||||
${(0, import_expectBundle.DIM_COLOR)(log.join("\n"))}
|
||||
`;
|
||||
};
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ExpectError,
|
||||
callLogText,
|
||||
formatMatcherMessage,
|
||||
isJestError
|
||||
});
|
||||
366
node_modules/playwright/lib/matchers/matchers.js
generated
vendored
Normal file
366
node_modules/playwright/lib/matchers/matchers.js
generated
vendored
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var matchers_exports = {};
|
||||
__export(matchers_exports, {
|
||||
toBeAttached: () => toBeAttached,
|
||||
toBeChecked: () => toBeChecked,
|
||||
toBeDisabled: () => toBeDisabled,
|
||||
toBeEditable: () => toBeEditable,
|
||||
toBeEmpty: () => toBeEmpty,
|
||||
toBeEnabled: () => toBeEnabled,
|
||||
toBeFocused: () => toBeFocused,
|
||||
toBeHidden: () => toBeHidden,
|
||||
toBeInViewport: () => toBeInViewport,
|
||||
toBeOK: () => toBeOK,
|
||||
toBeVisible: () => toBeVisible,
|
||||
toContainClass: () => toContainClass,
|
||||
toContainText: () => toContainText,
|
||||
toHaveAccessibleDescription: () => toHaveAccessibleDescription,
|
||||
toHaveAccessibleErrorMessage: () => toHaveAccessibleErrorMessage,
|
||||
toHaveAccessibleName: () => toHaveAccessibleName,
|
||||
toHaveAttribute: () => toHaveAttribute,
|
||||
toHaveCSS: () => toHaveCSS,
|
||||
toHaveClass: () => toHaveClass,
|
||||
toHaveCount: () => toHaveCount,
|
||||
toHaveId: () => toHaveId,
|
||||
toHaveJSProperty: () => toHaveJSProperty,
|
||||
toHaveRole: () => toHaveRole,
|
||||
toHaveText: () => toHaveText,
|
||||
toHaveTitle: () => toHaveTitle,
|
||||
toHaveURL: () => toHaveURL,
|
||||
toHaveValue: () => toHaveValue,
|
||||
toHaveValues: () => toHaveValues,
|
||||
toPass: () => toPass
|
||||
});
|
||||
module.exports = __toCommonJS(matchers_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_utils2 = require("playwright-core/lib/utils");
|
||||
var import_util = require("../util");
|
||||
var import_toBeTruthy = require("./toBeTruthy");
|
||||
var import_toEqual = require("./toEqual");
|
||||
var import_toHaveURL = require("./toHaveURL");
|
||||
var import_toMatchText = require("./toMatchText");
|
||||
var import_config = require("../common/config");
|
||||
var import_globals = require("../common/globals");
|
||||
var import_testInfo = require("../worker/testInfo");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
function toBeAttached(locator, options) {
|
||||
const attached = !options || options.attached === void 0 || options.attached;
|
||||
const expected = attached ? "attached" : "detached";
|
||||
const arg = attached ? "" : "{ attached: false }";
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeAttached", locator, "Locator", expected, arg, async (isNot, timeout) => {
|
||||
return await locator._expect(attached ? "to.be.attached" : "to.be.detached", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeChecked(locator, options) {
|
||||
const checked = options?.checked;
|
||||
const indeterminate = options?.indeterminate;
|
||||
const expectedValue = {
|
||||
checked,
|
||||
indeterminate
|
||||
};
|
||||
let expected;
|
||||
let arg;
|
||||
if (options?.indeterminate) {
|
||||
expected = "indeterminate";
|
||||
arg = `{ indeterminate: true }`;
|
||||
} else {
|
||||
expected = options?.checked === false ? "unchecked" : "checked";
|
||||
arg = options?.checked === false ? `{ checked: false }` : "";
|
||||
}
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeChecked", locator, "Locator", expected, arg, async (isNot, timeout) => {
|
||||
return await locator._expect("to.be.checked", { isNot, timeout, expectedValue });
|
||||
}, options);
|
||||
}
|
||||
function toBeDisabled(locator, options) {
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeDisabled", locator, "Locator", "disabled", "", async (isNot, timeout) => {
|
||||
return await locator._expect("to.be.disabled", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeEditable(locator, options) {
|
||||
const editable = !options || options.editable === void 0 || options.editable;
|
||||
const expected = editable ? "editable" : "readOnly";
|
||||
const arg = editable ? "" : "{ editable: false }";
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeEditable", locator, "Locator", expected, arg, async (isNot, timeout) => {
|
||||
return await locator._expect(editable ? "to.be.editable" : "to.be.readonly", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeEmpty(locator, options) {
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeEmpty", locator, "Locator", "empty", "", async (isNot, timeout) => {
|
||||
return await locator._expect("to.be.empty", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeEnabled(locator, options) {
|
||||
const enabled = !options || options.enabled === void 0 || options.enabled;
|
||||
const expected = enabled ? "enabled" : "disabled";
|
||||
const arg = enabled ? "" : "{ enabled: false }";
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeEnabled", locator, "Locator", expected, arg, async (isNot, timeout) => {
|
||||
return await locator._expect(enabled ? "to.be.enabled" : "to.be.disabled", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeFocused(locator, options) {
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeFocused", locator, "Locator", "focused", "", async (isNot, timeout) => {
|
||||
return await locator._expect("to.be.focused", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeHidden(locator, options) {
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeHidden", locator, "Locator", "hidden", "", async (isNot, timeout) => {
|
||||
return await locator._expect("to.be.hidden", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeVisible(locator, options) {
|
||||
const visible = !options || options.visible === void 0 || options.visible;
|
||||
const expected = visible ? "visible" : "hidden";
|
||||
const arg = visible ? "" : "{ visible: false }";
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeVisible", locator, "Locator", expected, arg, async (isNot, timeout) => {
|
||||
return await locator._expect(visible ? "to.be.visible" : "to.be.hidden", { isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toBeInViewport(locator, options) {
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toBeInViewport", locator, "Locator", "in viewport", "", async (isNot, timeout) => {
|
||||
return await locator._expect("to.be.in.viewport", { isNot, expectedNumber: options?.ratio, timeout });
|
||||
}, options);
|
||||
}
|
||||
function toContainText(locator, expected, options = {}) {
|
||||
if (Array.isArray(expected)) {
|
||||
return import_toEqual.toEqual.call(this, "toContainText", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)(expected, { matchSubstring: true, normalizeWhiteSpace: true, ignoreCase: options.ignoreCase });
|
||||
return await locator._expect("to.contain.text.array", { expectedText, isNot, useInnerText: options.useInnerText, timeout });
|
||||
}, expected, { ...options, contains: true });
|
||||
} else {
|
||||
return import_toMatchText.toMatchText.call(this, "toContainText", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { matchSubstring: true, normalizeWhiteSpace: true, ignoreCase: options.ignoreCase });
|
||||
return await locator._expect("to.have.text", { expectedText, isNot, useInnerText: options.useInnerText, timeout });
|
||||
}, expected, { ...options, matchSubstring: true });
|
||||
}
|
||||
}
|
||||
function toHaveAccessibleDescription(locator, expected, options) {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveAccessibleDescription", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { ignoreCase: options?.ignoreCase, normalizeWhiteSpace: true });
|
||||
return await locator._expect("to.have.accessible.description", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveAccessibleName(locator, expected, options) {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveAccessibleName", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { ignoreCase: options?.ignoreCase, normalizeWhiteSpace: true });
|
||||
return await locator._expect("to.have.accessible.name", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveAccessibleErrorMessage(locator, expected, options) {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveAccessibleErrorMessage", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { ignoreCase: options?.ignoreCase, normalizeWhiteSpace: true });
|
||||
return await locator._expect("to.have.accessible.error.message", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveAttribute(locator, name, expected, options) {
|
||||
if (!options) {
|
||||
if (typeof expected === "object" && !(0, import_utils.isRegExp)(expected)) {
|
||||
options = expected;
|
||||
expected = void 0;
|
||||
}
|
||||
}
|
||||
if (expected === void 0) {
|
||||
return import_toBeTruthy.toBeTruthy.call(this, "toHaveAttribute", locator, "Locator", "have attribute", "", async (isNot, timeout) => {
|
||||
return await locator._expect("to.have.attribute", { expressionArg: name, isNot, timeout });
|
||||
}, options);
|
||||
}
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveAttribute", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { ignoreCase: options?.ignoreCase });
|
||||
return await locator._expect("to.have.attribute.value", { expressionArg: name, expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveClass(locator, expected, options) {
|
||||
if (Array.isArray(expected)) {
|
||||
return import_toEqual.toEqual.call(this, "toHaveClass", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)(expected);
|
||||
return await locator._expect("to.have.class.array", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
} else {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveClass", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected]);
|
||||
return await locator._expect("to.have.class", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
}
|
||||
function toContainClass(locator, expected, options) {
|
||||
if (Array.isArray(expected)) {
|
||||
if (expected.some((e) => (0, import_utils.isRegExp)(e)))
|
||||
throw new Error(`"expected" argument in toContainClass cannot contain RegExp values`);
|
||||
return import_toEqual.toEqual.call(this, "toContainClass", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)(expected);
|
||||
return await locator._expect("to.contain.class.array", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
} else {
|
||||
if ((0, import_utils.isRegExp)(expected))
|
||||
throw new Error(`"expected" argument in toContainClass cannot be a RegExp value`);
|
||||
return import_toMatchText.toMatchText.call(this, "toContainClass", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected]);
|
||||
return await locator._expect("to.contain.class", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
}
|
||||
function toHaveCount(locator, expected, options) {
|
||||
return import_toEqual.toEqual.call(this, "toHaveCount", locator, "Locator", async (isNot, timeout) => {
|
||||
return await locator._expect("to.have.count", { expectedNumber: expected, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveCSS(locator, name, expected, options) {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveCSS", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected]);
|
||||
return await locator._expect("to.have.css", { expressionArg: name, expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveId(locator, expected, options) {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveId", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected]);
|
||||
return await locator._expect("to.have.id", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveJSProperty(locator, name, expected, options) {
|
||||
return import_toEqual.toEqual.call(this, "toHaveJSProperty", locator, "Locator", async (isNot, timeout) => {
|
||||
return await locator._expect("to.have.property", { expressionArg: name, expectedValue: expected, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveRole(locator, expected, options) {
|
||||
if (!(0, import_utils.isString)(expected))
|
||||
throw new Error(`"role" argument in toHaveRole must be a string`);
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveRole", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected]);
|
||||
return await locator._expect("to.have.role", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveText(locator, expected, options = {}) {
|
||||
if (Array.isArray(expected)) {
|
||||
return import_toEqual.toEqual.call(this, "toHaveText", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)(expected, { normalizeWhiteSpace: true, ignoreCase: options.ignoreCase });
|
||||
return await locator._expect("to.have.text.array", { expectedText, isNot, useInnerText: options?.useInnerText, timeout });
|
||||
}, expected, options);
|
||||
} else {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveText", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { normalizeWhiteSpace: true, ignoreCase: options.ignoreCase });
|
||||
return await locator._expect("to.have.text", { expectedText, isNot, useInnerText: options?.useInnerText, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
}
|
||||
function toHaveValue(locator, expected, options) {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveValue", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected]);
|
||||
return await locator._expect("to.have.value", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveValues(locator, expected, options) {
|
||||
return import_toEqual.toEqual.call(this, "toHaveValues", locator, "Locator", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)(expected);
|
||||
return await locator._expect("to.have.values", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveTitle(page, expected, options = {}) {
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveTitle", page, "Page", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { normalizeWhiteSpace: true });
|
||||
return await page.mainFrame()._expect("to.have.title", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
function toHaveURL(page, expected, options) {
|
||||
if (typeof expected === "function")
|
||||
return import_toHaveURL.toHaveURLWithPredicate.call(this, page, expected, options);
|
||||
const baseURL = page.context()._options.baseURL;
|
||||
expected = typeof expected === "string" ? (0, import_utils.constructURLBasedOnBaseURL)(baseURL, expected) : expected;
|
||||
return import_toMatchText.toMatchText.call(this, "toHaveURL", page, "Page", async (isNot, timeout) => {
|
||||
const expectedText = (0, import_utils.serializeExpectedTextValues)([expected], { ignoreCase: options?.ignoreCase });
|
||||
return await page.mainFrame()._expect("to.have.url", { expectedText, isNot, timeout });
|
||||
}, expected, options);
|
||||
}
|
||||
async function toBeOK(response) {
|
||||
const matcherName = "toBeOK";
|
||||
(0, import_util.expectTypes)(response, ["APIResponse"], matcherName);
|
||||
const contentType = response.headers()["content-type"];
|
||||
const isTextEncoding = contentType && (0, import_utils.isTextualMimeType)(contentType);
|
||||
const [log, text] = this.isNot === response.ok() ? await Promise.all([
|
||||
response._fetchLog(),
|
||||
isTextEncoding ? response.text() : null
|
||||
]) : [];
|
||||
const message = () => (0, import_matcherHint.formatMatcherMessage)(this, {
|
||||
matcherName,
|
||||
receiver: "response",
|
||||
expectation: "",
|
||||
log
|
||||
}) + (text === null ? "" : `
|
||||
Response text:
|
||||
${import_utils2.colors.dim(text?.substring(0, 1e3) || "")}`);
|
||||
const pass = response.ok();
|
||||
return { message, pass };
|
||||
}
|
||||
async function toPass(callback, options = {}) {
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
const timeout = (0, import_config.takeFirst)(options.timeout, testInfo?._projectInternal.expect?.toPass?.timeout, 0);
|
||||
const intervals = (0, import_config.takeFirst)(options.intervals, testInfo?._projectInternal.expect?.toPass?.intervals, [100, 250, 500, 1e3]);
|
||||
const { deadline, timeoutMessage } = testInfo ? testInfo._deadlineForMatcher(timeout) : import_testInfo.TestInfoImpl._defaultDeadlineForMatcher(timeout);
|
||||
const result = await (0, import_utils.pollAgainstDeadline)(async () => {
|
||||
if (testInfo && (0, import_globals.currentTestInfo)() !== testInfo)
|
||||
return { continuePolling: false, result: void 0 };
|
||||
try {
|
||||
await callback();
|
||||
return { continuePolling: !!this.isNot, result: void 0 };
|
||||
} catch (e) {
|
||||
return { continuePolling: !this.isNot, result: e };
|
||||
}
|
||||
}, deadline, intervals);
|
||||
if (result.timedOut) {
|
||||
const message = result.result ? [
|
||||
result.result.message,
|
||||
"",
|
||||
`Call Log:`,
|
||||
`- ${timeoutMessage}`
|
||||
].join("\n") : timeoutMessage;
|
||||
return { message: () => message, pass: !!this.isNot };
|
||||
}
|
||||
return { pass: !this.isNot, message: () => "" };
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toBeAttached,
|
||||
toBeChecked,
|
||||
toBeDisabled,
|
||||
toBeEditable,
|
||||
toBeEmpty,
|
||||
toBeEnabled,
|
||||
toBeFocused,
|
||||
toBeHidden,
|
||||
toBeInViewport,
|
||||
toBeOK,
|
||||
toBeVisible,
|
||||
toContainClass,
|
||||
toContainText,
|
||||
toHaveAccessibleDescription,
|
||||
toHaveAccessibleErrorMessage,
|
||||
toHaveAccessibleName,
|
||||
toHaveAttribute,
|
||||
toHaveCSS,
|
||||
toHaveClass,
|
||||
toHaveCount,
|
||||
toHaveId,
|
||||
toHaveJSProperty,
|
||||
toHaveRole,
|
||||
toHaveText,
|
||||
toHaveTitle,
|
||||
toHaveURL,
|
||||
toHaveValue,
|
||||
toHaveValues,
|
||||
toPass
|
||||
});
|
||||
73
node_modules/playwright/lib/matchers/toBeTruthy.js
generated
vendored
Normal file
73
node_modules/playwright/lib/matchers/toBeTruthy.js
generated
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var toBeTruthy_exports = {};
|
||||
__export(toBeTruthy_exports, {
|
||||
toBeTruthy: () => toBeTruthy
|
||||
});
|
||||
module.exports = __toCommonJS(toBeTruthy_exports);
|
||||
var import_util = require("../util");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
async function toBeTruthy(matcherName, locator, receiverType, expected, arg, query, options = {}) {
|
||||
(0, import_util.expectTypes)(locator, [receiverType], matcherName);
|
||||
const timeout = options.timeout ?? this.timeout;
|
||||
const { matches: pass, log, timedOut, received, errorMessage } = await query(!!this.isNot, timeout);
|
||||
if (pass === !this.isNot) {
|
||||
return {
|
||||
name: matcherName,
|
||||
message: () => "",
|
||||
pass,
|
||||
expected
|
||||
};
|
||||
}
|
||||
let printedReceived;
|
||||
let printedExpected;
|
||||
if (pass) {
|
||||
printedExpected = `Expected: not ${expected}`;
|
||||
printedReceived = errorMessage ? "" : `Received: ${expected}`;
|
||||
} else {
|
||||
printedExpected = `Expected: ${expected}`;
|
||||
printedReceived = errorMessage ? "" : `Received: ${received}`;
|
||||
}
|
||||
const message = () => {
|
||||
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
||||
matcherName,
|
||||
expectation: arg,
|
||||
locator,
|
||||
timeout,
|
||||
timedOut,
|
||||
printedExpected,
|
||||
printedReceived,
|
||||
errorMessage,
|
||||
log
|
||||
});
|
||||
};
|
||||
return {
|
||||
message,
|
||||
pass,
|
||||
actual: received,
|
||||
name: matcherName,
|
||||
expected,
|
||||
log,
|
||||
timeout: timedOut ? timeout : void 0
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toBeTruthy
|
||||
});
|
||||
99
node_modules/playwright/lib/matchers/toEqual.js
generated
vendored
Normal file
99
node_modules/playwright/lib/matchers/toEqual.js
generated
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var toEqual_exports = {};
|
||||
__export(toEqual_exports, {
|
||||
toEqual: () => toEqual
|
||||
});
|
||||
module.exports = __toCommonJS(toEqual_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_util = require("../util");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
const EXPECTED_LABEL = "Expected";
|
||||
const RECEIVED_LABEL = "Received";
|
||||
async function toEqual(matcherName, locator, receiverType, query, expected, options = {}) {
|
||||
(0, import_util.expectTypes)(locator, [receiverType], matcherName);
|
||||
const timeout = options.timeout ?? this.timeout;
|
||||
const { matches: pass, received, log, timedOut, errorMessage } = await query(!!this.isNot, timeout);
|
||||
if (pass === !this.isNot) {
|
||||
return {
|
||||
name: matcherName,
|
||||
message: () => "",
|
||||
pass,
|
||||
expected
|
||||
};
|
||||
}
|
||||
let printedReceived;
|
||||
let printedExpected;
|
||||
let printedDiff;
|
||||
if (pass) {
|
||||
printedExpected = `Expected: not ${this.utils.printExpected(expected)}`;
|
||||
printedReceived = errorMessage ? "" : `Received: ${this.utils.printReceived(received)}`;
|
||||
} else if (errorMessage) {
|
||||
printedExpected = `Expected: ${this.utils.printExpected(expected)}`;
|
||||
} else if (Array.isArray(expected) && Array.isArray(received)) {
|
||||
const normalizedExpected = expected.map((exp, index) => {
|
||||
const rec = received[index];
|
||||
if ((0, import_utils.isRegExp)(exp))
|
||||
return exp.test(rec) ? rec : exp;
|
||||
return exp;
|
||||
});
|
||||
printedDiff = this.utils.printDiffOrStringify(
|
||||
normalizedExpected,
|
||||
received,
|
||||
EXPECTED_LABEL,
|
||||
RECEIVED_LABEL,
|
||||
false
|
||||
);
|
||||
} else {
|
||||
printedDiff = this.utils.printDiffOrStringify(
|
||||
expected,
|
||||
received,
|
||||
EXPECTED_LABEL,
|
||||
RECEIVED_LABEL,
|
||||
false
|
||||
);
|
||||
}
|
||||
const message = () => {
|
||||
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
||||
matcherName,
|
||||
expectation: "expected",
|
||||
locator,
|
||||
timeout,
|
||||
timedOut,
|
||||
printedExpected,
|
||||
printedReceived,
|
||||
printedDiff,
|
||||
errorMessage,
|
||||
log
|
||||
});
|
||||
};
|
||||
return {
|
||||
actual: received,
|
||||
expected,
|
||||
message,
|
||||
name: matcherName,
|
||||
pass,
|
||||
log,
|
||||
timeout: timedOut ? timeout : void 0
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toEqual
|
||||
});
|
||||
102
node_modules/playwright/lib/matchers/toHaveURL.js
generated
vendored
Normal file
102
node_modules/playwright/lib/matchers/toHaveURL.js
generated
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var toHaveURL_exports = {};
|
||||
__export(toHaveURL_exports, {
|
||||
toHaveURLWithPredicate: () => toHaveURLWithPredicate
|
||||
});
|
||||
module.exports = __toCommonJS(toHaveURL_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_expect = require("./expect");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
var import_expectBundle = require("../common/expectBundle");
|
||||
async function toHaveURLWithPredicate(page, expected, options) {
|
||||
const matcherName = "toHaveURL";
|
||||
const timeout = options?.timeout ?? this.timeout;
|
||||
const baseURL = page.context()._options.baseURL;
|
||||
let conditionSucceeded = false;
|
||||
let lastCheckedURLString = void 0;
|
||||
try {
|
||||
await page.mainFrame().waitForURL(
|
||||
(url) => {
|
||||
lastCheckedURLString = url.toString();
|
||||
if (options?.ignoreCase) {
|
||||
return !this.isNot === (0, import_utils.urlMatches)(
|
||||
baseURL?.toLocaleLowerCase(),
|
||||
lastCheckedURLString.toLocaleLowerCase(),
|
||||
expected
|
||||
);
|
||||
}
|
||||
return !this.isNot === (0, import_utils.urlMatches)(baseURL, lastCheckedURLString, expected);
|
||||
},
|
||||
{ timeout }
|
||||
);
|
||||
conditionSucceeded = true;
|
||||
} catch (e) {
|
||||
conditionSucceeded = false;
|
||||
}
|
||||
if (conditionSucceeded)
|
||||
return { name: matcherName, pass: !this.isNot, message: () => "" };
|
||||
return {
|
||||
name: matcherName,
|
||||
pass: this.isNot,
|
||||
message: () => toHaveURLMessage(
|
||||
this,
|
||||
matcherName,
|
||||
expected,
|
||||
lastCheckedURLString,
|
||||
this.isNot,
|
||||
true,
|
||||
timeout
|
||||
),
|
||||
actual: lastCheckedURLString,
|
||||
timeout
|
||||
};
|
||||
}
|
||||
function toHaveURLMessage(state, matcherName, expected, received, pass, timedOut, timeout) {
|
||||
const receivedString = received || "";
|
||||
let printedReceived;
|
||||
let printedExpected;
|
||||
let printedDiff;
|
||||
if (typeof expected === "function") {
|
||||
printedExpected = `Expected: predicate to ${!state.isNot ? "succeed" : "fail"}`;
|
||||
printedReceived = `Received: ${(0, import_expectBundle.printReceived)(receivedString)}`;
|
||||
} else {
|
||||
if (pass) {
|
||||
printedExpected = `Expected pattern: not ${state.utils.printExpected(expected)}`;
|
||||
const formattedReceived = (0, import_expect.printReceivedStringContainExpectedResult)(receivedString, null);
|
||||
printedReceived = `Received string: ${formattedReceived}`;
|
||||
} else {
|
||||
const labelExpected = `Expected ${typeof expected === "string" ? "string" : "pattern"}`;
|
||||
printedDiff = state.utils.printDiffOrStringify(expected, receivedString, labelExpected, "Received string", false);
|
||||
}
|
||||
}
|
||||
return (0, import_matcherHint.formatMatcherMessage)(state, {
|
||||
matcherName,
|
||||
expectation: "expected",
|
||||
timeout,
|
||||
timedOut,
|
||||
printedExpected,
|
||||
printedReceived,
|
||||
printedDiff
|
||||
});
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toHaveURLWithPredicate
|
||||
});
|
||||
159
node_modules/playwright/lib/matchers/toMatchAriaSnapshot.js
generated
vendored
Normal file
159
node_modules/playwright/lib/matchers/toMatchAriaSnapshot.js
generated
vendored
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var toMatchAriaSnapshot_exports = {};
|
||||
__export(toMatchAriaSnapshot_exports, {
|
||||
toMatchAriaSnapshot: () => toMatchAriaSnapshot
|
||||
});
|
||||
module.exports = __toCommonJS(toMatchAriaSnapshot_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
var import_util = require("../util");
|
||||
var import_expect = require("./expect");
|
||||
var import_globals = require("../common/globals");
|
||||
async function toMatchAriaSnapshot(locator, expectedParam, options = {}) {
|
||||
const matcherName = "toMatchAriaSnapshot";
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo)
|
||||
throw new Error(`toMatchAriaSnapshot() must be called during the test`);
|
||||
if (testInfo._projectInternal.ignoreSnapshots)
|
||||
return { pass: !this.isNot, message: () => "", name: "toMatchAriaSnapshot", expected: "" };
|
||||
const updateSnapshots = testInfo.config.updateSnapshots;
|
||||
let expected;
|
||||
let timeout;
|
||||
let expectedPath;
|
||||
if ((0, import_utils.isString)(expectedParam)) {
|
||||
expected = expectedParam;
|
||||
timeout = options.timeout ?? this.timeout;
|
||||
} else {
|
||||
const legacyPath = testInfo._resolveSnapshotPaths("aria", expectedParam?.name, "dontUpdateSnapshotIndex", ".yml").absoluteSnapshotPath;
|
||||
expectedPath = testInfo._resolveSnapshotPaths("aria", expectedParam?.name, "updateSnapshotIndex").absoluteSnapshotPath;
|
||||
if (!await (0, import_util.fileExistsAsync)(expectedPath) && await (0, import_util.fileExistsAsync)(legacyPath))
|
||||
expectedPath = legacyPath;
|
||||
expected = await import_fs.default.promises.readFile(expectedPath, "utf8").catch(() => "");
|
||||
timeout = expectedParam?.timeout ?? this.timeout;
|
||||
}
|
||||
const generateMissingBaseline = updateSnapshots === "missing" && !expected;
|
||||
if (generateMissingBaseline) {
|
||||
if (this.isNot) {
|
||||
const message2 = `Matchers using ".not" can't generate new baselines`;
|
||||
return { pass: this.isNot, message: () => message2, name: "toMatchAriaSnapshot" };
|
||||
} else {
|
||||
expected = `- none "Generating new baseline"`;
|
||||
}
|
||||
}
|
||||
expected = unshift(expected);
|
||||
const { matches: pass, received, log, timedOut, errorMessage } = await locator._expect("to.match.aria", { expectedValue: expected, isNot: this.isNot, timeout });
|
||||
const typedReceived = received;
|
||||
const message = () => {
|
||||
let printedExpected;
|
||||
let printedReceived;
|
||||
let printedDiff;
|
||||
if (errorMessage) {
|
||||
printedExpected = `Expected: ${this.isNot ? "not " : ""}${this.utils.printExpected(expected)}`;
|
||||
} else if (pass) {
|
||||
const receivedString = (0, import_expect.printReceivedStringContainExpectedSubstring)(typedReceived.raw, typedReceived.raw.indexOf(expected), expected.length);
|
||||
printedExpected = `Expected: not ${this.utils.printExpected(expected)}`;
|
||||
printedReceived = `Received: ${receivedString}`;
|
||||
} else {
|
||||
printedDiff = this.utils.printDiffOrStringify(expected, typedReceived.raw, "Expected", "Received", false);
|
||||
}
|
||||
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
||||
matcherName,
|
||||
expectation: "expected",
|
||||
locator,
|
||||
timeout,
|
||||
timedOut,
|
||||
printedExpected,
|
||||
printedReceived,
|
||||
printedDiff,
|
||||
errorMessage,
|
||||
log
|
||||
});
|
||||
};
|
||||
if (errorMessage)
|
||||
return { pass: this.isNot, message, name: "toMatchAriaSnapshot", expected };
|
||||
if (!this.isNot) {
|
||||
if (updateSnapshots === "all" || updateSnapshots === "changed" && pass === this.isNot || generateMissingBaseline) {
|
||||
if (expectedPath) {
|
||||
await import_fs.default.promises.mkdir(import_path.default.dirname(expectedPath), { recursive: true });
|
||||
await import_fs.default.promises.writeFile(expectedPath, typedReceived.regex, "utf8");
|
||||
const relativePath = import_path.default.relative(process.cwd(), expectedPath);
|
||||
if (updateSnapshots === "missing") {
|
||||
const message2 = `A snapshot doesn't exist at ${relativePath}, writing actual.`;
|
||||
testInfo._hasNonRetriableError = true;
|
||||
testInfo._failWithError(new Error(message2));
|
||||
} else {
|
||||
const message2 = `A snapshot is generated at ${relativePath}.`;
|
||||
console.log(message2);
|
||||
}
|
||||
return { pass: true, message: () => "", name: "toMatchAriaSnapshot" };
|
||||
} else {
|
||||
const suggestedRebaseline = `\`
|
||||
${(0, import_utils.escapeTemplateString)(indent(typedReceived.regex, "{indent} "))}
|
||||
{indent}\``;
|
||||
if (updateSnapshots === "missing") {
|
||||
const message2 = "A snapshot is not provided, generating new baseline.";
|
||||
testInfo._hasNonRetriableError = true;
|
||||
testInfo._failWithError(new Error(message2));
|
||||
}
|
||||
return { pass: false, message: () => "", name: "toMatchAriaSnapshot", suggestedRebaseline };
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
name: matcherName,
|
||||
expected,
|
||||
message,
|
||||
pass,
|
||||
actual: received,
|
||||
log,
|
||||
timeout: timedOut ? timeout : void 0
|
||||
};
|
||||
}
|
||||
function unshift(snapshot) {
|
||||
const lines = snapshot.split("\n");
|
||||
let whitespacePrefixLength = 100;
|
||||
for (const line of lines) {
|
||||
if (!line.trim())
|
||||
continue;
|
||||
const match = line.match(/^(\s*)/);
|
||||
if (match && match[1].length < whitespacePrefixLength)
|
||||
whitespacePrefixLength = match[1].length;
|
||||
}
|
||||
return lines.filter((t) => t.trim()).map((line) => line.substring(whitespacePrefixLength)).join("\n");
|
||||
}
|
||||
function indent(snapshot, indent2) {
|
||||
return snapshot.split("\n").map((line) => indent2 + line).join("\n");
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toMatchAriaSnapshot
|
||||
});
|
||||
341
node_modules/playwright/lib/matchers/toMatchSnapshot.js
generated
vendored
Normal file
341
node_modules/playwright/lib/matchers/toMatchSnapshot.js
generated
vendored
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var toMatchSnapshot_exports = {};
|
||||
__export(toMatchSnapshot_exports, {
|
||||
toHaveScreenshot: () => toHaveScreenshot,
|
||||
toHaveScreenshotStepTitle: () => toHaveScreenshotStepTitle,
|
||||
toMatchSnapshot: () => toMatchSnapshot
|
||||
});
|
||||
module.exports = __toCommonJS(toMatchSnapshot_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_utils2 = require("playwright-core/lib/utils");
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_util = require("../util");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
var import_globals = require("../common/globals");
|
||||
const NonConfigProperties = [
|
||||
"clip",
|
||||
"fullPage",
|
||||
"mask",
|
||||
"maskColor",
|
||||
"omitBackground",
|
||||
"timeout"
|
||||
];
|
||||
class SnapshotHelper {
|
||||
constructor(testInfo, matcherName, locator, anonymousSnapshotExtension, configOptions, nameOrOptions, optOptions) {
|
||||
let name;
|
||||
if (Array.isArray(nameOrOptions) || typeof nameOrOptions === "string") {
|
||||
name = nameOrOptions;
|
||||
this.options = { ...optOptions };
|
||||
} else {
|
||||
const { name: nameFromOptions, ...options } = nameOrOptions;
|
||||
this.options = options;
|
||||
name = nameFromOptions;
|
||||
}
|
||||
this.name = Array.isArray(name) ? name.join(import_path.default.sep) : name || "";
|
||||
const resolvedPaths = testInfo._resolveSnapshotPaths(matcherName === "toHaveScreenshot" ? "screenshot" : "snapshot", name, "updateSnapshotIndex", anonymousSnapshotExtension);
|
||||
this.expectedPath = resolvedPaths.absoluteSnapshotPath;
|
||||
this.attachmentBaseName = resolvedPaths.relativeOutputPath;
|
||||
const outputBasePath = testInfo._getOutputPath(resolvedPaths.relativeOutputPath);
|
||||
this.legacyExpectedPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-expected");
|
||||
this.previousPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-previous");
|
||||
this.actualPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-actual");
|
||||
this.diffPath = (0, import_util.addSuffixToFilePath)(outputBasePath, "-diff");
|
||||
const filteredConfigOptions = { ...configOptions };
|
||||
for (const prop of NonConfigProperties)
|
||||
delete filteredConfigOptions[prop];
|
||||
this.options = {
|
||||
...filteredConfigOptions,
|
||||
...this.options
|
||||
};
|
||||
if (this.options._comparator) {
|
||||
this.options.comparator = this.options._comparator;
|
||||
delete this.options._comparator;
|
||||
}
|
||||
if (this.options.maxDiffPixels !== void 0 && this.options.maxDiffPixels < 0)
|
||||
throw new Error("`maxDiffPixels` option value must be non-negative integer");
|
||||
if (this.options.maxDiffPixelRatio !== void 0 && (this.options.maxDiffPixelRatio < 0 || this.options.maxDiffPixelRatio > 1))
|
||||
throw new Error("`maxDiffPixelRatio` option value must be between 0 and 1");
|
||||
this.matcherName = matcherName;
|
||||
this.locator = locator;
|
||||
this.updateSnapshots = testInfo.config.updateSnapshots;
|
||||
this.mimeType = import_utilsBundle.mime.getType(import_path.default.basename(this.expectedPath)) ?? "application/octet-stream";
|
||||
this.comparator = (0, import_utils.getComparator)(this.mimeType);
|
||||
this.testInfo = testInfo;
|
||||
this.kind = this.mimeType.startsWith("image/") ? "Screenshot" : "Snapshot";
|
||||
}
|
||||
createMatcherResult(message, pass, log) {
|
||||
const unfiltered = {
|
||||
name: this.matcherName,
|
||||
expected: this.expectedPath,
|
||||
actual: this.actualPath,
|
||||
diff: this.diffPath,
|
||||
pass,
|
||||
message: () => message,
|
||||
log
|
||||
};
|
||||
return Object.fromEntries(Object.entries(unfiltered).filter(([_, v]) => v !== void 0));
|
||||
}
|
||||
handleMissingNegated() {
|
||||
const isWriteMissingMode = this.updateSnapshots !== "none";
|
||||
const message = `A snapshot doesn't exist at ${this.expectedPath}${isWriteMissingMode ? `, matchers using ".not" won't write them automatically.` : "."}`;
|
||||
return this.createMatcherResult(message, true);
|
||||
}
|
||||
handleDifferentNegated() {
|
||||
return this.createMatcherResult("", false);
|
||||
}
|
||||
handleMatchingNegated() {
|
||||
const message = [
|
||||
import_utils2.colors.red(`${this.kind} comparison failed:`),
|
||||
"",
|
||||
indent("Expected result should be different from the actual one.", " ")
|
||||
].join("\n");
|
||||
return this.createMatcherResult(message, true);
|
||||
}
|
||||
handleMissing(actual, step) {
|
||||
const isWriteMissingMode = this.updateSnapshots !== "none";
|
||||
if (isWriteMissingMode)
|
||||
writeFileSync(this.expectedPath, actual);
|
||||
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-expected"), contentType: this.mimeType, path: this.expectedPath });
|
||||
writeFileSync(this.actualPath, actual);
|
||||
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-actual"), contentType: this.mimeType, path: this.actualPath });
|
||||
const message = `A snapshot doesn't exist at ${this.expectedPath}${isWriteMissingMode ? ", writing actual." : "."}`;
|
||||
if (this.updateSnapshots === "all" || this.updateSnapshots === "changed") {
|
||||
console.log(message);
|
||||
return this.createMatcherResult(message, true);
|
||||
}
|
||||
if (this.updateSnapshots === "missing") {
|
||||
this.testInfo._hasNonRetriableError = true;
|
||||
this.testInfo._failWithError(new Error(message));
|
||||
return this.createMatcherResult("", true);
|
||||
}
|
||||
return this.createMatcherResult(message, false);
|
||||
}
|
||||
handleDifferent(actual, expected, previous, diff, header, diffError, log, step) {
|
||||
const output = [`${header}${indent(diffError, " ")}`];
|
||||
if (this.name) {
|
||||
output.push("");
|
||||
output.push(` Snapshot: ${this.name}`);
|
||||
}
|
||||
if (expected !== void 0) {
|
||||
writeFileSync(this.legacyExpectedPath, expected);
|
||||
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-expected"), contentType: this.mimeType, path: this.expectedPath });
|
||||
}
|
||||
if (previous !== void 0) {
|
||||
writeFileSync(this.previousPath, previous);
|
||||
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-previous"), contentType: this.mimeType, path: this.previousPath });
|
||||
}
|
||||
if (actual !== void 0) {
|
||||
writeFileSync(this.actualPath, actual);
|
||||
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-actual"), contentType: this.mimeType, path: this.actualPath });
|
||||
}
|
||||
if (diff !== void 0) {
|
||||
writeFileSync(this.diffPath, diff);
|
||||
step?._attachToStep({ name: (0, import_util.addSuffixToFilePath)(this.attachmentBaseName, "-diff"), contentType: this.mimeType, path: this.diffPath });
|
||||
}
|
||||
if (log?.length)
|
||||
output.push((0, import_matcherHint.callLogText)(log));
|
||||
else
|
||||
output.push("");
|
||||
return this.createMatcherResult(output.join("\n"), false, log);
|
||||
}
|
||||
handleMatching() {
|
||||
return this.createMatcherResult("", true);
|
||||
}
|
||||
}
|
||||
function toMatchSnapshot(received, nameOrOptions = {}, optOptions = {}) {
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo)
|
||||
throw new Error(`toMatchSnapshot() must be called during the test`);
|
||||
if (received instanceof Promise)
|
||||
throw new Error("An unresolved Promise was passed to toMatchSnapshot(), make sure to resolve it by adding await to it.");
|
||||
if (testInfo._projectInternal.ignoreSnapshots)
|
||||
return { pass: !this.isNot, message: () => "", name: "toMatchSnapshot", expected: nameOrOptions };
|
||||
const configOptions = testInfo._projectInternal.expect?.toMatchSnapshot || {};
|
||||
const helper = new SnapshotHelper(
|
||||
testInfo,
|
||||
"toMatchSnapshot",
|
||||
void 0,
|
||||
"." + determineFileExtension(received),
|
||||
configOptions,
|
||||
nameOrOptions,
|
||||
optOptions
|
||||
);
|
||||
if (this.isNot) {
|
||||
if (!import_fs.default.existsSync(helper.expectedPath))
|
||||
return helper.handleMissingNegated();
|
||||
const isDifferent = !!helper.comparator(received, import_fs.default.readFileSync(helper.expectedPath), helper.options);
|
||||
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated();
|
||||
}
|
||||
if (!import_fs.default.existsSync(helper.expectedPath))
|
||||
return helper.handleMissing(received, this._stepInfo);
|
||||
const expected = import_fs.default.readFileSync(helper.expectedPath);
|
||||
if (helper.updateSnapshots === "all") {
|
||||
if (!(0, import_utils.compareBuffersOrStrings)(received, expected))
|
||||
return helper.handleMatching();
|
||||
writeFileSync(helper.expectedPath, received);
|
||||
console.log(helper.expectedPath + " is not the same, writing actual.");
|
||||
return helper.createMatcherResult(helper.expectedPath + " running with --update-snapshots, writing actual.", true);
|
||||
}
|
||||
if (helper.updateSnapshots === "changed") {
|
||||
const result2 = helper.comparator(received, expected, helper.options);
|
||||
if (!result2)
|
||||
return helper.handleMatching();
|
||||
writeFileSync(helper.expectedPath, received);
|
||||
console.log(helper.expectedPath + " does not match, writing actual.");
|
||||
return helper.createMatcherResult(helper.expectedPath + " running with --update-snapshots, writing actual.", true);
|
||||
}
|
||||
const result = helper.comparator(received, expected, helper.options);
|
||||
if (!result)
|
||||
return helper.handleMatching();
|
||||
const header = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toMatchSnapshot", receiver: (0, import_utils.isString)(received) ? "string" : "Buffer", expectation: "expected" });
|
||||
return helper.handleDifferent(received, expected, void 0, result.diff, header, result.errorMessage, void 0, this._stepInfo);
|
||||
}
|
||||
function toHaveScreenshotStepTitle(nameOrOptions = {}, optOptions = {}) {
|
||||
let name;
|
||||
if (typeof nameOrOptions === "object" && !Array.isArray(nameOrOptions))
|
||||
name = nameOrOptions.name;
|
||||
else
|
||||
name = nameOrOptions;
|
||||
return Array.isArray(name) ? name.join(import_path.default.sep) : name || "";
|
||||
}
|
||||
async function toHaveScreenshot(pageOrLocator, nameOrOptions = {}, optOptions = {}) {
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo)
|
||||
throw new Error(`toHaveScreenshot() must be called during the test`);
|
||||
if (testInfo._projectInternal.ignoreSnapshots)
|
||||
return { pass: !this.isNot, message: () => "", name: "toHaveScreenshot", expected: nameOrOptions };
|
||||
(0, import_util.expectTypes)(pageOrLocator, ["Page", "Locator"], "toHaveScreenshot");
|
||||
const [page, locator] = pageOrLocator.constructor.name === "Page" ? [pageOrLocator, void 0] : [pageOrLocator.page(), pageOrLocator];
|
||||
const configOptions = testInfo._projectInternal.expect?.toHaveScreenshot || {};
|
||||
const helper = new SnapshotHelper(testInfo, "toHaveScreenshot", locator, void 0, configOptions, nameOrOptions, optOptions);
|
||||
if (!helper.expectedPath.toLowerCase().endsWith(".png"))
|
||||
throw new Error(`Screenshot name "${import_path.default.basename(helper.expectedPath)}" must have '.png' extension`);
|
||||
(0, import_util.expectTypes)(pageOrLocator, ["Page", "Locator"], "toHaveScreenshot");
|
||||
const style = await loadScreenshotStyles(helper.options.stylePath);
|
||||
const timeout = helper.options.timeout ?? this.timeout;
|
||||
const expectScreenshotOptions = {
|
||||
locator,
|
||||
animations: helper.options.animations ?? "disabled",
|
||||
caret: helper.options.caret ?? "hide",
|
||||
clip: helper.options.clip,
|
||||
fullPage: helper.options.fullPage,
|
||||
mask: helper.options.mask,
|
||||
maskColor: helper.options.maskColor,
|
||||
omitBackground: helper.options.omitBackground,
|
||||
scale: helper.options.scale ?? "css",
|
||||
style,
|
||||
isNot: !!this.isNot,
|
||||
timeout,
|
||||
comparator: helper.options.comparator,
|
||||
maxDiffPixels: helper.options.maxDiffPixels,
|
||||
maxDiffPixelRatio: helper.options.maxDiffPixelRatio,
|
||||
threshold: helper.options.threshold
|
||||
};
|
||||
const hasSnapshot = import_fs.default.existsSync(helper.expectedPath);
|
||||
if (this.isNot) {
|
||||
if (!hasSnapshot)
|
||||
return helper.handleMissingNegated();
|
||||
expectScreenshotOptions.expected = await import_fs.default.promises.readFile(helper.expectedPath);
|
||||
const isDifferent = !(await page._expectScreenshot(expectScreenshotOptions)).errorMessage;
|
||||
return isDifferent ? helper.handleDifferentNegated() : helper.handleMatchingNegated();
|
||||
}
|
||||
if (helper.updateSnapshots === "none" && !hasSnapshot)
|
||||
return helper.createMatcherResult(`A snapshot doesn't exist at ${helper.expectedPath}.`, false);
|
||||
if (!hasSnapshot) {
|
||||
const { actual: actual2, previous: previous2, diff: diff2, errorMessage: errorMessage2, log: log2, timedOut: timedOut2 } = await page._expectScreenshot(expectScreenshotOptions);
|
||||
if (errorMessage2) {
|
||||
const header2 = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toHaveScreenshot", locator, expectation: "expected", timeout, timedOut: timedOut2 });
|
||||
return helper.handleDifferent(actual2, void 0, previous2, diff2, header2, errorMessage2, log2, this._stepInfo);
|
||||
}
|
||||
return helper.handleMissing(actual2, this._stepInfo);
|
||||
}
|
||||
const expected = await import_fs.default.promises.readFile(helper.expectedPath);
|
||||
expectScreenshotOptions.expected = helper.updateSnapshots === "all" ? void 0 : expected;
|
||||
const { actual, previous, diff, errorMessage, log, timedOut } = await page._expectScreenshot(expectScreenshotOptions);
|
||||
const writeFiles = (actualBuffer) => {
|
||||
writeFileSync(helper.expectedPath, actualBuffer);
|
||||
writeFileSync(helper.actualPath, actualBuffer);
|
||||
console.log(helper.expectedPath + " is re-generated, writing actual.");
|
||||
return helper.createMatcherResult(helper.expectedPath + " running with --update-snapshots, writing actual.", true);
|
||||
};
|
||||
if (!errorMessage) {
|
||||
if (helper.updateSnapshots === "all" && actual && (0, import_utils.compareBuffersOrStrings)(actual, expected)) {
|
||||
console.log(helper.expectedPath + " is re-generated, writing actual.");
|
||||
return writeFiles(actual);
|
||||
}
|
||||
return helper.handleMatching();
|
||||
}
|
||||
if (helper.updateSnapshots === "changed" || helper.updateSnapshots === "all") {
|
||||
if (actual)
|
||||
return writeFiles(actual);
|
||||
let header2 = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toHaveScreenshot", locator, expectation: "expected", timeout, timedOut });
|
||||
header2 += " Failed to re-generate expected.\n";
|
||||
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header2, errorMessage, log, this._stepInfo);
|
||||
}
|
||||
const header = (0, import_matcherHint.formatMatcherMessage)(this, { matcherName: "toHaveScreenshot", locator, expectation: "expected", timeout, timedOut });
|
||||
return helper.handleDifferent(actual, expectScreenshotOptions.expected, previous, diff, header, errorMessage, log, this._stepInfo);
|
||||
}
|
||||
function writeFileSync(aPath, content) {
|
||||
import_fs.default.mkdirSync(import_path.default.dirname(aPath), { recursive: true });
|
||||
import_fs.default.writeFileSync(aPath, content);
|
||||
}
|
||||
function indent(lines, tab) {
|
||||
return lines.replace(/^(?=.+$)/gm, tab);
|
||||
}
|
||||
function determineFileExtension(file) {
|
||||
if (typeof file === "string")
|
||||
return "txt";
|
||||
if (compareMagicBytes(file, [137, 80, 78, 71, 13, 10, 26, 10]))
|
||||
return "png";
|
||||
if (compareMagicBytes(file, [255, 216, 255]))
|
||||
return "jpg";
|
||||
return "dat";
|
||||
}
|
||||
function compareMagicBytes(file, magicBytes) {
|
||||
return Buffer.compare(Buffer.from(magicBytes), file.slice(0, magicBytes.length)) === 0;
|
||||
}
|
||||
async function loadScreenshotStyles(stylePath) {
|
||||
if (!stylePath)
|
||||
return;
|
||||
const stylePaths = Array.isArray(stylePath) ? stylePath : [stylePath];
|
||||
const styles = await Promise.all(stylePaths.map(async (stylePath2) => {
|
||||
const text = await import_fs.default.promises.readFile(stylePath2, "utf8");
|
||||
return text.trim();
|
||||
}));
|
||||
return styles.join("\n").trim() || void 0;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toHaveScreenshot,
|
||||
toHaveScreenshotStepTitle,
|
||||
toMatchSnapshot
|
||||
});
|
||||
99
node_modules/playwright/lib/matchers/toMatchText.js
generated
vendored
Normal file
99
node_modules/playwright/lib/matchers/toMatchText.js
generated
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var toMatchText_exports = {};
|
||||
__export(toMatchText_exports, {
|
||||
toMatchText: () => toMatchText
|
||||
});
|
||||
module.exports = __toCommonJS(toMatchText_exports);
|
||||
var import_util = require("../util");
|
||||
var import_expect = require("./expect");
|
||||
var import_matcherHint = require("./matcherHint");
|
||||
var import_expectBundle = require("../common/expectBundle");
|
||||
async function toMatchText(matcherName, receiver, receiverType, query, expected, options = {}) {
|
||||
(0, import_util.expectTypes)(receiver, [receiverType], matcherName);
|
||||
const locator = receiverType === "Locator" ? receiver : void 0;
|
||||
if (!(typeof expected === "string") && !(expected && typeof expected.test === "function")) {
|
||||
const errorMessage2 = `Error: ${(0, import_expectBundle.EXPECTED_COLOR)("expected")} value must be a string or regular expression
|
||||
${this.utils.printWithType("Expected", expected, this.utils.printExpected)}`;
|
||||
throw new Error((0, import_matcherHint.formatMatcherMessage)(this, { locator, matcherName, expectation: "expected", errorMessage: errorMessage2 }));
|
||||
}
|
||||
const timeout = options.timeout ?? this.timeout;
|
||||
const { matches: pass, received, log, timedOut, errorMessage } = await query(!!this.isNot, timeout);
|
||||
if (pass === !this.isNot) {
|
||||
return {
|
||||
name: matcherName,
|
||||
message: () => "",
|
||||
pass,
|
||||
expected
|
||||
};
|
||||
}
|
||||
const expectedSuffix = typeof expected === "string" ? options.matchSubstring ? " substring" : "" : " pattern";
|
||||
const receivedSuffix = typeof expected === "string" ? options.matchSubstring ? " string" : "" : " string";
|
||||
const receivedString = received || "";
|
||||
let printedReceived;
|
||||
let printedExpected;
|
||||
let printedDiff;
|
||||
if (pass) {
|
||||
if (typeof expected === "string") {
|
||||
printedExpected = `Expected${expectedSuffix}: not ${this.utils.printExpected(expected)}`;
|
||||
if (!errorMessage) {
|
||||
const formattedReceived = (0, import_expect.printReceivedStringContainExpectedSubstring)(receivedString, receivedString.indexOf(expected), expected.length);
|
||||
printedReceived = `Received${receivedSuffix}: ${formattedReceived}`;
|
||||
}
|
||||
} else {
|
||||
printedExpected = `Expected${expectedSuffix}: not ${this.utils.printExpected(expected)}`;
|
||||
if (!errorMessage) {
|
||||
const formattedReceived = (0, import_expect.printReceivedStringContainExpectedResult)(receivedString, typeof expected.exec === "function" ? expected.exec(receivedString) : null);
|
||||
printedReceived = `Received${receivedSuffix}: ${formattedReceived}`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (errorMessage)
|
||||
printedExpected = `Expected${expectedSuffix}: ${this.utils.printExpected(expected)}`;
|
||||
else
|
||||
printedDiff = this.utils.printDiffOrStringify(expected, receivedString, `Expected${expectedSuffix}`, `Received${receivedSuffix}`, false);
|
||||
}
|
||||
const message = () => {
|
||||
return (0, import_matcherHint.formatMatcherMessage)(this, {
|
||||
matcherName,
|
||||
expectation: "expected",
|
||||
locator,
|
||||
timeout,
|
||||
timedOut,
|
||||
printedExpected,
|
||||
printedReceived,
|
||||
printedDiff,
|
||||
log,
|
||||
errorMessage
|
||||
});
|
||||
};
|
||||
return {
|
||||
name: matcherName,
|
||||
expected,
|
||||
message,
|
||||
pass,
|
||||
actual: received,
|
||||
log,
|
||||
timeout: timedOut ? timeout : void 0
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
toMatchText
|
||||
});
|
||||
16
node_modules/playwright/lib/mcp/browser/actions.d.js
generated
vendored
Normal file
16
node_modules/playwright/lib/mcp/browser/actions.d.js
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var actions_d_exports = {};
|
||||
module.exports = __toCommonJS(actions_d_exports);
|
||||
296
node_modules/playwright/lib/mcp/browser/browserContextFactory.js
generated
vendored
Normal file
296
node_modules/playwright/lib/mcp/browser/browserContextFactory.js
generated
vendored
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserContextFactory_exports = {};
|
||||
__export(browserContextFactory_exports, {
|
||||
SharedContextFactory: () => SharedContextFactory,
|
||||
contextFactory: () => contextFactory
|
||||
});
|
||||
module.exports = __toCommonJS(browserContextFactory_exports);
|
||||
var import_crypto = __toESM(require("crypto"));
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_net = __toESM(require("net"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var playwright = __toESM(require("playwright-core"));
|
||||
var import_registry = require("playwright-core/lib/server/registry/index");
|
||||
var import_server = require("playwright-core/lib/server");
|
||||
var import_log = require("../log");
|
||||
var import_config = require("./config");
|
||||
var import_server2 = require("../sdk/server");
|
||||
function contextFactory(config) {
|
||||
if (config.sharedBrowserContext)
|
||||
return SharedContextFactory.create(config);
|
||||
if (config.browser.remoteEndpoint)
|
||||
return new RemoteContextFactory(config);
|
||||
if (config.browser.cdpEndpoint)
|
||||
return new CdpContextFactory(config);
|
||||
if (config.browser.isolated)
|
||||
return new IsolatedContextFactory(config);
|
||||
return new PersistentContextFactory(config);
|
||||
}
|
||||
class BaseContextFactory {
|
||||
constructor(name, config) {
|
||||
this._logName = name;
|
||||
this.config = config;
|
||||
}
|
||||
async _obtainBrowser(clientInfo) {
|
||||
if (this._browserPromise)
|
||||
return this._browserPromise;
|
||||
(0, import_log.testDebug)(`obtain browser (${this._logName})`);
|
||||
this._browserPromise = this._doObtainBrowser(clientInfo);
|
||||
void this._browserPromise.then((browser) => {
|
||||
browser.on("disconnected", () => {
|
||||
this._browserPromise = void 0;
|
||||
});
|
||||
}).catch(() => {
|
||||
this._browserPromise = void 0;
|
||||
});
|
||||
return this._browserPromise;
|
||||
}
|
||||
async _doObtainBrowser(clientInfo) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
async createContext(clientInfo) {
|
||||
(0, import_log.testDebug)(`create browser context (${this._logName})`);
|
||||
const browser = await this._obtainBrowser(clientInfo);
|
||||
const browserContext = await this._doCreateContext(browser);
|
||||
await addInitScript(browserContext, this.config.browser.initScript);
|
||||
return {
|
||||
browserContext,
|
||||
close: (afterClose) => this._closeBrowserContext(browserContext, browser, afterClose)
|
||||
};
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
async _closeBrowserContext(browserContext, browser, afterClose) {
|
||||
(0, import_log.testDebug)(`close browser context (${this._logName})`);
|
||||
if (browser.contexts().length === 1)
|
||||
this._browserPromise = void 0;
|
||||
await browserContext.close().catch(import_log.logUnhandledError);
|
||||
await afterClose();
|
||||
if (browser.contexts().length === 0) {
|
||||
(0, import_log.testDebug)(`close browser (${this._logName})`);
|
||||
await browser.close().catch(import_log.logUnhandledError);
|
||||
}
|
||||
}
|
||||
}
|
||||
class IsolatedContextFactory extends BaseContextFactory {
|
||||
constructor(config) {
|
||||
super("isolated", config);
|
||||
}
|
||||
async _doObtainBrowser(clientInfo) {
|
||||
await injectCdpPort(this.config.browser);
|
||||
const browserType = playwright[this.config.browser.browserName];
|
||||
const tracesDir = await computeTracesDir(this.config, clientInfo);
|
||||
if (tracesDir && this.config.saveTrace)
|
||||
await startTraceServer(this.config, tracesDir);
|
||||
return browserType.launch({
|
||||
tracesDir,
|
||||
...this.config.browser.launchOptions,
|
||||
handleSIGINT: false,
|
||||
handleSIGTERM: false
|
||||
}).catch((error) => {
|
||||
if (error.message.includes("Executable doesn't exist"))
|
||||
throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`);
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
return browser.newContext(this.config.browser.contextOptions);
|
||||
}
|
||||
}
|
||||
class CdpContextFactory extends BaseContextFactory {
|
||||
constructor(config) {
|
||||
super("cdp", config);
|
||||
}
|
||||
async _doObtainBrowser() {
|
||||
return playwright.chromium.connectOverCDP(this.config.browser.cdpEndpoint, { headers: this.config.browser.cdpHeaders });
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
return this.config.browser.isolated ? await browser.newContext() : browser.contexts()[0];
|
||||
}
|
||||
}
|
||||
class RemoteContextFactory extends BaseContextFactory {
|
||||
constructor(config) {
|
||||
super("remote", config);
|
||||
}
|
||||
async _doObtainBrowser() {
|
||||
const url = new URL(this.config.browser.remoteEndpoint);
|
||||
url.searchParams.set("browser", this.config.browser.browserName);
|
||||
if (this.config.browser.launchOptions)
|
||||
url.searchParams.set("launch-options", JSON.stringify(this.config.browser.launchOptions));
|
||||
return playwright[this.config.browser.browserName].connect(String(url));
|
||||
}
|
||||
async _doCreateContext(browser) {
|
||||
return browser.newContext();
|
||||
}
|
||||
}
|
||||
class PersistentContextFactory {
|
||||
constructor(config) {
|
||||
this.name = "persistent";
|
||||
this.description = "Create a new persistent browser context";
|
||||
this._userDataDirs = /* @__PURE__ */ new Set();
|
||||
this.config = config;
|
||||
}
|
||||
async createContext(clientInfo) {
|
||||
await injectCdpPort(this.config.browser);
|
||||
(0, import_log.testDebug)("create browser context (persistent)");
|
||||
const userDataDir = this.config.browser.userDataDir ?? await this._createUserDataDir(clientInfo);
|
||||
const tracesDir = await computeTracesDir(this.config, clientInfo);
|
||||
if (tracesDir && this.config.saveTrace)
|
||||
await startTraceServer(this.config, tracesDir);
|
||||
this._userDataDirs.add(userDataDir);
|
||||
(0, import_log.testDebug)("lock user data dir", userDataDir);
|
||||
const browserType = playwright[this.config.browser.browserName];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const launchOptions = {
|
||||
tracesDir,
|
||||
...this.config.browser.launchOptions,
|
||||
...this.config.browser.contextOptions,
|
||||
handleSIGINT: false,
|
||||
handleSIGTERM: false,
|
||||
ignoreDefaultArgs: [
|
||||
"--disable-extensions"
|
||||
],
|
||||
assistantMode: true
|
||||
};
|
||||
try {
|
||||
const browserContext = await browserType.launchPersistentContext(userDataDir, launchOptions);
|
||||
await addInitScript(browserContext, this.config.browser.initScript);
|
||||
const close = (afterClose) => this._closeBrowserContext(browserContext, userDataDir, afterClose);
|
||||
return { browserContext, close };
|
||||
} catch (error) {
|
||||
if (error.message.includes("Executable doesn't exist"))
|
||||
throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`);
|
||||
if (error.message.includes("ProcessSingleton") || error.message.includes("Invalid URL")) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
throw new Error(`Browser is already in use for ${userDataDir}, use --isolated to run multiple instances of the same browser`);
|
||||
}
|
||||
async _closeBrowserContext(browserContext, userDataDir, afterClose) {
|
||||
(0, import_log.testDebug)("close browser context (persistent)");
|
||||
(0, import_log.testDebug)("release user data dir", userDataDir);
|
||||
await browserContext.close().catch(() => {
|
||||
});
|
||||
await afterClose();
|
||||
this._userDataDirs.delete(userDataDir);
|
||||
(0, import_log.testDebug)("close browser context complete (persistent)");
|
||||
}
|
||||
async _createUserDataDir(clientInfo) {
|
||||
const dir = process.env.PWMCP_PROFILES_DIR_FOR_TEST ?? import_registry.registryDirectory;
|
||||
const browserToken = this.config.browser.launchOptions?.channel ?? this.config.browser?.browserName;
|
||||
const rootPath = (0, import_server2.firstRootPath)(clientInfo);
|
||||
const rootPathToken = rootPath ? `-${createHash(rootPath)}` : "";
|
||||
const result = import_path.default.join(dir, `mcp-${browserToken}${rootPathToken}`);
|
||||
await import_fs.default.promises.mkdir(result, { recursive: true });
|
||||
return result;
|
||||
}
|
||||
}
|
||||
async function injectCdpPort(browserConfig) {
|
||||
if (browserConfig.browserName === "chromium")
|
||||
browserConfig.launchOptions.cdpPort = await findFreePort();
|
||||
}
|
||||
async function findFreePort() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = import_net.default.createServer();
|
||||
server.listen(0, () => {
|
||||
const { port } = server.address();
|
||||
server.close(() => resolve(port));
|
||||
});
|
||||
server.on("error", reject);
|
||||
});
|
||||
}
|
||||
async function startTraceServer(config, tracesDir) {
|
||||
if (!config.saveTrace)
|
||||
return;
|
||||
const server = await (0, import_server.startTraceViewerServer)();
|
||||
const urlPrefix = server.urlPrefix("human-readable");
|
||||
const url = urlPrefix + "/trace/index.html?trace=" + tracesDir + "/trace.json";
|
||||
console.error("\nTrace viewer listening on " + url);
|
||||
}
|
||||
function createHash(data) {
|
||||
return import_crypto.default.createHash("sha256").update(data).digest("hex").slice(0, 7);
|
||||
}
|
||||
async function addInitScript(browserContext, initScript) {
|
||||
for (const scriptPath of initScript ?? [])
|
||||
await browserContext.addInitScript({ path: import_path.default.resolve(scriptPath) });
|
||||
}
|
||||
class SharedContextFactory {
|
||||
static create(config) {
|
||||
if (SharedContextFactory._instance)
|
||||
throw new Error("SharedContextFactory already exists");
|
||||
const baseConfig = { ...config, sharedBrowserContext: false };
|
||||
const baseFactory = contextFactory(baseConfig);
|
||||
SharedContextFactory._instance = new SharedContextFactory(baseFactory);
|
||||
return SharedContextFactory._instance;
|
||||
}
|
||||
constructor(baseFactory) {
|
||||
this._baseFactory = baseFactory;
|
||||
}
|
||||
async createContext(clientInfo, abortSignal, toolName) {
|
||||
if (!this._contextPromise) {
|
||||
(0, import_log.testDebug)("create shared browser context");
|
||||
this._contextPromise = this._baseFactory.createContext(clientInfo, abortSignal, toolName);
|
||||
}
|
||||
const { browserContext } = await this._contextPromise;
|
||||
(0, import_log.testDebug)(`shared context client connected`);
|
||||
return {
|
||||
browserContext,
|
||||
close: async () => {
|
||||
(0, import_log.testDebug)(`shared context client disconnected`);
|
||||
}
|
||||
};
|
||||
}
|
||||
static async dispose() {
|
||||
await SharedContextFactory._instance?._dispose();
|
||||
}
|
||||
async _dispose() {
|
||||
const contextPromise = this._contextPromise;
|
||||
this._contextPromise = void 0;
|
||||
if (!contextPromise)
|
||||
return;
|
||||
const { close } = await contextPromise;
|
||||
await close(async () => {
|
||||
});
|
||||
}
|
||||
}
|
||||
async function computeTracesDir(config, clientInfo) {
|
||||
if (!config.saveTrace && !config.capabilities?.includes("tracing"))
|
||||
return;
|
||||
return await (0, import_config.outputFile)(config, clientInfo, `traces`, { origin: "code", reason: "Collecting trace" });
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
SharedContextFactory,
|
||||
contextFactory
|
||||
});
|
||||
76
node_modules/playwright/lib/mcp/browser/browserServerBackend.js
generated
vendored
Normal file
76
node_modules/playwright/lib/mcp/browser/browserServerBackend.js
generated
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserServerBackend_exports = {};
|
||||
__export(browserServerBackend_exports, {
|
||||
BrowserServerBackend: () => BrowserServerBackend
|
||||
});
|
||||
module.exports = __toCommonJS(browserServerBackend_exports);
|
||||
var import_context = require("./context");
|
||||
var import_log = require("../log");
|
||||
var import_response = require("./response");
|
||||
var import_sessionLog = require("./sessionLog");
|
||||
var import_tools = require("./tools");
|
||||
var import_tool = require("../sdk/tool");
|
||||
class BrowserServerBackend {
|
||||
constructor(config, factory) {
|
||||
this._config = config;
|
||||
this._browserContextFactory = factory;
|
||||
this._tools = (0, import_tools.filteredTools)(config);
|
||||
}
|
||||
async initialize(server, clientInfo) {
|
||||
this._sessionLog = this._config.saveSession ? await import_sessionLog.SessionLog.create(this._config, clientInfo) : void 0;
|
||||
this._context = new import_context.Context({
|
||||
config: this._config,
|
||||
browserContextFactory: this._browserContextFactory,
|
||||
sessionLog: this._sessionLog,
|
||||
clientInfo
|
||||
});
|
||||
}
|
||||
async listTools() {
|
||||
return this._tools.map((tool) => (0, import_tool.toMcpTool)(tool.schema));
|
||||
}
|
||||
async callTool(name, rawArguments) {
|
||||
const tool = this._tools.find((tool2) => tool2.schema.name === name);
|
||||
if (!tool)
|
||||
throw new Error(`Tool "${name}" not found`);
|
||||
const parsedArguments = tool.schema.inputSchema.parse(rawArguments || {});
|
||||
const context = this._context;
|
||||
const response = new import_response.Response(context, name, parsedArguments);
|
||||
response.logBegin();
|
||||
context.setRunningTool(name);
|
||||
try {
|
||||
await tool.handle(context, parsedArguments, response);
|
||||
await response.finish();
|
||||
this._sessionLog?.logResponse(response);
|
||||
} catch (error) {
|
||||
response.addError(String(error));
|
||||
} finally {
|
||||
context.setRunningTool(void 0);
|
||||
}
|
||||
response.logEnd();
|
||||
return response.serialize();
|
||||
}
|
||||
serverClosed() {
|
||||
void this._context?.dispose().catch(import_log.logUnhandledError);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
BrowserServerBackend
|
||||
});
|
||||
66
node_modules/playwright/lib/mcp/browser/codegen.js
generated
vendored
Normal file
66
node_modules/playwright/lib/mcp/browser/codegen.js
generated
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var codegen_exports = {};
|
||||
__export(codegen_exports, {
|
||||
escapeWithQuotes: () => escapeWithQuotes,
|
||||
formatObject: () => formatObject,
|
||||
quote: () => quote
|
||||
});
|
||||
module.exports = __toCommonJS(codegen_exports);
|
||||
function escapeWithQuotes(text, char = "'") {
|
||||
const stringified = JSON.stringify(text);
|
||||
const escapedText = stringified.substring(1, stringified.length - 1).replace(/\\"/g, '"');
|
||||
if (char === "'")
|
||||
return char + escapedText.replace(/[']/g, "\\'") + char;
|
||||
if (char === '"')
|
||||
return char + escapedText.replace(/["]/g, '\\"') + char;
|
||||
if (char === "`")
|
||||
return char + escapedText.replace(/[`]/g, "\\`") + char;
|
||||
throw new Error("Invalid escape char");
|
||||
}
|
||||
function quote(text) {
|
||||
return escapeWithQuotes(text, "'");
|
||||
}
|
||||
function formatObject(value, indent = " ", mode = "multiline") {
|
||||
if (typeof value === "string")
|
||||
return quote(value);
|
||||
if (Array.isArray(value))
|
||||
return `[${value.map((o) => formatObject(o)).join(", ")}]`;
|
||||
if (typeof value === "object") {
|
||||
const keys = Object.keys(value).filter((key) => value[key] !== void 0).sort();
|
||||
if (!keys.length)
|
||||
return "{}";
|
||||
const tokens = [];
|
||||
for (const key of keys)
|
||||
tokens.push(`${key}: ${formatObject(value[key])}`);
|
||||
if (mode === "multiline")
|
||||
return `{
|
||||
${tokens.join(`,
|
||||
${indent}`)}
|
||||
}`;
|
||||
return `{ ${tokens.join(", ")} }`;
|
||||
}
|
||||
return String(value);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
escapeWithQuotes,
|
||||
formatObject,
|
||||
quote
|
||||
});
|
||||
383
node_modules/playwright/lib/mcp/browser/config.js
generated
vendored
Normal file
383
node_modules/playwright/lib/mcp/browser/config.js
generated
vendored
Normal file
|
|
@ -0,0 +1,383 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var config_exports = {};
|
||||
__export(config_exports, {
|
||||
commaSeparatedList: () => commaSeparatedList,
|
||||
configFromCLIOptions: () => configFromCLIOptions,
|
||||
defaultConfig: () => defaultConfig,
|
||||
dotenvFileLoader: () => dotenvFileLoader,
|
||||
headerParser: () => headerParser,
|
||||
numberParser: () => numberParser,
|
||||
outputDir: () => outputDir,
|
||||
outputFile: () => outputFile,
|
||||
resolutionParser: () => resolutionParser,
|
||||
resolveCLIConfig: () => resolveCLIConfig,
|
||||
resolveConfig: () => resolveConfig,
|
||||
semicolonSeparatedList: () => semicolonSeparatedList
|
||||
});
|
||||
module.exports = __toCommonJS(config_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_os = __toESM(require("os"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_playwright_core = require("playwright-core");
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_util = require("../../util");
|
||||
var import_server = require("../sdk/server");
|
||||
const defaultConfig = {
|
||||
browser: {
|
||||
browserName: "chromium",
|
||||
launchOptions: {
|
||||
channel: "chrome",
|
||||
headless: import_os.default.platform() === "linux" && !process.env.DISPLAY,
|
||||
chromiumSandbox: true
|
||||
},
|
||||
contextOptions: {
|
||||
viewport: null
|
||||
}
|
||||
},
|
||||
network: {
|
||||
allowedOrigins: void 0,
|
||||
blockedOrigins: void 0
|
||||
},
|
||||
server: {},
|
||||
saveTrace: false,
|
||||
timeouts: {
|
||||
action: 5e3,
|
||||
navigation: 6e4
|
||||
}
|
||||
};
|
||||
async function resolveConfig(config) {
|
||||
return mergeConfig(defaultConfig, config);
|
||||
}
|
||||
async function resolveCLIConfig(cliOptions) {
|
||||
const configInFile = await loadConfig(cliOptions.config);
|
||||
const envOverrides = configFromEnv();
|
||||
const cliOverrides = configFromCLIOptions(cliOptions);
|
||||
let result = defaultConfig;
|
||||
result = mergeConfig(result, configInFile);
|
||||
result = mergeConfig(result, envOverrides);
|
||||
result = mergeConfig(result, cliOverrides);
|
||||
await validateConfig(result);
|
||||
return result;
|
||||
}
|
||||
async function validateConfig(config) {
|
||||
if (config.browser.initScript) {
|
||||
for (const script of config.browser.initScript) {
|
||||
if (!await (0, import_util.fileExistsAsync)(script))
|
||||
throw new Error(`Init script file does not exist: ${script}`);
|
||||
}
|
||||
}
|
||||
if (config.sharedBrowserContext && config.saveVideo)
|
||||
throw new Error("saveVideo is not supported when sharedBrowserContext is true");
|
||||
}
|
||||
function configFromCLIOptions(cliOptions) {
|
||||
let browserName;
|
||||
let channel;
|
||||
switch (cliOptions.browser) {
|
||||
case "chrome":
|
||||
case "chrome-beta":
|
||||
case "chrome-canary":
|
||||
case "chrome-dev":
|
||||
case "chromium":
|
||||
case "msedge":
|
||||
case "msedge-beta":
|
||||
case "msedge-canary":
|
||||
case "msedge-dev":
|
||||
browserName = "chromium";
|
||||
channel = cliOptions.browser;
|
||||
break;
|
||||
case "firefox":
|
||||
browserName = "firefox";
|
||||
break;
|
||||
case "webkit":
|
||||
browserName = "webkit";
|
||||
break;
|
||||
}
|
||||
const launchOptions = {
|
||||
channel,
|
||||
executablePath: cliOptions.executablePath,
|
||||
headless: cliOptions.headless
|
||||
};
|
||||
if (cliOptions.sandbox === false)
|
||||
launchOptions.chromiumSandbox = false;
|
||||
if (cliOptions.proxyServer) {
|
||||
launchOptions.proxy = {
|
||||
server: cliOptions.proxyServer
|
||||
};
|
||||
if (cliOptions.proxyBypass)
|
||||
launchOptions.proxy.bypass = cliOptions.proxyBypass;
|
||||
}
|
||||
if (cliOptions.device && cliOptions.cdpEndpoint)
|
||||
throw new Error("Device emulation is not supported with cdpEndpoint.");
|
||||
const contextOptions = cliOptions.device ? import_playwright_core.devices[cliOptions.device] : {};
|
||||
if (cliOptions.storageState)
|
||||
contextOptions.storageState = cliOptions.storageState;
|
||||
if (cliOptions.userAgent)
|
||||
contextOptions.userAgent = cliOptions.userAgent;
|
||||
if (cliOptions.viewportSize)
|
||||
contextOptions.viewport = cliOptions.viewportSize;
|
||||
if (cliOptions.ignoreHttpsErrors)
|
||||
contextOptions.ignoreHTTPSErrors = true;
|
||||
if (cliOptions.blockServiceWorkers)
|
||||
contextOptions.serviceWorkers = "block";
|
||||
if (cliOptions.grantPermissions)
|
||||
contextOptions.permissions = cliOptions.grantPermissions;
|
||||
if (cliOptions.saveVideo) {
|
||||
contextOptions.recordVideo = {
|
||||
// Videos are moved to output directory on saveAs.
|
||||
dir: tmpDir(),
|
||||
size: cliOptions.saveVideo
|
||||
};
|
||||
}
|
||||
const result = {
|
||||
browser: {
|
||||
browserName,
|
||||
isolated: cliOptions.isolated,
|
||||
userDataDir: cliOptions.userDataDir,
|
||||
launchOptions,
|
||||
contextOptions,
|
||||
cdpEndpoint: cliOptions.cdpEndpoint,
|
||||
cdpHeaders: cliOptions.cdpHeader,
|
||||
initScript: cliOptions.initScript
|
||||
},
|
||||
server: {
|
||||
port: cliOptions.port,
|
||||
host: cliOptions.host,
|
||||
allowedHosts: cliOptions.allowedHosts
|
||||
},
|
||||
capabilities: cliOptions.caps,
|
||||
network: {
|
||||
allowedOrigins: cliOptions.allowedOrigins,
|
||||
blockedOrigins: cliOptions.blockedOrigins
|
||||
},
|
||||
saveSession: cliOptions.saveSession,
|
||||
saveTrace: cliOptions.saveTrace,
|
||||
saveVideo: cliOptions.saveVideo,
|
||||
secrets: cliOptions.secrets,
|
||||
sharedBrowserContext: cliOptions.sharedBrowserContext,
|
||||
outputDir: cliOptions.outputDir,
|
||||
imageResponses: cliOptions.imageResponses,
|
||||
timeouts: {
|
||||
action: cliOptions.timeoutAction,
|
||||
navigation: cliOptions.timeoutNavigation
|
||||
}
|
||||
};
|
||||
return result;
|
||||
}
|
||||
function configFromEnv() {
|
||||
const options = {};
|
||||
options.allowedHosts = commaSeparatedList(process.env.PLAYWRIGHT_MCP_ALLOWED_HOSTNAMES);
|
||||
options.allowedOrigins = semicolonSeparatedList(process.env.PLAYWRIGHT_MCP_ALLOWED_ORIGINS);
|
||||
options.blockedOrigins = semicolonSeparatedList(process.env.PLAYWRIGHT_MCP_BLOCKED_ORIGINS);
|
||||
options.blockServiceWorkers = envToBoolean(process.env.PLAYWRIGHT_MCP_BLOCK_SERVICE_WORKERS);
|
||||
options.browser = envToString(process.env.PLAYWRIGHT_MCP_BROWSER);
|
||||
options.caps = commaSeparatedList(process.env.PLAYWRIGHT_MCP_CAPS);
|
||||
options.cdpEndpoint = envToString(process.env.PLAYWRIGHT_MCP_CDP_ENDPOINT);
|
||||
options.cdpHeader = headerParser(process.env.PLAYWRIGHT_MCP_CDP_HEADERS, {});
|
||||
options.config = envToString(process.env.PLAYWRIGHT_MCP_CONFIG);
|
||||
options.device = envToString(process.env.PLAYWRIGHT_MCP_DEVICE);
|
||||
options.executablePath = envToString(process.env.PLAYWRIGHT_MCP_EXECUTABLE_PATH);
|
||||
options.grantPermissions = commaSeparatedList(process.env.PLAYWRIGHT_MCP_GRANT_PERMISSIONS);
|
||||
options.headless = envToBoolean(process.env.PLAYWRIGHT_MCP_HEADLESS);
|
||||
options.host = envToString(process.env.PLAYWRIGHT_MCP_HOST);
|
||||
options.ignoreHttpsErrors = envToBoolean(process.env.PLAYWRIGHT_MCP_IGNORE_HTTPS_ERRORS);
|
||||
const initScript = envToString(process.env.PLAYWRIGHT_MCP_INIT_SCRIPT);
|
||||
if (initScript)
|
||||
options.initScript = [initScript];
|
||||
options.isolated = envToBoolean(process.env.PLAYWRIGHT_MCP_ISOLATED);
|
||||
if (process.env.PLAYWRIGHT_MCP_IMAGE_RESPONSES === "omit")
|
||||
options.imageResponses = "omit";
|
||||
options.sandbox = envToBoolean(process.env.PLAYWRIGHT_MCP_SANDBOX);
|
||||
options.outputDir = envToString(process.env.PLAYWRIGHT_MCP_OUTPUT_DIR);
|
||||
options.port = numberParser(process.env.PLAYWRIGHT_MCP_PORT);
|
||||
options.proxyBypass = envToString(process.env.PLAYWRIGHT_MCP_PROXY_BYPASS);
|
||||
options.proxyServer = envToString(process.env.PLAYWRIGHT_MCP_PROXY_SERVER);
|
||||
options.saveTrace = envToBoolean(process.env.PLAYWRIGHT_MCP_SAVE_TRACE);
|
||||
options.saveVideo = resolutionParser("--save-video", process.env.PLAYWRIGHT_MCP_SAVE_VIDEO);
|
||||
options.secrets = dotenvFileLoader(process.env.PLAYWRIGHT_MCP_SECRETS_FILE);
|
||||
options.storageState = envToString(process.env.PLAYWRIGHT_MCP_STORAGE_STATE);
|
||||
options.timeoutAction = numberParser(process.env.PLAYWRIGHT_MCP_TIMEOUT_ACTION);
|
||||
options.timeoutNavigation = numberParser(process.env.PLAYWRIGHT_MCP_TIMEOUT_NAVIGATION);
|
||||
options.userAgent = envToString(process.env.PLAYWRIGHT_MCP_USER_AGENT);
|
||||
options.userDataDir = envToString(process.env.PLAYWRIGHT_MCP_USER_DATA_DIR);
|
||||
options.viewportSize = resolutionParser("--viewport-size", process.env.PLAYWRIGHT_MCP_VIEWPORT_SIZE);
|
||||
return configFromCLIOptions(options);
|
||||
}
|
||||
async function loadConfig(configFile) {
|
||||
if (!configFile)
|
||||
return {};
|
||||
try {
|
||||
return JSON.parse(await import_fs.default.promises.readFile(configFile, "utf8"));
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to load config file: ${configFile}, ${error}`);
|
||||
}
|
||||
}
|
||||
function tmpDir() {
|
||||
return import_path.default.join(process.env.PW_TMPDIR_FOR_TEST ?? import_os.default.tmpdir(), "playwright-mcp-output");
|
||||
}
|
||||
function outputDir(config, clientInfo) {
|
||||
const rootPath = (0, import_server.firstRootPath)(clientInfo);
|
||||
return config.outputDir ?? (rootPath ? import_path.default.join(rootPath, ".playwright-mcp") : void 0) ?? import_path.default.join(tmpDir(), String(clientInfo.timestamp));
|
||||
}
|
||||
async function outputFile(config, clientInfo, fileName, options) {
|
||||
const file = await resolveFile(config, clientInfo, fileName, options);
|
||||
(0, import_utilsBundle.debug)("pw:mcp:file")(options.reason, file);
|
||||
return file;
|
||||
}
|
||||
async function resolveFile(config, clientInfo, fileName, options) {
|
||||
const dir = outputDir(config, clientInfo);
|
||||
if (options.origin === "code")
|
||||
return import_path.default.resolve(dir, fileName);
|
||||
if (options.origin === "llm") {
|
||||
fileName = fileName.split("\\").join("/");
|
||||
const resolvedFile = import_path.default.resolve(dir, fileName);
|
||||
if (!resolvedFile.startsWith(import_path.default.resolve(dir) + import_path.default.sep))
|
||||
throw new Error(`Resolved file path for ${fileName} is outside of the output directory`);
|
||||
return resolvedFile;
|
||||
}
|
||||
return import_path.default.join(dir, sanitizeForFilePath(fileName));
|
||||
}
|
||||
function pickDefined(obj) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(obj ?? {}).filter(([_, v]) => v !== void 0)
|
||||
);
|
||||
}
|
||||
function mergeConfig(base, overrides) {
|
||||
const browser = {
|
||||
...pickDefined(base.browser),
|
||||
...pickDefined(overrides.browser),
|
||||
browserName: overrides.browser?.browserName ?? base.browser?.browserName ?? "chromium",
|
||||
isolated: overrides.browser?.isolated ?? base.browser?.isolated ?? false,
|
||||
launchOptions: {
|
||||
...pickDefined(base.browser?.launchOptions),
|
||||
...pickDefined(overrides.browser?.launchOptions),
|
||||
...{ assistantMode: true }
|
||||
},
|
||||
contextOptions: {
|
||||
...pickDefined(base.browser?.contextOptions),
|
||||
...pickDefined(overrides.browser?.contextOptions)
|
||||
}
|
||||
};
|
||||
if (browser.browserName !== "chromium" && browser.launchOptions)
|
||||
delete browser.launchOptions.channel;
|
||||
return {
|
||||
...pickDefined(base),
|
||||
...pickDefined(overrides),
|
||||
browser,
|
||||
network: {
|
||||
...pickDefined(base.network),
|
||||
...pickDefined(overrides.network)
|
||||
},
|
||||
server: {
|
||||
...pickDefined(base.server),
|
||||
...pickDefined(overrides.server)
|
||||
},
|
||||
timeouts: {
|
||||
...pickDefined(base.timeouts),
|
||||
...pickDefined(overrides.timeouts)
|
||||
}
|
||||
};
|
||||
}
|
||||
function semicolonSeparatedList(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return value.split(";").map((v) => v.trim());
|
||||
}
|
||||
function commaSeparatedList(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return value.split(",").map((v) => v.trim());
|
||||
}
|
||||
function dotenvFileLoader(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return import_utilsBundle.dotenv.parse(import_fs.default.readFileSync(value, "utf8"));
|
||||
}
|
||||
function numberParser(value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
return +value;
|
||||
}
|
||||
function resolutionParser(name, value) {
|
||||
if (!value)
|
||||
return void 0;
|
||||
if (value.includes("x")) {
|
||||
const [width, height] = value.split("x").map((v) => +v);
|
||||
if (isNaN(width) || isNaN(height) || width <= 0 || height <= 0)
|
||||
throw new Error(`Invalid resolution format: use ${name}="800x600"`);
|
||||
return { width, height };
|
||||
}
|
||||
if (value.includes(",")) {
|
||||
const [width, height] = value.split(",").map((v) => +v);
|
||||
if (isNaN(width) || isNaN(height) || width <= 0 || height <= 0)
|
||||
throw new Error(`Invalid resolution format: use ${name}="800x600"`);
|
||||
return { width, height };
|
||||
}
|
||||
throw new Error(`Invalid resolution format: use ${name}="800x600"`);
|
||||
}
|
||||
function headerParser(arg, previous) {
|
||||
if (!arg)
|
||||
return previous || {};
|
||||
const result = previous || {};
|
||||
const [name, value] = arg.split(":").map((v) => v.trim());
|
||||
result[name] = value;
|
||||
return result;
|
||||
}
|
||||
function envToBoolean(value) {
|
||||
if (value === "true" || value === "1")
|
||||
return true;
|
||||
if (value === "false" || value === "0")
|
||||
return false;
|
||||
return void 0;
|
||||
}
|
||||
function envToString(value) {
|
||||
return value ? value.trim() : void 0;
|
||||
}
|
||||
function sanitizeForFilePath(s) {
|
||||
const sanitize = (s2) => s2.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, "-");
|
||||
const separator = s.lastIndexOf(".");
|
||||
if (separator === -1)
|
||||
return sanitize(s);
|
||||
return sanitize(s.substring(0, separator)) + "." + sanitize(s.substring(separator + 1));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
commaSeparatedList,
|
||||
configFromCLIOptions,
|
||||
defaultConfig,
|
||||
dotenvFileLoader,
|
||||
headerParser,
|
||||
numberParser,
|
||||
outputDir,
|
||||
outputFile,
|
||||
resolutionParser,
|
||||
resolveCLIConfig,
|
||||
resolveConfig,
|
||||
semicolonSeparatedList
|
||||
});
|
||||
284
node_modules/playwright/lib/mcp/browser/context.js
generated
vendored
Normal file
284
node_modules/playwright/lib/mcp/browser/context.js
generated
vendored
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var context_exports = {};
|
||||
__export(context_exports, {
|
||||
Context: () => Context,
|
||||
InputRecorder: () => InputRecorder
|
||||
});
|
||||
module.exports = __toCommonJS(context_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_log = require("../log");
|
||||
var import_tab = require("./tab");
|
||||
var import_config = require("./config");
|
||||
var codegen = __toESM(require("./codegen"));
|
||||
var import_utils = require("./tools/utils");
|
||||
const testDebug = (0, import_utilsBundle.debug)("pw:mcp:test");
|
||||
class Context {
|
||||
constructor(options) {
|
||||
this._tabs = [];
|
||||
this._abortController = new AbortController();
|
||||
this.config = options.config;
|
||||
this.sessionLog = options.sessionLog;
|
||||
this.options = options;
|
||||
this._browserContextFactory = options.browserContextFactory;
|
||||
this._clientInfo = options.clientInfo;
|
||||
testDebug("create context");
|
||||
Context._allContexts.add(this);
|
||||
}
|
||||
static {
|
||||
this._allContexts = /* @__PURE__ */ new Set();
|
||||
}
|
||||
static async disposeAll() {
|
||||
await Promise.all([...Context._allContexts].map((context) => context.dispose()));
|
||||
}
|
||||
tabs() {
|
||||
return this._tabs;
|
||||
}
|
||||
currentTab() {
|
||||
return this._currentTab;
|
||||
}
|
||||
currentTabOrDie() {
|
||||
if (!this._currentTab)
|
||||
throw new Error('No open pages available. Use the "browser_navigate" tool to navigate to a page first.');
|
||||
return this._currentTab;
|
||||
}
|
||||
async newTab() {
|
||||
const { browserContext } = await this._ensureBrowserContext();
|
||||
const page = await browserContext.newPage();
|
||||
this._currentTab = this._tabs.find((t) => t.page === page);
|
||||
return this._currentTab;
|
||||
}
|
||||
async selectTab(index) {
|
||||
const tab = this._tabs[index];
|
||||
if (!tab)
|
||||
throw new Error(`Tab ${index} not found`);
|
||||
await tab.page.bringToFront();
|
||||
this._currentTab = tab;
|
||||
return tab;
|
||||
}
|
||||
async ensureTab() {
|
||||
const { browserContext } = await this._ensureBrowserContext();
|
||||
if (!this._currentTab)
|
||||
await browserContext.newPage();
|
||||
return this._currentTab;
|
||||
}
|
||||
async closeTab(index) {
|
||||
const tab = index === void 0 ? this._currentTab : this._tabs[index];
|
||||
if (!tab)
|
||||
throw new Error(`Tab ${index} not found`);
|
||||
const url = tab.page.url();
|
||||
await tab.page.close();
|
||||
return url;
|
||||
}
|
||||
async outputFile(fileName, options) {
|
||||
return (0, import_config.outputFile)(this.config, this._clientInfo, fileName, options);
|
||||
}
|
||||
_onPageCreated(page) {
|
||||
const tab = new import_tab.Tab(this, page, (tab2) => this._onPageClosed(tab2));
|
||||
this._tabs.push(tab);
|
||||
if (!this._currentTab)
|
||||
this._currentTab = tab;
|
||||
}
|
||||
_onPageClosed(tab) {
|
||||
const index = this._tabs.indexOf(tab);
|
||||
if (index === -1)
|
||||
return;
|
||||
this._tabs.splice(index, 1);
|
||||
if (this._currentTab === tab)
|
||||
this._currentTab = this._tabs[Math.min(index, this._tabs.length - 1)];
|
||||
if (!this._tabs.length)
|
||||
void this.closeBrowserContext();
|
||||
}
|
||||
async closeBrowserContext() {
|
||||
if (!this._closeBrowserContextPromise)
|
||||
this._closeBrowserContextPromise = this._closeBrowserContextImpl().catch(import_log.logUnhandledError);
|
||||
await this._closeBrowserContextPromise;
|
||||
this._closeBrowserContextPromise = void 0;
|
||||
}
|
||||
isRunningTool() {
|
||||
return this._runningToolName !== void 0;
|
||||
}
|
||||
setRunningTool(name) {
|
||||
this._runningToolName = name;
|
||||
}
|
||||
async _closeBrowserContextImpl() {
|
||||
if (!this._browserContextPromise)
|
||||
return;
|
||||
testDebug("close context");
|
||||
const promise = this._browserContextPromise;
|
||||
this._browserContextPromise = void 0;
|
||||
await promise.then(async ({ browserContext, close }) => {
|
||||
if (this.config.saveTrace)
|
||||
await browserContext.tracing.stop();
|
||||
const videos = this.config.saveVideo ? browserContext.pages().map((page) => page.video()).filter((video) => !!video) : [];
|
||||
await close(async () => {
|
||||
for (const video of videos) {
|
||||
const name = await this.outputFile((0, import_utils.dateAsFileName)("webm"), { origin: "code", reason: "Saving video" });
|
||||
await import_fs.default.promises.mkdir(import_path.default.dirname(name), { recursive: true });
|
||||
const p = await video.path();
|
||||
if (import_fs.default.existsSync(p)) {
|
||||
try {
|
||||
await import_fs.default.promises.rename(p, name);
|
||||
} catch (e) {
|
||||
if (e.code !== "EXDEV")
|
||||
(0, import_log.logUnhandledError)(e);
|
||||
try {
|
||||
await import_fs.default.promises.copyFile(p, name);
|
||||
await import_fs.default.promises.unlink(p);
|
||||
} catch (e2) {
|
||||
(0, import_log.logUnhandledError)(e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
async dispose() {
|
||||
this._abortController.abort("MCP context disposed");
|
||||
await this.closeBrowserContext();
|
||||
Context._allContexts.delete(this);
|
||||
}
|
||||
async _setupRequestInterception(context) {
|
||||
if (this.config.network?.allowedOrigins?.length) {
|
||||
await context.route("**", (route) => route.abort("blockedbyclient"));
|
||||
for (const origin of this.config.network.allowedOrigins)
|
||||
await context.route(originOrHostGlob(origin), (route) => route.continue());
|
||||
}
|
||||
if (this.config.network?.blockedOrigins?.length) {
|
||||
for (const origin of this.config.network.blockedOrigins)
|
||||
await context.route(originOrHostGlob(origin), (route) => route.abort("blockedbyclient"));
|
||||
}
|
||||
}
|
||||
async ensureBrowserContext() {
|
||||
const { browserContext } = await this._ensureBrowserContext();
|
||||
return browserContext;
|
||||
}
|
||||
_ensureBrowserContext() {
|
||||
if (!this._browserContextPromise) {
|
||||
this._browserContextPromise = this._setupBrowserContext();
|
||||
this._browserContextPromise.catch(() => {
|
||||
this._browserContextPromise = void 0;
|
||||
});
|
||||
}
|
||||
return this._browserContextPromise;
|
||||
}
|
||||
async _setupBrowserContext() {
|
||||
if (this._closeBrowserContextPromise)
|
||||
throw new Error("Another browser context is being closed.");
|
||||
const result = await this._browserContextFactory.createContext(this._clientInfo, this._abortController.signal, this._runningToolName);
|
||||
const { browserContext } = result;
|
||||
await this._setupRequestInterception(browserContext);
|
||||
if (this.sessionLog)
|
||||
await InputRecorder.create(this, browserContext);
|
||||
for (const page of browserContext.pages())
|
||||
this._onPageCreated(page);
|
||||
browserContext.on("page", (page) => this._onPageCreated(page));
|
||||
if (this.config.saveTrace) {
|
||||
await browserContext.tracing.start({
|
||||
name: "trace-" + Date.now(),
|
||||
screenshots: true,
|
||||
snapshots: true,
|
||||
_live: true
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
lookupSecret(secretName) {
|
||||
if (!this.config.secrets?.[secretName])
|
||||
return { value: secretName, code: codegen.quote(secretName) };
|
||||
return {
|
||||
value: this.config.secrets[secretName],
|
||||
code: `process.env['${secretName}']`
|
||||
};
|
||||
}
|
||||
}
|
||||
function originOrHostGlob(originOrHost) {
|
||||
try {
|
||||
const url = new URL(originOrHost);
|
||||
if (url.origin !== "null")
|
||||
return `${url.origin}/**`;
|
||||
} catch {
|
||||
}
|
||||
return `*://${originOrHost}/**`;
|
||||
}
|
||||
class InputRecorder {
|
||||
constructor(context, browserContext) {
|
||||
this._context = context;
|
||||
this._browserContext = browserContext;
|
||||
}
|
||||
static async create(context, browserContext) {
|
||||
const recorder = new InputRecorder(context, browserContext);
|
||||
await recorder._initialize();
|
||||
return recorder;
|
||||
}
|
||||
async _initialize() {
|
||||
const sessionLog = this._context.sessionLog;
|
||||
await this._browserContext._enableRecorder({
|
||||
mode: "recording",
|
||||
recorderMode: "api"
|
||||
}, {
|
||||
actionAdded: (page, data, code) => {
|
||||
if (this._context.isRunningTool())
|
||||
return;
|
||||
const tab = import_tab.Tab.forPage(page);
|
||||
if (tab)
|
||||
sessionLog.logUserAction(data.action, tab, code, false);
|
||||
},
|
||||
actionUpdated: (page, data, code) => {
|
||||
if (this._context.isRunningTool())
|
||||
return;
|
||||
const tab = import_tab.Tab.forPage(page);
|
||||
if (tab)
|
||||
sessionLog.logUserAction(data.action, tab, code, true);
|
||||
},
|
||||
signalAdded: (page, data) => {
|
||||
if (this._context.isRunningTool())
|
||||
return;
|
||||
if (data.signal.name !== "navigation")
|
||||
return;
|
||||
const tab = import_tab.Tab.forPage(page);
|
||||
const navigateAction = {
|
||||
name: "navigate",
|
||||
url: data.signal.url,
|
||||
signals: []
|
||||
};
|
||||
if (tab)
|
||||
sessionLog.logUserAction(navigateAction, tab, `await page.goto('${data.signal.url}');`, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Context,
|
||||
InputRecorder
|
||||
});
|
||||
228
node_modules/playwright/lib/mcp/browser/response.js
generated
vendored
Normal file
228
node_modules/playwright/lib/mcp/browser/response.js
generated
vendored
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var response_exports = {};
|
||||
__export(response_exports, {
|
||||
Response: () => Response,
|
||||
parseResponse: () => parseResponse,
|
||||
requestDebug: () => requestDebug
|
||||
});
|
||||
module.exports = __toCommonJS(response_exports);
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_tab = require("./tab");
|
||||
const requestDebug = (0, import_utilsBundle.debug)("pw:mcp:request");
|
||||
class Response {
|
||||
constructor(context, toolName, toolArgs) {
|
||||
this._result = [];
|
||||
this._code = [];
|
||||
this._images = [];
|
||||
this._includeSnapshot = false;
|
||||
this._includeTabs = false;
|
||||
this._context = context;
|
||||
this.toolName = toolName;
|
||||
this.toolArgs = toolArgs;
|
||||
}
|
||||
addResult(result) {
|
||||
this._result.push(result);
|
||||
}
|
||||
addError(error) {
|
||||
this._result.push(error);
|
||||
this._isError = true;
|
||||
}
|
||||
isError() {
|
||||
return this._isError;
|
||||
}
|
||||
result() {
|
||||
return this._result.join("\n");
|
||||
}
|
||||
addCode(code) {
|
||||
this._code.push(code);
|
||||
}
|
||||
code() {
|
||||
return this._code.join("\n");
|
||||
}
|
||||
addImage(image) {
|
||||
this._images.push(image);
|
||||
}
|
||||
images() {
|
||||
return this._images;
|
||||
}
|
||||
setIncludeSnapshot() {
|
||||
this._includeSnapshot = true;
|
||||
}
|
||||
setIncludeTabs() {
|
||||
this._includeTabs = true;
|
||||
}
|
||||
async finish() {
|
||||
if (this._includeSnapshot && this._context.currentTab())
|
||||
this._tabSnapshot = await this._context.currentTabOrDie().captureSnapshot();
|
||||
for (const tab of this._context.tabs())
|
||||
await tab.updateTitle();
|
||||
}
|
||||
tabSnapshot() {
|
||||
return this._tabSnapshot;
|
||||
}
|
||||
logBegin() {
|
||||
if (requestDebug.enabled)
|
||||
requestDebug(this.toolName, this.toolArgs);
|
||||
}
|
||||
logEnd() {
|
||||
if (requestDebug.enabled)
|
||||
requestDebug(this.serialize({ omitSnapshot: true, omitBlobs: true }));
|
||||
}
|
||||
serialize(options = {}) {
|
||||
const response = [];
|
||||
if (this._result.length) {
|
||||
response.push("### Result");
|
||||
response.push(this._result.join("\n"));
|
||||
response.push("");
|
||||
}
|
||||
if (this._code.length) {
|
||||
response.push(`### Ran Playwright code
|
||||
\`\`\`js
|
||||
${this._code.join("\n")}
|
||||
\`\`\``);
|
||||
response.push("");
|
||||
}
|
||||
if (this._includeSnapshot || this._includeTabs)
|
||||
response.push(...renderTabsMarkdown(this._context.tabs(), this._includeTabs));
|
||||
if (this._tabSnapshot?.modalStates.length) {
|
||||
response.push(...(0, import_tab.renderModalStates)(this._context, this._tabSnapshot.modalStates));
|
||||
response.push("");
|
||||
} else if (this._tabSnapshot) {
|
||||
response.push(renderTabSnapshot(this._tabSnapshot, options));
|
||||
response.push("");
|
||||
}
|
||||
const content = [
|
||||
{ type: "text", text: response.join("\n") }
|
||||
];
|
||||
if (this._context.config.imageResponses !== "omit") {
|
||||
for (const image of this._images)
|
||||
content.push({ type: "image", data: options.omitBlobs ? "<blob>" : image.data.toString("base64"), mimeType: image.contentType });
|
||||
}
|
||||
this._redactSecrets(content);
|
||||
return { content, isError: this._isError };
|
||||
}
|
||||
_redactSecrets(content) {
|
||||
if (!this._context.config.secrets)
|
||||
return;
|
||||
for (const item of content) {
|
||||
if (item.type !== "text")
|
||||
continue;
|
||||
for (const [secretName, secretValue] of Object.entries(this._context.config.secrets))
|
||||
item.text = item.text.replaceAll(secretValue, `<secret>${secretName}</secret>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
function renderTabSnapshot(tabSnapshot, options = {}) {
|
||||
const lines = [];
|
||||
if (tabSnapshot.consoleMessages.length) {
|
||||
lines.push(`### New console messages`);
|
||||
for (const message of tabSnapshot.consoleMessages)
|
||||
lines.push(`- ${trim(message.toString(), 100)}`);
|
||||
lines.push("");
|
||||
}
|
||||
if (tabSnapshot.downloads.length) {
|
||||
lines.push(`### Downloads`);
|
||||
for (const entry of tabSnapshot.downloads) {
|
||||
if (entry.finished)
|
||||
lines.push(`- Downloaded file ${entry.download.suggestedFilename()} to ${entry.outputFile}`);
|
||||
else
|
||||
lines.push(`- Downloading file ${entry.download.suggestedFilename()} ...`);
|
||||
}
|
||||
lines.push("");
|
||||
}
|
||||
lines.push(`### Page state`);
|
||||
lines.push(`- Page URL: ${tabSnapshot.url}`);
|
||||
lines.push(`- Page Title: ${tabSnapshot.title}`);
|
||||
lines.push(`- Page Snapshot:`);
|
||||
lines.push("```yaml");
|
||||
lines.push(options.omitSnapshot ? "<snapshot>" : tabSnapshot.ariaSnapshot);
|
||||
lines.push("```");
|
||||
return lines.join("\n");
|
||||
}
|
||||
function renderTabsMarkdown(tabs, force = false) {
|
||||
if (tabs.length === 1 && !force)
|
||||
return [];
|
||||
if (!tabs.length) {
|
||||
return [
|
||||
"### Open tabs",
|
||||
'No open tabs. Use the "browser_navigate" tool to navigate to a page first.',
|
||||
""
|
||||
];
|
||||
}
|
||||
const lines = ["### Open tabs"];
|
||||
for (let i = 0; i < tabs.length; i++) {
|
||||
const tab = tabs[i];
|
||||
const current = tab.isCurrentTab() ? " (current)" : "";
|
||||
lines.push(`- ${i}:${current} [${tab.lastTitle()}] (${tab.page.url()})`);
|
||||
}
|
||||
lines.push("");
|
||||
return lines;
|
||||
}
|
||||
function trim(text, maxLength) {
|
||||
if (text.length <= maxLength)
|
||||
return text;
|
||||
return text.slice(0, maxLength) + "...";
|
||||
}
|
||||
function parseSections(text) {
|
||||
const sections = /* @__PURE__ */ new Map();
|
||||
const sectionHeaders = text.split(/^### /m).slice(1);
|
||||
for (const section of sectionHeaders) {
|
||||
const firstNewlineIndex = section.indexOf("\n");
|
||||
if (firstNewlineIndex === -1)
|
||||
continue;
|
||||
const sectionName = section.substring(0, firstNewlineIndex);
|
||||
const sectionContent = section.substring(firstNewlineIndex + 1).trim();
|
||||
sections.set(sectionName, sectionContent);
|
||||
}
|
||||
return sections;
|
||||
}
|
||||
function parseResponse(response) {
|
||||
if (response.content?.[0].type !== "text")
|
||||
return void 0;
|
||||
const text = response.content[0].text;
|
||||
const sections = parseSections(text);
|
||||
const result = sections.get("Result");
|
||||
const code = sections.get("Ran Playwright code");
|
||||
const tabs = sections.get("Open tabs");
|
||||
const pageState = sections.get("Page state");
|
||||
const consoleMessages = sections.get("New console messages");
|
||||
const modalState = sections.get("Modal state");
|
||||
const downloads = sections.get("Downloads");
|
||||
const codeNoFrame = code?.replace(/^```js\n/, "").replace(/\n```$/, "");
|
||||
const isError = response.isError;
|
||||
const attachments = response.content.slice(1);
|
||||
return {
|
||||
result,
|
||||
code: codeNoFrame,
|
||||
tabs,
|
||||
pageState,
|
||||
consoleMessages,
|
||||
modalState,
|
||||
downloads,
|
||||
isError,
|
||||
attachments
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Response,
|
||||
parseResponse,
|
||||
requestDebug
|
||||
});
|
||||
160
node_modules/playwright/lib/mcp/browser/sessionLog.js
generated
vendored
Normal file
160
node_modules/playwright/lib/mcp/browser/sessionLog.js
generated
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var sessionLog_exports = {};
|
||||
__export(sessionLog_exports, {
|
||||
SessionLog: () => SessionLog
|
||||
});
|
||||
module.exports = __toCommonJS(sessionLog_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_log = require("../log");
|
||||
var import_config = require("./config");
|
||||
class SessionLog {
|
||||
constructor(sessionFolder) {
|
||||
this._ordinal = 0;
|
||||
this._pendingEntries = [];
|
||||
this._sessionFileQueue = Promise.resolve();
|
||||
this._folder = sessionFolder;
|
||||
this._file = import_path.default.join(this._folder, "session.md");
|
||||
}
|
||||
static async create(config, clientInfo) {
|
||||
const sessionFolder = await (0, import_config.outputFile)(config, clientInfo, `session-${Date.now()}`, { origin: "code", reason: "Saving session" });
|
||||
await import_fs.default.promises.mkdir(sessionFolder, { recursive: true });
|
||||
console.error(`Session: ${sessionFolder}`);
|
||||
return new SessionLog(sessionFolder);
|
||||
}
|
||||
logResponse(response) {
|
||||
const entry = {
|
||||
timestamp: performance.now(),
|
||||
toolCall: {
|
||||
toolName: response.toolName,
|
||||
toolArgs: response.toolArgs,
|
||||
result: response.result(),
|
||||
isError: response.isError()
|
||||
},
|
||||
code: response.code(),
|
||||
tabSnapshot: response.tabSnapshot()
|
||||
};
|
||||
this._appendEntry(entry);
|
||||
}
|
||||
logUserAction(action, tab, code, isUpdate) {
|
||||
code = code.trim();
|
||||
if (isUpdate) {
|
||||
const lastEntry = this._pendingEntries[this._pendingEntries.length - 1];
|
||||
if (lastEntry?.userAction?.name === action.name) {
|
||||
lastEntry.userAction = action;
|
||||
lastEntry.code = code;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (action.name === "navigate") {
|
||||
const lastEntry = this._pendingEntries[this._pendingEntries.length - 1];
|
||||
if (lastEntry?.tabSnapshot?.url === action.url)
|
||||
return;
|
||||
}
|
||||
const entry = {
|
||||
timestamp: performance.now(),
|
||||
userAction: action,
|
||||
code,
|
||||
tabSnapshot: {
|
||||
url: tab.page.url(),
|
||||
title: "",
|
||||
ariaSnapshot: action.ariaSnapshot || "",
|
||||
modalStates: [],
|
||||
consoleMessages: [],
|
||||
downloads: []
|
||||
}
|
||||
};
|
||||
this._appendEntry(entry);
|
||||
}
|
||||
_appendEntry(entry) {
|
||||
this._pendingEntries.push(entry);
|
||||
if (this._flushEntriesTimeout)
|
||||
clearTimeout(this._flushEntriesTimeout);
|
||||
this._flushEntriesTimeout = setTimeout(() => this._flushEntries(), 1e3);
|
||||
}
|
||||
async _flushEntries() {
|
||||
clearTimeout(this._flushEntriesTimeout);
|
||||
const entries = this._pendingEntries;
|
||||
this._pendingEntries = [];
|
||||
const lines = [""];
|
||||
for (const entry of entries) {
|
||||
const ordinal = (++this._ordinal).toString().padStart(3, "0");
|
||||
if (entry.toolCall) {
|
||||
lines.push(
|
||||
`### Tool call: ${entry.toolCall.toolName}`,
|
||||
`- Args`,
|
||||
"```json",
|
||||
JSON.stringify(entry.toolCall.toolArgs, null, 2),
|
||||
"```"
|
||||
);
|
||||
if (entry.toolCall.result) {
|
||||
lines.push(
|
||||
entry.toolCall.isError ? `- Error` : `- Result`,
|
||||
"```",
|
||||
entry.toolCall.result,
|
||||
"```"
|
||||
);
|
||||
}
|
||||
}
|
||||
if (entry.userAction) {
|
||||
const actionData = { ...entry.userAction };
|
||||
delete actionData.ariaSnapshot;
|
||||
delete actionData.selector;
|
||||
delete actionData.signals;
|
||||
lines.push(
|
||||
`### User action: ${entry.userAction.name}`,
|
||||
`- Args`,
|
||||
"```json",
|
||||
JSON.stringify(actionData, null, 2),
|
||||
"```"
|
||||
);
|
||||
}
|
||||
if (entry.code) {
|
||||
lines.push(
|
||||
`- Code`,
|
||||
"```js",
|
||||
entry.code,
|
||||
"```"
|
||||
);
|
||||
}
|
||||
if (entry.tabSnapshot) {
|
||||
const fileName = `${ordinal}.snapshot.yml`;
|
||||
import_fs.default.promises.writeFile(import_path.default.join(this._folder, fileName), entry.tabSnapshot.ariaSnapshot).catch(import_log.logUnhandledError);
|
||||
lines.push(`- Snapshot: ${fileName}`);
|
||||
}
|
||||
lines.push("", "");
|
||||
}
|
||||
this._sessionFileQueue = this._sessionFileQueue.then(() => import_fs.default.promises.appendFile(this._file, lines.join("\n")));
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
SessionLog
|
||||
});
|
||||
277
node_modules/playwright/lib/mcp/browser/tab.js
generated
vendored
Normal file
277
node_modules/playwright/lib/mcp/browser/tab.js
generated
vendored
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var tab_exports = {};
|
||||
__export(tab_exports, {
|
||||
Tab: () => Tab,
|
||||
TabEvents: () => TabEvents,
|
||||
renderModalStates: () => renderModalStates
|
||||
});
|
||||
module.exports = __toCommonJS(tab_exports);
|
||||
var import_events = require("events");
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_utils2 = require("./tools/utils");
|
||||
var import_log = require("../log");
|
||||
var import_dialogs = require("./tools/dialogs");
|
||||
var import_files = require("./tools/files");
|
||||
const TabEvents = {
|
||||
modalState: "modalState"
|
||||
};
|
||||
class Tab extends import_events.EventEmitter {
|
||||
constructor(context, page, onPageClose) {
|
||||
super();
|
||||
this._lastTitle = "about:blank";
|
||||
this._consoleMessages = [];
|
||||
this._recentConsoleMessages = [];
|
||||
this._requests = /* @__PURE__ */ new Set();
|
||||
this._modalStates = [];
|
||||
this._downloads = [];
|
||||
this.context = context;
|
||||
this.page = page;
|
||||
this._onPageClose = onPageClose;
|
||||
page.on("console", (event) => this._handleConsoleMessage(messageToConsoleMessage(event)));
|
||||
page.on("pageerror", (error) => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));
|
||||
page.on("request", (request) => this._requests.add(request));
|
||||
page.on("close", () => this._onClose());
|
||||
page.on("filechooser", (chooser) => {
|
||||
this.setModalState({
|
||||
type: "fileChooser",
|
||||
description: "File chooser",
|
||||
fileChooser: chooser,
|
||||
clearedBy: import_files.uploadFile.schema.name
|
||||
});
|
||||
});
|
||||
page.on("dialog", (dialog) => this._dialogShown(dialog));
|
||||
page.on("download", (download) => {
|
||||
void this._downloadStarted(download);
|
||||
});
|
||||
page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);
|
||||
page.setDefaultTimeout(this.context.config.timeouts.action);
|
||||
page[tabSymbol] = this;
|
||||
this._initializedPromise = this._initialize();
|
||||
}
|
||||
static forPage(page) {
|
||||
return page[tabSymbol];
|
||||
}
|
||||
static async collectConsoleMessages(page) {
|
||||
const result = [];
|
||||
const messages = await page.consoleMessages().catch(() => []);
|
||||
for (const message of messages)
|
||||
result.push(messageToConsoleMessage(message));
|
||||
const errors = await page.pageErrors().catch(() => []);
|
||||
for (const error of errors)
|
||||
result.push(pageErrorToConsoleMessage(error));
|
||||
return result;
|
||||
}
|
||||
async _initialize() {
|
||||
for (const message of await Tab.collectConsoleMessages(this.page))
|
||||
this._handleConsoleMessage(message);
|
||||
const requests = await this.page.requests().catch(() => []);
|
||||
for (const request of requests)
|
||||
this._requests.add(request);
|
||||
}
|
||||
modalStates() {
|
||||
return this._modalStates;
|
||||
}
|
||||
setModalState(modalState) {
|
||||
this._modalStates.push(modalState);
|
||||
this.emit(TabEvents.modalState, modalState);
|
||||
}
|
||||
clearModalState(modalState) {
|
||||
this._modalStates = this._modalStates.filter((state) => state !== modalState);
|
||||
}
|
||||
modalStatesMarkdown() {
|
||||
return renderModalStates(this.context, this.modalStates());
|
||||
}
|
||||
_dialogShown(dialog) {
|
||||
this.setModalState({
|
||||
type: "dialog",
|
||||
description: `"${dialog.type()}" dialog with message "${dialog.message()}"`,
|
||||
dialog,
|
||||
clearedBy: import_dialogs.handleDialog.schema.name
|
||||
});
|
||||
}
|
||||
async _downloadStarted(download) {
|
||||
const entry = {
|
||||
download,
|
||||
finished: false,
|
||||
outputFile: await this.context.outputFile(download.suggestedFilename(), { origin: "web", reason: "Saving download" })
|
||||
};
|
||||
this._downloads.push(entry);
|
||||
await download.saveAs(entry.outputFile);
|
||||
entry.finished = true;
|
||||
}
|
||||
_clearCollectedArtifacts() {
|
||||
this._consoleMessages.length = 0;
|
||||
this._recentConsoleMessages.length = 0;
|
||||
this._requests.clear();
|
||||
}
|
||||
_handleConsoleMessage(message) {
|
||||
this._consoleMessages.push(message);
|
||||
this._recentConsoleMessages.push(message);
|
||||
}
|
||||
_onClose() {
|
||||
this._clearCollectedArtifacts();
|
||||
this._onPageClose(this);
|
||||
}
|
||||
async updateTitle() {
|
||||
await this._raceAgainstModalStates(async () => {
|
||||
this._lastTitle = await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.title());
|
||||
});
|
||||
}
|
||||
lastTitle() {
|
||||
return this._lastTitle;
|
||||
}
|
||||
isCurrentTab() {
|
||||
return this === this.context.currentTab();
|
||||
}
|
||||
async waitForLoadState(state, options) {
|
||||
await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForLoadState(state, options).catch(import_log.logUnhandledError));
|
||||
}
|
||||
async navigate(url) {
|
||||
this._clearCollectedArtifacts();
|
||||
const downloadEvent = (0, import_utils2.callOnPageNoTrace)(this.page, (page) => page.waitForEvent("download").catch(import_log.logUnhandledError));
|
||||
try {
|
||||
await this.page.goto(url, { waitUntil: "domcontentloaded" });
|
||||
} catch (_e) {
|
||||
const e = _e;
|
||||
const mightBeDownload = e.message.includes("net::ERR_ABORTED") || e.message.includes("Download is starting");
|
||||
if (!mightBeDownload)
|
||||
throw e;
|
||||
const download = await Promise.race([
|
||||
downloadEvent,
|
||||
new Promise((resolve) => setTimeout(resolve, 3e3))
|
||||
]);
|
||||
if (!download)
|
||||
throw e;
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
return;
|
||||
}
|
||||
await this.waitForLoadState("load", { timeout: 5e3 });
|
||||
}
|
||||
async consoleMessages(type) {
|
||||
await this._initializedPromise;
|
||||
return this._consoleMessages.filter((message) => type ? message.type === type : true);
|
||||
}
|
||||
async requests() {
|
||||
await this._initializedPromise;
|
||||
return this._requests;
|
||||
}
|
||||
async captureSnapshot() {
|
||||
let tabSnapshot;
|
||||
const modalStates = await this._raceAgainstModalStates(async () => {
|
||||
const snapshot = await this.page._snapshotForAI();
|
||||
tabSnapshot = {
|
||||
url: this.page.url(),
|
||||
title: await this.page.title(),
|
||||
ariaSnapshot: snapshot,
|
||||
modalStates: [],
|
||||
consoleMessages: [],
|
||||
downloads: this._downloads
|
||||
};
|
||||
});
|
||||
if (tabSnapshot) {
|
||||
tabSnapshot.consoleMessages = this._recentConsoleMessages;
|
||||
this._recentConsoleMessages = [];
|
||||
}
|
||||
return tabSnapshot ?? {
|
||||
url: this.page.url(),
|
||||
title: "",
|
||||
ariaSnapshot: "",
|
||||
modalStates,
|
||||
consoleMessages: [],
|
||||
downloads: []
|
||||
};
|
||||
}
|
||||
_javaScriptBlocked() {
|
||||
return this._modalStates.some((state) => state.type === "dialog");
|
||||
}
|
||||
async _raceAgainstModalStates(action) {
|
||||
if (this.modalStates().length)
|
||||
return this.modalStates();
|
||||
const promise = new import_utils.ManualPromise();
|
||||
const listener = (modalState) => promise.resolve([modalState]);
|
||||
this.once(TabEvents.modalState, listener);
|
||||
return await Promise.race([
|
||||
action().then(() => {
|
||||
this.off(TabEvents.modalState, listener);
|
||||
return [];
|
||||
}),
|
||||
promise
|
||||
]);
|
||||
}
|
||||
async waitForCompletion(callback) {
|
||||
await this._raceAgainstModalStates(() => (0, import_utils2.waitForCompletion)(this, callback));
|
||||
}
|
||||
async refLocator(params) {
|
||||
return (await this.refLocators([params]))[0];
|
||||
}
|
||||
async refLocators(params) {
|
||||
const snapshot = await this.page._snapshotForAI();
|
||||
return params.map((param) => {
|
||||
if (!snapshot.includes(`[ref=${param.ref}]`))
|
||||
throw new Error(`Ref ${param.ref} not found in the current page snapshot. Try capturing new snapshot.`);
|
||||
return this.page.locator(`aria-ref=${param.ref}`).describe(param.element);
|
||||
});
|
||||
}
|
||||
async waitForTimeout(time) {
|
||||
if (this._javaScriptBlocked()) {
|
||||
await new Promise((f) => setTimeout(f, time));
|
||||
return;
|
||||
}
|
||||
await (0, import_utils2.callOnPageNoTrace)(this.page, (page) => {
|
||||
return page.evaluate(() => new Promise((f) => setTimeout(f, 1e3)));
|
||||
});
|
||||
}
|
||||
}
|
||||
function messageToConsoleMessage(message) {
|
||||
return {
|
||||
type: message.type(),
|
||||
text: message.text(),
|
||||
toString: () => `[${message.type().toUpperCase()}] ${message.text()} @ ${message.location().url}:${message.location().lineNumber}`
|
||||
};
|
||||
}
|
||||
function pageErrorToConsoleMessage(errorOrValue) {
|
||||
if (errorOrValue instanceof Error) {
|
||||
return {
|
||||
type: "error",
|
||||
text: errorOrValue.message,
|
||||
toString: () => errorOrValue.stack || errorOrValue.message
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: "error",
|
||||
text: String(errorOrValue),
|
||||
toString: () => String(errorOrValue)
|
||||
};
|
||||
}
|
||||
function renderModalStates(context, modalStates) {
|
||||
const result = ["### Modal state"];
|
||||
if (modalStates.length === 0)
|
||||
result.push("- There is no modal state present");
|
||||
for (const state of modalStates)
|
||||
result.push(`- [${state.description}]: can be handled by the "${state.clearedBy}" tool`);
|
||||
return result;
|
||||
}
|
||||
const tabSymbol = Symbol("tabSymbol");
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
Tab,
|
||||
TabEvents,
|
||||
renderModalStates
|
||||
});
|
||||
80
node_modules/playwright/lib/mcp/browser/tools.js
generated
vendored
Normal file
80
node_modules/playwright/lib/mcp/browser/tools.js
generated
vendored
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var tools_exports = {};
|
||||
__export(tools_exports, {
|
||||
browserTools: () => browserTools,
|
||||
filteredTools: () => filteredTools
|
||||
});
|
||||
module.exports = __toCommonJS(tools_exports);
|
||||
var import_common = __toESM(require("./tools/common"));
|
||||
var import_console = __toESM(require("./tools/console"));
|
||||
var import_dialogs = __toESM(require("./tools/dialogs"));
|
||||
var import_evaluate = __toESM(require("./tools/evaluate"));
|
||||
var import_files = __toESM(require("./tools/files"));
|
||||
var import_form = __toESM(require("./tools/form"));
|
||||
var import_install = __toESM(require("./tools/install"));
|
||||
var import_keyboard = __toESM(require("./tools/keyboard"));
|
||||
var import_mouse = __toESM(require("./tools/mouse"));
|
||||
var import_navigate = __toESM(require("./tools/navigate"));
|
||||
var import_network = __toESM(require("./tools/network"));
|
||||
var import_pdf = __toESM(require("./tools/pdf"));
|
||||
var import_snapshot = __toESM(require("./tools/snapshot"));
|
||||
var import_screenshot = __toESM(require("./tools/screenshot"));
|
||||
var import_tabs = __toESM(require("./tools/tabs"));
|
||||
var import_tracing = __toESM(require("./tools/tracing"));
|
||||
var import_wait = __toESM(require("./tools/wait"));
|
||||
var import_verify = __toESM(require("./tools/verify"));
|
||||
const browserTools = [
|
||||
...import_common.default,
|
||||
...import_console.default,
|
||||
...import_dialogs.default,
|
||||
...import_evaluate.default,
|
||||
...import_files.default,
|
||||
...import_form.default,
|
||||
...import_install.default,
|
||||
...import_keyboard.default,
|
||||
...import_navigate.default,
|
||||
...import_network.default,
|
||||
...import_mouse.default,
|
||||
...import_pdf.default,
|
||||
...import_screenshot.default,
|
||||
...import_snapshot.default,
|
||||
...import_tabs.default,
|
||||
...import_tracing.default,
|
||||
...import_wait.default,
|
||||
...import_verify.default
|
||||
];
|
||||
function filteredTools(config) {
|
||||
return browserTools.filter((tool) => tool.capability.startsWith("core") || config.capabilities?.includes(tool.capability));
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
browserTools,
|
||||
filteredTools
|
||||
});
|
||||
63
node_modules/playwright/lib/mcp/browser/tools/common.js
generated
vendored
Normal file
63
node_modules/playwright/lib/mcp/browser/tools/common.js
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var common_exports = {};
|
||||
__export(common_exports, {
|
||||
default: () => common_default
|
||||
});
|
||||
module.exports = __toCommonJS(common_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const close = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_close",
|
||||
title: "Close browser",
|
||||
description: "Close the page",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
await context.closeBrowserContext();
|
||||
response.setIncludeTabs();
|
||||
response.addCode(`await page.close()`);
|
||||
}
|
||||
});
|
||||
const resize = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_resize",
|
||||
title: "Resize browser window",
|
||||
description: "Resize the browser window",
|
||||
inputSchema: import_bundle.z.object({
|
||||
width: import_bundle.z.number().describe("Width of the browser window"),
|
||||
height: import_bundle.z.number().describe("Height of the browser window")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.addCode(`await page.setViewportSize({ width: ${params.width}, height: ${params.height} });`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.setViewportSize({ width: params.width, height: params.height });
|
||||
});
|
||||
}
|
||||
});
|
||||
var common_default = [
|
||||
close,
|
||||
resize
|
||||
];
|
||||
44
node_modules/playwright/lib/mcp/browser/tools/console.js
generated
vendored
Normal file
44
node_modules/playwright/lib/mcp/browser/tools/console.js
generated
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var console_exports = {};
|
||||
__export(console_exports, {
|
||||
default: () => console_default
|
||||
});
|
||||
module.exports = __toCommonJS(console_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const console = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_console_messages",
|
||||
title: "Get console messages",
|
||||
description: "Returns all console messages",
|
||||
inputSchema: import_bundle.z.object({
|
||||
onlyErrors: import_bundle.z.boolean().optional().describe("Only return error messages")
|
||||
}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const messages = await tab.consoleMessages(params.onlyErrors ? "error" : void 0);
|
||||
messages.map((message) => response.addResult(message.toString()));
|
||||
}
|
||||
});
|
||||
var console_default = [
|
||||
console
|
||||
];
|
||||
60
node_modules/playwright/lib/mcp/browser/tools/dialogs.js
generated
vendored
Normal file
60
node_modules/playwright/lib/mcp/browser/tools/dialogs.js
generated
vendored
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var dialogs_exports = {};
|
||||
__export(dialogs_exports, {
|
||||
default: () => dialogs_default,
|
||||
handleDialog: () => handleDialog
|
||||
});
|
||||
module.exports = __toCommonJS(dialogs_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const handleDialog = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_handle_dialog",
|
||||
title: "Handle a dialog",
|
||||
description: "Handle a dialog",
|
||||
inputSchema: import_bundle.z.object({
|
||||
accept: import_bundle.z.boolean().describe("Whether to accept the dialog."),
|
||||
promptText: import_bundle.z.string().optional().describe("The text of the prompt in case of a prompt dialog.")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const dialogState = tab.modalStates().find((state) => state.type === "dialog");
|
||||
if (!dialogState)
|
||||
throw new Error("No dialog visible");
|
||||
tab.clearModalState(dialogState);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.accept)
|
||||
await dialogState.dialog.accept(params.promptText);
|
||||
else
|
||||
await dialogState.dialog.dismiss();
|
||||
});
|
||||
},
|
||||
clearsModalState: "dialog"
|
||||
});
|
||||
var dialogs_default = [
|
||||
handleDialog
|
||||
];
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
handleDialog
|
||||
});
|
||||
70
node_modules/playwright/lib/mcp/browser/tools/evaluate.js
generated
vendored
Normal file
70
node_modules/playwright/lib/mcp/browser/tools/evaluate.js
generated
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var evaluate_exports = {};
|
||||
__export(evaluate_exports, {
|
||||
default: () => evaluate_default
|
||||
});
|
||||
module.exports = __toCommonJS(evaluate_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const evaluateSchema = import_bundle.z.object({
|
||||
function: import_bundle.z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
|
||||
element: import_bundle.z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
|
||||
ref: import_bundle.z.string().optional().describe("Exact target element reference from the page snapshot")
|
||||
});
|
||||
const evaluate = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_evaluate",
|
||||
title: "Evaluate JavaScript",
|
||||
description: "Evaluate JavaScript expression on page or element",
|
||||
inputSchema: evaluateSchema,
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
let locator;
|
||||
if (params.ref && params.element) {
|
||||
locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.evaluate(${javascript.quote(params.function)});`);
|
||||
} else {
|
||||
response.addCode(`await page.evaluate(${javascript.quote(params.function)});`);
|
||||
}
|
||||
await tab.waitForCompletion(async () => {
|
||||
const receiver = locator ?? tab.page;
|
||||
const result = await receiver._evaluateFunction(params.function);
|
||||
response.addResult(JSON.stringify(result, null, 2) || "undefined");
|
||||
});
|
||||
}
|
||||
});
|
||||
var evaluate_default = [
|
||||
evaluate
|
||||
];
|
||||
58
node_modules/playwright/lib/mcp/browser/tools/files.js
generated
vendored
Normal file
58
node_modules/playwright/lib/mcp/browser/tools/files.js
generated
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var files_exports = {};
|
||||
__export(files_exports, {
|
||||
default: () => files_default,
|
||||
uploadFile: () => uploadFile
|
||||
});
|
||||
module.exports = __toCommonJS(files_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const uploadFile = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_file_upload",
|
||||
title: "Upload files",
|
||||
description: "Upload one or multiple files",
|
||||
inputSchema: import_bundle.z.object({
|
||||
paths: import_bundle.z.array(import_bundle.z.string()).optional().describe("The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const modalState = tab.modalStates().find((state) => state.type === "fileChooser");
|
||||
if (!modalState)
|
||||
throw new Error("No file chooser visible");
|
||||
response.addCode(`await fileChooser.setFiles(${JSON.stringify(params.paths)})`);
|
||||
tab.clearModalState(modalState);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.paths)
|
||||
await modalState.fileChooser.setFiles(params.paths);
|
||||
});
|
||||
},
|
||||
clearsModalState: "fileChooser"
|
||||
});
|
||||
var files_default = [
|
||||
uploadFile
|
||||
];
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
uploadFile
|
||||
});
|
||||
74
node_modules/playwright/lib/mcp/browser/tools/form.js
generated
vendored
Normal file
74
node_modules/playwright/lib/mcp/browser/tools/form.js
generated
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var form_exports = {};
|
||||
__export(form_exports, {
|
||||
default: () => form_default
|
||||
});
|
||||
module.exports = __toCommonJS(form_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var import_utils = require("./utils");
|
||||
var codegen = __toESM(require("../codegen"));
|
||||
const fillForm = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_fill_form",
|
||||
title: "Fill form",
|
||||
description: "Fill multiple form fields",
|
||||
inputSchema: import_bundle.z.object({
|
||||
fields: import_bundle.z.array(import_bundle.z.object({
|
||||
name: import_bundle.z.string().describe("Human-readable field name"),
|
||||
type: import_bundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the field"),
|
||||
ref: import_bundle.z.string().describe("Exact target field reference from the page snapshot"),
|
||||
value: import_bundle.z.string().describe("Value to fill in the field. If the field is a checkbox, the value should be `true` or `false`. If the field is a combobox, the value should be the text of the option.")
|
||||
})).describe("Fields to fill in")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
for (const field of params.fields) {
|
||||
const locator = await tab.refLocator({ element: field.name, ref: field.ref });
|
||||
const locatorSource = `await page.${await (0, import_utils.generateLocator)(locator)}`;
|
||||
if (field.type === "textbox" || field.type === "slider") {
|
||||
const secret = tab.context.lookupSecret(field.value);
|
||||
await locator.fill(secret.value);
|
||||
response.addCode(`${locatorSource}.fill(${secret.code});`);
|
||||
} else if (field.type === "checkbox" || field.type === "radio") {
|
||||
await locator.setChecked(field.value === "true");
|
||||
response.addCode(`${locatorSource}.setChecked(${field.value});`);
|
||||
} else if (field.type === "combobox") {
|
||||
await locator.selectOption({ label: field.value });
|
||||
response.addCode(`${locatorSource}.selectOption(${codegen.quote(field.value)});`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
var form_default = [
|
||||
fillForm
|
||||
];
|
||||
69
node_modules/playwright/lib/mcp/browser/tools/install.js
generated
vendored
Normal file
69
node_modules/playwright/lib/mcp/browser/tools/install.js
generated
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var install_exports = {};
|
||||
__export(install_exports, {
|
||||
default: () => install_default
|
||||
});
|
||||
module.exports = __toCommonJS(install_exports);
|
||||
var import_child_process = require("child_process");
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const install = (0, import_tool.defineTool)({
|
||||
capability: "core-install",
|
||||
schema: {
|
||||
name: "browser_install",
|
||||
title: "Install the browser specified in the config",
|
||||
description: "Install the browser specified in the config. Call this if you get an error about the browser not being installed.",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const channel = context.config.browser?.launchOptions?.channel ?? context.config.browser?.browserName ?? "chrome";
|
||||
const cliPath = import_path.default.join(require.resolve("playwright/package.json"), "../cli.js");
|
||||
const child = (0, import_child_process.fork)(cliPath, ["install", channel], {
|
||||
stdio: "pipe"
|
||||
});
|
||||
const output = [];
|
||||
child.stdout?.on("data", (data) => output.push(data.toString()));
|
||||
child.stderr?.on("data", (data) => output.push(data.toString()));
|
||||
await new Promise((resolve, reject) => {
|
||||
child.on("close", (code) => {
|
||||
if (code === 0)
|
||||
resolve();
|
||||
else
|
||||
reject(new Error(`Failed to install browser: ${output.join("")}`));
|
||||
});
|
||||
});
|
||||
response.setIncludeTabs();
|
||||
}
|
||||
});
|
||||
var install_default = [
|
||||
install
|
||||
];
|
||||
85
node_modules/playwright/lib/mcp/browser/tools/keyboard.js
generated
vendored
Normal file
85
node_modules/playwright/lib/mcp/browser/tools/keyboard.js
generated
vendored
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var keyboard_exports = {};
|
||||
__export(keyboard_exports, {
|
||||
default: () => keyboard_default
|
||||
});
|
||||
module.exports = __toCommonJS(keyboard_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var import_snapshot = require("./snapshot");
|
||||
var import_utils = require("./utils");
|
||||
const pressKey = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_press_key",
|
||||
title: "Press a key",
|
||||
description: "Press a key on the keyboard",
|
||||
inputSchema: import_bundle.z.object({
|
||||
key: import_bundle.z.string().describe("Name of the key to press or a character to generate, such as `ArrowLeft` or `a`")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Press ${params.key}`);
|
||||
response.addCode(`await page.keyboard.press('${params.key}');`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.keyboard.press(params.key);
|
||||
});
|
||||
}
|
||||
});
|
||||
const typeSchema = import_snapshot.elementSchema.extend({
|
||||
text: import_bundle.z.string().describe("Text to type into the element"),
|
||||
submit: import_bundle.z.boolean().optional().describe("Whether to submit entered text (press Enter after)"),
|
||||
slowly: import_bundle.z.boolean().optional().describe("Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.")
|
||||
});
|
||||
const type = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_type",
|
||||
title: "Type text",
|
||||
description: "Type text into editable element",
|
||||
inputSchema: typeSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator(params);
|
||||
const secret = tab.context.lookupSecret(params.text);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.slowly) {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.pressSequentially(${secret.code});`);
|
||||
await locator.pressSequentially(secret.value);
|
||||
} else {
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.fill(${secret.code});`);
|
||||
await locator.fill(secret.value);
|
||||
}
|
||||
if (params.submit) {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.press('Enter');`);
|
||||
await locator.press("Enter");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
var keyboard_default = [
|
||||
pressKey,
|
||||
type
|
||||
];
|
||||
107
node_modules/playwright/lib/mcp/browser/tools/mouse.js
generated
vendored
Normal file
107
node_modules/playwright/lib/mcp/browser/tools/mouse.js
generated
vendored
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var mouse_exports = {};
|
||||
__export(mouse_exports, {
|
||||
default: () => mouse_default
|
||||
});
|
||||
module.exports = __toCommonJS(mouse_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const elementSchema = import_bundle.z.object({
|
||||
element: import_bundle.z.string().describe("Human-readable element description used to obtain permission to interact with the element")
|
||||
});
|
||||
const mouseMove = (0, import_tool.defineTabTool)({
|
||||
capability: "vision",
|
||||
schema: {
|
||||
name: "browser_mouse_move_xy",
|
||||
title: "Move mouse",
|
||||
description: "Move mouse to a given position",
|
||||
inputSchema: elementSchema.extend({
|
||||
x: import_bundle.z.number().describe("X coordinate"),
|
||||
y: import_bundle.z.number().describe("Y coordinate")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.addCode(`// Move mouse to (${params.x}, ${params.y})`);
|
||||
response.addCode(`await page.mouse.move(${params.x}, ${params.y});`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.mouse.move(params.x, params.y);
|
||||
});
|
||||
}
|
||||
});
|
||||
const mouseClick = (0, import_tool.defineTabTool)({
|
||||
capability: "vision",
|
||||
schema: {
|
||||
name: "browser_mouse_click_xy",
|
||||
title: "Click",
|
||||
description: "Click left mouse button at a given position",
|
||||
inputSchema: elementSchema.extend({
|
||||
x: import_bundle.z.number().describe("X coordinate"),
|
||||
y: import_bundle.z.number().describe("Y coordinate")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Click mouse at coordinates (${params.x}, ${params.y})`);
|
||||
response.addCode(`await page.mouse.move(${params.x}, ${params.y});`);
|
||||
response.addCode(`await page.mouse.down();`);
|
||||
response.addCode(`await page.mouse.up();`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.mouse.move(params.x, params.y);
|
||||
await tab.page.mouse.down();
|
||||
await tab.page.mouse.up();
|
||||
});
|
||||
}
|
||||
});
|
||||
const mouseDrag = (0, import_tool.defineTabTool)({
|
||||
capability: "vision",
|
||||
schema: {
|
||||
name: "browser_mouse_drag_xy",
|
||||
title: "Drag mouse",
|
||||
description: "Drag left mouse button to a given position",
|
||||
inputSchema: elementSchema.extend({
|
||||
startX: import_bundle.z.number().describe("Start X coordinate"),
|
||||
startY: import_bundle.z.number().describe("Start Y coordinate"),
|
||||
endX: import_bundle.z.number().describe("End X coordinate"),
|
||||
endY: import_bundle.z.number().describe("End Y coordinate")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`// Drag mouse from (${params.startX}, ${params.startY}) to (${params.endX}, ${params.endY})`);
|
||||
response.addCode(`await page.mouse.move(${params.startX}, ${params.startY});`);
|
||||
response.addCode(`await page.mouse.down();`);
|
||||
response.addCode(`await page.mouse.move(${params.endX}, ${params.endY});`);
|
||||
response.addCode(`await page.mouse.up();`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await tab.page.mouse.move(params.startX, params.startY);
|
||||
await tab.page.mouse.down();
|
||||
await tab.page.mouse.move(params.endX, params.endY);
|
||||
await tab.page.mouse.up();
|
||||
});
|
||||
}
|
||||
});
|
||||
var mouse_default = [
|
||||
mouseMove,
|
||||
mouseClick,
|
||||
mouseDrag
|
||||
];
|
||||
62
node_modules/playwright/lib/mcp/browser/tools/navigate.js
generated
vendored
Normal file
62
node_modules/playwright/lib/mcp/browser/tools/navigate.js
generated
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var navigate_exports = {};
|
||||
__export(navigate_exports, {
|
||||
default: () => navigate_default
|
||||
});
|
||||
module.exports = __toCommonJS(navigate_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const navigate = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_navigate",
|
||||
title: "Navigate to a URL",
|
||||
description: "Navigate to a URL",
|
||||
inputSchema: import_bundle.z.object({
|
||||
url: import_bundle.z.string().describe("The URL to navigate to")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const tab = await context.ensureTab();
|
||||
await tab.navigate(params.url);
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.goto('${params.url}');`);
|
||||
}
|
||||
});
|
||||
const goBack = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_navigate_back",
|
||||
title: "Go back",
|
||||
description: "Go back to the previous page",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
await tab.page.goBack();
|
||||
response.setIncludeSnapshot();
|
||||
response.addCode(`await page.goBack();`);
|
||||
}
|
||||
});
|
||||
var navigate_default = [
|
||||
navigate,
|
||||
goBack
|
||||
];
|
||||
54
node_modules/playwright/lib/mcp/browser/tools/network.js
generated
vendored
Normal file
54
node_modules/playwright/lib/mcp/browser/tools/network.js
generated
vendored
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var network_exports = {};
|
||||
__export(network_exports, {
|
||||
default: () => network_default
|
||||
});
|
||||
module.exports = __toCommonJS(network_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const requests = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_network_requests",
|
||||
title: "List network requests",
|
||||
description: "Returns all network requests since loading the page",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const requests2 = await tab.requests();
|
||||
for (const request of requests2)
|
||||
response.addResult(await renderRequest(request));
|
||||
}
|
||||
});
|
||||
async function renderRequest(request) {
|
||||
const result = [];
|
||||
result.push(`[${request.method().toUpperCase()}] ${request.url()}`);
|
||||
const hasResponse = request._hasResponse;
|
||||
if (hasResponse) {
|
||||
const response = await request.response();
|
||||
if (response)
|
||||
result.push(`=> [${response.status()}] ${response.statusText()}`);
|
||||
}
|
||||
return result.join(" ");
|
||||
}
|
||||
var network_default = [
|
||||
requests
|
||||
];
|
||||
59
node_modules/playwright/lib/mcp/browser/tools/pdf.js
generated
vendored
Normal file
59
node_modules/playwright/lib/mcp/browser/tools/pdf.js
generated
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var pdf_exports = {};
|
||||
__export(pdf_exports, {
|
||||
default: () => pdf_default
|
||||
});
|
||||
module.exports = __toCommonJS(pdf_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const pdfSchema = import_bundle.z.object({
|
||||
filename: import_bundle.z.string().optional().describe("File name to save the pdf to. Defaults to `page-{timestamp}.pdf` if not specified.")
|
||||
});
|
||||
const pdf = (0, import_tool.defineTabTool)({
|
||||
capability: "pdf",
|
||||
schema: {
|
||||
name: "browser_pdf_save",
|
||||
title: "Save as PDF",
|
||||
description: "Save page as PDF",
|
||||
inputSchema: pdfSchema,
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const fileName = await tab.context.outputFile(params.filename ?? (0, import_utils.dateAsFileName)("pdf"), { origin: "llm", reason: "Saving PDF" });
|
||||
response.addCode(`await page.pdf(${javascript.formatObject({ path: fileName })});`);
|
||||
response.addResult(`Saved page as ${fileName}`);
|
||||
await tab.page.pdf({ path: fileName });
|
||||
}
|
||||
});
|
||||
var pdf_default = [
|
||||
pdf
|
||||
];
|
||||
88
node_modules/playwright/lib/mcp/browser/tools/screenshot.js
generated
vendored
Normal file
88
node_modules/playwright/lib/mcp/browser/tools/screenshot.js
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var screenshot_exports = {};
|
||||
__export(screenshot_exports, {
|
||||
default: () => screenshot_default
|
||||
});
|
||||
module.exports = __toCommonJS(screenshot_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const screenshotSchema = import_bundle.z.object({
|
||||
type: import_bundle.z.enum(["png", "jpeg"]).default("png").describe("Image format for the screenshot. Default is png."),
|
||||
filename: import_bundle.z.string().optional().describe("File name to save the screenshot to. Defaults to `page-{timestamp}.{png|jpeg}` if not specified."),
|
||||
element: import_bundle.z.string().optional().describe("Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too."),
|
||||
ref: import_bundle.z.string().optional().describe("Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too."),
|
||||
fullPage: import_bundle.z.boolean().optional().describe("When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots.")
|
||||
});
|
||||
const screenshot = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_take_screenshot",
|
||||
title: "Take a screenshot",
|
||||
description: `Take a screenshot of the current page. You can't perform actions based on the screenshot, use browser_snapshot for actions.`,
|
||||
inputSchema: screenshotSchema,
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
if (!!params.element !== !!params.ref)
|
||||
throw new Error("Both element and ref must be provided or neither.");
|
||||
if (params.fullPage && params.ref)
|
||||
throw new Error("fullPage cannot be used with element screenshots.");
|
||||
const fileType = params.type || "png";
|
||||
const fileName = await tab.context.outputFile(params.filename ?? (0, import_utils.dateAsFileName)(fileType), { origin: "llm", reason: "Saving screenshot" });
|
||||
const options = {
|
||||
type: fileType,
|
||||
quality: fileType === "png" ? void 0 : 90,
|
||||
scale: "css",
|
||||
path: fileName,
|
||||
...params.fullPage !== void 0 && { fullPage: params.fullPage }
|
||||
};
|
||||
const isElementScreenshot = params.element && params.ref;
|
||||
const screenshotTarget = isElementScreenshot ? params.element : params.fullPage ? "full page" : "viewport";
|
||||
response.addCode(`// Screenshot ${screenshotTarget} and save it as ${fileName}`);
|
||||
const locator = params.ref ? await tab.refLocator({ element: params.element || "", ref: params.ref }) : null;
|
||||
if (locator)
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.screenshot(${javascript.formatObject(options)});`);
|
||||
else
|
||||
response.addCode(`await page.screenshot(${javascript.formatObject(options)});`);
|
||||
const buffer = locator ? await locator.screenshot(options) : await tab.page.screenshot(options);
|
||||
response.addResult(`Took the ${screenshotTarget} screenshot and saved it as ${fileName}`);
|
||||
if (!params.fullPage) {
|
||||
response.addImage({
|
||||
contentType: fileType === "png" ? "image/png" : "image/jpeg",
|
||||
data: buffer
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
var screenshot_default = [
|
||||
screenshot
|
||||
];
|
||||
182
node_modules/playwright/lib/mcp/browser/tools/snapshot.js
generated
vendored
Normal file
182
node_modules/playwright/lib/mcp/browser/tools/snapshot.js
generated
vendored
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var snapshot_exports = {};
|
||||
__export(snapshot_exports, {
|
||||
default: () => snapshot_default,
|
||||
elementSchema: () => elementSchema
|
||||
});
|
||||
module.exports = __toCommonJS(snapshot_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const snapshot = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_snapshot",
|
||||
title: "Page snapshot",
|
||||
description: "Capture accessibility snapshot of the current page, this is better than screenshot",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
await context.ensureTab();
|
||||
response.setIncludeSnapshot();
|
||||
}
|
||||
});
|
||||
const elementSchema = import_bundle.z.object({
|
||||
element: import_bundle.z.string().describe("Human-readable element description used to obtain permission to interact with the element"),
|
||||
ref: import_bundle.z.string().describe("Exact target element reference from the page snapshot")
|
||||
});
|
||||
const clickSchema = elementSchema.extend({
|
||||
doubleClick: import_bundle.z.boolean().optional().describe("Whether to perform a double click instead of a single click"),
|
||||
button: import_bundle.z.enum(["left", "right", "middle"]).optional().describe("Button to click, defaults to left"),
|
||||
modifiers: import_bundle.z.array(import_bundle.z.enum(["Alt", "Control", "ControlOrMeta", "Meta", "Shift"])).optional().describe("Modifier keys to press")
|
||||
});
|
||||
const click = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_click",
|
||||
title: "Click",
|
||||
description: "Perform click on a web page",
|
||||
inputSchema: clickSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const locator = await tab.refLocator(params);
|
||||
const options = {
|
||||
button: params.button,
|
||||
modifiers: params.modifiers
|
||||
};
|
||||
const formatted = javascript.formatObject(options, " ", "oneline");
|
||||
const optionsAttr = formatted !== "{}" ? formatted : "";
|
||||
if (params.doubleClick)
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.dblclick(${optionsAttr});`);
|
||||
else
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.click(${optionsAttr});`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
if (params.doubleClick)
|
||||
await locator.dblclick(options);
|
||||
else
|
||||
await locator.click(options);
|
||||
});
|
||||
}
|
||||
});
|
||||
const drag = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_drag",
|
||||
title: "Drag mouse",
|
||||
description: "Perform drag and drop between two elements",
|
||||
inputSchema: import_bundle.z.object({
|
||||
startElement: import_bundle.z.string().describe("Human-readable source element description used to obtain the permission to interact with the element"),
|
||||
startRef: import_bundle.z.string().describe("Exact source element reference from the page snapshot"),
|
||||
endElement: import_bundle.z.string().describe("Human-readable target element description used to obtain the permission to interact with the element"),
|
||||
endRef: import_bundle.z.string().describe("Exact target element reference from the page snapshot")
|
||||
}),
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const [startLocator, endLocator] = await tab.refLocators([
|
||||
{ ref: params.startRef, element: params.startElement },
|
||||
{ ref: params.endRef, element: params.endElement }
|
||||
]);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await startLocator.dragTo(endLocator);
|
||||
});
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(startLocator)}.dragTo(page.${await (0, import_utils.generateLocator)(endLocator)});`);
|
||||
}
|
||||
});
|
||||
const hover = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_hover",
|
||||
title: "Hover mouse",
|
||||
description: "Hover over element on page",
|
||||
inputSchema: elementSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const locator = await tab.refLocator(params);
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.hover();`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await locator.hover();
|
||||
});
|
||||
}
|
||||
});
|
||||
const selectOptionSchema = elementSchema.extend({
|
||||
values: import_bundle.z.array(import_bundle.z.string()).describe("Array of values to select in the dropdown. This can be a single value or multiple values.")
|
||||
});
|
||||
const selectOption = (0, import_tool.defineTabTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_select_option",
|
||||
title: "Select option",
|
||||
description: "Select an option in a dropdown",
|
||||
inputSchema: selectOptionSchema,
|
||||
type: "input"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
response.setIncludeSnapshot();
|
||||
const locator = await tab.refLocator(params);
|
||||
response.addCode(`await page.${await (0, import_utils.generateLocator)(locator)}.selectOption(${javascript.formatObject(params.values)});`);
|
||||
await tab.waitForCompletion(async () => {
|
||||
await locator.selectOption(params.values);
|
||||
});
|
||||
}
|
||||
});
|
||||
const pickLocator = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_generate_locator",
|
||||
title: "Create locator for element",
|
||||
description: "Generate locator for the given element to use in tests",
|
||||
inputSchema: elementSchema,
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator(params);
|
||||
response.addResult(await (0, import_utils.generateLocator)(locator));
|
||||
}
|
||||
});
|
||||
var snapshot_default = [
|
||||
snapshot,
|
||||
click,
|
||||
drag,
|
||||
hover,
|
||||
selectOption,
|
||||
pickLocator
|
||||
];
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
elementSchema
|
||||
});
|
||||
67
node_modules/playwright/lib/mcp/browser/tools/tabs.js
generated
vendored
Normal file
67
node_modules/playwright/lib/mcp/browser/tools/tabs.js
generated
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var tabs_exports = {};
|
||||
__export(tabs_exports, {
|
||||
default: () => tabs_default
|
||||
});
|
||||
module.exports = __toCommonJS(tabs_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const browserTabs = (0, import_tool.defineTool)({
|
||||
capability: "core-tabs",
|
||||
schema: {
|
||||
name: "browser_tabs",
|
||||
title: "Manage tabs",
|
||||
description: "List, create, close, or select a browser tab.",
|
||||
inputSchema: import_bundle.z.object({
|
||||
action: import_bundle.z.enum(["list", "new", "close", "select"]).describe("Operation to perform"),
|
||||
index: import_bundle.z.number().optional().describe("Tab index, used for close/select. If omitted for close, current tab is closed.")
|
||||
}),
|
||||
type: "action"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
switch (params.action) {
|
||||
case "list": {
|
||||
await context.ensureTab();
|
||||
response.setIncludeTabs();
|
||||
return;
|
||||
}
|
||||
case "new": {
|
||||
await context.newTab();
|
||||
response.setIncludeTabs();
|
||||
return;
|
||||
}
|
||||
case "close": {
|
||||
await context.closeTab(params.index);
|
||||
response.setIncludeSnapshot();
|
||||
return;
|
||||
}
|
||||
case "select": {
|
||||
if (params.index === void 0)
|
||||
throw new Error("Tab index is required");
|
||||
await context.selectTab(params.index);
|
||||
response.setIncludeSnapshot();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
var tabs_default = [
|
||||
browserTabs
|
||||
];
|
||||
49
node_modules/playwright/lib/mcp/browser/tools/tool.js
generated
vendored
Normal file
49
node_modules/playwright/lib/mcp/browser/tools/tool.js
generated
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var tool_exports = {};
|
||||
__export(tool_exports, {
|
||||
defineTabTool: () => defineTabTool,
|
||||
defineTool: () => defineTool
|
||||
});
|
||||
module.exports = __toCommonJS(tool_exports);
|
||||
function defineTool(tool) {
|
||||
return tool;
|
||||
}
|
||||
function defineTabTool(tool) {
|
||||
return {
|
||||
...tool,
|
||||
handle: async (context, params, response) => {
|
||||
const tab = await context.ensureTab();
|
||||
const modalStates = tab.modalStates().map((state) => state.type);
|
||||
if (tool.clearsModalState && !modalStates.includes(tool.clearsModalState))
|
||||
response.addError(`Error: The tool "${tool.schema.name}" can only be used when there is related modal state present.
|
||||
` + tab.modalStatesMarkdown().join("\n"));
|
||||
else if (!tool.clearsModalState && modalStates.length)
|
||||
response.addError(`Error: Tool "${tool.schema.name}" does not handle the modal state.
|
||||
` + tab.modalStatesMarkdown().join("\n"));
|
||||
else
|
||||
return tool.handle(tab, params, response);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
defineTabTool,
|
||||
defineTool
|
||||
});
|
||||
74
node_modules/playwright/lib/mcp/browser/tools/tracing.js
generated
vendored
Normal file
74
node_modules/playwright/lib/mcp/browser/tools/tracing.js
generated
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var tracing_exports = {};
|
||||
__export(tracing_exports, {
|
||||
default: () => tracing_default
|
||||
});
|
||||
module.exports = __toCommonJS(tracing_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const tracingStart = (0, import_tool.defineTool)({
|
||||
capability: "tracing",
|
||||
schema: {
|
||||
name: "browser_start_tracing",
|
||||
title: "Start tracing",
|
||||
description: "Start trace recording",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const browserContext = await context.ensureBrowserContext();
|
||||
const tracesDir = await context.outputFile(`traces`, { origin: "code", reason: "Collecting trace" });
|
||||
const name = "trace-" + Date.now();
|
||||
await browserContext.tracing.start({
|
||||
name,
|
||||
screenshots: true,
|
||||
snapshots: true,
|
||||
_live: true
|
||||
});
|
||||
const traceLegend = `- Action log: ${tracesDir}/${name}.trace
|
||||
- Network log: ${tracesDir}/${name}.network
|
||||
- Resources with content by sha1: ${tracesDir}/resources`;
|
||||
response.addResult(`Tracing started, saving to ${tracesDir}.
|
||||
${traceLegend}`);
|
||||
browserContext.tracing[traceLegendSymbol] = traceLegend;
|
||||
}
|
||||
});
|
||||
const tracingStop = (0, import_tool.defineTool)({
|
||||
capability: "tracing",
|
||||
schema: {
|
||||
name: "browser_stop_tracing",
|
||||
title: "Stop tracing",
|
||||
description: "Stop trace recording",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
const browserContext = await context.ensureBrowserContext();
|
||||
await browserContext.tracing.stop();
|
||||
const traceLegend = browserContext.tracing[traceLegendSymbol];
|
||||
response.addResult(`Tracing stopped.
|
||||
${traceLegend}`);
|
||||
}
|
||||
});
|
||||
var tracing_default = [
|
||||
tracingStart,
|
||||
tracingStop
|
||||
];
|
||||
const traceLegendSymbol = Symbol("tracesDir");
|
||||
100
node_modules/playwright/lib/mcp/browser/tools/utils.js
generated
vendored
Normal file
100
node_modules/playwright/lib/mcp/browser/tools/utils.js
generated
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var utils_exports = {};
|
||||
__export(utils_exports, {
|
||||
callOnPageNoTrace: () => callOnPageNoTrace,
|
||||
dateAsFileName: () => dateAsFileName,
|
||||
generateLocator: () => generateLocator,
|
||||
waitForCompletion: () => waitForCompletion
|
||||
});
|
||||
module.exports = __toCommonJS(utils_exports);
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
async function waitForCompletion(tab, callback) {
|
||||
const requests = /* @__PURE__ */ new Set();
|
||||
let frameNavigated = false;
|
||||
let waitCallback = () => {
|
||||
};
|
||||
const waitBarrier = new Promise((f) => {
|
||||
waitCallback = f;
|
||||
});
|
||||
const responseListener = (request) => {
|
||||
requests.delete(request);
|
||||
if (!requests.size)
|
||||
waitCallback();
|
||||
};
|
||||
const requestListener = (request) => {
|
||||
requests.add(request);
|
||||
void request.response().then(() => responseListener(request)).catch(() => {
|
||||
});
|
||||
};
|
||||
const frameNavigateListener = (frame) => {
|
||||
if (frame.parentFrame())
|
||||
return;
|
||||
frameNavigated = true;
|
||||
dispose();
|
||||
clearTimeout(timeout);
|
||||
void tab.waitForLoadState("load").then(waitCallback);
|
||||
};
|
||||
const onTimeout = () => {
|
||||
dispose();
|
||||
waitCallback();
|
||||
};
|
||||
tab.page.on("request", requestListener);
|
||||
tab.page.on("requestfailed", responseListener);
|
||||
tab.page.on("framenavigated", frameNavigateListener);
|
||||
const timeout = setTimeout(onTimeout, 1e4);
|
||||
const dispose = () => {
|
||||
tab.page.off("request", requestListener);
|
||||
tab.page.off("requestfailed", responseListener);
|
||||
tab.page.off("framenavigated", frameNavigateListener);
|
||||
clearTimeout(timeout);
|
||||
};
|
||||
try {
|
||||
const result = await callback();
|
||||
if (!requests.size && !frameNavigated)
|
||||
waitCallback();
|
||||
await waitBarrier;
|
||||
await tab.waitForTimeout(1e3);
|
||||
return result;
|
||||
} finally {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
async function generateLocator(locator) {
|
||||
try {
|
||||
const { resolvedSelector } = await locator._resolveSelector();
|
||||
return (0, import_utils.asLocator)("javascript", resolvedSelector);
|
||||
} catch (e) {
|
||||
throw new Error("Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.");
|
||||
}
|
||||
}
|
||||
async function callOnPageNoTrace(page, callback) {
|
||||
return await page._wrapApiCall(() => callback(page), { internal: true });
|
||||
}
|
||||
function dateAsFileName(extension) {
|
||||
const date = /* @__PURE__ */ new Date();
|
||||
return `page-${date.toISOString().replace(/[:.]/g, "-")}.${extension}`;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
callOnPageNoTrace,
|
||||
dateAsFileName,
|
||||
generateLocator,
|
||||
waitForCompletion
|
||||
});
|
||||
154
node_modules/playwright/lib/mcp/browser/tools/verify.js
generated
vendored
Normal file
154
node_modules/playwright/lib/mcp/browser/tools/verify.js
generated
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var verify_exports = {};
|
||||
__export(verify_exports, {
|
||||
default: () => verify_default
|
||||
});
|
||||
module.exports = __toCommonJS(verify_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
var javascript = __toESM(require("../codegen"));
|
||||
var import_utils = require("./utils");
|
||||
const verifyElement = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_element_visible",
|
||||
title: "Verify element visible",
|
||||
description: "Verify element is visible on the page",
|
||||
inputSchema: import_bundle.z.object({
|
||||
role: import_bundle.z.string().describe('ROLE of the element. Can be found in the snapshot like this: `- {ROLE} "Accessible Name":`'),
|
||||
accessibleName: import_bundle.z.string().describe('ACCESSIBLE_NAME of the element. Can be found in the snapshot like this: `- role "{ACCESSIBLE_NAME}"`')
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = tab.page.getByRole(params.role, { name: params.accessibleName });
|
||||
if (await locator.count() === 0) {
|
||||
response.addError(`Element with role "${params.role}" and accessible name "${params.accessibleName}" not found`);
|
||||
return;
|
||||
}
|
||||
response.addCode(`await expect(page.getByRole(${javascript.escapeWithQuotes(params.role)}, { name: ${javascript.escapeWithQuotes(params.accessibleName)} })).toBeVisible();`);
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
const verifyText = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_text_visible",
|
||||
title: "Verify text visible",
|
||||
description: `Verify text is visible on the page. Prefer ${verifyElement.schema.name} if possible.`,
|
||||
inputSchema: import_bundle.z.object({
|
||||
text: import_bundle.z.string().describe('TEXT to verify. Can be found in the snapshot like this: `- role "Accessible Name": {TEXT}` or like this: `- text: {TEXT}`')
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = tab.page.getByText(params.text).filter({ visible: true });
|
||||
if (await locator.count() === 0) {
|
||||
response.addError("Text not found");
|
||||
return;
|
||||
}
|
||||
response.addCode(`await expect(page.getByText(${javascript.escapeWithQuotes(params.text)})).toBeVisible();`);
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
const verifyList = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_list_visible",
|
||||
title: "Verify list visible",
|
||||
description: "Verify list is visible on the page",
|
||||
inputSchema: import_bundle.z.object({
|
||||
element: import_bundle.z.string().describe("Human-readable list description"),
|
||||
ref: import_bundle.z.string().describe("Exact target element reference that points to the list"),
|
||||
items: import_bundle.z.array(import_bundle.z.string()).describe("Items to verify")
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
||||
const itemTexts = [];
|
||||
for (const item of params.items) {
|
||||
const itemLocator = locator.getByText(item);
|
||||
if (await itemLocator.count() === 0) {
|
||||
response.addError(`Item "${item}" not found`);
|
||||
return;
|
||||
}
|
||||
itemTexts.push(await itemLocator.textContent());
|
||||
}
|
||||
const ariaSnapshot = `\`
|
||||
- list:
|
||||
${itemTexts.map((t) => ` - listitem: ${javascript.escapeWithQuotes(t, '"')}`).join("\n")}
|
||||
\``;
|
||||
response.addCode(`await expect(page.locator('body')).toMatchAriaSnapshot(${ariaSnapshot});`);
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
const verifyValue = (0, import_tool.defineTabTool)({
|
||||
capability: "testing",
|
||||
schema: {
|
||||
name: "browser_verify_value",
|
||||
title: "Verify value",
|
||||
description: "Verify element value",
|
||||
inputSchema: import_bundle.z.object({
|
||||
type: import_bundle.z.enum(["textbox", "checkbox", "radio", "combobox", "slider"]).describe("Type of the element"),
|
||||
element: import_bundle.z.string().describe("Human-readable element description"),
|
||||
ref: import_bundle.z.string().describe("Exact target element reference that points to the element"),
|
||||
value: import_bundle.z.string().describe('Value to verify. For checkbox, use "true" or "false".')
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (tab, params, response) => {
|
||||
const locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
||||
const locatorSource = `page.${await (0, import_utils.generateLocator)(locator)}`;
|
||||
if (params.type === "textbox" || params.type === "slider" || params.type === "combobox") {
|
||||
const value = await locator.inputValue();
|
||||
if (value !== params.value) {
|
||||
response.addError(`Expected value "${params.value}", but got "${value}"`);
|
||||
return;
|
||||
}
|
||||
response.addCode(`await expect(${locatorSource}).toHaveValue(${javascript.quote(params.value)});`);
|
||||
} else if (params.type === "checkbox" || params.type === "radio") {
|
||||
const value = await locator.isChecked();
|
||||
if (value !== (params.value === "true")) {
|
||||
response.addError(`Expected value "${params.value}", but got "${value}"`);
|
||||
return;
|
||||
}
|
||||
const matcher = value ? "toBeChecked" : "not.toBeChecked";
|
||||
response.addCode(`await expect(${locatorSource}).${matcher}();`);
|
||||
}
|
||||
response.addResult("Done");
|
||||
}
|
||||
});
|
||||
var verify_default = [
|
||||
verifyElement,
|
||||
verifyText,
|
||||
verifyList,
|
||||
verifyValue
|
||||
];
|
||||
63
node_modules/playwright/lib/mcp/browser/tools/wait.js
generated
vendored
Normal file
63
node_modules/playwright/lib/mcp/browser/tools/wait.js
generated
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var wait_exports = {};
|
||||
__export(wait_exports, {
|
||||
default: () => wait_default
|
||||
});
|
||||
module.exports = __toCommonJS(wait_exports);
|
||||
var import_bundle = require("../../sdk/bundle");
|
||||
var import_tool = require("./tool");
|
||||
const wait = (0, import_tool.defineTool)({
|
||||
capability: "core",
|
||||
schema: {
|
||||
name: "browser_wait_for",
|
||||
title: "Wait for",
|
||||
description: "Wait for text to appear or disappear or a specified time to pass",
|
||||
inputSchema: import_bundle.z.object({
|
||||
time: import_bundle.z.number().optional().describe("The time to wait in seconds"),
|
||||
text: import_bundle.z.string().optional().describe("The text to wait for"),
|
||||
textGone: import_bundle.z.string().optional().describe("The text to wait for to disappear")
|
||||
}),
|
||||
type: "assertion"
|
||||
},
|
||||
handle: async (context, params, response) => {
|
||||
if (!params.text && !params.textGone && !params.time)
|
||||
throw new Error("Either time, text or textGone must be provided");
|
||||
if (params.time) {
|
||||
response.addCode(`await new Promise(f => setTimeout(f, ${params.time} * 1000));`);
|
||||
await new Promise((f) => setTimeout(f, Math.min(3e4, params.time * 1e3)));
|
||||
}
|
||||
const tab = context.currentTabOrDie();
|
||||
const locator = params.text ? tab.page.getByText(params.text).first() : void 0;
|
||||
const goneLocator = params.textGone ? tab.page.getByText(params.textGone).first() : void 0;
|
||||
if (goneLocator) {
|
||||
response.addCode(`await page.getByText(${JSON.stringify(params.textGone)}).first().waitFor({ state: 'hidden' });`);
|
||||
await goneLocator.waitFor({ state: "hidden" });
|
||||
}
|
||||
if (locator) {
|
||||
response.addCode(`await page.getByText(${JSON.stringify(params.text)}).first().waitFor({ state: 'visible' });`);
|
||||
await locator.waitFor({ state: "visible" });
|
||||
}
|
||||
response.addResult(`Waited for ${params.text || params.textGone || params.time}`);
|
||||
response.setIncludeSnapshot();
|
||||
}
|
||||
});
|
||||
var wait_default = [
|
||||
wait
|
||||
];
|
||||
44
node_modules/playwright/lib/mcp/browser/watchdog.js
generated
vendored
Normal file
44
node_modules/playwright/lib/mcp/browser/watchdog.js
generated
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var watchdog_exports = {};
|
||||
__export(watchdog_exports, {
|
||||
setupExitWatchdog: () => setupExitWatchdog
|
||||
});
|
||||
module.exports = __toCommonJS(watchdog_exports);
|
||||
var import_browserContextFactory = require("./browserContextFactory");
|
||||
var import_context = require("./context");
|
||||
function setupExitWatchdog() {
|
||||
let isExiting = false;
|
||||
const handleExit = async () => {
|
||||
if (isExiting)
|
||||
return;
|
||||
isExiting = true;
|
||||
setTimeout(() => process.exit(0), 15e3);
|
||||
await import_context.Context.disposeAll();
|
||||
await import_browserContextFactory.SharedContextFactory.dispose();
|
||||
process.exit(0);
|
||||
};
|
||||
process.stdin.on("close", handleExit);
|
||||
process.on("SIGINT", handleExit);
|
||||
process.on("SIGTERM", handleExit);
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
setupExitWatchdog
|
||||
});
|
||||
16
node_modules/playwright/lib/mcp/config.d.js
generated
vendored
Normal file
16
node_modules/playwright/lib/mcp/config.d.js
generated
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var config_d_exports = {};
|
||||
module.exports = __toCommonJS(config_d_exports);
|
||||
351
node_modules/playwright/lib/mcp/extension/cdpRelay.js
generated
vendored
Normal file
351
node_modules/playwright/lib/mcp/extension/cdpRelay.js
generated
vendored
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var cdpRelay_exports = {};
|
||||
__export(cdpRelay_exports, {
|
||||
CDPRelayServer: () => CDPRelayServer
|
||||
});
|
||||
module.exports = __toCommonJS(cdpRelay_exports);
|
||||
var import_child_process = require("child_process");
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_registry = require("playwright-core/lib/server/registry/index");
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_http2 = require("../sdk/http");
|
||||
var import_log = require("../log");
|
||||
var protocol = __toESM(require("./protocol"));
|
||||
const debugLogger = (0, import_utilsBundle.debug)("pw:mcp:relay");
|
||||
class CDPRelayServer {
|
||||
constructor(server, browserChannel, userDataDir, executablePath) {
|
||||
this._playwrightConnection = null;
|
||||
this._extensionConnection = null;
|
||||
this._nextSessionId = 1;
|
||||
this._wsHost = (0, import_http2.httpAddressToString)(server.address()).replace(/^http/, "ws");
|
||||
this._browserChannel = browserChannel;
|
||||
this._userDataDir = userDataDir;
|
||||
this._executablePath = executablePath;
|
||||
const uuid = crypto.randomUUID();
|
||||
this._cdpPath = `/cdp/${uuid}`;
|
||||
this._extensionPath = `/extension/${uuid}`;
|
||||
this._resetExtensionConnection();
|
||||
this._wss = new import_utilsBundle.wsServer({ server });
|
||||
this._wss.on("connection", this._onConnection.bind(this));
|
||||
}
|
||||
cdpEndpoint() {
|
||||
return `${this._wsHost}${this._cdpPath}`;
|
||||
}
|
||||
extensionEndpoint() {
|
||||
return `${this._wsHost}${this._extensionPath}`;
|
||||
}
|
||||
async ensureExtensionConnectionForMCPContext(clientInfo, abortSignal, toolName) {
|
||||
debugLogger("Ensuring extension connection for MCP context");
|
||||
if (this._extensionConnection)
|
||||
return;
|
||||
this._connectBrowser(clientInfo, toolName);
|
||||
debugLogger("Waiting for incoming extension connection");
|
||||
await Promise.race([
|
||||
this._extensionConnectionPromise,
|
||||
new Promise((_, reject) => setTimeout(() => {
|
||||
reject(new Error(`Extension connection timeout. Make sure the "Playwright MCP Bridge" extension is installed. See https://github.com/microsoft/playwright-mcp/blob/main/extension/README.md for installation instructions.`));
|
||||
}, process.env.PWMCP_TEST_CONNECTION_TIMEOUT ? parseInt(process.env.PWMCP_TEST_CONNECTION_TIMEOUT, 10) : 5e3)),
|
||||
new Promise((_, reject) => abortSignal.addEventListener("abort", reject))
|
||||
]);
|
||||
debugLogger("Extension connection established");
|
||||
}
|
||||
_connectBrowser(clientInfo, toolName) {
|
||||
const mcpRelayEndpoint = `${this._wsHost}${this._extensionPath}`;
|
||||
const url = new URL("chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html");
|
||||
url.searchParams.set("mcpRelayUrl", mcpRelayEndpoint);
|
||||
const client = {
|
||||
name: clientInfo.name,
|
||||
version: clientInfo.version
|
||||
};
|
||||
url.searchParams.set("client", JSON.stringify(client));
|
||||
url.searchParams.set("protocolVersion", process.env.PWMCP_TEST_PROTOCOL_VERSION ?? protocol.VERSION.toString());
|
||||
if (toolName)
|
||||
url.searchParams.set("newTab", String(toolName === "browser_navigate"));
|
||||
const token = process.env.PLAYWRIGHT_MCP_EXTENSION_TOKEN;
|
||||
if (token)
|
||||
url.searchParams.set("token", token);
|
||||
const href = url.toString();
|
||||
let executablePath = this._executablePath;
|
||||
if (!executablePath) {
|
||||
const executableInfo = import_registry.registry.findExecutable(this._browserChannel);
|
||||
if (!executableInfo)
|
||||
throw new Error(`Unsupported channel: "${this._browserChannel}"`);
|
||||
executablePath = executableInfo.executablePath("javascript");
|
||||
if (!executablePath)
|
||||
throw new Error(`"${this._browserChannel}" executable not found. Make sure it is installed at a standard location.`);
|
||||
}
|
||||
const args = [];
|
||||
if (this._userDataDir)
|
||||
args.push(`--user-data-dir=${this._userDataDir}`);
|
||||
args.push(href);
|
||||
(0, import_child_process.spawn)(executablePath, args, {
|
||||
windowsHide: true,
|
||||
detached: true,
|
||||
shell: false,
|
||||
stdio: "ignore"
|
||||
});
|
||||
}
|
||||
stop() {
|
||||
this.closeConnections("Server stopped");
|
||||
this._wss.close();
|
||||
}
|
||||
closeConnections(reason) {
|
||||
this._closePlaywrightConnection(reason);
|
||||
this._closeExtensionConnection(reason);
|
||||
}
|
||||
_onConnection(ws2, request) {
|
||||
const url = new URL(`http://localhost${request.url}`);
|
||||
debugLogger(`New connection to ${url.pathname}`);
|
||||
if (url.pathname === this._cdpPath) {
|
||||
this._handlePlaywrightConnection(ws2);
|
||||
} else if (url.pathname === this._extensionPath) {
|
||||
this._handleExtensionConnection(ws2);
|
||||
} else {
|
||||
debugLogger(`Invalid path: ${url.pathname}`);
|
||||
ws2.close(4004, "Invalid path");
|
||||
}
|
||||
}
|
||||
_handlePlaywrightConnection(ws2) {
|
||||
if (this._playwrightConnection) {
|
||||
debugLogger("Rejecting second Playwright connection");
|
||||
ws2.close(1e3, "Another CDP client already connected");
|
||||
return;
|
||||
}
|
||||
this._playwrightConnection = ws2;
|
||||
ws2.on("message", async (data) => {
|
||||
try {
|
||||
const message = JSON.parse(data.toString());
|
||||
await this._handlePlaywrightMessage(message);
|
||||
} catch (error) {
|
||||
debugLogger(`Error while handling Playwright message
|
||||
${data.toString()}
|
||||
`, error);
|
||||
}
|
||||
});
|
||||
ws2.on("close", () => {
|
||||
if (this._playwrightConnection !== ws2)
|
||||
return;
|
||||
this._playwrightConnection = null;
|
||||
this._closeExtensionConnection("Playwright client disconnected");
|
||||
debugLogger("Playwright WebSocket closed");
|
||||
});
|
||||
ws2.on("error", (error) => {
|
||||
debugLogger("Playwright WebSocket error:", error);
|
||||
});
|
||||
debugLogger("Playwright MCP connected");
|
||||
}
|
||||
_closeExtensionConnection(reason) {
|
||||
this._extensionConnection?.close(reason);
|
||||
this._extensionConnectionPromise.reject(new Error(reason));
|
||||
this._resetExtensionConnection();
|
||||
}
|
||||
_resetExtensionConnection() {
|
||||
this._connectedTabInfo = void 0;
|
||||
this._extensionConnection = null;
|
||||
this._extensionConnectionPromise = new import_utils.ManualPromise();
|
||||
void this._extensionConnectionPromise.catch(import_log.logUnhandledError);
|
||||
}
|
||||
_closePlaywrightConnection(reason) {
|
||||
if (this._playwrightConnection?.readyState === import_utilsBundle.ws.OPEN)
|
||||
this._playwrightConnection.close(1e3, reason);
|
||||
this._playwrightConnection = null;
|
||||
}
|
||||
_handleExtensionConnection(ws2) {
|
||||
if (this._extensionConnection) {
|
||||
ws2.close(1e3, "Another extension connection already established");
|
||||
return;
|
||||
}
|
||||
this._extensionConnection = new ExtensionConnection(ws2);
|
||||
this._extensionConnection.onclose = (c, reason) => {
|
||||
debugLogger("Extension WebSocket closed:", reason, c === this._extensionConnection);
|
||||
if (this._extensionConnection !== c)
|
||||
return;
|
||||
this._resetExtensionConnection();
|
||||
this._closePlaywrightConnection(`Extension disconnected: ${reason}`);
|
||||
};
|
||||
this._extensionConnection.onmessage = this._handleExtensionMessage.bind(this);
|
||||
this._extensionConnectionPromise.resolve();
|
||||
}
|
||||
_handleExtensionMessage(method, params) {
|
||||
switch (method) {
|
||||
case "forwardCDPEvent":
|
||||
const sessionId = params.sessionId || this._connectedTabInfo?.sessionId;
|
||||
this._sendToPlaywright({
|
||||
sessionId,
|
||||
method: params.method,
|
||||
params: params.params
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
async _handlePlaywrightMessage(message) {
|
||||
debugLogger("\u2190 Playwright:", `${message.method} (id=${message.id})`);
|
||||
const { id, sessionId, method, params } = message;
|
||||
try {
|
||||
const result = await this._handleCDPCommand(method, params, sessionId);
|
||||
this._sendToPlaywright({ id, sessionId, result });
|
||||
} catch (e) {
|
||||
debugLogger("Error in the extension:", e);
|
||||
this._sendToPlaywright({
|
||||
id,
|
||||
sessionId,
|
||||
error: { message: e.message }
|
||||
});
|
||||
}
|
||||
}
|
||||
async _handleCDPCommand(method, params, sessionId) {
|
||||
switch (method) {
|
||||
case "Browser.getVersion": {
|
||||
return {
|
||||
protocolVersion: "1.3",
|
||||
product: "Chrome/Extension-Bridge",
|
||||
userAgent: "CDP-Bridge-Server/1.0.0"
|
||||
};
|
||||
}
|
||||
case "Browser.setDownloadBehavior": {
|
||||
return {};
|
||||
}
|
||||
case "Target.setAutoAttach": {
|
||||
if (sessionId)
|
||||
break;
|
||||
const { targetInfo } = await this._extensionConnection.send("attachToTab", {});
|
||||
this._connectedTabInfo = {
|
||||
targetInfo,
|
||||
sessionId: `pw-tab-${this._nextSessionId++}`
|
||||
};
|
||||
debugLogger("Simulating auto-attach");
|
||||
this._sendToPlaywright({
|
||||
method: "Target.attachedToTarget",
|
||||
params: {
|
||||
sessionId: this._connectedTabInfo.sessionId,
|
||||
targetInfo: {
|
||||
...this._connectedTabInfo.targetInfo,
|
||||
attached: true
|
||||
},
|
||||
waitingForDebugger: false
|
||||
}
|
||||
});
|
||||
return {};
|
||||
}
|
||||
case "Target.getTargetInfo": {
|
||||
return this._connectedTabInfo?.targetInfo;
|
||||
}
|
||||
}
|
||||
return await this._forwardToExtension(method, params, sessionId);
|
||||
}
|
||||
async _forwardToExtension(method, params, sessionId) {
|
||||
if (!this._extensionConnection)
|
||||
throw new Error("Extension not connected");
|
||||
if (this._connectedTabInfo?.sessionId === sessionId)
|
||||
sessionId = void 0;
|
||||
return await this._extensionConnection.send("forwardCDPCommand", { sessionId, method, params });
|
||||
}
|
||||
_sendToPlaywright(message) {
|
||||
debugLogger("\u2192 Playwright:", `${message.method ?? `response(id=${message.id})`}`);
|
||||
this._playwrightConnection?.send(JSON.stringify(message));
|
||||
}
|
||||
}
|
||||
class ExtensionConnection {
|
||||
constructor(ws2) {
|
||||
this._callbacks = /* @__PURE__ */ new Map();
|
||||
this._lastId = 0;
|
||||
this._ws = ws2;
|
||||
this._ws.on("message", this._onMessage.bind(this));
|
||||
this._ws.on("close", this._onClose.bind(this));
|
||||
this._ws.on("error", this._onError.bind(this));
|
||||
}
|
||||
async send(method, params) {
|
||||
if (this._ws.readyState !== import_utilsBundle.ws.OPEN)
|
||||
throw new Error(`Unexpected WebSocket state: ${this._ws.readyState}`);
|
||||
const id = ++this._lastId;
|
||||
this._ws.send(JSON.stringify({ id, method, params }));
|
||||
const error = new Error(`Protocol error: ${method}`);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._callbacks.set(id, { resolve, reject, error });
|
||||
});
|
||||
}
|
||||
close(message) {
|
||||
debugLogger("closing extension connection:", message);
|
||||
if (this._ws.readyState === import_utilsBundle.ws.OPEN)
|
||||
this._ws.close(1e3, message);
|
||||
}
|
||||
_onMessage(event) {
|
||||
const eventData = event.toString();
|
||||
let parsedJson;
|
||||
try {
|
||||
parsedJson = JSON.parse(eventData);
|
||||
} catch (e) {
|
||||
debugLogger(`<closing ws> Closing websocket due to malformed JSON. eventData=${eventData} e=${e?.message}`);
|
||||
this._ws.close();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this._handleParsedMessage(parsedJson);
|
||||
} catch (e) {
|
||||
debugLogger(`<closing ws> Closing websocket due to failed onmessage callback. eventData=${eventData} e=${e?.message}`);
|
||||
this._ws.close();
|
||||
}
|
||||
}
|
||||
_handleParsedMessage(object) {
|
||||
if (object.id && this._callbacks.has(object.id)) {
|
||||
const callback = this._callbacks.get(object.id);
|
||||
this._callbacks.delete(object.id);
|
||||
if (object.error) {
|
||||
const error = callback.error;
|
||||
error.message = object.error;
|
||||
callback.reject(error);
|
||||
} else {
|
||||
callback.resolve(object.result);
|
||||
}
|
||||
} else if (object.id) {
|
||||
debugLogger("\u2190 Extension: unexpected response", object);
|
||||
} else {
|
||||
this.onmessage?.(object.method, object.params);
|
||||
}
|
||||
}
|
||||
_onClose(event) {
|
||||
debugLogger(`<ws closed> code=${event.code} reason=${event.reason}`);
|
||||
this._dispose();
|
||||
this.onclose?.(this, event.reason);
|
||||
}
|
||||
_onError(event) {
|
||||
debugLogger(`<ws error> message=${event.message} type=${event.type} target=${event.target}`);
|
||||
this._dispose();
|
||||
}
|
||||
_dispose() {
|
||||
for (const callback of this._callbacks.values())
|
||||
callback.reject(new Error("WebSocket closed"));
|
||||
this._callbacks.clear();
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CDPRelayServer
|
||||
});
|
||||
75
node_modules/playwright/lib/mcp/extension/extensionContextFactory.js
generated
vendored
Normal file
75
node_modules/playwright/lib/mcp/extension/extensionContextFactory.js
generated
vendored
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var extensionContextFactory_exports = {};
|
||||
__export(extensionContextFactory_exports, {
|
||||
ExtensionContextFactory: () => ExtensionContextFactory
|
||||
});
|
||||
module.exports = __toCommonJS(extensionContextFactory_exports);
|
||||
var playwright = __toESM(require("playwright-core"));
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_http = require("../sdk/http");
|
||||
var import_cdpRelay = require("./cdpRelay");
|
||||
const debugLogger = (0, import_utilsBundle.debug)("pw:mcp:relay");
|
||||
class ExtensionContextFactory {
|
||||
constructor(browserChannel, userDataDir, executablePath) {
|
||||
this._browserChannel = browserChannel;
|
||||
this._userDataDir = userDataDir;
|
||||
this._executablePath = executablePath;
|
||||
}
|
||||
async createContext(clientInfo, abortSignal, toolName) {
|
||||
const browser = await this._obtainBrowser(clientInfo, abortSignal, toolName);
|
||||
return {
|
||||
browserContext: browser.contexts()[0],
|
||||
close: async () => {
|
||||
debugLogger("close() called for browser context");
|
||||
await browser.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
async _obtainBrowser(clientInfo, abortSignal, toolName) {
|
||||
const relay = await this._startRelay(abortSignal);
|
||||
await relay.ensureExtensionConnectionForMCPContext(clientInfo, abortSignal, toolName);
|
||||
return await playwright.chromium.connectOverCDP(relay.cdpEndpoint());
|
||||
}
|
||||
async _startRelay(abortSignal) {
|
||||
const httpServer = await (0, import_http.startHttpServer)({});
|
||||
if (abortSignal.aborted) {
|
||||
httpServer.close();
|
||||
throw new Error(abortSignal.reason);
|
||||
}
|
||||
const cdpRelayServer = new import_cdpRelay.CDPRelayServer(httpServer, this._browserChannel, this._userDataDir, this._executablePath);
|
||||
abortSignal.addEventListener("abort", () => cdpRelayServer.stop());
|
||||
debugLogger(`CDP relay server started, extension endpoint: ${cdpRelayServer.extensionEndpoint()}.`);
|
||||
return cdpRelayServer;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ExtensionContextFactory
|
||||
});
|
||||
28
node_modules/playwright/lib/mcp/extension/protocol.js
generated
vendored
Normal file
28
node_modules/playwright/lib/mcp/extension/protocol.js
generated
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var protocol_exports = {};
|
||||
__export(protocol_exports, {
|
||||
VERSION: () => VERSION
|
||||
});
|
||||
module.exports = __toCommonJS(protocol_exports);
|
||||
const VERSION = 1;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
VERSION
|
||||
});
|
||||
61
node_modules/playwright/lib/mcp/index.js
generated
vendored
Normal file
61
node_modules/playwright/lib/mcp/index.js
generated
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var mcp_exports = {};
|
||||
__export(mcp_exports, {
|
||||
createConnection: () => createConnection
|
||||
});
|
||||
module.exports = __toCommonJS(mcp_exports);
|
||||
var import_browserServerBackend = require("./browser/browserServerBackend");
|
||||
var import_config = require("./browser/config");
|
||||
var import_browserContextFactory = require("./browser/browserContextFactory");
|
||||
var mcpServer = __toESM(require("./sdk/server"));
|
||||
const packageJSON = require("../../package.json");
|
||||
async function createConnection(userConfig = {}, contextGetter) {
|
||||
const config = await (0, import_config.resolveConfig)(userConfig);
|
||||
const factory = contextGetter ? new SimpleBrowserContextFactory(contextGetter) : (0, import_browserContextFactory.contextFactory)(config);
|
||||
return mcpServer.createServer("Playwright", packageJSON.version, new import_browserServerBackend.BrowserServerBackend(config, factory), false);
|
||||
}
|
||||
class SimpleBrowserContextFactory {
|
||||
constructor(contextGetter) {
|
||||
this.name = "custom";
|
||||
this.description = "Connect to a browser using a custom context getter";
|
||||
this._contextGetter = contextGetter;
|
||||
}
|
||||
async createContext() {
|
||||
const browserContext = await this._contextGetter();
|
||||
return {
|
||||
browserContext,
|
||||
close: () => browserContext.close()
|
||||
};
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
createConnection
|
||||
});
|
||||
35
node_modules/playwright/lib/mcp/log.js
generated
vendored
Normal file
35
node_modules/playwright/lib/mcp/log.js
generated
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var log_exports = {};
|
||||
__export(log_exports, {
|
||||
logUnhandledError: () => logUnhandledError,
|
||||
testDebug: () => testDebug
|
||||
});
|
||||
module.exports = __toCommonJS(log_exports);
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
const errorDebug = (0, import_utilsBundle.debug)("pw:mcp:error");
|
||||
function logUnhandledError(error) {
|
||||
errorDebug(error);
|
||||
}
|
||||
const testDebug = (0, import_utilsBundle.debug)("pw:mcp:test");
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
logUnhandledError,
|
||||
testDebug
|
||||
});
|
||||
96
node_modules/playwright/lib/mcp/program.js
generated
vendored
Normal file
96
node_modules/playwright/lib/mcp/program.js
generated
vendored
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var program_exports = {};
|
||||
__export(program_exports, {
|
||||
decorateCommand: () => decorateCommand
|
||||
});
|
||||
module.exports = __toCommonJS(program_exports);
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var mcpServer = __toESM(require("./sdk/server"));
|
||||
var import_config = require("./browser/config");
|
||||
var import_watchdog = require("./browser/watchdog");
|
||||
var import_browserContextFactory = require("./browser/browserContextFactory");
|
||||
var import_proxyBackend = require("./sdk/proxyBackend");
|
||||
var import_browserServerBackend = require("./browser/browserServerBackend");
|
||||
var import_extensionContextFactory = require("./extension/extensionContextFactory");
|
||||
function decorateCommand(command, version) {
|
||||
command.option("--allowed-hosts <hosts...>", "comma-separated list of hosts this server is allowed to serve from. Defaults to the host the server is bound to. Pass '*' to disable the host check.", import_config.commaSeparatedList).option("--allowed-origins <origins>", "semicolon-separated list of origins to allow the browser to request. Default is to allow all.", import_config.semicolonSeparatedList).option("--blocked-origins <origins>", "semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.", import_config.semicolonSeparatedList).option("--block-service-workers", "block service workers").option("--browser <browser>", "browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.").option("--caps <caps>", "comma-separated list of additional capabilities to enable, possible values: vision, pdf.", import_config.commaSeparatedList).option("--cdp-endpoint <endpoint>", "CDP endpoint to connect to.").option("--cdp-header <headers...>", "CDP headers to send with the connect request, multiple can be specified.", import_config.headerParser).option("--config <path>", "path to the configuration file.").option("--device <device>", 'device to emulate, for example: "iPhone 15"').option("--executable-path <path>", "path to the browser executable.").option("--extension", 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed.').option("--grant-permissions <permissions...>", 'List of permissions to grant to the browser context, for example "geolocation", "clipboard-read", "clipboard-write".', import_config.commaSeparatedList).option("--headless", "run browser in headless mode, headed by default").option("--host <host>", "host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.").option("--ignore-https-errors", "ignore https errors").option("--init-script <path...>", "path to JavaScript file to add as an initialization script. The script will be evaluated in every page before any of the page's scripts. Can be specified multiple times.").option("--isolated", "keep the browser profile in memory, do not save it to disk.").option("--image-responses <mode>", 'whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".').option("--no-sandbox", "disable the sandbox for all process types that are normally sandboxed.").option("--output-dir <path>", "path to the directory for output files.").option("--port <port>", "port to listen on for SSE transport.").option("--proxy-bypass <bypass>", 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"').option("--proxy-server <proxy>", 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"').option("--save-session", "Whether to save the Playwright MCP session into the output directory.").option("--save-trace", "Whether to save the Playwright Trace of the session into the output directory.").option("--save-video <size>", 'Whether to save the video of the session into the output directory. For example "--save-video=800x600"', import_config.resolutionParser.bind(null, "--save-video")).option("--secrets <path>", "path to a file containing secrets in the dotenv format", import_config.dotenvFileLoader).option("--shared-browser-context", "reuse the same browser context between all connected HTTP clients.").option("--storage-state <path>", "path to the storage state file for isolated sessions.").option("--timeout-action <timeout>", "specify action timeout in milliseconds, defaults to 5000ms", import_config.numberParser).option("--timeout-navigation <timeout>", "specify navigation timeout in milliseconds, defaults to 60000ms", import_config.numberParser).option("--user-agent <ua string>", "specify user agent string").option("--user-data-dir <path>", "path to the user data directory. If not specified, a temporary directory will be created.").option("--viewport-size <size>", 'specify browser viewport size in pixels, for example "1280x720"', import_config.resolutionParser.bind(null, "--viewport-size")).addOption(new import_utilsBundle.ProgramOption("--connect-tool", "Allow to switch between different browser connection methods.").hideHelp()).addOption(new import_utilsBundle.ProgramOption("--vision", "Legacy option, use --caps=vision instead").hideHelp()).action(async (options) => {
|
||||
(0, import_watchdog.setupExitWatchdog)();
|
||||
if (options.vision) {
|
||||
console.error("The --vision option is deprecated, use --caps=vision instead");
|
||||
options.caps = "vision";
|
||||
}
|
||||
const config = await (0, import_config.resolveCLIConfig)(options);
|
||||
const browserContextFactory = (0, import_browserContextFactory.contextFactory)(config);
|
||||
const extensionContextFactory = new import_extensionContextFactory.ExtensionContextFactory(config.browser.launchOptions.channel || "chrome", config.browser.userDataDir, config.browser.launchOptions.executablePath);
|
||||
if (options.extension) {
|
||||
const serverBackendFactory = {
|
||||
name: "Playwright w/ extension",
|
||||
nameInConfig: "playwright-extension",
|
||||
version,
|
||||
create: () => new import_browserServerBackend.BrowserServerBackend(config, extensionContextFactory)
|
||||
};
|
||||
await mcpServer.start(serverBackendFactory, config.server);
|
||||
return;
|
||||
}
|
||||
if (options.connectTool) {
|
||||
const providers = [
|
||||
{
|
||||
name: "default",
|
||||
description: "Starts standalone browser",
|
||||
connect: () => mcpServer.wrapInProcess(new import_browserServerBackend.BrowserServerBackend(config, browserContextFactory))
|
||||
},
|
||||
{
|
||||
name: "extension",
|
||||
description: "Connect to a browser using the Playwright MCP extension",
|
||||
connect: () => mcpServer.wrapInProcess(new import_browserServerBackend.BrowserServerBackend(config, extensionContextFactory))
|
||||
}
|
||||
];
|
||||
const factory2 = {
|
||||
name: "Playwright w/ switch",
|
||||
nameInConfig: "playwright-switch",
|
||||
version,
|
||||
create: () => new import_proxyBackend.ProxyBackend(providers)
|
||||
};
|
||||
await mcpServer.start(factory2, config.server);
|
||||
return;
|
||||
}
|
||||
const factory = {
|
||||
name: "Playwright",
|
||||
nameInConfig: "playwright",
|
||||
version,
|
||||
create: () => new import_browserServerBackend.BrowserServerBackend(config, browserContextFactory)
|
||||
};
|
||||
await mcpServer.start(factory, config.server);
|
||||
});
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
decorateCommand
|
||||
});
|
||||
81
node_modules/playwright/lib/mcp/sdk/bundle.js
generated
vendored
Normal file
81
node_modules/playwright/lib/mcp/sdk/bundle.js
generated
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var bundle_exports = {};
|
||||
__export(bundle_exports, {
|
||||
CallToolRequestSchema: () => CallToolRequestSchema,
|
||||
Client: () => Client,
|
||||
ListRootsRequestSchema: () => ListRootsRequestSchema,
|
||||
ListToolsRequestSchema: () => ListToolsRequestSchema,
|
||||
PingRequestSchema: () => PingRequestSchema,
|
||||
ProgressNotificationSchema: () => ProgressNotificationSchema,
|
||||
SSEClientTransport: () => SSEClientTransport,
|
||||
SSEServerTransport: () => SSEServerTransport,
|
||||
Server: () => Server,
|
||||
StdioClientTransport: () => StdioClientTransport,
|
||||
StdioServerTransport: () => StdioServerTransport,
|
||||
StreamableHTTPClientTransport: () => StreamableHTTPClientTransport,
|
||||
StreamableHTTPServerTransport: () => StreamableHTTPServerTransport,
|
||||
z: () => z,
|
||||
zodToJsonSchema: () => zodToJsonSchema
|
||||
});
|
||||
module.exports = __toCommonJS(bundle_exports);
|
||||
var bundle = __toESM(require("../../mcpBundleImpl"));
|
||||
const zodToJsonSchema = bundle.zodToJsonSchema;
|
||||
const Client = bundle.Client;
|
||||
const Server = bundle.Server;
|
||||
const SSEClientTransport = bundle.SSEClientTransport;
|
||||
const SSEServerTransport = bundle.SSEServerTransport;
|
||||
const StdioClientTransport = bundle.StdioClientTransport;
|
||||
const StdioServerTransport = bundle.StdioServerTransport;
|
||||
const StreamableHTTPServerTransport = bundle.StreamableHTTPServerTransport;
|
||||
const StreamableHTTPClientTransport = bundle.StreamableHTTPClientTransport;
|
||||
const CallToolRequestSchema = bundle.CallToolRequestSchema;
|
||||
const ListRootsRequestSchema = bundle.ListRootsRequestSchema;
|
||||
const ProgressNotificationSchema = bundle.ProgressNotificationSchema;
|
||||
const ListToolsRequestSchema = bundle.ListToolsRequestSchema;
|
||||
const PingRequestSchema = bundle.PingRequestSchema;
|
||||
const z = bundle.z;
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
CallToolRequestSchema,
|
||||
Client,
|
||||
ListRootsRequestSchema,
|
||||
ListToolsRequestSchema,
|
||||
PingRequestSchema,
|
||||
ProgressNotificationSchema,
|
||||
SSEClientTransport,
|
||||
SSEServerTransport,
|
||||
Server,
|
||||
StdioClientTransport,
|
||||
StdioServerTransport,
|
||||
StreamableHTTPClientTransport,
|
||||
StreamableHTTPServerTransport,
|
||||
z,
|
||||
zodToJsonSchema
|
||||
});
|
||||
32
node_modules/playwright/lib/mcp/sdk/exports.js
generated
vendored
Normal file
32
node_modules/playwright/lib/mcp/sdk/exports.js
generated
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var exports_exports = {};
|
||||
module.exports = __toCommonJS(exports_exports);
|
||||
__reExport(exports_exports, require("./inProcessTransport"), module.exports);
|
||||
__reExport(exports_exports, require("./proxyBackend"), module.exports);
|
||||
__reExport(exports_exports, require("./server"), module.exports);
|
||||
__reExport(exports_exports, require("./tool"), module.exports);
|
||||
__reExport(exports_exports, require("./http"), module.exports);
|
||||
__reExport(exports_exports, require("./mdb"), module.exports);
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
...require("./inProcessTransport"),
|
||||
...require("./proxyBackend"),
|
||||
...require("./server"),
|
||||
...require("./tool"),
|
||||
...require("./http"),
|
||||
...require("./mdb")
|
||||
});
|
||||
180
node_modules/playwright/lib/mcp/sdk/http.js
generated
vendored
Normal file
180
node_modules/playwright/lib/mcp/sdk/http.js
generated
vendored
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var http_exports = {};
|
||||
__export(http_exports, {
|
||||
httpAddressToString: () => httpAddressToString,
|
||||
installHttpTransport: () => installHttpTransport,
|
||||
startHttpServer: () => startHttpServer
|
||||
});
|
||||
module.exports = __toCommonJS(http_exports);
|
||||
var import_assert = __toESM(require("assert"));
|
||||
var import_http = __toESM(require("http"));
|
||||
var import_crypto = __toESM(require("crypto"));
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var mcpBundle = __toESM(require("./bundle"));
|
||||
var mcpServer = __toESM(require("./server"));
|
||||
const testDebug = (0, import_utilsBundle.debug)("pw:mcp:test");
|
||||
async function startHttpServer(config, abortSignal) {
|
||||
const { host, port } = config;
|
||||
const httpServer = import_http.default.createServer();
|
||||
decorateServer(httpServer);
|
||||
await new Promise((resolve, reject) => {
|
||||
httpServer.on("error", reject);
|
||||
abortSignal?.addEventListener("abort", () => {
|
||||
httpServer.close();
|
||||
reject(new Error("Aborted"));
|
||||
});
|
||||
httpServer.listen(port, host, () => {
|
||||
resolve();
|
||||
httpServer.removeListener("error", reject);
|
||||
});
|
||||
});
|
||||
return httpServer;
|
||||
}
|
||||
function httpAddressToString(address) {
|
||||
(0, import_assert.default)(address, "Could not bind server socket");
|
||||
if (typeof address === "string")
|
||||
return address;
|
||||
const resolvedPort = address.port;
|
||||
let resolvedHost = address.family === "IPv4" ? address.address : `[${address.address}]`;
|
||||
if (resolvedHost === "0.0.0.0" || resolvedHost === "[::]")
|
||||
resolvedHost = "localhost";
|
||||
return `http://${resolvedHost}:${resolvedPort}`;
|
||||
}
|
||||
async function installHttpTransport(httpServer, serverBackendFactory, allowedHosts) {
|
||||
const url = httpAddressToString(httpServer.address());
|
||||
const host = new URL(url).host;
|
||||
allowedHosts = (allowedHosts || [host]).map((h) => h.toLowerCase());
|
||||
const allowAnyHost = allowedHosts.includes("*");
|
||||
const sseSessions = /* @__PURE__ */ new Map();
|
||||
const streamableSessions = /* @__PURE__ */ new Map();
|
||||
httpServer.on("request", async (req, res) => {
|
||||
if (!allowAnyHost) {
|
||||
const host2 = req.headers.host?.toLowerCase();
|
||||
if (!host2) {
|
||||
res.statusCode = 400;
|
||||
return res.end("Missing host");
|
||||
}
|
||||
if (!allowedHosts.includes(host2)) {
|
||||
res.statusCode = 403;
|
||||
return res.end("Access is only allowed at " + allowedHosts.join(", "));
|
||||
}
|
||||
}
|
||||
const url2 = new URL(`http://localhost${req.url}`);
|
||||
if (url2.pathname === "/killkillkill" && req.method === "GET") {
|
||||
res.statusCode = 200;
|
||||
res.end("Killing process");
|
||||
process.emit("SIGINT");
|
||||
return;
|
||||
}
|
||||
if (url2.pathname.startsWith("/sse"))
|
||||
await handleSSE(serverBackendFactory, req, res, url2, sseSessions);
|
||||
else
|
||||
await handleStreamable(serverBackendFactory, req, res, streamableSessions);
|
||||
});
|
||||
}
|
||||
async function handleSSE(serverBackendFactory, req, res, url, sessions) {
|
||||
if (req.method === "POST") {
|
||||
const sessionId = url.searchParams.get("sessionId");
|
||||
if (!sessionId) {
|
||||
res.statusCode = 400;
|
||||
return res.end("Missing sessionId");
|
||||
}
|
||||
const transport = sessions.get(sessionId);
|
||||
if (!transport) {
|
||||
res.statusCode = 404;
|
||||
return res.end("Session not found");
|
||||
}
|
||||
return await transport.handlePostMessage(req, res);
|
||||
} else if (req.method === "GET") {
|
||||
const transport = new mcpBundle.SSEServerTransport("/sse", res);
|
||||
sessions.set(transport.sessionId, transport);
|
||||
testDebug(`create SSE session: ${transport.sessionId}`);
|
||||
await mcpServer.connect(serverBackendFactory, transport, false);
|
||||
res.on("close", () => {
|
||||
testDebug(`delete SSE session: ${transport.sessionId}`);
|
||||
sessions.delete(transport.sessionId);
|
||||
});
|
||||
return;
|
||||
}
|
||||
res.statusCode = 405;
|
||||
res.end("Method not allowed");
|
||||
}
|
||||
async function handleStreamable(serverBackendFactory, req, res, sessions) {
|
||||
const sessionId = req.headers["mcp-session-id"];
|
||||
if (sessionId) {
|
||||
const transport = sessions.get(sessionId);
|
||||
if (!transport) {
|
||||
res.statusCode = 404;
|
||||
res.end("Session not found");
|
||||
return;
|
||||
}
|
||||
return await transport.handleRequest(req, res);
|
||||
}
|
||||
if (req.method === "POST") {
|
||||
const transport = new mcpBundle.StreamableHTTPServerTransport({
|
||||
sessionIdGenerator: () => import_crypto.default.randomUUID(),
|
||||
onsessioninitialized: async (sessionId2) => {
|
||||
testDebug(`create http session: ${transport.sessionId}`);
|
||||
await mcpServer.connect(serverBackendFactory, transport, true);
|
||||
sessions.set(sessionId2, transport);
|
||||
}
|
||||
});
|
||||
transport.onclose = () => {
|
||||
if (!transport.sessionId)
|
||||
return;
|
||||
sessions.delete(transport.sessionId);
|
||||
testDebug(`delete http session: ${transport.sessionId}`);
|
||||
};
|
||||
await transport.handleRequest(req, res);
|
||||
return;
|
||||
}
|
||||
res.statusCode = 400;
|
||||
res.end("Invalid request");
|
||||
}
|
||||
function decorateServer(server) {
|
||||
const sockets = /* @__PURE__ */ new Set();
|
||||
server.on("connection", (socket) => {
|
||||
sockets.add(socket);
|
||||
socket.once("close", () => sockets.delete(socket));
|
||||
});
|
||||
const close = server.close;
|
||||
server.close = (callback) => {
|
||||
for (const socket of sockets)
|
||||
socket.destroy();
|
||||
sockets.clear();
|
||||
return close.call(server, callback);
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
httpAddressToString,
|
||||
installHttpTransport,
|
||||
startHttpServer
|
||||
});
|
||||
71
node_modules/playwright/lib/mcp/sdk/inProcessTransport.js
generated
vendored
Normal file
71
node_modules/playwright/lib/mcp/sdk/inProcessTransport.js
generated
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var inProcessTransport_exports = {};
|
||||
__export(inProcessTransport_exports, {
|
||||
InProcessTransport: () => InProcessTransport
|
||||
});
|
||||
module.exports = __toCommonJS(inProcessTransport_exports);
|
||||
class InProcessTransport {
|
||||
constructor(server) {
|
||||
this._connected = false;
|
||||
this._server = server;
|
||||
this._serverTransport = new InProcessServerTransport(this);
|
||||
}
|
||||
async start() {
|
||||
if (this._connected)
|
||||
throw new Error("InprocessTransport already started!");
|
||||
await this._server.connect(this._serverTransport);
|
||||
this._connected = true;
|
||||
}
|
||||
async send(message, options) {
|
||||
if (!this._connected)
|
||||
throw new Error("Transport not connected");
|
||||
this._serverTransport._receiveFromClient(message);
|
||||
}
|
||||
async close() {
|
||||
if (this._connected) {
|
||||
this._connected = false;
|
||||
this.onclose?.();
|
||||
this._serverTransport.onclose?.();
|
||||
}
|
||||
}
|
||||
_receiveFromServer(message, extra) {
|
||||
this.onmessage?.(message, extra);
|
||||
}
|
||||
}
|
||||
class InProcessServerTransport {
|
||||
constructor(clientTransport) {
|
||||
this._clientTransport = clientTransport;
|
||||
}
|
||||
async start() {
|
||||
}
|
||||
async send(message, options) {
|
||||
this._clientTransport._receiveFromServer(message);
|
||||
}
|
||||
async close() {
|
||||
this.onclose?.();
|
||||
}
|
||||
_receiveFromClient(message) {
|
||||
this.onmessage?.(message);
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
InProcessTransport
|
||||
});
|
||||
208
node_modules/playwright/lib/mcp/sdk/mdb.js
generated
vendored
Normal file
208
node_modules/playwright/lib/mcp/sdk/mdb.js
generated
vendored
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var mdb_exports = {};
|
||||
__export(mdb_exports, {
|
||||
MDBBackend: () => MDBBackend,
|
||||
runMainBackend: () => runMainBackend,
|
||||
runOnPauseBackendLoop: () => runOnPauseBackendLoop
|
||||
});
|
||||
module.exports = __toCommonJS(mdb_exports);
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_tool = require("./tool");
|
||||
var mcpBundle = __toESM(require("./bundle"));
|
||||
var mcpServer = __toESM(require("./server"));
|
||||
var mcpHttp = __toESM(require("./http"));
|
||||
const mdbDebug = (0, import_utilsBundle.debug)("pw:mcp:mdb");
|
||||
const errorsDebug = (0, import_utilsBundle.debug)("pw:mcp:errors");
|
||||
const z = mcpBundle.z;
|
||||
class MDBBackend {
|
||||
constructor(mainBackend) {
|
||||
this._progress = [];
|
||||
this._mainBackend = mainBackend;
|
||||
this._progressCallback = (params) => {
|
||||
if (params.message)
|
||||
this._progress.push({ type: "text", text: params.message });
|
||||
};
|
||||
}
|
||||
async initialize(server, clientInfo) {
|
||||
if (!this._clientInfo) {
|
||||
this._clientInfo = clientInfo;
|
||||
await this._mainBackend.initialize?.(server, clientInfo);
|
||||
}
|
||||
}
|
||||
async listTools() {
|
||||
return await this._mainBackend.listTools();
|
||||
}
|
||||
async callTool(name, args) {
|
||||
if (name === pushToolsSchema.name) {
|
||||
await this._createOnPauseClient(pushToolsSchema.inputSchema.parse(args || {}));
|
||||
return { content: [{ type: "text", text: "Tools pushed" }] };
|
||||
}
|
||||
if (this._onPauseClient?.tools.find((tool) => tool.name === name)) {
|
||||
const result2 = await this._onPauseClient.client.callTool({
|
||||
name,
|
||||
arguments: args
|
||||
});
|
||||
await this._mainBackend.afterCallTool?.(name, args, result2);
|
||||
return result2;
|
||||
}
|
||||
await this._onPauseClient?.transport.terminateSession().catch(errorsDebug);
|
||||
await this._onPauseClient?.client.close().catch(errorsDebug);
|
||||
this._onPauseClient = void 0;
|
||||
const resultPromise = new import_utils.ManualPromise();
|
||||
const interruptPromise = new import_utils.ManualPromise();
|
||||
this._interruptPromise = interruptPromise;
|
||||
this._mainBackend.callTool(name, args, this._progressCallback).then((result2) => {
|
||||
resultPromise.resolve(result2);
|
||||
}).catch((e) => {
|
||||
resultPromise.resolve({ content: [{ type: "text", text: String(e) }], isError: true });
|
||||
});
|
||||
const result = await Promise.race([interruptPromise, resultPromise]);
|
||||
if (interruptPromise.isDone())
|
||||
mdbDebug("client call intercepted", result);
|
||||
else
|
||||
mdbDebug("client call result", result);
|
||||
result.content.unshift(...this._progress);
|
||||
this._progress.length = 0;
|
||||
return result;
|
||||
}
|
||||
async _createOnPauseClient(params) {
|
||||
if (this._onPauseClient)
|
||||
await this._onPauseClient.client.close().catch(errorsDebug);
|
||||
this._onPauseClient = await this._createClient(params.mcpUrl);
|
||||
this._interruptPromise?.resolve({
|
||||
content: [{
|
||||
type: "text",
|
||||
text: params.introMessage || ""
|
||||
}]
|
||||
});
|
||||
this._interruptPromise = void 0;
|
||||
}
|
||||
async _createClient(url) {
|
||||
const client = new mcpBundle.Client({ name: "Interrupting client", version: "0.0.0" }, { capabilities: { roots: {} } });
|
||||
client.setRequestHandler(mcpBundle.ListRootsRequestSchema, () => ({ roots: this._clientInfo?.roots || [] }));
|
||||
client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
|
||||
client.setNotificationHandler(mcpBundle.ProgressNotificationSchema, (notification) => {
|
||||
if (notification.method === "notifications/progress") {
|
||||
const { message } = notification.params;
|
||||
if (message)
|
||||
this._progress.push({ type: "text", text: message });
|
||||
}
|
||||
});
|
||||
const transport = new mcpBundle.StreamableHTTPClientTransport(new URL(url));
|
||||
await client.connect(transport);
|
||||
const { tools } = await client.listTools();
|
||||
return { client, tools, transport };
|
||||
}
|
||||
}
|
||||
const pushToolsSchema = (0, import_tool.defineToolSchema)({
|
||||
name: "mdb_push_tools",
|
||||
title: "Push MCP tools to the tools stack",
|
||||
description: "Push MCP tools to the tools stack",
|
||||
inputSchema: z.object({
|
||||
mcpUrl: z.string(),
|
||||
introMessage: z.string().optional()
|
||||
}),
|
||||
type: "readOnly"
|
||||
});
|
||||
async function runMainBackend(backendFactory, options) {
|
||||
const mdbBackend = new MDBBackend(backendFactory.create());
|
||||
const factory = {
|
||||
...backendFactory,
|
||||
create: () => mdbBackend
|
||||
};
|
||||
const url = await startAsHttp(factory, { port: options?.port || 0 });
|
||||
process.env.PLAYWRIGHT_DEBUGGER_MCP = url;
|
||||
if (options?.port !== void 0)
|
||||
return url;
|
||||
await mcpServer.connect(factory, new mcpBundle.StdioServerTransport(), false);
|
||||
}
|
||||
async function runOnPauseBackendLoop(backend, introMessage) {
|
||||
const wrappedBackend = new ServerBackendWithCloseListener(backend);
|
||||
const factory = {
|
||||
name: "on-pause-backend",
|
||||
nameInConfig: "on-pause-backend",
|
||||
version: "0.0.0",
|
||||
create: () => wrappedBackend
|
||||
};
|
||||
const httpServer = await mcpHttp.startHttpServer({ port: 0 });
|
||||
await mcpHttp.installHttpTransport(httpServer, factory);
|
||||
const url = mcpHttp.httpAddressToString(httpServer.address());
|
||||
const client = new mcpBundle.Client({ name: "Pushing client", version: "0.0.0" });
|
||||
client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
|
||||
const transport = new mcpBundle.StreamableHTTPClientTransport(new URL(process.env.PLAYWRIGHT_DEBUGGER_MCP));
|
||||
await client.connect(transport);
|
||||
const pushToolsResult = await client.callTool({
|
||||
name: pushToolsSchema.name,
|
||||
arguments: {
|
||||
mcpUrl: url,
|
||||
introMessage
|
||||
}
|
||||
});
|
||||
if (pushToolsResult.isError)
|
||||
errorsDebug("Failed to push tools", pushToolsResult.content);
|
||||
await transport.terminateSession();
|
||||
await client.close();
|
||||
await wrappedBackend.waitForClosed();
|
||||
httpServer.close();
|
||||
}
|
||||
async function startAsHttp(backendFactory, options) {
|
||||
const httpServer = await mcpHttp.startHttpServer(options);
|
||||
await mcpHttp.installHttpTransport(httpServer, backendFactory);
|
||||
return mcpHttp.httpAddressToString(httpServer.address());
|
||||
}
|
||||
class ServerBackendWithCloseListener {
|
||||
constructor(backend) {
|
||||
this._serverClosedPromise = new import_utils.ManualPromise();
|
||||
this._backend = backend;
|
||||
}
|
||||
async initialize(server, clientInfo) {
|
||||
await this._backend.initialize?.(server, clientInfo);
|
||||
}
|
||||
async listTools() {
|
||||
return this._backend.listTools();
|
||||
}
|
||||
async callTool(name, args, progress) {
|
||||
return this._backend.callTool(name, args, progress);
|
||||
}
|
||||
serverClosed(server) {
|
||||
this._backend.serverClosed?.(server);
|
||||
this._serverClosedPromise.resolve();
|
||||
}
|
||||
async waitForClosed() {
|
||||
await this._serverClosedPromise;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
MDBBackend,
|
||||
runMainBackend,
|
||||
runOnPauseBackendLoop
|
||||
});
|
||||
128
node_modules/playwright/lib/mcp/sdk/proxyBackend.js
generated
vendored
Normal file
128
node_modules/playwright/lib/mcp/sdk/proxyBackend.js
generated
vendored
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var proxyBackend_exports = {};
|
||||
__export(proxyBackend_exports, {
|
||||
ProxyBackend: () => ProxyBackend
|
||||
});
|
||||
module.exports = __toCommonJS(proxyBackend_exports);
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var mcpBundle = __toESM(require("./bundle"));
|
||||
const errorsDebug = (0, import_utilsBundle.debug)("pw:mcp:errors");
|
||||
const { z, zodToJsonSchema } = mcpBundle;
|
||||
class ProxyBackend {
|
||||
constructor(mcpProviders) {
|
||||
this._mcpProviders = mcpProviders;
|
||||
this._contextSwitchTool = this._defineContextSwitchTool();
|
||||
}
|
||||
async initialize(server, clientInfo) {
|
||||
this._clientInfo = clientInfo;
|
||||
}
|
||||
async listTools() {
|
||||
const currentClient = await this._ensureCurrentClient();
|
||||
const response = await currentClient.listTools();
|
||||
if (this._mcpProviders.length === 1)
|
||||
return response.tools;
|
||||
return [
|
||||
...response.tools,
|
||||
this._contextSwitchTool
|
||||
];
|
||||
}
|
||||
async callTool(name, args) {
|
||||
if (name === this._contextSwitchTool.name)
|
||||
return this._callContextSwitchTool(args);
|
||||
const currentClient = await this._ensureCurrentClient();
|
||||
return await currentClient.callTool({
|
||||
name,
|
||||
arguments: args
|
||||
});
|
||||
}
|
||||
serverClosed() {
|
||||
void this._currentClient?.close().catch(errorsDebug);
|
||||
}
|
||||
async _callContextSwitchTool(params) {
|
||||
try {
|
||||
const factory = this._mcpProviders.find((factory2) => factory2.name === params.name);
|
||||
if (!factory)
|
||||
throw new Error("Unknown connection method: " + params.name);
|
||||
await this._setCurrentClient(factory);
|
||||
return {
|
||||
content: [{ type: "text", text: "### Result\nSuccessfully changed connection method.\n" }]
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [{ type: "text", text: `### Result
|
||||
Error: ${error}
|
||||
` }],
|
||||
isError: true
|
||||
};
|
||||
}
|
||||
}
|
||||
_defineContextSwitchTool() {
|
||||
return {
|
||||
name: "browser_connect",
|
||||
description: [
|
||||
"Connect to a browser using one of the available methods:",
|
||||
...this._mcpProviders.map((factory) => `- "${factory.name}": ${factory.description}`)
|
||||
].join("\n"),
|
||||
inputSchema: zodToJsonSchema(z.object({
|
||||
name: z.enum(this._mcpProviders.map((factory) => factory.name)).default(this._mcpProviders[0].name).describe("The method to use to connect to the browser")
|
||||
}), { strictUnions: true }),
|
||||
annotations: {
|
||||
title: "Connect to a browser context",
|
||||
readOnlyHint: true,
|
||||
openWorldHint: false
|
||||
}
|
||||
};
|
||||
}
|
||||
async _ensureCurrentClient() {
|
||||
if (this._currentClient)
|
||||
return this._currentClient;
|
||||
return await this._setCurrentClient(this._mcpProviders[0]);
|
||||
}
|
||||
async _setCurrentClient(factory) {
|
||||
await this._currentClient?.close();
|
||||
this._currentClient = void 0;
|
||||
const client = new mcpBundle.Client({ name: "Playwright MCP Proxy", version: "0.0.0" });
|
||||
client.registerCapabilities({
|
||||
roots: {
|
||||
listRoots: true
|
||||
}
|
||||
});
|
||||
client.setRequestHandler(mcpBundle.ListRootsRequestSchema, () => ({ roots: this._clientInfo?.roots || [] }));
|
||||
client.setRequestHandler(mcpBundle.PingRequestSchema, () => ({}));
|
||||
const transport = await factory.connect();
|
||||
await client.connect(transport);
|
||||
this._currentClient = client;
|
||||
return client;
|
||||
}
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ProxyBackend
|
||||
});
|
||||
190
node_modules/playwright/lib/mcp/sdk/server.js
generated
vendored
Normal file
190
node_modules/playwright/lib/mcp/sdk/server.js
generated
vendored
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var server_exports = {};
|
||||
__export(server_exports, {
|
||||
connect: () => connect,
|
||||
createServer: () => createServer,
|
||||
firstRootPath: () => firstRootPath,
|
||||
start: () => start,
|
||||
wrapInProcess: () => wrapInProcess
|
||||
});
|
||||
module.exports = __toCommonJS(server_exports);
|
||||
var import_url = require("url");
|
||||
var import_utilsBundle = require("playwright-core/lib/utilsBundle");
|
||||
var mcpBundle = __toESM(require("./bundle"));
|
||||
var import_http = require("./http");
|
||||
var import_inProcessTransport = require("./inProcessTransport");
|
||||
const serverDebug = (0, import_utilsBundle.debug)("pw:mcp:server");
|
||||
async function connect(factory, transport, runHeartbeat) {
|
||||
const server = createServer(factory.name, factory.version, factory.create(), runHeartbeat);
|
||||
await server.connect(transport);
|
||||
}
|
||||
async function wrapInProcess(backend) {
|
||||
const server = createServer("Internal", "0.0.0", backend, false);
|
||||
return new import_inProcessTransport.InProcessTransport(server);
|
||||
}
|
||||
function createServer(name, version, backend, runHeartbeat) {
|
||||
const server = new mcpBundle.Server({ name, version }, {
|
||||
capabilities: {
|
||||
tools: {}
|
||||
}
|
||||
});
|
||||
server.setRequestHandler(mcpBundle.ListToolsRequestSchema, async () => {
|
||||
serverDebug("listTools");
|
||||
const tools = await backend.listTools();
|
||||
return { tools };
|
||||
});
|
||||
let initializePromise;
|
||||
server.setRequestHandler(mcpBundle.CallToolRequestSchema, async (request, extra) => {
|
||||
serverDebug("callTool", request);
|
||||
const progressToken = request.params._meta?.progressToken;
|
||||
let progressCounter = 0;
|
||||
const progress = progressToken ? (params) => {
|
||||
extra.sendNotification({
|
||||
method: "notifications/progress",
|
||||
params: {
|
||||
progressToken,
|
||||
progress: params.progress ?? ++progressCounter,
|
||||
total: params.total,
|
||||
message: params.message
|
||||
}
|
||||
}).catch(serverDebug);
|
||||
} : () => {
|
||||
};
|
||||
try {
|
||||
if (!initializePromise)
|
||||
initializePromise = initializeServer(server, backend, runHeartbeat);
|
||||
await initializePromise;
|
||||
return mergeTextParts(await backend.callTool(request.params.name, request.params.arguments || {}, progress));
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [{ type: "text", text: "### Result\n" + String(error) }],
|
||||
isError: true
|
||||
};
|
||||
}
|
||||
});
|
||||
addServerListener(server, "close", () => backend.serverClosed?.(server));
|
||||
return server;
|
||||
}
|
||||
const initializeServer = async (server, backend, runHeartbeat) => {
|
||||
const capabilities = server.getClientCapabilities();
|
||||
let clientRoots = [];
|
||||
if (capabilities?.roots) {
|
||||
const { roots } = await server.listRoots().catch((e) => {
|
||||
serverDebug(e);
|
||||
return { roots: [] };
|
||||
});
|
||||
clientRoots = roots;
|
||||
}
|
||||
const clientInfo = {
|
||||
name: server.getClientVersion()?.name ?? "unknown",
|
||||
version: server.getClientVersion()?.version ?? "unknown",
|
||||
roots: clientRoots,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
await backend.initialize?.(server, clientInfo);
|
||||
if (runHeartbeat)
|
||||
startHeartbeat(server);
|
||||
};
|
||||
const startHeartbeat = (server) => {
|
||||
const beat = () => {
|
||||
Promise.race([
|
||||
server.ping(),
|
||||
new Promise((_, reject) => setTimeout(() => reject(new Error("ping timeout")), 5e3))
|
||||
]).then(() => {
|
||||
setTimeout(beat, 3e3);
|
||||
}).catch(() => {
|
||||
void server.close();
|
||||
});
|
||||
};
|
||||
beat();
|
||||
};
|
||||
function addServerListener(server, event, listener) {
|
||||
const oldListener = server[`on${event}`];
|
||||
server[`on${event}`] = () => {
|
||||
oldListener?.();
|
||||
listener();
|
||||
};
|
||||
}
|
||||
async function start(serverBackendFactory, options) {
|
||||
if (options.port === void 0) {
|
||||
await connect(serverBackendFactory, new mcpBundle.StdioServerTransport(), false);
|
||||
return;
|
||||
}
|
||||
const httpServer = await (0, import_http.startHttpServer)(options);
|
||||
const url = (0, import_http.httpAddressToString)(httpServer.address());
|
||||
await (0, import_http.installHttpTransport)(httpServer, serverBackendFactory, options.allowedHosts);
|
||||
const mcpConfig = { mcpServers: {} };
|
||||
mcpConfig.mcpServers[serverBackendFactory.nameInConfig] = {
|
||||
url: `${url}/mcp`
|
||||
};
|
||||
const message = [
|
||||
`Listening on ${url}`,
|
||||
"Put this in your client config:",
|
||||
JSON.stringify(mcpConfig, void 0, 2),
|
||||
"For legacy SSE transport support, you can use the /sse endpoint instead."
|
||||
].join("\n");
|
||||
console.error(message);
|
||||
}
|
||||
function firstRootPath(clientInfo) {
|
||||
if (clientInfo.roots.length === 0)
|
||||
return void 0;
|
||||
const firstRootUri = clientInfo.roots[0]?.uri;
|
||||
const url = firstRootUri ? new URL(firstRootUri) : void 0;
|
||||
return url ? (0, import_url.fileURLToPath)(url) : void 0;
|
||||
}
|
||||
function mergeTextParts(result) {
|
||||
const content = [];
|
||||
const testParts = [];
|
||||
for (const part of result.content) {
|
||||
if (part.type === "text") {
|
||||
testParts.push(part.text);
|
||||
continue;
|
||||
}
|
||||
if (testParts.length > 0) {
|
||||
content.push({ type: "text", text: testParts.join("\n") });
|
||||
testParts.length = 0;
|
||||
}
|
||||
content.push(part);
|
||||
}
|
||||
if (testParts.length > 0)
|
||||
content.push({ type: "text", text: testParts.join("\n") });
|
||||
return {
|
||||
...result,
|
||||
content
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
connect,
|
||||
createServer,
|
||||
firstRootPath,
|
||||
start,
|
||||
wrapInProcess
|
||||
});
|
||||
51
node_modules/playwright/lib/mcp/sdk/tool.js
generated
vendored
Normal file
51
node_modules/playwright/lib/mcp/sdk/tool.js
generated
vendored
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var tool_exports = {};
|
||||
__export(tool_exports, {
|
||||
defineToolSchema: () => defineToolSchema,
|
||||
toMcpTool: () => toMcpTool
|
||||
});
|
||||
module.exports = __toCommonJS(tool_exports);
|
||||
var import_bundle = require("../sdk/bundle");
|
||||
const typesWithIntent = ["action", "assertion", "input"];
|
||||
function toMcpTool(tool, options) {
|
||||
const inputSchema = options?.addIntent && typesWithIntent.includes(tool.type) ? tool.inputSchema.extend({
|
||||
intent: import_bundle.z.string().describe("The intent of the call, for example the test step description plan idea")
|
||||
}) : tool.inputSchema;
|
||||
const readOnly = tool.type === "readOnly" || tool.type === "assertion";
|
||||
return {
|
||||
name: tool.name,
|
||||
description: tool.description,
|
||||
inputSchema: (0, import_bundle.zodToJsonSchema)(inputSchema, { strictUnions: true }),
|
||||
annotations: {
|
||||
title: tool.title,
|
||||
readOnlyHint: readOnly,
|
||||
destructiveHint: !readOnly,
|
||||
openWorldHint: true
|
||||
}
|
||||
};
|
||||
}
|
||||
function defineToolSchema(tool) {
|
||||
return tool;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
defineToolSchema,
|
||||
toMcpTool
|
||||
});
|
||||
98
node_modules/playwright/lib/mcp/test/browserBackend.js
generated
vendored
Normal file
98
node_modules/playwright/lib/mcp/test/browserBackend.js
generated
vendored
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var browserBackend_exports = {};
|
||||
__export(browserBackend_exports, {
|
||||
runBrowserBackendAtEnd: () => runBrowserBackendAtEnd
|
||||
});
|
||||
module.exports = __toCommonJS(browserBackend_exports);
|
||||
var mcp = __toESM(require("../sdk/exports"));
|
||||
var import_globals = require("../../common/globals");
|
||||
var import_util = require("../../util");
|
||||
var import_config = require("../browser/config");
|
||||
var import_browserServerBackend = require("../browser/browserServerBackend");
|
||||
var import_tab = require("../browser/tab");
|
||||
async function runBrowserBackendAtEnd(context, errorMessage) {
|
||||
const testInfo = (0, import_globals.currentTestInfo)();
|
||||
if (!testInfo)
|
||||
return;
|
||||
const shouldPause = errorMessage ? testInfo?._pauseOnError() : testInfo?._pauseAtEnd();
|
||||
if (!shouldPause)
|
||||
return;
|
||||
const lines = [];
|
||||
if (errorMessage)
|
||||
lines.push(`### Paused on error:`, (0, import_util.stripAnsiEscapes)(errorMessage));
|
||||
else
|
||||
lines.push(`### Paused at end of test. ready for interaction`);
|
||||
for (let i = 0; i < context.pages().length; i++) {
|
||||
const page = context.pages()[i];
|
||||
const stateSuffix = context.pages().length > 1 ? i + 1 + " of " + context.pages().length : "state";
|
||||
lines.push(
|
||||
"",
|
||||
`### Page ${stateSuffix}`,
|
||||
`- Page URL: ${page.url()}`,
|
||||
`- Page Title: ${await page.title()}`.trim()
|
||||
);
|
||||
let console = errorMessage ? await import_tab.Tab.collectConsoleMessages(page) : [];
|
||||
console = console.filter((msg) => !msg.type || msg.type === "error");
|
||||
if (console.length) {
|
||||
lines.push("- Console Messages:");
|
||||
for (const message of console)
|
||||
lines.push(` - ${message.toString()}`);
|
||||
}
|
||||
lines.push(
|
||||
`- Page Snapshot:`,
|
||||
"```yaml",
|
||||
await page._snapshotForAI(),
|
||||
"```"
|
||||
);
|
||||
}
|
||||
lines.push("");
|
||||
if (errorMessage)
|
||||
lines.push(`### Task`, `Try recovering from the error prior to continuing`);
|
||||
const config = {
|
||||
...import_config.defaultConfig,
|
||||
capabilities: ["testing"]
|
||||
};
|
||||
await mcp.runOnPauseBackendLoop(new import_browserServerBackend.BrowserServerBackend(config, identityFactory(context)), lines.join("\n"));
|
||||
}
|
||||
function identityFactory(browserContext) {
|
||||
return {
|
||||
createContext: async (clientInfo, abortSignal, toolName) => {
|
||||
return {
|
||||
browserContext,
|
||||
close: async () => {
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
runBrowserBackendAtEnd
|
||||
});
|
||||
122
node_modules/playwright/lib/mcp/test/generatorTools.js
generated
vendored
Normal file
122
node_modules/playwright/lib/mcp/test/generatorTools.js
generated
vendored
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var generatorTools_exports = {};
|
||||
__export(generatorTools_exports, {
|
||||
generatorReadLog: () => generatorReadLog,
|
||||
generatorWriteTest: () => generatorWriteTest,
|
||||
setupPage: () => setupPage
|
||||
});
|
||||
module.exports = __toCommonJS(generatorTools_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_bundle = require("../sdk/bundle");
|
||||
var import_testTool = require("./testTool");
|
||||
var import_testContext = require("./testContext");
|
||||
const setupPage = (0, import_testTool.defineTestTool)({
|
||||
schema: {
|
||||
name: "generator_setup_page",
|
||||
title: "Setup generator page",
|
||||
description: "Setup the page for test.",
|
||||
inputSchema: import_bundle.z.object({
|
||||
plan: import_bundle.z.string().describe("The plan for the test. This should be the actual test plan with all the steps."),
|
||||
project: import_bundle.z.string().optional().describe('Project to use for setup. For example: "chromium", if no project is provided uses the first project in the config.'),
|
||||
seedFile: import_bundle.z.string().optional().describe('A seed file contains a single test that is used to setup the page for testing, for example: "tests/seed.spec.ts". If no seed file is provided, a default seed file is created.')
|
||||
}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, progress) => {
|
||||
const seed = await context.getOrCreateSeedFile(params.seedFile, params.project);
|
||||
context.generatorJournal = new import_testContext.GeneratorJournal(context.rootPath, params.plan, seed);
|
||||
await context.runSeedTest(seed.file, seed.projectName, progress);
|
||||
return { content: [] };
|
||||
}
|
||||
});
|
||||
const generatorReadLog = (0, import_testTool.defineTestTool)({
|
||||
schema: {
|
||||
name: "generator_read_log",
|
||||
title: "Retrieve test log",
|
||||
description: "Retrieve the performed test log",
|
||||
inputSchema: import_bundle.z.object({}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context) => {
|
||||
if (!context.generatorJournal)
|
||||
throw new Error(`Please setup page using "${setupPage.schema.name}" first.`);
|
||||
const result = context.generatorJournal.journal();
|
||||
return { content: [{
|
||||
type: "text",
|
||||
text: result
|
||||
}] };
|
||||
}
|
||||
});
|
||||
const generatorWriteTest = (0, import_testTool.defineTestTool)({
|
||||
schema: {
|
||||
name: "generator_write_test",
|
||||
title: "Write test",
|
||||
description: "Write the generated test to the test file",
|
||||
inputSchema: import_bundle.z.object({
|
||||
fileName: import_bundle.z.string().describe("The file to write the test to"),
|
||||
code: import_bundle.z.string().describe("The generated test code")
|
||||
}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params) => {
|
||||
if (!context.generatorJournal)
|
||||
throw new Error(`Please setup page using "${setupPage.schema.name}" first.`);
|
||||
const testRunner = context.existingTestRunner();
|
||||
if (!testRunner)
|
||||
throw new Error("No test runner found, please setup page and perform actions first.");
|
||||
const config = await testRunner.loadConfig();
|
||||
const dirs = [];
|
||||
for (const project of config.projects) {
|
||||
const testDir = import_path.default.relative(context.rootPath, project.project.testDir).replace(/\\/g, "/");
|
||||
const fileName = params.fileName.replace(/\\/g, "/");
|
||||
if (fileName.startsWith(testDir)) {
|
||||
const resolvedFile = import_path.default.resolve(context.rootPath, fileName);
|
||||
await import_fs.default.promises.mkdir(import_path.default.dirname(resolvedFile), { recursive: true });
|
||||
await import_fs.default.promises.writeFile(resolvedFile, params.code);
|
||||
return {
|
||||
content: [{
|
||||
type: "text",
|
||||
text: `### Result
|
||||
Test written to ${params.fileName}`
|
||||
}]
|
||||
};
|
||||
}
|
||||
dirs.push(testDir);
|
||||
}
|
||||
throw new Error(`Test file did not match any of the test dirs: ${dirs.join(", ")}`);
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
generatorReadLog,
|
||||
generatorWriteTest,
|
||||
setupPage
|
||||
});
|
||||
46
node_modules/playwright/lib/mcp/test/plannerTools.js
generated
vendored
Normal file
46
node_modules/playwright/lib/mcp/test/plannerTools.js
generated
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
"use strict";
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var plannerTools_exports = {};
|
||||
__export(plannerTools_exports, {
|
||||
setupPage: () => setupPage
|
||||
});
|
||||
module.exports = __toCommonJS(plannerTools_exports);
|
||||
var import_bundle = require("../sdk/bundle");
|
||||
var import_testTool = require("./testTool");
|
||||
const setupPage = (0, import_testTool.defineTestTool)({
|
||||
schema: {
|
||||
name: "planner_setup_page",
|
||||
title: "Setup planner page",
|
||||
description: "Setup the page for test planning",
|
||||
inputSchema: import_bundle.z.object({
|
||||
project: import_bundle.z.string().optional().describe('Project to use for setup. For example: "chromium", if no project is provided uses the first project in the config.'),
|
||||
seedFile: import_bundle.z.string().optional().describe('A seed file contains a single test that is used to setup the page for testing, for example: "tests/seed.spec.ts". If no seed file is provided, a default seed file is created.')
|
||||
}),
|
||||
type: "readOnly"
|
||||
},
|
||||
handle: async (context, params, progress) => {
|
||||
const seed = await context.getOrCreateSeedFile(params.seedFile, params.project);
|
||||
await context.runSeedTest(seed.file, seed.projectName, progress);
|
||||
return { content: [] };
|
||||
}
|
||||
});
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
setupPage
|
||||
});
|
||||
72
node_modules/playwright/lib/mcp/test/seed.js
generated
vendored
Normal file
72
node_modules/playwright/lib/mcp/test/seed.js
generated
vendored
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
"use strict";
|
||||
var __create = Object.create;
|
||||
var __defProp = Object.defineProperty;
|
||||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||||
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||||
var __getProtoOf = Object.getPrototypeOf;
|
||||
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
var __export = (target, all) => {
|
||||
for (var name in all)
|
||||
__defProp(target, name, { get: all[name], enumerable: true });
|
||||
};
|
||||
var __copyProps = (to, from, except, desc) => {
|
||||
if (from && typeof from === "object" || typeof from === "function") {
|
||||
for (let key of __getOwnPropNames(from))
|
||||
if (!__hasOwnProp.call(to, key) && key !== except)
|
||||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
||||
}
|
||||
return to;
|
||||
};
|
||||
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
||||
// If the importer is in node compatibility mode or this is not an ESM
|
||||
// file that has been converted to a CommonJS file using a Babel-
|
||||
// compatible transform (i.e. "__esModule" has not been set), then set
|
||||
// "default" to the CommonJS "module.exports" for node compatibility.
|
||||
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
||||
mod
|
||||
));
|
||||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
||||
var seed_exports = {};
|
||||
__export(seed_exports, {
|
||||
ensureSeedTest: () => ensureSeedTest,
|
||||
seedProject: () => seedProject
|
||||
});
|
||||
module.exports = __toCommonJS(seed_exports);
|
||||
var import_fs = __toESM(require("fs"));
|
||||
var import_path = __toESM(require("path"));
|
||||
var import_utils = require("playwright-core/lib/utils");
|
||||
var import_projectUtils = require("../../runner/projectUtils");
|
||||
function seedProject(config, projectName) {
|
||||
if (!projectName)
|
||||
return (0, import_projectUtils.findTopLevelProjects)(config)[0];
|
||||
const project = config.projects.find((p) => p.project.name === projectName);
|
||||
if (!project)
|
||||
throw new Error(`Project ${projectName} not found`);
|
||||
return project;
|
||||
}
|
||||
async function ensureSeedTest(project, logNew) {
|
||||
const files = await (0, import_projectUtils.collectFilesForProject)(project);
|
||||
const seed = files.find((file) => import_path.default.basename(file).includes("seed"));
|
||||
if (seed)
|
||||
return seed;
|
||||
const testDir = project.project.testDir;
|
||||
const seedFile = import_path.default.resolve(testDir, "seed.spec.ts");
|
||||
if (logNew) {
|
||||
console.log(`Writing file: ${import_path.default.relative(process.cwd(), seedFile)}`);
|
||||
}
|
||||
await (0, import_utils.mkdirIfNeeded)(seedFile);
|
||||
await import_fs.default.promises.writeFile(seedFile, `import { test, expect } from '@playwright/test';
|
||||
|
||||
test.describe('Test group', () => {
|
||||
test('seed', async ({ page }) => {
|
||||
// generate code here.
|
||||
});
|
||||
});
|
||||
`);
|
||||
return seedFile;
|
||||
}
|
||||
// Annotate the CommonJS export names for ESM import in node:
|
||||
0 && (module.exports = {
|
||||
ensureSeedTest,
|
||||
seedProject
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue