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
|
||||
|
||||
[](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)
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
|
|||
| | Linux | macOS | Windows |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| 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: |
|
||||
|
||||
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
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
### Highlights
|
||||
|
|
|
|||
|
|
@ -12,6 +12,21 @@ toc_max_heading_level: 2
|
|||
|
||||
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
|
||||
|
||||
### Highlights
|
||||
|
|
|
|||
|
|
@ -6,6 +6,21 @@ toc_max_heading_level: 2
|
|||
|
||||
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
|
||||
|
||||
<LiteYouTube
|
||||
|
|
|
|||
|
|
@ -4,6 +4,21 @@ title: "Release notes"
|
|||
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
|
||||
|
||||
### Highlights
|
||||
|
|
|
|||
82
package-lock.json
generated
82
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "playwright-internal",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "playwright-internal",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"workspaces": [
|
||||
"packages/*"
|
||||
|
|
@ -6191,11 +6191,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright": {
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6205,11 +6205,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-chromium": {
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6219,7 +6219,7 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-core": {
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
|
|
@ -6230,11 +6230,11 @@
|
|||
},
|
||||
"packages/playwright-ct-core": {
|
||||
"name": "@playwright/experimental-ct-core",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/test": "1.36.0-next",
|
||||
"playwright-core": "1.36.0-next",
|
||||
"@playwright/test": "1.36.2",
|
||||
"playwright-core": "1.36.2",
|
||||
"vite": "^4.3.9"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6246,10 +6246,10 @@
|
|||
},
|
||||
"packages/playwright-ct-react": {
|
||||
"name": "@playwright/experimental-ct-react",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6278,10 +6278,10 @@
|
|||
},
|
||||
"packages/playwright-ct-react17": {
|
||||
"name": "@playwright/experimental-ct-react17",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6310,10 +6310,10 @@
|
|||
},
|
||||
"packages/playwright-ct-solid": {
|
||||
"name": "@playwright/experimental-ct-solid",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6328,10 +6328,10 @@
|
|||
},
|
||||
"packages/playwright-ct-svelte": {
|
||||
"name": "@playwright/experimental-ct-svelte",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6346,10 +6346,10 @@
|
|||
},
|
||||
"packages/playwright-ct-vue": {
|
||||
"name": "@playwright/experimental-ct-vue",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-vue": "^4.2.1"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6397,10 +6397,10 @@
|
|||
},
|
||||
"packages/playwright-ct-vue2": {
|
||||
"name": "@playwright/experimental-ct-vue2",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-vue2": "^2.2.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
@ -6414,11 +6414,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-firefox": {
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6429,11 +6429,11 @@
|
|||
},
|
||||
"packages/playwright-test": {
|
||||
"name": "@playwright/test",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -6446,11 +6446,11 @@
|
|||
}
|
||||
},
|
||||
"packages/playwright-webkit": {
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
|
|
@ -7260,15 +7260,15 @@
|
|||
"@playwright/experimental-ct-core": {
|
||||
"version": "file:packages/playwright-ct-core",
|
||||
"requires": {
|
||||
"@playwright/test": "1.36.0-next",
|
||||
"playwright-core": "1.36.0-next",
|
||||
"@playwright/test": "1.36.2",
|
||||
"playwright-core": "1.36.2",
|
||||
"vite": "^4.3.9"
|
||||
}
|
||||
},
|
||||
"@playwright/experimental-ct-react": {
|
||||
"version": "file:packages/playwright-ct-react",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -7288,7 +7288,7 @@
|
|||
"@playwright/experimental-ct-react17": {
|
||||
"version": "file:packages/playwright-ct-react17",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -7308,7 +7308,7 @@
|
|||
"@playwright/experimental-ct-solid": {
|
||||
"version": "file:packages/playwright-ct-solid",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"solid-js": "^1.7.0",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
}
|
||||
|
|
@ -7316,7 +7316,7 @@
|
|||
"@playwright/experimental-ct-svelte": {
|
||||
"version": "file:packages/playwright-ct-svelte",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.1.1",
|
||||
"svelte": "^3.55.1"
|
||||
}
|
||||
|
|
@ -7324,7 +7324,7 @@
|
|||
"@playwright/experimental-ct-vue": {
|
||||
"version": "file:packages/playwright-ct-vue",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-vue": "^4.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
@ -7358,7 +7358,7 @@
|
|||
"@playwright/experimental-ct-vue2": {
|
||||
"version": "file:packages/playwright-ct-vue2",
|
||||
"requires": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-vue2": "^2.2.0",
|
||||
"vue": "^2.7.14"
|
||||
}
|
||||
|
|
@ -7368,7 +7368,7 @@
|
|||
"requires": {
|
||||
"@types/node": "*",
|
||||
"fsevents": "2.3.2",
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
|
|
@ -9656,13 +9656,13 @@
|
|||
"playwright": {
|
||||
"version": "file:packages/playwright",
|
||||
"requires": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
},
|
||||
"playwright-chromium": {
|
||||
"version": "file:packages/playwright-chromium",
|
||||
"requires": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
|
|
@ -9671,13 +9671,13 @@
|
|||
"playwright-firefox": {
|
||||
"version": "file:packages/playwright-firefox",
|
||||
"requires": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
},
|
||||
"playwright-webkit": {
|
||||
"version": "file:packages/playwright-webkit",
|
||||
"requires": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "playwright-internal",
|
||||
"private": true,
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-chromium",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "A high-level API to automate Chromium",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,6 +27,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
"mac11-arm64": "1816",
|
||||
"ubuntu18.04": "1728"
|
||||
},
|
||||
"browserVersion": "16.4"
|
||||
"browserVersion": "17.0"
|
||||
},
|
||||
{
|
||||
"name": "ffmpeg",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-core",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"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": {
|
||||
"width": 600,
|
||||
"height": 1024
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 1024,
|
||||
"height": 600
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -44,7 +44,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -66,7 +66,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -77,7 +77,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 360,
|
||||
"height": 640
|
||||
|
|
@ -99,7 +99,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 640,
|
||||
"height": 360
|
||||
|
|
@ -198,7 +198,7 @@
|
|||
"defaultBrowserType": "chromium"
|
||||
},
|
||||
"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": {
|
||||
"width": 768,
|
||||
"height": 1024
|
||||
|
|
@ -209,7 +209,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 1024,
|
||||
"height": 768
|
||||
|
|
@ -220,7 +220,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 810,
|
||||
"height": 1080
|
||||
|
|
@ -231,7 +231,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 1080,
|
||||
"height": 810
|
||||
|
|
@ -242,7 +242,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 768,
|
||||
"height": 1024
|
||||
|
|
@ -253,7 +253,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 1024,
|
||||
"height": 768
|
||||
|
|
@ -264,7 +264,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 834,
|
||||
"height": 1194
|
||||
|
|
@ -275,7 +275,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 1194,
|
||||
"height": 834
|
||||
|
|
@ -286,7 +286,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 667
|
||||
|
|
@ -297,7 +297,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 667,
|
||||
"height": 375
|
||||
|
|
@ -308,7 +308,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 736
|
||||
|
|
@ -319,7 +319,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 736,
|
||||
"height": 414
|
||||
|
|
@ -330,7 +330,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 667
|
||||
|
|
@ -341,7 +341,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 667,
|
||||
"height": 375
|
||||
|
|
@ -352,7 +352,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 736
|
||||
|
|
@ -363,7 +363,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 736,
|
||||
"height": 414
|
||||
|
|
@ -374,7 +374,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 667
|
||||
|
|
@ -385,7 +385,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 667,
|
||||
"height": 375
|
||||
|
|
@ -396,7 +396,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 736
|
||||
|
|
@ -407,7 +407,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 736,
|
||||
"height": 414
|
||||
|
|
@ -418,7 +418,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 320,
|
||||
"height": 568
|
||||
|
|
@ -429,7 +429,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 568,
|
||||
"height": 320
|
||||
|
|
@ -440,7 +440,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -451,7 +451,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 812,
|
||||
"height": 375
|
||||
|
|
@ -462,7 +462,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -473,7 +473,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 896,
|
||||
"height": 414
|
||||
|
|
@ -484,7 +484,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -499,7 +499,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -514,7 +514,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -529,7 +529,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -544,7 +544,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -559,7 +559,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 414,
|
||||
"height": 896
|
||||
|
|
@ -574,7 +574,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -589,7 +589,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -604,7 +604,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -619,7 +619,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -634,7 +634,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -649,7 +649,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -664,7 +664,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -679,7 +679,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -694,7 +694,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -709,7 +709,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -724,7 +724,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -739,7 +739,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 390,
|
||||
"height": 844
|
||||
|
|
@ -754,7 +754,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -769,7 +769,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 428,
|
||||
"height": 926
|
||||
|
|
@ -784,7 +784,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -799,7 +799,7 @@
|
|||
"defaultBrowserType": "webkit"
|
||||
},
|
||||
"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": {
|
||||
"width": 375,
|
||||
"height": 812
|
||||
|
|
@ -1315,7 +1315,7 @@
|
|||
"defaultBrowserType": "firefox"
|
||||
},
|
||||
"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": {
|
||||
"width": 1792,
|
||||
"height": 1120
|
||||
|
|
|
|||
|
|
@ -437,6 +437,12 @@ export class HarTracer {
|
|||
const pageEntry = this._createPageEntryIfNeeded(page);
|
||||
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 = {
|
||||
status: response.status(),
|
||||
statusText: response.statusText(),
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ type RecordingState = {
|
|||
networkSha1s: Set<string>,
|
||||
traceSha1s: Set<string>,
|
||||
recording: boolean;
|
||||
callIds: Set<string>;
|
||||
};
|
||||
|
||||
const kScreencastOptions = { width: 800, height: 600, quality: 90 };
|
||||
|
|
@ -146,7 +147,8 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||
chunkOrdinal: 0,
|
||||
traceSha1s: new Set(),
|
||||
networkSha1s: new Set(),
|
||||
recording: false
|
||||
recording: false,
|
||||
callIds: new Set(),
|
||||
};
|
||||
const state = this._state;
|
||||
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: [],
|
||||
};
|
||||
state.recording = true;
|
||||
state.callIds.clear();
|
||||
|
||||
if (options.name && options.name !== this._state.traceName)
|
||||
this._changeTraceName(this._state, options.name);
|
||||
|
|
@ -352,11 +355,14 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||
return Promise.resolve();
|
||||
sdkObject.attribution.page?.temporarlyDisableTracingScreencastThrottling();
|
||||
event.beforeSnapshot = `before@${metadata.id}`;
|
||||
this._state?.callIds.add(metadata.id);
|
||||
this._appendTraceEvent(event);
|
||||
return this._captureSnapshot(event.beforeSnapshot, sdkObject, metadata);
|
||||
}
|
||||
|
||||
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.
|
||||
const event = createInputActionTraceEvent(metadata);
|
||||
if (!event)
|
||||
|
|
@ -368,9 +374,12 @@ export class Tracing extends SdkObject implements InstrumentationListener, Snaps
|
|||
}
|
||||
|
||||
async onAfterCall(sdkObject: SdkObject, metadata: CallMetadata) {
|
||||
if (!this._state?.callIds.has(metadata.id))
|
||||
return;
|
||||
this._state?.callIds.delete(metadata.id);
|
||||
const event = createAfterActionTraceEvent(metadata);
|
||||
if (!event)
|
||||
return Promise.resolve();
|
||||
return;
|
||||
sdkObject.attribution.page?.temporarlyDisableTracingScreencastThrottling();
|
||||
event.afterSnapshot = `after@${metadata.id}`;
|
||||
this._appendTraceEvent(event);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@ import { WKPage } from './wkPage';
|
|||
import { kBrowserClosedError } from '../../common/errors';
|
||||
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 BROWSER_VERSION = '16.4';
|
||||
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 = '17.0';
|
||||
|
||||
export class WKBrowser extends Browser {
|
||||
private readonly _connection: WKConnection;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ export function globToRegex(glob: string): RegExp {
|
|||
case '?':
|
||||
tokens.push('.');
|
||||
break;
|
||||
case '[':
|
||||
tokens.push('[');
|
||||
break;
|
||||
case ']':
|
||||
tokens.push(']');
|
||||
break;
|
||||
case '{':
|
||||
inGroup = true;
|
||||
tokens.push('(');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-core",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "Playwright Component Testing Helpers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -21,9 +21,9 @@
|
|||
"./lib/vitePlugin": "./lib/vitePlugin.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next",
|
||||
"playwright-core": "1.36.2",
|
||||
"vite": "^4.3.9",
|
||||
"@playwright/test": "1.36.0-next"
|
||||
"@playwright/test": "1.36.2"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "./cli.js"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-react",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "Playwright Component Testing for React",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-react17",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "Playwright Component Testing for React",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-react": "^4.0.0"
|
||||
},
|
||||
"bin": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-solid",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "Playwright Component Testing for Solid",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"vite-plugin-solid": "^2.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-svelte",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "Playwright Component Testing for Svelte",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-vue",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "Playwright Component Testing for Vue",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-vue": "^4.2.1"
|
||||
},
|
||||
"bin": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/experimental-ct-vue2",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "Playwright Component Testing for Vue2",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@playwright/experimental-ct-core": "1.36.0-next",
|
||||
"@playwright/experimental-ct-core": "1.36.2",
|
||||
"@vitejs/plugin-vue2": "^2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-firefox",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "A high-level API to automate Firefox",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,6 +27,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@playwright/test",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"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 type { PageScreenshotOptions } from 'playwright-core/types/types';
|
||||
import {
|
||||
serializeError, sanitizeForFilePath,
|
||||
addSuffixToFilePath, serializeError, sanitizeForFilePath,
|
||||
trimLongString, callLogText,
|
||||
expectTypes } from '../util';
|
||||
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 outputPathSegments = Array.isArray(name) ? name : [addSuffixToFilePath(name, actualModifier, undefined, true)];
|
||||
this.snapshotPath = snapshotPathResolver(...inputPathSegments);
|
||||
const inputFile = testInfo.outputPath(...inputPathSegments);
|
||||
const outputFile = testInfo.outputPath(...outputPathSegments);
|
||||
const inputFile = testInfo._getOutputPath(...inputPathSegments);
|
||||
const outputFile = testInfo._getOutputPath(...outputPathSegments);
|
||||
this.expectedPath = addSuffixToFilePath(inputFile, '-expected');
|
||||
this.previousPath = addSuffixToFilePath(outputFile, '-previous');
|
||||
this.actualPath = addSuffixToFilePath(outputFile, '-actual');
|
||||
|
|
@ -440,14 +440,3 @@ function determineFileExtension(file: string | Buffer): string {
|
|||
function compareMagicBytes(file: Buffer, magicBytes: number[]): boolean {
|
||||
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) {
|
||||
let nonTrivialSubstitute = false;
|
||||
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 sanitizeForFilePath(s: string) {
|
||||
return s.replace(/[\x00-\x2C\x2E-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+/g, '-');
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -382,7 +382,12 @@ export class TestInfoImpl implements TestInfo {
|
|||
}
|
||||
|
||||
outputPath(...pathSegments: string[]){
|
||||
const outputPath = this._getOutputPath(...pathSegments);
|
||||
fs.mkdirSync(this.outputDir, { recursive: true });
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
_getOutputPath(...pathSegments: string[]){
|
||||
const joinedPath = path.join(...pathSegments);
|
||||
const outputPath = getContainedPath(this.outputDir, joinedPath);
|
||||
if (outputPath)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright-webkit",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "A high-level API to automate WebKit",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -27,6 +27,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"playwright-core": "1.36.0-next"
|
||||
"playwright-core": "1.36.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "playwright",
|
||||
"version": "1.36.0-next",
|
||||
"version": "1.36.2",
|
||||
"description": "A high-level API to automate web browsers",
|
||||
"repository": "github:Microsoft/playwright",
|
||||
"homepage": "https://playwright.dev",
|
||||
|
|
@ -28,6 +28,6 @@
|
|||
"install": "node install.js"
|
||||
},
|
||||
"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 };
|
||||
}
|
||||
|
||||
resourceByUrl(url: string): ResourceSnapshot | undefined {
|
||||
resourceByUrl(url: string, method: string): ResourceSnapshot | undefined {
|
||||
const snapshot = this._snapshot;
|
||||
let result: ResourceSnapshot | undefined;
|
||||
|
||||
// First try locating exact resource belonging to this frame.
|
||||
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)
|
||||
break;
|
||||
if (resource._frameref !== snapshot.frameId)
|
||||
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
|
||||
// at the time of snapshot, not the earlier aborted resource with the same url.
|
||||
result = resource;
|
||||
|
|
@ -132,9 +134,11 @@ export class SnapshotRenderer {
|
|||
if (!result) {
|
||||
// Then fall back to resource with this URL to account for memory cache.
|
||||
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)
|
||||
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
|
||||
// at the time of snapshot, not the earlier aborted resource with the same url.
|
||||
result = resource;
|
||||
|
|
@ -142,7 +146,7 @@ export class SnapshotRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
if (result) {
|
||||
if (result && method.toUpperCase() === 'GET') {
|
||||
// Patch override if necessary.
|
||||
for (const o of snapshot.resourceOverrides) {
|
||||
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;
|
||||
const snapshot = this._snapshotIds.get(snapshotUrl)!;
|
||||
for (const requestUrl of requestUrlAlternatives) {
|
||||
resource = snapshot?.resourceByUrl(removeHash(requestUrl));
|
||||
resource = snapshot?.resourceByUrl(removeHash(requestUrl), method);
|
||||
if (resource)
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,4 +56,9 @@ export class SnapshotStorage {
|
|||
snapshotsForTest() {
|
||||
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];
|
||||
if (isDeployedAsHttps && request.url.startsWith('https://'))
|
||||
lookupUrls.push(request.url.replace(/^https/, 'http'));
|
||||
return snapshotServer.serveResource(lookupUrls, snapshotUrl);
|
||||
return snapshotServer.serveResource(lookupUrls, request.method, snapshotUrl);
|
||||
}
|
||||
|
||||
async function gc() {
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ export class TraceModel {
|
|||
|
||||
this.contextEntries.push(contextEntry);
|
||||
}
|
||||
|
||||
this._snapshotStorage!.finalize();
|
||||
}
|
||||
|
||||
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 resources = new Map<string, Buffer>();
|
||||
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')) {
|
||||
if (line) {
|
||||
const event = JSON.parse(line) as TraceEvent;
|
||||
events.push(event);
|
||||
|
||||
if (event.type === 'before') {
|
||||
const action: ActionTraceEvent = {
|
||||
...event,
|
||||
|
|
@ -118,7 +120,6 @@ export async function parseTraceRaw(file: string): Promise<{ events: any[], reso
|
|||
endTime: 0,
|
||||
log: []
|
||||
};
|
||||
events.push(action);
|
||||
actionMap.set(event.callId, action);
|
||||
} else if (event.type === 'input') {
|
||||
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.error = event.error;
|
||||
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);
|
||||
}
|
||||
|
||||
const actionObjects = [...actionMap.values()];
|
||||
actionObjects.sort((a, b) => a.startTime - b.startTime);
|
||||
return {
|
||||
events,
|
||||
resources,
|
||||
actions: eventsToActions(events),
|
||||
actions: actionObjects.map(a => a.apiName),
|
||||
actionObjects,
|
||||
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[] }> {
|
||||
const backend = new TraceBackend(file);
|
||||
const traceModel = new TraceModel();
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ it.describe('snapshots', () => {
|
|||
});
|
||||
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 resource = snapshot.resourceByUrl(`http://localhost:${server.PORT}/style.css`);
|
||||
const resource = snapshot.resourceByUrl(`http://localhost:${server.PORT}/style.css`, 'GET');
|
||||
expect(resource).toBeTruthy();
|
||||
});
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ it.describe('snapshots', () => {
|
|||
|
||||
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 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; }');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -851,7 +851,7 @@ test('should open trace-1.31', async ({ showTraceViewer }) => {
|
|||
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 = `
|
||||
<body>
|
||||
<script>
|
||||
|
|
@ -862,13 +862,22 @@ test('should prefer later resource request', async ({ page, server, runAndTrace
|
|||
|
||||
if (!window.location.href.includes('reloaded'))
|
||||
window.location.href = window.location.href + '?reloaded';
|
||||
else
|
||||
link.onload = () => fetch('style.css', { method: 'HEAD' });
|
||||
</script>
|
||||
<div>Hello</div>
|
||||
</body>
|
||||
`;
|
||||
|
||||
let reloadStartedCallback = () => {};
|
||||
const reloadStartedPromise = new Promise<void>(f => reloadStartedCallback = f);
|
||||
server.setRoute('/style.css', async (req, res) => {
|
||||
if (req.method === 'HEAD') {
|
||||
res.statusCode = 200;
|
||||
res.end('');
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure reload happens before style arrives.
|
||||
await reloadStartedPromise;
|
||||
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 headRequest = page.waitForRequest(req => req.url() === server.PREFIX + '/style.css' && req.method() === 'HEAD');
|
||||
await page.goto(server.PREFIX + '/index.html');
|
||||
await headRequest;
|
||||
await page.locator('div').click();
|
||||
});
|
||||
const frame = await traceViewer.snapshotFrame('page.goto');
|
||||
await expect(frame.locator('body')).toHaveCSS('background-color', 'rgb(123, 123, 123)');
|
||||
const frame1 = await traceViewer.snapshotFrame('page.goto');
|
||||
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.screenshot();
|
||||
await context.tracing.stop({ path: testInfo.outputPath('trace.zip') });
|
||||
const { events } = await parseTraceRaw(testInfo.outputPath('trace.zip'));
|
||||
const screenshotEvent = events.find(e => e.type === 'action' && e.apiName === 'page.screenshot');
|
||||
const { actionObjects } = await parseTraceRaw(testInfo.outputPath('trace.zip'));
|
||||
const screenshotEvent = actionObjects.find(a => a.apiName === 'page.screenshot');
|
||||
expect(screenshotEvent.beforeSnapshot).toBeTruthy();
|
||||
expect(screenshotEvent.afterSnapshot).toBeTruthy();
|
||||
expect(screenshotEvent.result).toEqual({});
|
||||
|
|
@ -526,7 +526,7 @@ test('should hide internal stack frames', async ({ context, page }, testInfo) =>
|
|||
await context.tracing.stop({ path: 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);
|
||||
for (const action of actions)
|
||||
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 });
|
||||
|
||||
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);
|
||||
for (const action of actions)
|
||||
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);
|
||||
});
|
||||
|
||||
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) {
|
||||
const r = pixels.readUInt8(offset);
|
||||
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-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('[a-z]')).toEqual(/^[a-z]$/);
|
||||
expect(globToRegex('$^+.\\*()|\\?\\{\\}\\[\\]')).toEqual(/^\$\^\+\.\*\(\)\|\?\{\}\[\]$/);
|
||||
});
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
test('shared failing', async ({ }) => {
|
||||
test('shared failing', async ({ }) => {
|
||||
await page.click('text=And me');
|
||||
expect(1).toBe(2);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ test(`testInfo.attach name should be sanitized`, async ({ runInlineTest }) => {
|
|||
expect(result.failed).toBe(1);
|
||||
|
||||
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 }) => {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ test('should use project name', async ({ runInlineTest }, testInfo) => {
|
|||
test('passes', async ({ page }, testInfo) => {});
|
||||
`,
|
||||
}, { 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(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].contentType).toBe('x-playwright/custom');
|
||||
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);
|
||||
expect(contents.toString()).toBe('We <3 Playwright!');
|
||||
}
|
||||
|
|
@ -255,5 +255,5 @@ test('dupe project names', async ({ runInlineTest }, testInfo) => {
|
|||
`,
|
||||
}, { reporter: 'dot,' + kRawReporterPath });
|
||||
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');
|
||||
|
||||
// test1, run with bar
|
||||
expect(result.output).toContain('test-results/my-test-test-1-Bar-space-dc1461/bar.txt');
|
||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-dc1461.txt');
|
||||
expect(result.output).toContain('test-results/my-test-test-1-Bar-space-dc1461-retry1/bar.txt');
|
||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-dc1461.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-.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-.txt');
|
||||
|
||||
// test2, run with empty
|
||||
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');
|
||||
|
||||
// test2, run with bar
|
||||
expect(result.output).toContain('test-results/my-test-test-2-Bar-space-dc1461/bar.txt');
|
||||
expect(result.output).toContain('my-test.spec.js-snapshots/bar-Bar-space-dc1461-suffix.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--suffix.txt');
|
||||
});
|
||||
|
||||
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-こんにちは世界'));
|
||||
});
|
||||
|
||||
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) => {
|
||||
const result = await runInlineTest({
|
||||
'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];
|
||||
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) => {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue