Compare commits
10 commits
main
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1f983acac0 | ||
|
|
40e2096fbc | ||
|
|
4417b78552 | ||
|
|
cf5900f142 | ||
|
|
74ec8c243a | ||
|
|
1e8e8b4b02 | ||
|
|
6ee70e2ce3 | ||
|
|
e9e6cf551f | ||
|
|
b7dcc2bb16 | ||
|
|
52f594e0eb |
|
|
@ -1,6 +1,6 @@
|
||||||
# 🎭 Playwright
|
# 🎭 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://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 -->
|
||||||
|
|
||||||
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
|
## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
|
||||||
| | Linux | macOS | Windows |
|
| | Linux | macOS | Windows |
|
||||||
| :--- | :---: | :---: | :---: |
|
| :--- | :---: | :---: | :---: |
|
||||||
| Chromium <!-- GEN:chromium-version -->115.0.5790.75<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| Chromium <!-- GEN:chromium-version -->115.0.5790.75<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
| WebKit <!-- GEN:webkit-version -->16.4<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| WebKit <!-- GEN:webkit-version -->17.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||||
| Firefox <!-- GEN:firefox-version -->115.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
| Firefox <!-- GEN:firefox-version -->115.0<!-- 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.
|
Headless execution is supported for all browsers on all platforms. Check out [system requirements](https://playwright.dev/docs/intro#system-requirements) for details.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,21 @@ title: "Release notes"
|
||||||
toc_max_heading_level: 2
|
toc_max_heading_level: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Version 1.36
|
||||||
|
|
||||||
|
🏝️ Summer maintenance release.
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 115.0.5790.75
|
||||||
|
* Mozilla Firefox 115.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 114
|
||||||
|
* Microsoft Edge 114
|
||||||
|
|
||||||
## Version 1.35
|
## Version 1.35
|
||||||
|
|
||||||
### Highlights
|
### Highlights
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,21 @@ toc_max_heading_level: 2
|
||||||
|
|
||||||
import LiteYouTube from '@site/src/components/LiteYouTube';
|
import LiteYouTube from '@site/src/components/LiteYouTube';
|
||||||
|
|
||||||
|
## Version 1.36
|
||||||
|
|
||||||
|
🏝️ Summer maintenance release.
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 115.0.5790.75
|
||||||
|
* Mozilla Firefox 115.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 114
|
||||||
|
* Microsoft Edge 114
|
||||||
|
|
||||||
## Version 1.35
|
## Version 1.35
|
||||||
|
|
||||||
### Highlights
|
### Highlights
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,21 @@ toc_max_heading_level: 2
|
||||||
|
|
||||||
import LiteYouTube from '@site/src/components/LiteYouTube';
|
import LiteYouTube from '@site/src/components/LiteYouTube';
|
||||||
|
|
||||||
|
## Version 1.36
|
||||||
|
|
||||||
|
🏝️ Summer maintenance release.
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 115.0.5790.75
|
||||||
|
* Mozilla Firefox 115.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 114
|
||||||
|
* Microsoft Edge 114
|
||||||
|
|
||||||
## Version 1.35
|
## Version 1.35
|
||||||
|
|
||||||
<LiteYouTube
|
<LiteYouTube
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,21 @@ title: "Release notes"
|
||||||
toc_max_heading_level: 2
|
toc_max_heading_level: 2
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Version 1.36
|
||||||
|
|
||||||
|
🏝️ Summer maintenance release.
|
||||||
|
|
||||||
|
### Browser Versions
|
||||||
|
|
||||||
|
* Chromium 115.0.5790.75
|
||||||
|
* Mozilla Firefox 115.0
|
||||||
|
* WebKit 17.0
|
||||||
|
|
||||||
|
This version was also tested against the following stable channels:
|
||||||
|
|
||||||
|
* Google Chrome 114
|
||||||
|
* Microsoft Edge 114
|
||||||
|
|
||||||
## Version 1.35
|
## Version 1.35
|
||||||
|
|
||||||
### Highlights
|
### Highlights
|
||||||
|
|
|
||||||
82
package-lock.json
generated
82
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
@ -6191,11 +6191,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright": {
|
"packages/playwright": {
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6205,11 +6205,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-chromium": {
|
"packages/playwright-chromium": {
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6219,7 +6219,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-core": {
|
"packages/playwright-core": {
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright-core": "cli.js"
|
"playwright-core": "cli.js"
|
||||||
|
|
@ -6230,11 +6230,11 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-core": {
|
"packages/playwright-ct-core": {
|
||||||
"name": "@playwright/experimental-ct-core",
|
"name": "@playwright/experimental-ct-core",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/test": "1.36.0-next",
|
"@playwright/test": "1.36.2",
|
||||||
"playwright-core": "1.36.0-next",
|
"playwright-core": "1.36.2",
|
||||||
"vite": "^4.3.9"
|
"vite": "^4.3.9"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6246,10 +6246,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-react": {
|
"packages/playwright-ct-react": {
|
||||||
"name": "@playwright/experimental-ct-react",
|
"name": "@playwright/experimental-ct-react",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6278,10 +6278,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-react17": {
|
"packages/playwright-ct-react17": {
|
||||||
"name": "@playwright/experimental-ct-react17",
|
"name": "@playwright/experimental-ct-react17",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6310,10 +6310,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-solid": {
|
"packages/playwright-ct-solid": {
|
||||||
"name": "@playwright/experimental-ct-solid",
|
"name": "@playwright/experimental-ct-solid",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"vite-plugin-solid": "^2.7.0"
|
"vite-plugin-solid": "^2.7.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6328,10 +6328,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-svelte": {
|
"packages/playwright-ct-svelte": {
|
||||||
"name": "@playwright/experimental-ct-svelte",
|
"name": "@playwright/experimental-ct-svelte",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6346,10 +6346,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-vue": {
|
"packages/playwright-ct-vue": {
|
||||||
"name": "@playwright/experimental-ct-vue",
|
"name": "@playwright/experimental-ct-vue",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-vue": "^4.2.1"
|
"@vitejs/plugin-vue": "^4.2.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6397,10 +6397,10 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-ct-vue2": {
|
"packages/playwright-ct-vue2": {
|
||||||
"name": "@playwright/experimental-ct-vue2",
|
"name": "@playwright/experimental-ct-vue2",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-vue2": "^2.2.0"
|
"@vitejs/plugin-vue2": "^2.2.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
@ -6414,11 +6414,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-firefox": {
|
"packages/playwright-firefox": {
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6429,11 +6429,11 @@
|
||||||
},
|
},
|
||||||
"packages/playwright-test": {
|
"packages/playwright-test": {
|
||||||
"name": "@playwright/test",
|
"name": "@playwright/test",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -6446,11 +6446,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/playwright-webkit": {
|
"packages/playwright-webkit": {
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "cli.js"
|
"playwright": "cli.js"
|
||||||
|
|
@ -7260,15 +7260,15 @@
|
||||||
"@playwright/experimental-ct-core": {
|
"@playwright/experimental-ct-core": {
|
||||||
"version": "file:packages/playwright-ct-core",
|
"version": "file:packages/playwright-ct-core",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/test": "1.36.0-next",
|
"@playwright/test": "1.36.2",
|
||||||
"playwright-core": "1.36.0-next",
|
"playwright-core": "1.36.2",
|
||||||
"vite": "^4.3.9"
|
"vite": "^4.3.9"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@playwright/experimental-ct-react": {
|
"@playwright/experimental-ct-react": {
|
||||||
"version": "file:packages/playwright-ct-react",
|
"version": "file:packages/playwright-ct-react",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -7288,7 +7288,7 @@
|
||||||
"@playwright/experimental-ct-react17": {
|
"@playwright/experimental-ct-react17": {
|
||||||
"version": "file:packages/playwright-ct-react17",
|
"version": "file:packages/playwright-ct-react17",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -7308,7 +7308,7 @@
|
||||||
"@playwright/experimental-ct-solid": {
|
"@playwright/experimental-ct-solid": {
|
||||||
"version": "file:packages/playwright-ct-solid",
|
"version": "file:packages/playwright-ct-solid",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"solid-js": "^1.7.0",
|
"solid-js": "^1.7.0",
|
||||||
"vite-plugin-solid": "^2.7.0"
|
"vite-plugin-solid": "^2.7.0"
|
||||||
}
|
}
|
||||||
|
|
@ -7316,7 +7316,7 @@
|
||||||
"@playwright/experimental-ct-svelte": {
|
"@playwright/experimental-ct-svelte": {
|
||||||
"version": "file:packages/playwright-ct-svelte",
|
"version": "file:packages/playwright-ct-svelte",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
||||||
"svelte": "^3.55.1"
|
"svelte": "^3.55.1"
|
||||||
}
|
}
|
||||||
|
|
@ -7324,7 +7324,7 @@
|
||||||
"@playwright/experimental-ct-vue": {
|
"@playwright/experimental-ct-vue": {
|
||||||
"version": "file:packages/playwright-ct-vue",
|
"version": "file:packages/playwright-ct-vue",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-vue": "^4.2.1"
|
"@vitejs/plugin-vue": "^4.2.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -7358,7 +7358,7 @@
|
||||||
"@playwright/experimental-ct-vue2": {
|
"@playwright/experimental-ct-vue2": {
|
||||||
"version": "file:packages/playwright-ct-vue2",
|
"version": "file:packages/playwright-ct-vue2",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-vue2": "^2.2.0",
|
"@vitejs/plugin-vue2": "^2.2.0",
|
||||||
"vue": "^2.7.14"
|
"vue": "^2.7.14"
|
||||||
}
|
}
|
||||||
|
|
@ -7368,7 +7368,7 @@
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"fsevents": "2.3.2",
|
"fsevents": "2.3.2",
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
|
|
@ -9656,13 +9656,13 @@
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"version": "file:packages/playwright",
|
"version": "file:packages/playwright",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-chromium": {
|
"playwright-chromium": {
|
||||||
"version": "file:packages/playwright-chromium",
|
"version": "file:packages/playwright-chromium",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-core": {
|
"playwright-core": {
|
||||||
|
|
@ -9671,13 +9671,13 @@
|
||||||
"playwright-firefox": {
|
"playwright-firefox": {
|
||||||
"version": "file:packages/playwright-firefox",
|
"version": "file:packages/playwright-firefox",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"playwright-webkit": {
|
"playwright-webkit": {
|
||||||
"version": "file:packages/playwright-webkit",
|
"version": "file:packages/playwright-webkit",
|
||||||
"requires": {
|
"requires": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-internal",
|
"name": "playwright-internal",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-chromium",
|
"name": "playwright-chromium",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "A high-level API to automate Chromium",
|
"description": "A high-level API to automate Chromium",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -27,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
"mac11-arm64": "1816",
|
"mac11-arm64": "1816",
|
||||||
"ubuntu18.04": "1728"
|
"ubuntu18.04": "1728"
|
||||||
},
|
},
|
||||||
"browserVersion": "16.4"
|
"browserVersion": "17.0"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "ffmpeg",
|
"name": "ffmpeg",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-core",
|
"name": "playwright-core",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"Blackberry PlayBook": {
|
"Blackberry PlayBook": {
|
||||||
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/16.4 Safari/536.2+",
|
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/17.0 Safari/536.2+",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 600,
|
"width": 600,
|
||||||
"height": 1024
|
"height": 1024
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Blackberry PlayBook landscape": {
|
"Blackberry PlayBook landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/16.4 Safari/536.2+",
|
"userAgent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/17.0 Safari/536.2+",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 1024,
|
"width": 1024,
|
||||||
"height": 600
|
"height": 600
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"BlackBerry Z30": {
|
"BlackBerry Z30": {
|
||||||
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/16.4 Mobile Safari/537.10+",
|
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/17.0 Mobile Safari/537.10+",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"BlackBerry Z30 landscape": {
|
"BlackBerry Z30 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/16.4 Mobile Safari/537.10+",
|
"userAgent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/17.0 Mobile Safari/537.10+",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -44,7 +44,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Galaxy Note 3": {
|
"Galaxy Note 3": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/16.4 Mobile Safari/534.30",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.0 Mobile Safari/534.30",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Galaxy Note 3 landscape": {
|
"Galaxy Note 3 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/16.4 Mobile Safari/534.30",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.0 Mobile Safari/534.30",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -66,7 +66,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Galaxy Note II": {
|
"Galaxy Note II": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/16.4 Mobile Safari/534.30",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.0 Mobile Safari/534.30",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Galaxy Note II landscape": {
|
"Galaxy Note II landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/16.4 Mobile Safari/534.30",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.0 Mobile Safari/534.30",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -88,7 +88,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Galaxy S III": {
|
"Galaxy S III": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/16.4 Mobile Safari/534.30",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.0 Mobile Safari/534.30",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 360,
|
"width": 360,
|
||||||
"height": 640
|
"height": 640
|
||||||
|
|
@ -99,7 +99,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"Galaxy S III landscape": {
|
"Galaxy S III landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/16.4 Mobile Safari/534.30",
|
"userAgent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/17.0 Mobile Safari/534.30",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 640,
|
"width": 640,
|
||||||
"height": 360
|
"height": 360
|
||||||
|
|
@ -198,7 +198,7 @@
|
||||||
"defaultBrowserType": "chromium"
|
"defaultBrowserType": "chromium"
|
||||||
},
|
},
|
||||||
"iPad (gen 6)": {
|
"iPad (gen 6)": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 768,
|
"width": 768,
|
||||||
"height": 1024
|
"height": 1024
|
||||||
|
|
@ -209,7 +209,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPad (gen 6) landscape": {
|
"iPad (gen 6) landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 1024,
|
"width": 1024,
|
||||||
"height": 768
|
"height": 768
|
||||||
|
|
@ -220,7 +220,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPad (gen 7)": {
|
"iPad (gen 7)": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 810,
|
"width": 810,
|
||||||
"height": 1080
|
"height": 1080
|
||||||
|
|
@ -231,7 +231,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPad (gen 7) landscape": {
|
"iPad (gen 7) landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 1080,
|
"width": 1080,
|
||||||
"height": 810
|
"height": 810
|
||||||
|
|
@ -242,7 +242,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPad Mini": {
|
"iPad Mini": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 768,
|
"width": 768,
|
||||||
"height": 1024
|
"height": 1024
|
||||||
|
|
@ -253,7 +253,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPad Mini landscape": {
|
"iPad Mini landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 1024,
|
"width": 1024,
|
||||||
"height": 768
|
"height": 768
|
||||||
|
|
@ -264,7 +264,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPad Pro 11": {
|
"iPad Pro 11": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 834,
|
"width": 834,
|
||||||
"height": 1194
|
"height": 1194
|
||||||
|
|
@ -275,7 +275,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPad Pro 11 landscape": {
|
"iPad Pro 11 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPad; CPU OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 1194,
|
"width": 1194,
|
||||||
"height": 834
|
"height": 834
|
||||||
|
|
@ -286,7 +286,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 6": {
|
"iPhone 6": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 667
|
"height": 667
|
||||||
|
|
@ -297,7 +297,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 6 landscape": {
|
"iPhone 6 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 667,
|
"width": 667,
|
||||||
"height": 375
|
"height": 375
|
||||||
|
|
@ -308,7 +308,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 6 Plus": {
|
"iPhone 6 Plus": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 736
|
"height": 736
|
||||||
|
|
@ -319,7 +319,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 6 Plus landscape": {
|
"iPhone 6 Plus landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 736,
|
"width": 736,
|
||||||
"height": 414
|
"height": 414
|
||||||
|
|
@ -330,7 +330,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 7": {
|
"iPhone 7": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 667
|
"height": 667
|
||||||
|
|
@ -341,7 +341,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 7 landscape": {
|
"iPhone 7 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 667,
|
"width": 667,
|
||||||
"height": 375
|
"height": 375
|
||||||
|
|
@ -352,7 +352,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 7 Plus": {
|
"iPhone 7 Plus": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 736
|
"height": 736
|
||||||
|
|
@ -363,7 +363,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 7 Plus landscape": {
|
"iPhone 7 Plus landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 736,
|
"width": 736,
|
||||||
"height": 414
|
"height": 414
|
||||||
|
|
@ -374,7 +374,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 8": {
|
"iPhone 8": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 667
|
"height": 667
|
||||||
|
|
@ -385,7 +385,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 8 landscape": {
|
"iPhone 8 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 667,
|
"width": 667,
|
||||||
"height": 375
|
"height": 375
|
||||||
|
|
@ -396,7 +396,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 8 Plus": {
|
"iPhone 8 Plus": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 736
|
"height": 736
|
||||||
|
|
@ -407,7 +407,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 8 Plus landscape": {
|
"iPhone 8 Plus landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 736,
|
"width": 736,
|
||||||
"height": 414
|
"height": 414
|
||||||
|
|
@ -418,7 +418,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone SE": {
|
"iPhone SE": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/16.4 Mobile/14E304 Safari/602.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/17.0 Mobile/14E304 Safari/602.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 320,
|
"width": 320,
|
||||||
"height": 568
|
"height": 568
|
||||||
|
|
@ -429,7 +429,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone SE landscape": {
|
"iPhone SE landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/16.4 Mobile/14E304 Safari/602.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/17.0 Mobile/14E304 Safari/602.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 568,
|
"width": 568,
|
||||||
"height": 320
|
"height": 320
|
||||||
|
|
@ -440,7 +440,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone X": {
|
"iPhone X": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 812
|
"height": 812
|
||||||
|
|
@ -451,7 +451,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone X landscape": {
|
"iPhone X landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/16.4 Mobile/15A372 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/17.0 Mobile/15A372 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 812,
|
"width": 812,
|
||||||
"height": 375
|
"height": 375
|
||||||
|
|
@ -462,7 +462,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone XR": {
|
"iPhone XR": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 896
|
"height": 896
|
||||||
|
|
@ -473,7 +473,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone XR landscape": {
|
"iPhone XR landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"viewport": {
|
"viewport": {
|
||||||
"width": 896,
|
"width": 896,
|
||||||
"height": 414
|
"height": 414
|
||||||
|
|
@ -484,7 +484,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 11": {
|
"iPhone 11": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 896
|
"height": 896
|
||||||
|
|
@ -499,7 +499,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 11 landscape": {
|
"iPhone 11 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 896
|
"height": 896
|
||||||
|
|
@ -514,7 +514,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 11 Pro": {
|
"iPhone 11 Pro": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 812
|
"height": 812
|
||||||
|
|
@ -529,7 +529,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 11 Pro landscape": {
|
"iPhone 11 Pro landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 812
|
"height": 812
|
||||||
|
|
@ -544,7 +544,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 11 Pro Max": {
|
"iPhone 11 Pro Max": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 896
|
"height": 896
|
||||||
|
|
@ -559,7 +559,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 11 Pro Max landscape": {
|
"iPhone 11 Pro Max landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 12_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 414,
|
"width": 414,
|
||||||
"height": 896
|
"height": 896
|
||||||
|
|
@ -574,7 +574,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12": {
|
"iPhone 12": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -589,7 +589,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12 landscape": {
|
"iPhone 12 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -604,7 +604,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12 Pro": {
|
"iPhone 12 Pro": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -619,7 +619,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12 Pro landscape": {
|
"iPhone 12 Pro landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -634,7 +634,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12 Pro Max": {
|
"iPhone 12 Pro Max": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 428,
|
"width": 428,
|
||||||
"height": 926
|
"height": 926
|
||||||
|
|
@ -649,7 +649,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12 Pro Max landscape": {
|
"iPhone 12 Pro Max landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 428,
|
"width": 428,
|
||||||
"height": 926
|
"height": 926
|
||||||
|
|
@ -664,7 +664,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12 Mini": {
|
"iPhone 12 Mini": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 812
|
"height": 812
|
||||||
|
|
@ -679,7 +679,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 12 Mini landscape": {
|
"iPhone 12 Mini landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 812
|
"height": 812
|
||||||
|
|
@ -694,7 +694,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13": {
|
"iPhone 13": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -709,7 +709,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13 landscape": {
|
"iPhone 13 landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -724,7 +724,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13 Pro": {
|
"iPhone 13 Pro": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -739,7 +739,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13 Pro landscape": {
|
"iPhone 13 Pro landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 390,
|
"width": 390,
|
||||||
"height": 844
|
"height": 844
|
||||||
|
|
@ -754,7 +754,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13 Pro Max": {
|
"iPhone 13 Pro Max": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 428,
|
"width": 428,
|
||||||
"height": 926
|
"height": 926
|
||||||
|
|
@ -769,7 +769,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13 Pro Max landscape": {
|
"iPhone 13 Pro Max landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 428,
|
"width": 428,
|
||||||
"height": 926
|
"height": 926
|
||||||
|
|
@ -784,7 +784,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13 Mini": {
|
"iPhone 13 Mini": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 812
|
"height": 812
|
||||||
|
|
@ -799,7 +799,7 @@
|
||||||
"defaultBrowserType": "webkit"
|
"defaultBrowserType": "webkit"
|
||||||
},
|
},
|
||||||
"iPhone 13 Mini landscape": {
|
"iPhone 13 Mini landscape": {
|
||||||
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Mobile/15E148 Safari/604.1",
|
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 375,
|
"width": 375,
|
||||||
"height": 812
|
"height": 812
|
||||||
|
|
@ -1315,7 +1315,7 @@
|
||||||
"defaultBrowserType": "firefox"
|
"defaultBrowserType": "firefox"
|
||||||
},
|
},
|
||||||
"Desktop Safari": {
|
"Desktop Safari": {
|
||||||
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15",
|
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",
|
||||||
"screen": {
|
"screen": {
|
||||||
"width": 1792,
|
"width": 1792,
|
||||||
"height": 1120
|
"height": 1120
|
||||||
|
|
|
||||||
|
|
@ -437,6 +437,12 @@ export class HarTracer {
|
||||||
const pageEntry = this._createPageEntryIfNeeded(page);
|
const pageEntry = this._createPageEntryIfNeeded(page);
|
||||||
const request = response.request();
|
const request = response.request();
|
||||||
|
|
||||||
|
// Prefer "response received" time over "request sent" time
|
||||||
|
// for the purpose of matching requests that were used in a particular snapshot.
|
||||||
|
// Note that both snapshot time and request time are taken here in the Node process.
|
||||||
|
if (this._options.includeTraceInfo)
|
||||||
|
harEntry._monotonicTime = monotonicTime();
|
||||||
|
|
||||||
harEntry.response = {
|
harEntry.response = {
|
||||||
status: response.status(),
|
status: response.status(),
|
||||||
statusText: response.statusText(),
|
statusText: response.statusText(),
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ type RecordingState = {
|
||||||
networkSha1s: Set<string>,
|
networkSha1s: Set<string>,
|
||||||
traceSha1s: Set<string>,
|
traceSha1s: Set<string>,
|
||||||
recording: boolean;
|
recording: boolean;
|
||||||
|
callIds: Set<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const kScreencastOptions = { width: 800, height: 600, quality: 90 };
|
const kScreencastOptions = { width: 800, height: 600, quality: 90 };
|
||||||
|
|
@ -146,7 +147,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||||
chunkOrdinal: 0,
|
chunkOrdinal: 0,
|
||||||
traceSha1s: new Set(),
|
traceSha1s: new Set(),
|
||||||
networkSha1s: new Set(),
|
networkSha1s: new Set(),
|
||||||
recording: false
|
recording: false,
|
||||||
|
callIds: new Set(),
|
||||||
};
|
};
|
||||||
const state = this._state;
|
const state = this._state;
|
||||||
this._writeChain = fs.promises.mkdir(state.resourcesDir, { recursive: true }).then(() => fs.promises.writeFile(state.networkFile.file, ''));
|
this._writeChain = fs.promises.mkdir(state.resourcesDir, { recursive: true }).then(() => fs.promises.writeFile(state.networkFile.file, ''));
|
||||||
|
|
@ -171,6 +173,7 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||||
buffer: [],
|
buffer: [],
|
||||||
};
|
};
|
||||||
state.recording = true;
|
state.recording = true;
|
||||||
|
state.callIds.clear();
|
||||||
|
|
||||||
if (options.name && options.name !== this._state.traceName)
|
if (options.name && options.name !== this._state.traceName)
|
||||||
this._changeTraceName(this._state, options.name);
|
this._changeTraceName(this._state, options.name);
|
||||||
|
|
@ -352,11 +355,14 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
sdkObject.attribution.page?.temporarlyDisableTracingScreencastThrottling();
|
sdkObject.attribution.page?.temporarlyDisableTracingScreencastThrottling();
|
||||||
event.beforeSnapshot = `before@${metadata.id}`;
|
event.beforeSnapshot = `before@${metadata.id}`;
|
||||||
|
this._state?.callIds.add(metadata.id);
|
||||||
this._appendTraceEvent(event);
|
this._appendTraceEvent(event);
|
||||||
return this._captureSnapshot(event.beforeSnapshot, sdkObject, metadata);
|
return this._captureSnapshot(event.beforeSnapshot, sdkObject, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeInputAction(sdkObject: SdkObject, metadata: CallMetadata, element: ElementHandle) {
|
onBeforeInputAction(sdkObject: SdkObject, metadata: CallMetadata, element: ElementHandle) {
|
||||||
|
if (!this._state?.callIds.has(metadata.id))
|
||||||
|
return Promise.resolve();
|
||||||
// IMPORTANT: no awaits before this._appendTraceEvent in this method.
|
// IMPORTANT: no awaits before this._appendTraceEvent in this method.
|
||||||
const event = createInputActionTraceEvent(metadata);
|
const event = createInputActionTraceEvent(metadata);
|
||||||
if (!event)
|
if (!event)
|
||||||
|
|
@ -368,9 +374,12 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
||||||
}
|
}
|
||||||
|
|
||||||
async onAfterCall(sdkObject: SdkObject, metadata: CallMetadata) {
|
async onAfterCall(sdkObject: SdkObject, metadata: CallMetadata) {
|
||||||
|
if (!this._state?.callIds.has(metadata.id))
|
||||||
|
return;
|
||||||
|
this._state?.callIds.delete(metadata.id);
|
||||||
const event = createAfterActionTraceEvent(metadata);
|
const event = createAfterActionTraceEvent(metadata);
|
||||||
if (!event)
|
if (!event)
|
||||||
return Promise.resolve();
|
return;
|
||||||
sdkObject.attribution.page?.temporarlyDisableTracingScreencastThrottling();
|
sdkObject.attribution.page?.temporarlyDisableTracingScreencastThrottling();
|
||||||
event.afterSnapshot = `after@${metadata.id}`;
|
event.afterSnapshot = `after@${metadata.id}`;
|
||||||
this._appendTraceEvent(event);
|
this._appendTraceEvent(event);
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ import { WKPage } from './wkPage';
|
||||||
import { kBrowserClosedError } from '../../common/errors';
|
import { kBrowserClosedError } from '../../common/errors';
|
||||||
import type { SdkObject } from '../instrumentation';
|
import type { SdkObject } from '../instrumentation';
|
||||||
|
|
||||||
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15';
|
const DEFAULT_USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15';
|
||||||
const BROWSER_VERSION = '16.4';
|
const BROWSER_VERSION = '17.0';
|
||||||
|
|
||||||
export class WKBrowser extends Browser {
|
export class WKBrowser extends Browser {
|
||||||
private readonly _connection: WKConnection;
|
private readonly _connection: WKConnection;
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,12 @@ export function globToRegex(glob: string): RegExp {
|
||||||
case '?':
|
case '?':
|
||||||
tokens.push('.');
|
tokens.push('.');
|
||||||
break;
|
break;
|
||||||
|
case '[':
|
||||||
|
tokens.push('[');
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
tokens.push(']');
|
||||||
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
inGroup = true;
|
inGroup = true;
|
||||||
tokens.push('(');
|
tokens.push('(');
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-core",
|
"name": "@playwright/experimental-ct-core",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "Playwright Component Testing Helpers",
|
"description": "Playwright Component Testing Helpers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -21,9 +21,9 @@
|
||||||
"./lib/vitePlugin": "./lib/vitePlugin.js"
|
"./lib/vitePlugin": "./lib/vitePlugin.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next",
|
"playwright-core": "1.36.2",
|
||||||
"vite": "^4.3.9",
|
"vite": "^4.3.9",
|
||||||
"@playwright/test": "1.36.0-next"
|
"@playwright/test": "1.36.2"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"playwright": "./cli.js"
|
"playwright": "./cli.js"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-react",
|
"name": "@playwright/experimental-ct-react",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "Playwright Component Testing for React",
|
"description": "Playwright Component Testing for React",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-react17",
|
"name": "@playwright/experimental-ct-react17",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "Playwright Component Testing for React",
|
"description": "Playwright Component Testing for React",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-react": "^4.0.0"
|
"@vitejs/plugin-react": "^4.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-solid",
|
"name": "@playwright/experimental-ct-solid",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "Playwright Component Testing for Solid",
|
"description": "Playwright Component Testing for Solid",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"vite-plugin-solid": "^2.7.0"
|
"vite-plugin-solid": "^2.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-svelte",
|
"name": "@playwright/experimental-ct-svelte",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "Playwright Component Testing for Svelte",
|
"description": "Playwright Component Testing for Svelte",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-vue",
|
"name": "@playwright/experimental-ct-vue",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "Playwright Component Testing for Vue",
|
"description": "Playwright Component Testing for Vue",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-vue": "^4.2.1"
|
"@vitejs/plugin-vue": "^4.2.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/experimental-ct-vue2",
|
"name": "@playwright/experimental-ct-vue2",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "Playwright Component Testing for Vue2",
|
"description": "Playwright Component Testing for Vue2",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
"@playwright/experimental-ct-core": "1.36.2",
|
||||||
"@vitejs/plugin-vue2": "^2.2.0"
|
"@vitejs/plugin-vue2": "^2.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-firefox",
|
"name": "playwright-firefox",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "A high-level API to automate Firefox",
|
"description": "A high-level API to automate Firefox",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -27,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@playwright/test",
|
"name": "@playwright/test",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"fsevents": "2.3.2"
|
"fsevents": "2.3.2"
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import type { ImageComparatorOptions, Comparator } from 'playwright-core/lib/uti
|
||||||
import { getComparator } from 'playwright-core/lib/utils';
|
import { getComparator } from 'playwright-core/lib/utils';
|
||||||
import type { PageScreenshotOptions } from 'playwright-core/types/types';
|
import type { PageScreenshotOptions } from 'playwright-core/types/types';
|
||||||
import {
|
import {
|
||||||
serializeError, sanitizeForFilePath,
|
addSuffixToFilePath, serializeError, sanitizeForFilePath,
|
||||||
trimLongString, callLogText,
|
trimLongString, callLogText,
|
||||||
expectTypes } from '../util';
|
expectTypes } from '../util';
|
||||||
import { colors } from 'playwright-core/lib/utilsBundle';
|
import { colors } from 'playwright-core/lib/utilsBundle';
|
||||||
|
|
@ -124,8 +124,8 @@ class SnapshotHelper<T extends ImageComparatorOptions> {
|
||||||
const inputPathSegments = Array.isArray(name) ? name : [addSuffixToFilePath(name, '', undefined, true)];
|
const inputPathSegments = Array.isArray(name) ? name : [addSuffixToFilePath(name, '', undefined, true)];
|
||||||
const outputPathSegments = Array.isArray(name) ? name : [addSuffixToFilePath(name, actualModifier, undefined, true)];
|
const outputPathSegments = Array.isArray(name) ? name : [addSuffixToFilePath(name, actualModifier, undefined, true)];
|
||||||
this.snapshotPath = snapshotPathResolver(...inputPathSegments);
|
this.snapshotPath = snapshotPathResolver(...inputPathSegments);
|
||||||
const inputFile = testInfo.outputPath(...inputPathSegments);
|
const inputFile = testInfo._getOutputPath(...inputPathSegments);
|
||||||
const outputFile = testInfo.outputPath(...outputPathSegments);
|
const outputFile = testInfo._getOutputPath(...outputPathSegments);
|
||||||
this.expectedPath = addSuffixToFilePath(inputFile, '-expected');
|
this.expectedPath = addSuffixToFilePath(inputFile, '-expected');
|
||||||
this.previousPath = addSuffixToFilePath(outputFile, '-previous');
|
this.previousPath = addSuffixToFilePath(outputFile, '-previous');
|
||||||
this.actualPath = addSuffixToFilePath(outputFile, '-actual');
|
this.actualPath = addSuffixToFilePath(outputFile, '-actual');
|
||||||
|
|
@ -440,14 +440,3 @@ function determineFileExtension(file: string | Buffer): string {
|
||||||
function compareMagicBytes(file: Buffer, magicBytes: number[]): boolean {
|
function compareMagicBytes(file: Buffer, magicBytes: number[]): boolean {
|
||||||
return Buffer.compare(Buffer.from(magicBytes), file.slice(0, magicBytes.length)) === 0;
|
return Buffer.compare(Buffer.from(magicBytes), file.slice(0, magicBytes.length)) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSuffixToFilePath(filePath: string, suffix: string, customExtension?: string, sanitize = false): string {
|
|
||||||
const dirname = path.dirname(filePath);
|
|
||||||
const ext = path.extname(filePath);
|
|
||||||
const name = path.basename(filePath, ext);
|
|
||||||
const base = path.join(dirname, name);
|
|
||||||
const sanitizeForSnapshotFilePath = (s: string) => {
|
|
||||||
return s.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, '-');
|
|
||||||
};
|
|
||||||
return (sanitize ? sanitizeForSnapshotFilePath(base) : base) + suffix + (customExtension || ext);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -195,18 +195,8 @@ export function expectTypes(receiver: any, types: string[], matcherName: string)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sanitizeForFilePath(input: string) {
|
export function sanitizeForFilePath(s: string) {
|
||||||
let nonTrivialSubstitute = false;
|
return s.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, '-');
|
||||||
let sanitized = input.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F\x2A\-\*]+/g, substring => {
|
|
||||||
if (substring !== ' ')
|
|
||||||
nonTrivialSubstitute = true;
|
|
||||||
return '-';
|
|
||||||
});
|
|
||||||
if (!nonTrivialSubstitute)
|
|
||||||
return sanitized;
|
|
||||||
// If we sanitized the beginning or end, remove it for cosmetic reasons.
|
|
||||||
sanitized = sanitized.replace(/^-/, '').replace(/-$/, '');
|
|
||||||
return sanitized + '-' + calculateSha1(input).substring(0, 6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function trimLongString(s: string, length = 100) {
|
export function trimLongString(s: string, length = 100) {
|
||||||
|
|
@ -219,6 +209,14 @@ export function trimLongString(s: string, length = 100) {
|
||||||
return s.substring(0, start) + middle + s.slice(-end);
|
return s.substring(0, start) + middle + s.slice(-end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function addSuffixToFilePath(filePath: string, suffix: string, customExtension?: string, sanitize = false): string {
|
||||||
|
const dirname = path.dirname(filePath);
|
||||||
|
const ext = path.extname(filePath);
|
||||||
|
const name = path.basename(filePath, ext);
|
||||||
|
const base = path.join(dirname, name);
|
||||||
|
return (sanitize ? sanitizeForFilePath(base) : base) + suffix + (customExtension || ext);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns absolute path contained within parent directory.
|
* Returns absolute path contained within parent directory.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -382,7 +382,12 @@ export class TestInfoImpl implements TestInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
outputPath(...pathSegments: string[]){
|
outputPath(...pathSegments: string[]){
|
||||||
|
const outputPath = this._getOutputPath(...pathSegments);
|
||||||
fs.mkdirSync(this.outputDir, { recursive: true });
|
fs.mkdirSync(this.outputDir, { recursive: true });
|
||||||
|
return outputPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
_getOutputPath(...pathSegments: string[]){
|
||||||
const joinedPath = path.join(...pathSegments);
|
const joinedPath = path.join(...pathSegments);
|
||||||
const outputPath = getContainedPath(this.outputDir, joinedPath);
|
const outputPath = getContainedPath(this.outputDir, joinedPath);
|
||||||
if (outputPath)
|
if (outputPath)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright-webkit",
|
"name": "playwright-webkit",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "A high-level API to automate WebKit",
|
"description": "A high-level API to automate WebKit",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -27,6 +27,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "playwright",
|
"name": "playwright",
|
||||||
"version": "1.36.0-next",
|
"version": "1.36.2",
|
||||||
"description": "A high-level API to automate web browsers",
|
"description": "A high-level API to automate web browsers",
|
||||||
"repository": "github:Microsoft/playwright",
|
"repository": "github:Microsoft/playwright",
|
||||||
"homepage": "https://playwright.dev",
|
"homepage": "https://playwright.dev",
|
||||||
|
|
@ -28,6 +28,6 @@
|
||||||
"install": "node install.js"
|
"install": "node install.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"playwright-core": "1.36.0-next"
|
"playwright-core": "1.36.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -112,17 +112,19 @@ export class SnapshotRenderer {
|
||||||
return { html, pageId: snapshot.pageId, frameId: snapshot.frameId, index: this._index };
|
return { html, pageId: snapshot.pageId, frameId: snapshot.frameId, index: this._index };
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceByUrl(url: string): ResourceSnapshot | undefined {
|
resourceByUrl(url: string, method: string): ResourceSnapshot | undefined {
|
||||||
const snapshot = this._snapshot;
|
const snapshot = this._snapshot;
|
||||||
let result: ResourceSnapshot | undefined;
|
let result: ResourceSnapshot | undefined;
|
||||||
|
|
||||||
// First try locating exact resource belonging to this frame.
|
// First try locating exact resource belonging to this frame.
|
||||||
for (const resource of this._resources) {
|
for (const resource of this._resources) {
|
||||||
|
// Only use resources that received response before the snapshot.
|
||||||
|
// Note that both snapshot time and request time are taken in the same Node process.
|
||||||
if (typeof resource._monotonicTime === 'number' && resource._monotonicTime >= snapshot.timestamp)
|
if (typeof resource._monotonicTime === 'number' && resource._monotonicTime >= snapshot.timestamp)
|
||||||
break;
|
break;
|
||||||
if (resource._frameref !== snapshot.frameId)
|
if (resource._frameref !== snapshot.frameId)
|
||||||
continue;
|
continue;
|
||||||
if (resource.request.url === url) {
|
if (resource.request.url === url && resource.request.method === method) {
|
||||||
// Pick the last resource with matching url - most likely it was used
|
// Pick the last resource with matching url - most likely it was used
|
||||||
// at the time of snapshot, not the earlier aborted resource with the same url.
|
// at the time of snapshot, not the earlier aborted resource with the same url.
|
||||||
result = resource;
|
result = resource;
|
||||||
|
|
@ -132,9 +134,11 @@ export class SnapshotRenderer {
|
||||||
if (!result) {
|
if (!result) {
|
||||||
// Then fall back to resource with this URL to account for memory cache.
|
// Then fall back to resource with this URL to account for memory cache.
|
||||||
for (const resource of this._resources) {
|
for (const resource of this._resources) {
|
||||||
|
// Only use resources that received response before the snapshot.
|
||||||
|
// Note that both snapshot time and request time are taken in the same Node process.
|
||||||
if (typeof resource._monotonicTime === 'number' && resource._monotonicTime >= snapshot.timestamp)
|
if (typeof resource._monotonicTime === 'number' && resource._monotonicTime >= snapshot.timestamp)
|
||||||
break;
|
break;
|
||||||
if (resource.request.url === url) {
|
if (resource.request.url === url && resource.request.method === method) {
|
||||||
// Pick the last resource with matching url - most likely it was used
|
// Pick the last resource with matching url - most likely it was used
|
||||||
// at the time of snapshot, not the earlier aborted resource with the same url.
|
// at the time of snapshot, not the earlier aborted resource with the same url.
|
||||||
result = resource;
|
result = resource;
|
||||||
|
|
@ -142,7 +146,7 @@ export class SnapshotRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result) {
|
if (result && method.toUpperCase() === 'GET') {
|
||||||
// Patch override if necessary.
|
// Patch override if necessary.
|
||||||
for (const o of snapshot.resourceOverrides) {
|
for (const o of snapshot.resourceOverrides) {
|
||||||
if (url === o.url && o.sha1) {
|
if (url === o.url && o.sha1) {
|
||||||
|
|
|
||||||
|
|
@ -65,11 +65,11 @@ export class SnapshotServer {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async serveResource(requestUrlAlternatives: string[], snapshotUrl: string): Promise<Response> {
|
async serveResource(requestUrlAlternatives: string[], method: string, snapshotUrl: string): Promise<Response> {
|
||||||
let resource: ResourceSnapshot | undefined;
|
let resource: ResourceSnapshot | undefined;
|
||||||
const snapshot = this._snapshotIds.get(snapshotUrl)!;
|
const snapshot = this._snapshotIds.get(snapshotUrl)!;
|
||||||
for (const requestUrl of requestUrlAlternatives) {
|
for (const requestUrl of requestUrlAlternatives) {
|
||||||
resource = snapshot?.resourceByUrl(removeHash(requestUrl));
|
resource = snapshot?.resourceByUrl(removeHash(requestUrl), method);
|
||||||
if (resource)
|
if (resource)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,4 +56,9 @@ export class SnapshotStorage {
|
||||||
snapshotsForTest() {
|
snapshotsForTest() {
|
||||||
return [...this._frameSnapshots.keys()];
|
return [...this._frameSnapshots.keys()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finalize() {
|
||||||
|
// Resources are not necessarily sorted in the trace file, so sort them now.
|
||||||
|
this._resources.sort((a, b) => (a._monotonicTime || 0) - (b._monotonicTime || 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ async function doFetch(event: FetchEvent): Promise<Response> {
|
||||||
const lookupUrls = [request.url];
|
const lookupUrls = [request.url];
|
||||||
if (isDeployedAsHttps && request.url.startsWith('https://'))
|
if (isDeployedAsHttps && request.url.startsWith('https://'))
|
||||||
lookupUrls.push(request.url.replace(/^https/, 'http'));
|
lookupUrls.push(request.url.replace(/^https/, 'http'));
|
||||||
return snapshotServer.serveResource(lookupUrls, snapshotUrl);
|
return snapshotServer.serveResource(lookupUrls, request.method, snapshotUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function gc() {
|
async function gc() {
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ export class TraceModel {
|
||||||
|
|
||||||
this.contextEntries.push(contextEntry);
|
this.contextEntries.push(contextEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._snapshotStorage!.finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
async hasEntry(filename: string): Promise<boolean> {
|
async hasEntry(filename: string): Promise<boolean> {
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ export function suppressCertificateWarning() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseTraceRaw(file: string): Promise<{ events: any[], resources: Map<string, Buffer>, actions: string[], stacks: Map<string, StackFrame[]> }> {
|
export async function parseTraceRaw(file: string): Promise<{ events: any[], resources: Map<string, Buffer>, actions: string[], actionObjects: ActionTraceEvent[], stacks: Map<string, StackFrame[]> }> {
|
||||||
const zipFS = new ZipFile(file);
|
const zipFS = new ZipFile(file);
|
||||||
const resources = new Map<string, Buffer>();
|
const resources = new Map<string, Buffer>();
|
||||||
for (const entry of await zipFS.entries())
|
for (const entry of await zipFS.entries())
|
||||||
|
|
@ -111,6 +111,8 @@ export async function parseTraceRaw(file: string): Promise<{ events: any[], reso
|
||||||
for (const line of resources.get(traceFile)!.toString().split('\n')) {
|
for (const line of resources.get(traceFile)!.toString().split('\n')) {
|
||||||
if (line) {
|
if (line) {
|
||||||
const event = JSON.parse(line) as TraceEvent;
|
const event = JSON.parse(line) as TraceEvent;
|
||||||
|
events.push(event);
|
||||||
|
|
||||||
if (event.type === 'before') {
|
if (event.type === 'before') {
|
||||||
const action: ActionTraceEvent = {
|
const action: ActionTraceEvent = {
|
||||||
...event,
|
...event,
|
||||||
|
|
@ -118,7 +120,6 @@ export async function parseTraceRaw(file: string): Promise<{ events: any[], reso
|
||||||
endTime: 0,
|
endTime: 0,
|
||||||
log: []
|
log: []
|
||||||
};
|
};
|
||||||
events.push(action);
|
|
||||||
actionMap.set(event.callId, action);
|
actionMap.set(event.callId, action);
|
||||||
} else if (event.type === 'input') {
|
} else if (event.type === 'input') {
|
||||||
const existing = actionMap.get(event.callId);
|
const existing = actionMap.get(event.callId);
|
||||||
|
|
@ -131,8 +132,6 @@ export async function parseTraceRaw(file: string): Promise<{ events: any[], reso
|
||||||
existing.log = event.log;
|
existing.log = event.log;
|
||||||
existing.error = event.error;
|
existing.error = event.error;
|
||||||
existing.result = event.result;
|
existing.result = event.result;
|
||||||
} else {
|
|
||||||
events.push(event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -151,21 +150,17 @@ export async function parseTraceRaw(file: string): Promise<{ events: any[], reso
|
||||||
stacks.set(key, value);
|
stacks.set(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const actionObjects = [...actionMap.values()];
|
||||||
|
actionObjects.sort((a, b) => a.startTime - b.startTime);
|
||||||
return {
|
return {
|
||||||
events,
|
events,
|
||||||
resources,
|
resources,
|
||||||
actions: eventsToActions(events),
|
actions: actionObjects.map(a => a.apiName),
|
||||||
|
actionObjects,
|
||||||
stacks,
|
stacks,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function eventsToActions(events: ActionTraceEvent[]): string[] {
|
|
||||||
// Trace viewer only shows non-internal non-tracing actions.
|
|
||||||
return events.filter(e => e.type === 'action')
|
|
||||||
.sort((a, b) => a.startTime - b.startTime)
|
|
||||||
.map(e => e.apiName);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function parseTrace(file: string): Promise<{ resources: Map<string, Buffer>, events: EventTraceEvent[], actions: ActionTraceEvent[], apiNames: string[], traceModel: TraceModel, model: MultiTraceModel, actionTree: string[] }> {
|
export async function parseTrace(file: string): Promise<{ resources: Map<string, Buffer>, events: EventTraceEvent[], actions: ActionTraceEvent[], apiNames: string[], traceModel: TraceModel, model: MultiTraceModel, actionTree: string[] }> {
|
||||||
const backend = new TraceBackend(file);
|
const backend = new TraceBackend(file);
|
||||||
const traceModel = new TraceModel();
|
const traceModel = new TraceModel();
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ it.describe('snapshots', () => {
|
||||||
});
|
});
|
||||||
await page.setContent('<link rel="stylesheet" href="style.css"><button>Hello</button>');
|
await page.setContent('<link rel="stylesheet" href="style.css"><button>Hello</button>');
|
||||||
const snapshot = await snapshotter.captureSnapshot(toImpl(page), 'call@1', 'snapshot@call@1');
|
const snapshot = await snapshotter.captureSnapshot(toImpl(page), 'call@1', 'snapshot@call@1');
|
||||||
const resource = snapshot.resourceByUrl(`http://localhost:${server.PORT}/style.css`);
|
const resource = snapshot.resourceByUrl(`http://localhost:${server.PORT}/style.css`, 'GET');
|
||||||
expect(resource).toBeTruthy();
|
expect(resource).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -124,7 +124,7 @@ it.describe('snapshots', () => {
|
||||||
|
|
||||||
await page.evaluate(() => { (document.styleSheets[0].cssRules[0] as any).style.color = 'blue'; });
|
await page.evaluate(() => { (document.styleSheets[0].cssRules[0] as any).style.color = 'blue'; });
|
||||||
const snapshot2 = await snapshotter.captureSnapshot(toImpl(page), 'call@2', 'snapshot@call@2');
|
const snapshot2 = await snapshotter.captureSnapshot(toImpl(page), 'call@2', 'snapshot@call@2');
|
||||||
const resource = snapshot2.resourceByUrl(`http://localhost:${server.PORT}/style.css`);
|
const resource = snapshot2.resourceByUrl(`http://localhost:${server.PORT}/style.css`, 'GET');
|
||||||
expect((await snapshotter.resourceContentForTest(resource.response.content._sha1)).toString()).toBe('button { color: blue; }');
|
expect((await snapshotter.resourceContentForTest(resource.response.content._sha1)).toString()).toBe('button { color: blue; }');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -851,7 +851,7 @@ test('should open trace-1.31', async ({ showTraceViewer }) => {
|
||||||
await expect(snapshot.locator('[__playwright_target__]')).toHaveText(['Submit']);
|
await expect(snapshot.locator('[__playwright_target__]')).toHaveText(['Submit']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should prefer later resource request', async ({ page, server, runAndTrace }) => {
|
test('should prefer later resource request with the same method', async ({ page, server, runAndTrace }) => {
|
||||||
const html = `
|
const html = `
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -862,13 +862,22 @@ test('should prefer later resource request', async ({ page, server, runAndTrace
|
||||||
|
|
||||||
if (!window.location.href.includes('reloaded'))
|
if (!window.location.href.includes('reloaded'))
|
||||||
window.location.href = window.location.href + '?reloaded';
|
window.location.href = window.location.href + '?reloaded';
|
||||||
|
else
|
||||||
|
link.onload = () => fetch('style.css', { method: 'HEAD' });
|
||||||
</script>
|
</script>
|
||||||
|
<div>Hello</div>
|
||||||
</body>
|
</body>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
let reloadStartedCallback = () => {};
|
let reloadStartedCallback = () => {};
|
||||||
const reloadStartedPromise = new Promise<void>(f => reloadStartedCallback = f);
|
const reloadStartedPromise = new Promise<void>(f => reloadStartedCallback = f);
|
||||||
server.setRoute('/style.css', async (req, res) => {
|
server.setRoute('/style.css', async (req, res) => {
|
||||||
|
if (req.method === 'HEAD') {
|
||||||
|
res.statusCode = 200;
|
||||||
|
res.end('');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure reload happens before style arrives.
|
// Make sure reload happens before style arrives.
|
||||||
await reloadStartedPromise;
|
await reloadStartedPromise;
|
||||||
res.end('body { background-color: rgb(123, 123, 123) }');
|
res.end('body { background-color: rgb(123, 123, 123) }');
|
||||||
|
|
@ -880,8 +889,13 @@ test('should prefer later resource request', async ({ page, server, runAndTrace
|
||||||
});
|
});
|
||||||
|
|
||||||
const traceViewer = await runAndTrace(async () => {
|
const traceViewer = await runAndTrace(async () => {
|
||||||
|
const headRequest = page.waitForRequest(req => req.url() === server.PREFIX + '/style.css' && req.method() === 'HEAD');
|
||||||
await page.goto(server.PREFIX + '/index.html');
|
await page.goto(server.PREFIX + '/index.html');
|
||||||
|
await headRequest;
|
||||||
|
await page.locator('div').click();
|
||||||
});
|
});
|
||||||
const frame = await traceViewer.snapshotFrame('page.goto');
|
const frame1 = await traceViewer.snapshotFrame('page.goto');
|
||||||
await expect(frame.locator('body')).toHaveCSS('background-color', 'rgb(123, 123, 123)');
|
await expect(frame1.locator('body')).toHaveCSS('background-color', 'rgb(123, 123, 123)');
|
||||||
|
const frame2 = await traceViewer.snapshotFrame('locator.click');
|
||||||
|
await expect(frame2.locator('body')).toHaveCSS('background-color', 'rgb(123, 123, 123)');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -112,8 +112,8 @@ test('should not include buffers in the trace', async ({ context, page, server,
|
||||||
await page.goto(server.PREFIX + '/empty.html');
|
await page.goto(server.PREFIX + '/empty.html');
|
||||||
await page.screenshot();
|
await page.screenshot();
|
||||||
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
|
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
|
||||||
const { events } = await parseTraceRaw(testInfo.outputPath('trace.zip'));
|
const { actionObjects } = await parseTraceRaw(testInfo.outputPath('trace.zip'));
|
||||||
const screenshotEvent = events.find(e => e.type === 'action' && e.apiName === 'page.screenshot');
|
const screenshotEvent = actionObjects.find(a => a.apiName === 'page.screenshot');
|
||||||
expect(screenshotEvent.beforeSnapshot).toBeTruthy();
|
expect(screenshotEvent.beforeSnapshot).toBeTruthy();
|
||||||
expect(screenshotEvent.afterSnapshot).toBeTruthy();
|
expect(screenshotEvent.afterSnapshot).toBeTruthy();
|
||||||
expect(screenshotEvent.result).toEqual({});
|
expect(screenshotEvent.result).toEqual({});
|
||||||
|
|
@ -526,7 +526,7 @@ test('should hide internal stack frames', async ({ context, page }, testInfo) =>
|
||||||
await context.tracing.stop({ path: tracePath });
|
await context.tracing.stop({ path: tracePath });
|
||||||
|
|
||||||
const trace = await parseTraceRaw(tracePath);
|
const trace = await parseTraceRaw(tracePath);
|
||||||
const actions = trace.events.filter(e => e.type === 'action' && !e.apiName.startsWith('tracing.'));
|
const actions = trace.actionObjects.filter(a => !a.apiName.startsWith('tracing.'));
|
||||||
expect(actions).toHaveLength(4);
|
expect(actions).toHaveLength(4);
|
||||||
for (const action of actions)
|
for (const action of actions)
|
||||||
expect(relativeStack(action, trace.stacks)).toEqual(['tracing.spec.ts']);
|
expect(relativeStack(action, trace.stacks)).toEqual(['tracing.spec.ts']);
|
||||||
|
|
@ -547,7 +547,7 @@ test('should hide internal stack frames in expect', async ({ context, page }, te
|
||||||
await context.tracing.stop({ path: tracePath });
|
await context.tracing.stop({ path: tracePath });
|
||||||
|
|
||||||
const trace = await parseTraceRaw(tracePath);
|
const trace = await parseTraceRaw(tracePath);
|
||||||
const actions = trace.events.filter(e => e.type === 'action' && !e.apiName.startsWith('tracing.'));
|
const actions = trace.actionObjects.filter(a => !a.apiName.startsWith('tracing.'));
|
||||||
expect(actions).toHaveLength(5);
|
expect(actions).toHaveLength(5);
|
||||||
for (const action of actions)
|
for (const action of actions)
|
||||||
expect(relativeStack(action, trace.stacks)).toEqual(['tracing.spec.ts']);
|
expect(relativeStack(action, trace.stacks)).toEqual(['tracing.spec.ts']);
|
||||||
|
|
@ -703,6 +703,66 @@ test('should flush console events on tracing stop', async ({ context, page }, te
|
||||||
expect(events).toHaveLength(100);
|
expect(events).toHaveLength(100);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should not emit after w/o before', async ({ browserType, mode }, testInfo) => {
|
||||||
|
test.skip(mode === 'service', 'Service ignores tracesDir');
|
||||||
|
|
||||||
|
const tracesDir = testInfo.outputPath('traces');
|
||||||
|
const browser = await browserType.launch({ tracesDir });
|
||||||
|
const context = await browser.newContext();
|
||||||
|
const page = await context.newPage();
|
||||||
|
|
||||||
|
await context.tracing.start({ name: 'name1', snapshots: true });
|
||||||
|
const evaluatePromise = page.evaluate(() => new Promise(f => (window as any).callback = f)).catch(() => {});
|
||||||
|
await context.tracing.stopChunk({ path: testInfo.outputPath('trace1.zip') });
|
||||||
|
expect(fs.existsSync(path.join(tracesDir, 'name1.trace'))).toBe(true);
|
||||||
|
|
||||||
|
await context.tracing.startChunk({ name: 'name2' });
|
||||||
|
await page.evaluateHandle(() => (window as any).callback());
|
||||||
|
await evaluatePromise;
|
||||||
|
await context.tracing.stop({ path: testInfo.outputPath('trace2.zip') });
|
||||||
|
expect(fs.existsSync(path.join(tracesDir, 'name2.trace'))).toBe(true);
|
||||||
|
|
||||||
|
await browser.close();
|
||||||
|
let minCallId = 100000;
|
||||||
|
const sanitize = (e: any) => {
|
||||||
|
if (e.type === 'after' || e.type === 'before') {
|
||||||
|
minCallId = Math.min(minCallId, +e.callId.split('@')[1]);
|
||||||
|
return {
|
||||||
|
type: e.type,
|
||||||
|
callId: +e.callId.split('@')[1] - minCallId,
|
||||||
|
apiName: e.apiName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
const { events } = await parseTraceRaw(testInfo.outputPath('trace1.zip'));
|
||||||
|
expect(events.map(sanitize).filter(Boolean)).toEqual([
|
||||||
|
{
|
||||||
|
type: 'before',
|
||||||
|
callId: 0,
|
||||||
|
apiName: 'page.evaluate'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const { events } = await parseTraceRaw(testInfo.outputPath('trace2.zip'));
|
||||||
|
expect(events.map(sanitize).filter(Boolean)).toEqual([
|
||||||
|
{
|
||||||
|
type: 'before',
|
||||||
|
callId: 6,
|
||||||
|
apiName: 'page.evaluateHandle'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'after',
|
||||||
|
callId: 6,
|
||||||
|
apiName: undefined
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function expectRed(pixels: Buffer, offset: number) {
|
function expectRed(pixels: Buffer, offset: number) {
|
||||||
const r = pixels.readUInt8(offset);
|
const r = pixels.readUInt8(offset);
|
||||||
const g = pixels.readUInt8(offset + 1);
|
const g = pixels.readUInt8(offset + 1);
|
||||||
|
|
|
||||||
|
|
@ -91,12 +91,14 @@ it('should work with glob', async () => {
|
||||||
expect(globToRegex('http://localhost:3000/signin-oidc*').test('http://localhost:3000/signin-oidc/foo')).toBeFalsy();
|
expect(globToRegex('http://localhost:3000/signin-oidc*').test('http://localhost:3000/signin-oidc/foo')).toBeFalsy();
|
||||||
expect(globToRegex('http://localhost:3000/signin-oidc*').test('http://localhost:3000/signin-oidcnice')).toBeTruthy();
|
expect(globToRegex('http://localhost:3000/signin-oidc*').test('http://localhost:3000/signin-oidcnice')).toBeTruthy();
|
||||||
|
|
||||||
|
expect(globToRegex('**/three-columns/settings.html?**id=[a-z]**').test('http://mydomain:8080/blah/blah/three-columns/settings.html?id=settings-e3c58efe-02e9-44b0-97ac-dd138100cf7c&blah')).toBeTruthy();
|
||||||
|
|
||||||
expect(globToRegex('\\?')).toEqual(/^\?$/);
|
expect(globToRegex('\\?')).toEqual(/^\?$/);
|
||||||
expect(globToRegex('\\')).toEqual(/^\\$/);
|
expect(globToRegex('\\')).toEqual(/^\\$/);
|
||||||
expect(globToRegex('\\\\')).toEqual(/^\\$/);
|
expect(globToRegex('\\\\')).toEqual(/^\\$/);
|
||||||
expect(globToRegex('\\[')).toEqual(/^\[$/);
|
expect(globToRegex('\\[')).toEqual(/^\[$/);
|
||||||
expect(globToRegex('[')).toEqual(/^\[$/);
|
expect(globToRegex('[a-z]')).toEqual(/^[a-z]$/);
|
||||||
expect(globToRegex('$^+.\\*()|\\?\\{\\}[]')).toEqual(/^\$\^\+\.\*\(\)\|\?\{\}\[\]$/);
|
expect(globToRegex('$^+.\\*()|\\?\\{\\}\\[\\]')).toEqual(/^\$\^\+\.\*\(\)\|\?\{\}\[\]$/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should intercept network activity from worker', async function({ page, server, isAndroid, browserName, browserMajorVersion }) {
|
it('should intercept network activity from worker', async function({ page, server, isAndroid, browserName, browserMajorVersion }) {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ const testFiles = {
|
||||||
await page.click('text=Click me');
|
await page.click('text=Click me');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('shared failing', async ({ }) => {
|
test('shared failing', async ({ }) => {
|
||||||
await page.click('text=And me');
|
await page.click('text=And me');
|
||||||
expect(1).toBe(2);
|
expect(1).toBe(2);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -235,7 +235,7 @@ test(`testInfo.attach name should be sanitized`, async ({ runInlineTest }) => {
|
||||||
expect(result.failed).toBe(1);
|
expect(result.failed).toBe(1);
|
||||||
|
|
||||||
expect(result.output).toContain('attachment #1: ../../../test (text/plain)');
|
expect(result.output).toContain('attachment #1: ../../../test (text/plain)');
|
||||||
expect(result.output).toContain(`attachments${path.sep}test-8d909b-`);
|
expect(result.output).toContain(`attachments${path.sep}-test`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test(`testInfo.attach name can be empty string`, async ({ runInlineTest }) => {
|
test(`testInfo.attach name can be empty string`, async ({ runInlineTest }) => {
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ test('should use project name', async ({ runInlineTest }, testInfo) => {
|
||||||
test('passes', async ({ page }, testInfo) => {});
|
test('passes', async ({ page }, testInfo) => {});
|
||||||
`,
|
`,
|
||||||
}, { reporter: 'dot,' + kRawReporterPath });
|
}, { reporter: 'dot,' + kRawReporterPath });
|
||||||
const json = JSON.parse(fs.readFileSync(testInfo.outputPath('output', 'report', 'project-name-656a9b.report'), 'utf-8'));
|
const json = JSON.parse(fs.readFileSync(testInfo.outputPath('output', 'report', 'project-name.report'), 'utf-8'));
|
||||||
expect(json.project.name).toBe('project-name');
|
expect(json.project.name).toBe('project-name');
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
@ -173,7 +173,7 @@ test(`testInfo.attach should save attachments via path`, async ({ runInlineTest
|
||||||
expect(result.attachments[0].name).toBe('example.png');
|
expect(result.attachments[0].name).toBe('example.png');
|
||||||
expect(result.attachments[0].contentType).toBe('x-playwright/custom');
|
expect(result.attachments[0].contentType).toBe('x-playwright/custom');
|
||||||
const p = result.attachments[0].path;
|
const p = result.attachments[0].path;
|
||||||
expect(p).toMatch(/[/\\]attachments[/\\]example-png-[0-9a-f]{6}-[0-9a-f]+\.json$/);
|
expect(p).toMatch(/[/\\]attachments[/\\]example-png-[0-9a-f]+\.json$/);
|
||||||
const contents = fs.readFileSync(p);
|
const contents = fs.readFileSync(p);
|
||||||
expect(contents.toString()).toBe('We <3 Playwright!');
|
expect(contents.toString()).toBe('We <3 Playwright!');
|
||||||
}
|
}
|
||||||
|
|
@ -255,5 +255,5 @@ test('dupe project names', async ({ runInlineTest }, testInfo) => {
|
||||||
`,
|
`,
|
||||||
}, { reporter: 'dot,' + kRawReporterPath });
|
}, { reporter: 'dot,' + kRawReporterPath });
|
||||||
const files = fs.readdirSync(testInfo.outputPath('test-results', 'report'));
|
const files = fs.readdirSync(testInfo.outputPath('test-results', 'report'));
|
||||||
expect(new Set(files)).toEqual(new Set(['project-name-656a9b.report', 'project-name-656a9b-1.report', 'project-name-656a9b-2.report']));
|
expect(new Set(files)).toEqual(new Set(['project-name.report', 'project-name-1.report', 'project-name-2.report']));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -194,10 +194,10 @@ test('should include the project name', async ({ runInlineTest }) => {
|
||||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-foo.txt');
|
expect(result.output).toContain('my-test.spec.js-snapshots/bar-foo.txt');
|
||||||
|
|
||||||
// test1, run with bar
|
// test1, run with bar
|
||||||
expect(result.output).toContain('test-results/my-test-test-1-Bar-space-dc1461/bar.txt');
|
expect(result.output).toContain('test-results/my-test-test-1-Bar-space-/bar.txt');
|
||||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-dc1461.txt');
|
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-.txt');
|
||||||
expect(result.output).toContain('test-results/my-test-test-1-Bar-space-dc1461-retry1/bar.txt');
|
expect(result.output).toContain('test-results/my-test-test-1-Bar-space--retry1/bar.txt');
|
||||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-dc1461.txt');
|
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-.txt');
|
||||||
|
|
||||||
// test2, run with empty
|
// test2, run with empty
|
||||||
expect(result.output).toContain('test-results/my-test-test-2/bar.txt');
|
expect(result.output).toContain('test-results/my-test-test-2/bar.txt');
|
||||||
|
|
@ -212,8 +212,8 @@ test('should include the project name', async ({ runInlineTest }) => {
|
||||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-foo-suffix.txt');
|
expect(result.output).toContain('my-test.spec.js-snapshots/bar-foo-suffix.txt');
|
||||||
|
|
||||||
// test2, run with bar
|
// test2, run with bar
|
||||||
expect(result.output).toContain('test-results/my-test-test-2-Bar-space-dc1461/bar.txt');
|
expect(result.output).toContain('test-results/my-test-test-2-Bar-space-/bar.txt');
|
||||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-dc1461-suffix.txt');
|
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space--suffix.txt');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should include path option in snapshot', async ({ runInlineTest }) => {
|
test('should include path option in snapshot', async ({ runInlineTest }) => {
|
||||||
|
|
@ -401,58 +401,6 @@ test('should allow nonAscii characters in the output dir', async ({ runInlineTes
|
||||||
expect(outputDir).toBe(path.join(testInfo.outputDir, 'test-results', 'my-test-こんにちは世界'));
|
expect(outputDir).toBe(path.join(testInfo.outputDir, 'test-results', 'my-test-こんにちは世界'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not collide with other tests when nonAscii characters are replaced', async ({ runInlineTest }) => {
|
|
||||||
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/23386' });
|
|
||||||
const result = await runInlineTest({
|
|
||||||
'my-test.spec.js': `
|
|
||||||
import { test, expect } from '@playwright/test';
|
|
||||||
const specialChars = ['>', '=', '<', '+', '#', '-', '.', '!', '$', '%', '&', '\\'', '*', '/', '?', '^', '_', '\`', '{', '|', '}', '~', '(', ')', '[', ']', '@'];
|
|
||||||
for (const char of specialChars) {
|
|
||||||
test('test' + char, async ({}, testInfo) => {
|
|
||||||
console.log('\\n%%' + testInfo.outputDir);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
});
|
|
||||||
expect(result.exitCode).toBe(0);
|
|
||||||
const outputDirs = result.outputLines;
|
|
||||||
expect(outputDirs.length).toBe(27);
|
|
||||||
expect(new Set(outputDirs).size).toBe(outputDirs.length);
|
|
||||||
const forbiddenCharacters = ['\\', '/', ':', '*', '?', '"', '<', '>', '|', '%'];
|
|
||||||
for (const outputDir of outputDirs) {
|
|
||||||
const relativePath = path.relative(path.join(test.info().outputDir, 'test-results'), outputDir);
|
|
||||||
for (const forbiddenCharacter of forbiddenCharacters)
|
|
||||||
expect(relativePath).not.toContain(forbiddenCharacter);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should generate expected output dir names', async ({ runInlineTest }, testInfo) => {
|
|
||||||
const runTests = async (fileName: string, testNames: string[]) => {
|
|
||||||
const result = await runInlineTest({
|
|
||||||
[fileName]: `
|
|
||||||
import { test, expect } from '@playwright/test';
|
|
||||||
${testNames.map(name => `test('${name}', async ({}, testInfo) => console.log('\\n%%' + testInfo.outputDir));`).join('\n')}
|
|
||||||
`,
|
|
||||||
});
|
|
||||||
expect(result.exitCode).toBe(0);
|
|
||||||
const outputDirs = result.outputLines.map(line => path.relative(path.join(testInfo.outputDir, 'test-results'), line));
|
|
||||||
return outputDirs;
|
|
||||||
};
|
|
||||||
expect(await runTests('filename.spec.js', [
|
|
||||||
'testing > foo',
|
|
||||||
'testing multiple spaces',
|
|
||||||
'testing multiple spaces',
|
|
||||||
'!!!hello!!!',
|
|
||||||
'dashes-are-used',
|
|
||||||
])).toEqual([
|
|
||||||
'filename-testing-foo-574286',
|
|
||||||
'filename-testing-multiple-spaces',
|
|
||||||
'filename-testing-multiple-spaces-f5d359',
|
|
||||||
'filename-hello-8eb257',
|
|
||||||
'filename-dashes-are-used-c67e31',
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should allow shorten long output dirs characters in the output dir', async ({ runInlineTest }, testInfo) => {
|
test('should allow shorten long output dirs characters in the output dir', async ({ runInlineTest }, testInfo) => {
|
||||||
const result = await runInlineTest({
|
const result = await runInlineTest({
|
||||||
'very/deep/and/long/file/name/that/i/want/to/be/trimmed/my-test.spec.js': `
|
'very/deep/and/long/file/name/that/i/want/to/be/trimmed/my-test.spec.js': `
|
||||||
|
|
@ -478,7 +426,7 @@ test('should not mangle double dashes', async ({ runInlineTest }, testInfo) => {
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
const outputDir = result.outputLines[0];
|
const outputDir = result.outputLines[0];
|
||||||
expect(outputDir).toBe(path.join(testInfo.outputDir, 'test-results', 'my--file-my-test-68b7dd'));
|
expect(outputDir).toBe(path.join(testInfo.outputDir, 'test-results', 'my--file-my--test'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should allow include the describe name the output dir', async ({ runInlineTest }, testInfo) => {
|
test('should allow include the describe name the output dir', async ({ runInlineTest }, testInfo) => {
|
||||||
|
|
|
||||||
|
|
@ -283,6 +283,7 @@ test('should support clip option for page', async ({ runInlineTest }, testInfo)
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
});
|
});
|
||||||
|
expect(fs.existsSync(testInfo.outputPath('test-results', 'a-is-a-test'))).toBe(false);
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue