test: roll test runner to 0.9.20 (#4062)
This commit is contained in:
parent
2df6425254
commit
0db09f8ed4
166
package-lock.json
generated
166
package-lock.json
generated
|
|
@ -1096,9 +1096,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@jest/types": {
|
"@jest/types": {
|
||||||
"version": "26.3.0",
|
"version": "26.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.0.tgz",
|
||||||
"integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
|
"integrity": "sha512-nH9DFLqaIhB+RVgjivemvMiFSWw/BKwbZGxBAMv8CCTvUyFoK8RwHhAlmlXIvMBrf5Z3YQ4p9cq3Qh9EDctGvA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/istanbul-lib-coverage": "^2.0.0",
|
"@types/istanbul-lib-coverage": "^2.0.0",
|
||||||
|
|
@ -1109,12 +1109,11 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1161,22 +1160,19 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@playwright/test": {
|
"@playwright/test": {
|
||||||
"version": "0.9.7",
|
"version": "0.9.9",
|
||||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-0.9.7.tgz",
|
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-0.9.9.tgz",
|
||||||
"integrity": "sha512-llqV967KlRZ5mWNm0DpEkqi/42UBIssM/JzZ83KbTQdbmGhmx8L4hcJ6c1ExeFe/qq5uvL0mae1yuKfqxPBrPg==",
|
"integrity": "sha512-JcpesJZG1EEdqlWllRHlprQ7v7IxL9IujwuIK/YcGpeeihEgZCyacL55Zg9i45n+0BWzXnOPQURCdWL4VnXySw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"jpeg-js": "^0.4.2",
|
|
||||||
"pixelmatch": "^5.2.1",
|
|
||||||
"playwright": "1.4.0-next.1601161680085",
|
"playwright": "1.4.0-next.1601161680085",
|
||||||
"pngjs": "^5.0.0",
|
|
||||||
"rimraf": "^3.0.2"
|
"rimraf": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@playwright/test-runner": {
|
"@playwright/test-runner": {
|
||||||
"version": "0.9.17",
|
"version": "0.9.20",
|
||||||
"resolved": "https://registry.npmjs.org/@playwright/test-runner/-/test-runner-0.9.17.tgz",
|
"resolved": "https://registry.npmjs.org/@playwright/test-runner/-/test-runner-0.9.20.tgz",
|
||||||
"integrity": "sha512-9d0b99Rir+Vck8r1Zak17QB6vG/AzabURLXv9nlvVFFDRqmttRVPfnGgvlQ7Ae4lkUhYk2JSHX2ETq/nvMfwlg==",
|
"integrity": "sha512-3en4cjeWn2JgrHTJEmPVrYmEBkYegSu3uML49mcmQLpNyozyGy4EKysoeUuyXRoZQz4ptWY6AzFtFPyt34KLCw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.10.4",
|
"@babel/code-frame": "^7.10.4",
|
||||||
|
|
@ -1188,9 +1184,13 @@
|
||||||
"commander": "^6.1.0",
|
"commander": "^6.1.0",
|
||||||
"debug": "^4.1.5",
|
"debug": "^4.1.5",
|
||||||
"expect": "^26.4.2",
|
"expect": "^26.4.2",
|
||||||
|
"jpeg-js": "^0.4.2",
|
||||||
"micromatch": "^4.0.2",
|
"micromatch": "^4.0.2",
|
||||||
"ms": "^2.1.2",
|
"ms": "^2.1.2",
|
||||||
"pirates": "^4.0.1",
|
"pirates": "^4.0.1",
|
||||||
|
"pixelmatch": "^5.2.1",
|
||||||
|
"pngjs": "^5.0.0",
|
||||||
|
"pretty-format": "^26.4.2",
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"source-map-support": "^0.5.19",
|
"source-map-support": "^0.5.19",
|
||||||
"stack-utils": "^2.0.2"
|
"stack-utils": "^2.0.2"
|
||||||
|
|
@ -1211,12 +1211,6 @@
|
||||||
"defer-to-connect": "^1.0.1"
|
"defer-to-connect": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/color-name": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"@types/debug": {
|
"@types/debug": {
|
||||||
"version": "4.1.5",
|
"version": "4.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
|
||||||
|
|
@ -1346,9 +1340,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/stack-utils": {
|
"@types/stack-utils": {
|
||||||
"version": "1.0.1",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz",
|
||||||
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
|
"integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/ws": {
|
"@types/ws": {
|
||||||
|
|
@ -1667,9 +1661,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "7.4.0",
|
"version": "7.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||||
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
|
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"acorn-jsx": {
|
"acorn-jsx": {
|
||||||
|
|
@ -2231,9 +2225,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"caniuse-lite": {
|
"caniuse-lite": {
|
||||||
"version": "1.0.30001141",
|
"version": "1.0.30001143",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001141.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001143.tgz",
|
||||||
"integrity": "sha512-EHfInJHoQTmlMdVZrEc5gmwPc0zyN/hVufmGHPbVNQwlk7tJfCmQ2ysRZMY2MeleBivALUTyyxXnQjK18XrVpA==",
|
"integrity": "sha512-p/PO5YbwmCpBJPxjOiKBvAlUPgF8dExhfEpnsH+ys4N/791WHrYrGg0cyHiAURl5hSbx5vIcjKmQAP6sHDYH3w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
|
|
@ -2760,9 +2754,9 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"diff-sequences": {
|
"diff-sequences": {
|
||||||
"version": "26.3.0",
|
"version": "26.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.5.0.tgz",
|
||||||
"integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==",
|
"integrity": "sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"diffie-hellman": {
|
"diffie-hellman": {
|
||||||
|
|
@ -2818,9 +2812,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "9.3.1",
|
"version": "9.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-9.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-9.3.2.tgz",
|
||||||
"integrity": "sha512-DScrhqBT4a54KfdF0EoipALpHmdQTn3m7SSCtbpTcEcG+UDUiXad2cOfW6DHeVH7N+CVDKDG12q2PhVJjXkFAA==",
|
"integrity": "sha512-0lleEf9msAXGDi2GukAuiGdw3VDgSTlONOnJgqDEz1fuSEVsXz5RX+hNPKDsVDerLTFg/C34RuJf4LwHvkKcBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^1.0.1",
|
"@electron/get": "^1.0.1",
|
||||||
|
|
@ -3056,12 +3050,11 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -3303,26 +3296,25 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"expect": {
|
"expect": {
|
||||||
"version": "26.4.2",
|
"version": "26.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/expect/-/expect-26.5.0.tgz",
|
||||||
"integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==",
|
"integrity": "sha512-oIOy3mHWjnF5ZICuaui5kdtJZQ+D7XHWyUQDxk1WhIRCkcIYc24X23bOfikgCNU6i9wcSqLQhwPOqeRp09naxg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@jest/types": "^26.3.0",
|
"@jest/types": "^26.5.0",
|
||||||
"ansi-styles": "^4.0.0",
|
"ansi-styles": "^4.0.0",
|
||||||
"jest-get-type": "^26.3.0",
|
"jest-get-type": "^26.3.0",
|
||||||
"jest-matcher-utils": "^26.4.2",
|
"jest-matcher-utils": "^26.5.0",
|
||||||
"jest-message-util": "^26.3.0",
|
"jest-message-util": "^26.5.0",
|
||||||
"jest-regex-util": "^26.0.0"
|
"jest-regex-util": "^26.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -4376,24 +4368,23 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"jest-diff": {
|
"jest-diff": {
|
||||||
"version": "26.4.2",
|
"version": "26.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.5.0.tgz",
|
||||||
"integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==",
|
"integrity": "sha512-CmDMMPkVMxrrh0Dv/4M9kh1tsYsZnYTQMMTvIFpePBSk9wMVfcyfg30TCq+oR9AzGbw8vsI50Gk1HmlMMlhoJg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"diff-sequences": "^26.3.0",
|
"diff-sequences": "^26.5.0",
|
||||||
"jest-get-type": "^26.3.0",
|
"jest-get-type": "^26.3.0",
|
||||||
"pretty-format": "^26.4.2"
|
"pretty-format": "^26.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -4446,24 +4437,23 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"jest-matcher-utils": {
|
"jest-matcher-utils": {
|
||||||
"version": "26.4.2",
|
"version": "26.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.5.0.tgz",
|
||||||
"integrity": "sha512-KcbNqWfWUG24R7tu9WcAOKKdiXiXCbMvQYT6iodZ9k1f7065k0keUOW6XpJMMvah+hTfqkhJhRXmA3r3zMAg0Q==",
|
"integrity": "sha512-QgbbxqFT8wiTi4o/7MWj2vHlcmMjACG8vnJ9pJ7svVDmkzEnTUGdHXWLKB1aZhbnyXetMNRF+TSMcDS9aGfuzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"jest-diff": "^26.4.2",
|
"jest-diff": "^26.5.0",
|
||||||
"jest-get-type": "^26.3.0",
|
"jest-get-type": "^26.3.0",
|
||||||
"pretty-format": "^26.4.2"
|
"pretty-format": "^26.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -4510,14 +4500,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jest-message-util": {
|
"jest-message-util": {
|
||||||
"version": "26.3.0",
|
"version": "26.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.5.0.tgz",
|
||||||
"integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==",
|
"integrity": "sha512-UEOqdoTfX0AFyReL4q5N3CfDBWt+AtQzeszZuuGapU39vwEk90rTSBghCA/3FFEZzvGfH2LE4+0NaBI81Cu2Ow==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/code-frame": "^7.0.0",
|
"@babel/code-frame": "^7.0.0",
|
||||||
"@jest/types": "^26.3.0",
|
"@jest/types": "^26.5.0",
|
||||||
"@types/stack-utils": "^1.0.1",
|
"@types/stack-utils": "^2.0.0",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"graceful-fs": "^4.2.4",
|
"graceful-fs": "^4.2.4",
|
||||||
"micromatch": "^4.0.2",
|
"micromatch": "^4.0.2",
|
||||||
|
|
@ -4526,12 +4516,11 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -5458,24 +5447,23 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"pretty-format": {
|
"pretty-format": {
|
||||||
"version": "26.4.2",
|
"version": "26.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.0.tgz",
|
||||||
"integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
|
"integrity": "sha512-NcgRuuTutUJ9+Br4P19DFThpJYnYBiugfRmZEA6pXrUeG+IcMSmppb88rU+iPA+XAJcjTYlCb5Ed6miHg/Qqqw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@jest/types": "^26.3.0",
|
"@jest/types": "^26.5.0",
|
||||||
"ansi-regex": "^5.0.0",
|
"ansi-regex": "^5.0.0",
|
||||||
"ansi-styles": "^4.0.0",
|
"ansi-styles": "^4.0.0",
|
||||||
"react-is": "^16.12.0"
|
"react-is": "^16.12.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -7214,9 +7202,9 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "6.4.1",
|
"version": "6.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
|
||||||
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
|
"integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"braces": {
|
"braces": {
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@
|
||||||
"ws": "^7.3.1"
|
"ws": "^7.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@playwright/test": "^0.9.7",
|
"@playwright/test": "0.9.9",
|
||||||
"@playwright/test-runner": "^0.9.17",
|
"@playwright/test-runner": "0.9.20",
|
||||||
"@types/debug": "^4.1.5",
|
"@types/debug": "^4.1.5",
|
||||||
"@types/extract-zip": "^1.6.2",
|
"@types/extract-zip": "^1.6.2",
|
||||||
"@types/mime": "^2.0.3",
|
"@types/mime": "^2.0.3",
|
||||||
|
|
|
||||||
|
|
@ -234,9 +234,11 @@ describe('connect', (suite, { wire }) => {
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save videos from remote browser', async ({browserType, remoteServer, testOutputPath}) => {
|
it('should save videos from remote browser', (test, {browserName, platform}) => {
|
||||||
|
test.flaky(browserName === 'firefox' && platform === 'win32');
|
||||||
|
}, async ({browserType, remoteServer, testInfo}) => {
|
||||||
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
const remote = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||||
const videosPath = testOutputPath();
|
const videosPath = testInfo.outputPath();
|
||||||
const context = await remote.newContext({
|
const context = await remote.newContext({
|
||||||
videosPath,
|
videosPath,
|
||||||
videoSize: { width: 320, height: 240 },
|
videoSize: { width: 320, height: 240 },
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,16 @@ type DomainFixtures = {
|
||||||
domain: any;
|
domain: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fixtures = baseFixtures.declareWorkerFixtures<DomainFixtures>();
|
const fixtures = baseFixtures.defineWorkerFixtures<DomainFixtures>({
|
||||||
fixtures.defineWorkerFixture('domain', async ({ }, test) => {
|
domain: async ({ }, test) => {
|
||||||
const local = domain.create();
|
const local = domain.create();
|
||||||
local.run(() => { });
|
local.run(() => { });
|
||||||
let err;
|
let err;
|
||||||
local.on('error', e => err = e);
|
local.on('error', e => err = e);
|
||||||
await test(null);
|
await test(null);
|
||||||
if (err)
|
if (err)
|
||||||
throw err;
|
throw err;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { it, expect } = fixtures;
|
const { it, expect } = fixtures;
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fixtures as playwrightFixtures } from '../fixtures';
|
import { fixtures as playwrightFixtures } from '../fixtures';
|
||||||
const { it, expect, describe, overrideWorkerFixture } = playwrightFixtures;
|
const { it, expect, describe, overrideWorkerFixtures } = playwrightFixtures;
|
||||||
|
|
||||||
overrideWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, test) => {
|
overrideWorkerFixtures({
|
||||||
const browser = await browserType.launch({
|
browser: async ({browserType, defaultBrowserOptions}, test) => {
|
||||||
...defaultBrowserOptions,
|
const browser = await browserType.launch({
|
||||||
args: (defaultBrowserOptions.args || []).concat(['--site-per-process'])
|
...defaultBrowserOptions,
|
||||||
});
|
args: (defaultBrowserOptions.args || []).concat(['--site-per-process'])
|
||||||
await test(browser);
|
});
|
||||||
await browser.close();
|
await test(browser);
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('oopif', (suite, { browserName }) => {
|
describe('oopif', (suite, { browserName }) => {
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,14 @@ import type { ChromiumBrowser } from '../..';
|
||||||
type TestState = {
|
type TestState = {
|
||||||
outputTraceFile: string;
|
outputTraceFile: string;
|
||||||
};
|
};
|
||||||
const fixtures = playwrightFixtures.declareTestFixtures<TestState>();
|
const fixtures = playwrightFixtures.defineTestFixtures<TestState>({
|
||||||
const { it, expect, describe, defineTestFixture } = fixtures;
|
outputTraceFile: async ({ testInfo }, test) => {
|
||||||
|
await test(testInfo.outputPath(path.join(`trace.json`)));
|
||||||
defineTestFixture('outputTraceFile', async ({testOutputPath}, test) => {
|
}
|
||||||
await test(testOutputPath(path.join(`trace.json`)));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { it, expect, describe } = fixtures;
|
||||||
|
|
||||||
describe('oopif', (suite, { browserName }) => {
|
describe('oopif', (suite, { browserName }) => {
|
||||||
suite.skip(browserName !== 'chromium');
|
suite.skip(browserName !== 'chromium');
|
||||||
}, () => {
|
}, () => {
|
||||||
|
|
@ -39,8 +40,8 @@ describe('oopif', (suite, { browserName }) => {
|
||||||
expect(fs.existsSync(outputTraceFile)).toBe(true);
|
expect(fs.existsSync(outputTraceFile)).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create directories as needed', async ({browser, page, server, testOutputPath}) => {
|
it('should create directories as needed', async ({browser, page, server, testInfo}) => {
|
||||||
const filePath = testOutputPath(path.join('these', 'are', 'directories', 'trace.json'));
|
const filePath = testInfo.outputPath(path.join('these', 'are', 'directories', 'trace.json'));
|
||||||
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: filePath});
|
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: filePath});
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
await (browser as ChromiumBrowser).stopTracing();
|
await (browser as ChromiumBrowser).stopTracing();
|
||||||
|
|
|
||||||
|
|
@ -61,28 +61,28 @@ it('should report downloads with acceptDownloads: true', async ({browser, server
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save to user-specified path', async ({testOutputPath, browser, server}) => {
|
it('should save to user-specified path', async ({testInfo, browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const userPath = testOutputPath('download.txt');
|
const userPath = testInfo.outputPath('download.txt');
|
||||||
await download.saveAs(userPath);
|
await download.saveAs(userPath);
|
||||||
expect(fs.existsSync(userPath)).toBeTruthy();
|
expect(fs.existsSync(userPath)).toBeTruthy();
|
||||||
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save to user-specified path without updating original path', async ({testOutputPath, browser, server}) => {
|
it('should save to user-specified path without updating original path', async ({testInfo, browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const userPath = testOutputPath('download.txt');
|
const userPath = testInfo.outputPath('download.txt');
|
||||||
await download.saveAs(userPath);
|
await download.saveAs(userPath);
|
||||||
expect(fs.existsSync(userPath)).toBeTruthy();
|
expect(fs.existsSync(userPath)).toBeTruthy();
|
||||||
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
||||||
|
|
@ -93,33 +93,33 @@ it('should save to user-specified path without updating original path', async ({
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save to two different paths with multiple saveAs calls', async ({testOutputPath, browser, server}) => {
|
it('should save to two different paths with multiple saveAs calls', async ({testInfo, browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const userPath = testOutputPath('download.txt');
|
const userPath = testInfo.outputPath('download.txt');
|
||||||
await download.saveAs(userPath);
|
await download.saveAs(userPath);
|
||||||
expect(fs.existsSync(userPath)).toBeTruthy();
|
expect(fs.existsSync(userPath)).toBeTruthy();
|
||||||
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
|
||||||
|
|
||||||
const anotherUserPath = testOutputPath('download (2).txt');
|
const anotherUserPath = testInfo.outputPath('download (2).txt');
|
||||||
await download.saveAs(anotherUserPath);
|
await download.saveAs(anotherUserPath);
|
||||||
expect(fs.existsSync(anotherUserPath)).toBeTruthy();
|
expect(fs.existsSync(anotherUserPath)).toBeTruthy();
|
||||||
expect(fs.readFileSync(anotherUserPath).toString()).toBe('Hello world');
|
expect(fs.readFileSync(anotherUserPath).toString()).toBe('Hello world');
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should save to overwritten filepath', async ({testOutputPath, browser, server}) => {
|
it('should save to overwritten filepath', async ({testInfo, browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const dir = testOutputPath('downloads');
|
const dir = testInfo.outputPath('downloads');
|
||||||
const userPath = path.join(dir, 'download.txt');
|
const userPath = path.join(dir, 'download.txt');
|
||||||
await download.saveAs(userPath);
|
await download.saveAs(userPath);
|
||||||
expect((await util.promisify(fs.readdir)(dir)).length).toBe(1);
|
expect((await util.promisify(fs.readdir)(dir)).length).toBe(1);
|
||||||
|
|
@ -130,14 +130,14 @@ it('should save to overwritten filepath', async ({testOutputPath, browser, serve
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create subdirectories when saving to non-existent user-specified path', async ({testOutputPath, browser, server}) => {
|
it('should create subdirectories when saving to non-existent user-specified path', async ({testInfo, browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const nestedPath = testOutputPath(path.join('these', 'are', 'directories', 'download.txt'));
|
const nestedPath = testInfo.outputPath(path.join('these', 'are', 'directories', 'download.txt'));
|
||||||
await download.saveAs(nestedPath);
|
await download.saveAs(nestedPath);
|
||||||
expect(fs.existsSync(nestedPath)).toBeTruthy();
|
expect(fs.existsSync(nestedPath)).toBeTruthy();
|
||||||
expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world');
|
expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world');
|
||||||
|
|
@ -146,7 +146,7 @@ it('should create subdirectories when saving to non-existent user-specified path
|
||||||
|
|
||||||
it('should save when connected remotely', (test, { wire }) => {
|
it('should save when connected remotely', (test, { wire }) => {
|
||||||
test.skip(wire);
|
test.skip(wire);
|
||||||
}, async ({testOutputPath, server, browserType, remoteServer}) => {
|
}, async ({testInfo, server, browserType, remoteServer}) => {
|
||||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
|
|
@ -154,7 +154,7 @@ it('should save when connected remotely', (test, { wire }) => {
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const nestedPath = testOutputPath(path.join('these', 'are', 'directories', 'download.txt'));
|
const nestedPath = testInfo.outputPath(path.join('these', 'are', 'directories', 'download.txt'));
|
||||||
await download.saveAs(nestedPath);
|
await download.saveAs(nestedPath);
|
||||||
expect(fs.existsSync(nestedPath)).toBeTruthy();
|
expect(fs.existsSync(nestedPath)).toBeTruthy();
|
||||||
expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world');
|
expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world');
|
||||||
|
|
@ -163,27 +163,27 @@ it('should save when connected remotely', (test, { wire }) => {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error when saving with downloads disabled', async ({testOutputPath, browser, server}) => {
|
it('should error when saving with downloads disabled', async ({testInfo, browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: false });
|
const page = await browser.newPage({ acceptDownloads: false });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const userPath = testOutputPath('download.txt');
|
const userPath = testInfo.outputPath('download.txt');
|
||||||
const { message } = await download.saveAs(userPath).catch(e => e);
|
const { message } = await download.saveAs(userPath).catch(e => e);
|
||||||
expect(message).toContain('Pass { acceptDownloads: true } when you are creating your browser context');
|
expect(message).toContain('Pass { acceptDownloads: true } when you are creating your browser context');
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error when saving after deletion', async ({testOutputPath, browser, server}) => {
|
it('should error when saving after deletion', async ({testInfo, browser, server}) => {
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const userPath = testOutputPath('download.txt');
|
const userPath = testInfo.outputPath('download.txt');
|
||||||
await download.delete();
|
await download.delete();
|
||||||
const { message } = await download.saveAs(userPath).catch(e => e);
|
const { message } = await download.saveAs(userPath).catch(e => e);
|
||||||
expect(message).toContain('Download already deleted. Save before deleting.');
|
expect(message).toContain('Download already deleted. Save before deleting.');
|
||||||
|
|
@ -192,7 +192,7 @@ it('should error when saving after deletion', async ({testOutputPath, browser, s
|
||||||
|
|
||||||
it('should error when saving after deletion when connected remotely', (test, { wire }) => {
|
it('should error when saving after deletion when connected remotely', (test, { wire }) => {
|
||||||
test.skip(wire);
|
test.skip(wire);
|
||||||
}, async ({testOutputPath, server, browserType, remoteServer}) => {
|
}, async ({testInfo, server, browserType, remoteServer}) => {
|
||||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||||
const page = await browser.newPage({ acceptDownloads: true });
|
const page = await browser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
|
|
@ -200,7 +200,7 @@ it('should error when saving after deletion when connected remotely', (test, { w
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const userPath = testOutputPath('download.txt');
|
const userPath = testInfo.outputPath('download.txt');
|
||||||
await download.delete();
|
await download.delete();
|
||||||
const { message } = await download.saveAs(userPath).catch(e => e);
|
const { message } = await download.saveAs(userPath).catch(e => e);
|
||||||
expect(message).toContain('Download already deleted. Save before deleting.');
|
expect(message).toContain('Download already deleted. Save before deleting.');
|
||||||
|
|
|
||||||
|
|
@ -23,41 +23,42 @@ type TestState = {
|
||||||
downloadsBrowser: Browser;
|
downloadsBrowser: Browser;
|
||||||
persistentDownloadsContext: BrowserContext;
|
persistentDownloadsContext: BrowserContext;
|
||||||
};
|
};
|
||||||
const fixtures = baseFixtures.declareTestFixtures<TestState>();
|
const fixtures = baseFixtures.defineTestFixtures<TestState>({
|
||||||
const { it, expect, defineTestFixture } = fixtures;
|
downloadsBrowser: async ({ server, browserType, defaultBrowserOptions, testInfo }, test) => {
|
||||||
|
server.setRoute('/download', (req, res) => {
|
||||||
|
res.setHeader('Content-Type', 'application/octet-stream');
|
||||||
|
res.setHeader('Content-Disposition', 'attachment; filename=file.txt');
|
||||||
|
res.end(`Hello world`);
|
||||||
|
});
|
||||||
|
const browser = await browserType.launch({
|
||||||
|
...defaultBrowserOptions,
|
||||||
|
downloadsPath: testInfo.outputPath(''),
|
||||||
|
});
|
||||||
|
await test(browser);
|
||||||
|
await browser.close();
|
||||||
|
},
|
||||||
|
|
||||||
defineTestFixture('downloadsBrowser', async ({server, browserType, defaultBrowserOptions, testOutputPath}, test) => {
|
persistentDownloadsContext: async ({ server, launchPersistent, testInfo }, test) => {
|
||||||
server.setRoute('/download', (req, res) => {
|
server.setRoute('/download', (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/octet-stream');
|
res.setHeader('Content-Type', 'application/octet-stream');
|
||||||
res.setHeader('Content-Disposition', 'attachment; filename=file.txt');
|
res.setHeader('Content-Disposition', 'attachment; filename=file.txt');
|
||||||
res.end(`Hello world`);
|
res.end(`Hello world`);
|
||||||
});
|
});
|
||||||
const browser = await browserType.launch({
|
const { context, page } = await launchPersistent(
|
||||||
...defaultBrowserOptions,
|
{
|
||||||
downloadsPath: testOutputPath(''),
|
downloadsPath: testInfo.outputPath(''),
|
||||||
});
|
acceptDownloads: true
|
||||||
await test(browser);
|
}
|
||||||
await browser.close();
|
);
|
||||||
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
|
await test(context);
|
||||||
|
await context.close();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
defineTestFixture('persistentDownloadsContext', async ({server, launchPersistent, testOutputPath}, test) => {
|
const { it, expect } = fixtures;
|
||||||
server.setRoute('/download', (req, res) => {
|
|
||||||
res.setHeader('Content-Type', 'application/octet-stream');
|
|
||||||
res.setHeader('Content-Disposition', 'attachment; filename=file.txt');
|
|
||||||
res.end(`Hello world`);
|
|
||||||
});
|
|
||||||
const { context, page } = await launchPersistent(
|
|
||||||
{
|
|
||||||
downloadsPath: testOutputPath(''),
|
|
||||||
acceptDownloads: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
|
||||||
await test(context);
|
|
||||||
await context.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should keep downloadsPath folder', async ({downloadsBrowser, testOutputPath, server}) => {
|
it('should keep downloadsPath folder', async ({downloadsBrowser, testInfo, server}) => {
|
||||||
const page = await downloadsBrowser.newPage();
|
const page = await downloadsBrowser.newPage();
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
|
|
@ -69,7 +70,7 @@ it('should keep downloadsPath folder', async ({downloadsBrowser, testOutputPath,
|
||||||
await download.path().catch(e => void 0);
|
await download.path().catch(e => void 0);
|
||||||
await page.close();
|
await page.close();
|
||||||
await downloadsBrowser.close();
|
await downloadsBrowser.close();
|
||||||
expect(fs.existsSync(testOutputPath(''))).toBeTruthy();
|
expect(fs.existsSync(testInfo.outputPath(''))).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete downloads when context closes', async ({downloadsBrowser, server}) => {
|
it('should delete downloads when context closes', async ({downloadsBrowser, server}) => {
|
||||||
|
|
@ -85,7 +86,7 @@ it('should delete downloads when context closes', async ({downloadsBrowser, serv
|
||||||
expect(fs.existsSync(path)).toBeFalsy();
|
expect(fs.existsSync(path)).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should report downloads in downloadsPath folder', async ({downloadsBrowser, testOutputPath, server}) => {
|
it('should report downloads in downloadsPath folder', async ({downloadsBrowser, testInfo, server}) => {
|
||||||
const page = await downloadsBrowser.newPage({ acceptDownloads: true });
|
const page = await downloadsBrowser.newPage({ acceptDownloads: true });
|
||||||
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
|
|
@ -93,11 +94,11 @@ it('should report downloads in downloadsPath folder', async ({downloadsBrowser,
|
||||||
page.click('a')
|
page.click('a')
|
||||||
]);
|
]);
|
||||||
const path = await download.path();
|
const path = await download.path();
|
||||||
expect(path.startsWith(testOutputPath(''))).toBeTruthy();
|
expect(path.startsWith(testInfo.outputPath(''))).toBeTruthy();
|
||||||
await page.close();
|
await page.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept downloads in persistent context', async ({persistentDownloadsContext, testOutputPath, server}) => {
|
it('should accept downloads in persistent context', async ({persistentDownloadsContext, testInfo, server}) => {
|
||||||
const page = persistentDownloadsContext.pages()[0];
|
const page = persistentDownloadsContext.pages()[0];
|
||||||
const [ download ] = await Promise.all([
|
const [ download ] = await Promise.all([
|
||||||
page.waitForEvent('download'),
|
page.waitForEvent('download'),
|
||||||
|
|
@ -106,7 +107,7 @@ it('should accept downloads in persistent context', async ({persistentDownloadsC
|
||||||
expect(download.url()).toBe(`${server.PREFIX}/download`);
|
expect(download.url()).toBe(`${server.PREFIX}/download`);
|
||||||
expect(download.suggestedFilename()).toBe(`file.txt`);
|
expect(download.suggestedFilename()).toBe(`file.txt`);
|
||||||
const path = await download.path();
|
const path = await download.path();
|
||||||
expect(path.startsWith(testOutputPath(''))).toBeTruthy();
|
expect(path.startsWith(testInfo.outputPath(''))).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete downloads when persistent context closes', async ({persistentDownloadsContext}) => {
|
it('should delete downloads when persistent context closes', async ({persistentDownloadsContext}) => {
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { fixtures as baseFixtures } from '../fixtures';
|
import { fixtures as baseFixtures } from '../fixtures';
|
||||||
import type {ElectronApplication, ElectronLauncher, ElectronPage} from '../../electron-types';
|
import type { ElectronApplication, ElectronLauncher, ElectronPage } from '../../electron-types';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
|
||||||
|
|
@ -25,24 +25,23 @@ type TestState = {
|
||||||
window: ElectronPage;
|
window: ElectronPage;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const electronFixtures = baseFixtures.declareTestFixtures<TestState>();
|
export const electronFixtures = baseFixtures.defineTestFixtures<TestState>({
|
||||||
const { defineTestFixture } = electronFixtures;
|
application: async ({ playwright }, test) => {
|
||||||
|
const electronPath = path.join(__dirname, '..', '..', 'node_modules', '.bin', electronName);
|
||||||
|
const application = await playwright.electron.launch(electronPath, {
|
||||||
|
args: [path.join(__dirname, 'testApp.js')],
|
||||||
|
});
|
||||||
|
await test(application);
|
||||||
|
await application.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
window: async ({ application }, test) => {
|
||||||
|
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
||||||
|
await test(page);
|
||||||
|
await page.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
declare module '../../index' {
|
declare module '../../index' {
|
||||||
const electron: ElectronLauncher;
|
const electron: ElectronLauncher;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineTestFixture('application', async ({playwright}, test) => {
|
|
||||||
const electronPath = path.join(__dirname, '..', '..', 'node_modules', '.bin', electronName);
|
|
||||||
const application = await playwright.electron.launch(electronPath, {
|
|
||||||
args: [path.join(__dirname, 'testApp.js')],
|
|
||||||
});
|
|
||||||
await test(application);
|
|
||||||
await application.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
defineTestFixture('window', async ({application}, test) => {
|
|
||||||
const page = await application.newBrowserWindow({ width: 800, height: 600 });
|
|
||||||
await test(page);
|
|
||||||
await page.close();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -384,12 +384,12 @@ describe('element screenshot', (suite, parameters) => {
|
||||||
expect(screenshot).toBeInstanceOf(Buffer);
|
expect(screenshot).toBeInstanceOf(Buffer);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('path option should create subdirectories', async ({page, server, testOutputPath}) => {
|
it('path option should create subdirectories', async ({page, server, testInfo}) => {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
await page.evaluate(() => window.scrollBy(50, 100));
|
await page.evaluate(() => window.scrollBy(50, 100));
|
||||||
const elementHandle = await page.$('.box:nth-of-type(3)');
|
const elementHandle = await page.$('.box:nth-of-type(3)');
|
||||||
const outputPath = testOutputPath(path.join('these', 'are', 'directories', 'screenshot.png'));
|
const outputPath = testInfo.outputPath(path.join('these', 'are', 'directories', 'screenshot.png'));
|
||||||
await elementHandle.screenshot({path: outputPath});
|
await elementHandle.screenshot({path: outputPath});
|
||||||
expect(await fs.promises.readFile(outputPath)).toMatchImage('screenshot-element-bounding-box.png');
|
expect(await fs.promises.readFile(outputPath)).toMatchImage('screenshot-element-bounding-box.png');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -25,24 +25,25 @@ export type FixturesFixtures = {
|
||||||
stallingConnectedRemoteServer: RemoteServer;
|
stallingConnectedRemoteServer: RemoteServer;
|
||||||
};
|
};
|
||||||
|
|
||||||
const fixturesFixtures = serverFixtures.declareTestFixtures<FixturesFixtures>();
|
const fixturesFixtures = serverFixtures.defineTestFixtures<FixturesFixtures>({
|
||||||
const { it, describe, expect, defineTestFixture } = fixturesFixtures;
|
connectedRemoteServer: async ({browserType, remoteServer, server}, test) => {
|
||||||
|
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
||||||
|
const page = await browser.newPage();
|
||||||
|
await page.goto(server.EMPTY_PAGE);
|
||||||
|
await test(remoteServer);
|
||||||
|
await browser.close();
|
||||||
|
},
|
||||||
|
|
||||||
defineTestFixture('connectedRemoteServer', async ({browserType, remoteServer, server}, test) => {
|
stallingConnectedRemoteServer: async ({browserType, stallingRemoteServer, server}, test) => {
|
||||||
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
|
const browser = await browserType.connect({ wsEndpoint: stallingRemoteServer.wsEndpoint() });
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await test(remoteServer);
|
await test(stallingRemoteServer);
|
||||||
await browser.close();
|
await browser.close();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
defineTestFixture('stallingConnectedRemoteServer', async ({browserType, stallingRemoteServer, server}, test) => {
|
const { it, describe, expect } = fixturesFixtures;
|
||||||
const browser = await browserType.connect({ wsEndpoint: stallingRemoteServer.wsEndpoint() });
|
|
||||||
const page = await browser.newPage();
|
|
||||||
await page.goto(server.EMPTY_PAGE);
|
|
||||||
await test(stallingRemoteServer);
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should close the browser when the node process closes', test => {
|
it('should close the browser when the node process closes', test => {
|
||||||
test.slow();
|
test.slow();
|
||||||
|
|
|
||||||
180
test/fixtures.ts
180
test/fixtures.ts
|
|
@ -27,26 +27,53 @@ import { installCoverageHooks } from './coverage';
|
||||||
import { fixtures as httpFixtures } from './http.fixtures';
|
import { fixtures as httpFixtures } from './http.fixtures';
|
||||||
import { fixtures as implFixtures } from './impl.fixtures';
|
import { fixtures as implFixtures } from './impl.fixtures';
|
||||||
import { fixtures as playwrightFixtures } from './playwright.fixtures';
|
import { fixtures as playwrightFixtures } from './playwright.fixtures';
|
||||||
export { expect } from '@playwright/test/out/matcher.fixtures';
|
export { expect, config } from '@playwright/test-runner';
|
||||||
export { config } from '@playwright/test-runner';
|
|
||||||
|
|
||||||
const removeFolderAsync = util.promisify(require('rimraf'));
|
const removeFolderAsync = util.promisify(require('rimraf'));
|
||||||
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
const mkdtempAsync = util.promisify(fs.mkdtemp);
|
||||||
|
|
||||||
type AllParameters = {
|
|
||||||
wire: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type AllTestFixtures = {
|
type AllTestFixtures = {
|
||||||
createUserDataDir: () => Promise<string>;
|
createUserDataDir: () => Promise<string>;
|
||||||
launchPersistent: (options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) => Promise<{context: BrowserContext, page: Page}>;
|
launchPersistent: (options?: Parameters<BrowserType<Browser>['launchPersistentContext']>[1]) => Promise<{ context: BrowserContext, page: Page }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fixtures = playwrightFixtures
|
export const fixtures = playwrightFixtures
|
||||||
.union(httpFixtures)
|
.union(httpFixtures)
|
||||||
.union(implFixtures)
|
.union(implFixtures)
|
||||||
.declareParameters<AllParameters>()
|
.defineParameter('wire', 'Wire testing mode', !!process.env.PWWIRE || false)
|
||||||
.declareTestFixtures<AllTestFixtures>();
|
.defineTestFixtures<AllTestFixtures>({
|
||||||
|
createUserDataDir: async ({ }, runTest) => {
|
||||||
|
const dirs: string[] = [];
|
||||||
|
async function createUserDataDir() {
|
||||||
|
// We do not put user data dir in testOutputPath,
|
||||||
|
// because we do not want to upload them as test result artifacts.
|
||||||
|
//
|
||||||
|
// Additionally, it is impossible to upload user data dir after test run:
|
||||||
|
// - Firefox removes lock file later, presumably from another watchdog process?
|
||||||
|
// - WebKit has circular symlinks that makes CI go crazy.
|
||||||
|
const dir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
|
||||||
|
dirs.push(dir);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
await runTest(createUserDataDir);
|
||||||
|
await Promise.all(dirs.map(dir => removeFolderAsync(dir).catch(e => { })));
|
||||||
|
},
|
||||||
|
|
||||||
|
launchPersistent: async ({ createUserDataDir, defaultBrowserOptions, browserType }, test) => {
|
||||||
|
let context;
|
||||||
|
async function launchPersistent(options) {
|
||||||
|
if (context)
|
||||||
|
throw new Error('can only launch one persitent context');
|
||||||
|
const userDataDir = await createUserDataDir();
|
||||||
|
context = await browserType.launchPersistentContext(userDataDir, { ...defaultBrowserOptions, ...options });
|
||||||
|
const page = context.pages()[0];
|
||||||
|
return { context, page };
|
||||||
|
}
|
||||||
|
await test(launchPersistent);
|
||||||
|
if (context)
|
||||||
|
await context.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export const it = fixtures.it;
|
export const it = fixtures.it;
|
||||||
export const fit = fixtures.fit;
|
export const fit = fixtures.fit;
|
||||||
|
|
@ -59,7 +86,6 @@ export const afterEach = fixtures.afterEach;
|
||||||
export const beforeAll = fixtures.beforeAll;
|
export const beforeAll = fixtures.beforeAll;
|
||||||
export const afterAll = fixtures.afterAll;
|
export const afterAll = fixtures.afterAll;
|
||||||
|
|
||||||
fixtures.defineParameter('wire', 'Wire testing mode', !!process.env.PWWIRE || false);
|
|
||||||
|
|
||||||
fixtures.generateParametrizedTests(
|
fixtures.generateParametrizedTests(
|
||||||
'platform',
|
'platform',
|
||||||
|
|
@ -74,90 +100,62 @@ const getExecutablePath = browserName => {
|
||||||
return process.env.WKPATH;
|
return process.env.WKPATH;
|
||||||
};
|
};
|
||||||
|
|
||||||
fixtures.overrideWorkerFixture('defaultBrowserOptions', async ({ browserName, headful, slowMo }, runTest) => {
|
fixtures.overrideWorkerFixtures({
|
||||||
const executablePath = getExecutablePath(browserName);
|
defaultBrowserOptions: async ({ browserName, headful, slowMo }, runTest) => {
|
||||||
if (executablePath)
|
const executablePath = getExecutablePath(browserName);
|
||||||
console.error(`Using executable at ${executablePath}`);
|
if (executablePath)
|
||||||
await runTest({
|
console.error(`Using executable at ${executablePath}`);
|
||||||
executablePath,
|
await runTest({
|
||||||
handleSIGINT: false,
|
executablePath,
|
||||||
slowMo,
|
handleSIGINT: false,
|
||||||
headless: !headful,
|
slowMo,
|
||||||
});
|
headless: !headful,
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.overrideWorkerFixture('playwright', async ({ browserName, testWorkerIndex, platform, wire }, runTest) => {
|
|
||||||
assert(platform); // Depend on platform to generate all tests.
|
|
||||||
const {coverage, uninstall} = installCoverageHooks(browserName);
|
|
||||||
if (wire) {
|
|
||||||
require('../lib/utils/utils').setUnderTest();
|
|
||||||
const connection = new Connection();
|
|
||||||
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'driver.js'), ['serve'], {
|
|
||||||
stdio: 'pipe',
|
|
||||||
detached: true,
|
|
||||||
});
|
});
|
||||||
spawnedProcess.unref();
|
},
|
||||||
const onExit = (exitCode, signal) => {
|
|
||||||
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
|
||||||
};
|
|
||||||
spawnedProcess.on('exit', onExit);
|
|
||||||
const transport = new Transport(spawnedProcess.stdin, spawnedProcess.stdout);
|
|
||||||
connection.onmessage = message => transport.send(JSON.stringify(message));
|
|
||||||
transport.onmessage = message => connection.dispatch(JSON.parse(message));
|
|
||||||
const playwrightObject = await connection.waitForObjectWithKnownName('Playwright');
|
|
||||||
await runTest(playwrightObject);
|
|
||||||
spawnedProcess.removeListener('exit', onExit);
|
|
||||||
spawnedProcess.stdin.destroy();
|
|
||||||
spawnedProcess.stdout.destroy();
|
|
||||||
spawnedProcess.stderr.destroy();
|
|
||||||
await teardownCoverage();
|
|
||||||
} else {
|
|
||||||
const playwright = require('../index');
|
|
||||||
await runTest(playwright);
|
|
||||||
await teardownCoverage();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function teardownCoverage() {
|
playwright: async ({ browserName, testWorkerIndex, platform, wire }, runTest) => {
|
||||||
uninstall();
|
assert(platform); // Depend on platform to generate all tests.
|
||||||
const coveragePath = path.join(__dirname, 'coverage-report', testWorkerIndex + '.json');
|
const { coverage, uninstall } = installCoverageHooks(browserName);
|
||||||
const coverageJSON = [...coverage.keys()].filter(key => coverage.get(key));
|
if (wire) {
|
||||||
await fs.promises.mkdir(path.dirname(coveragePath), { recursive: true });
|
require('../lib/utils/utils').setUnderTest();
|
||||||
await fs.promises.writeFile(coveragePath, JSON.stringify(coverageJSON, undefined, 2), 'utf8');
|
const connection = new Connection();
|
||||||
}
|
const spawnedProcess = childProcess.fork(path.join(__dirname, '..', 'lib', 'driver.js'), ['serve'], {
|
||||||
|
stdio: 'pipe',
|
||||||
|
detached: true,
|
||||||
|
});
|
||||||
|
spawnedProcess.unref();
|
||||||
|
const onExit = (exitCode, signal) => {
|
||||||
|
throw new Error(`Server closed with exitCode=${exitCode} signal=${signal}`);
|
||||||
|
};
|
||||||
|
spawnedProcess.on('exit', onExit);
|
||||||
|
const transport = new Transport(spawnedProcess.stdin, spawnedProcess.stdout);
|
||||||
|
connection.onmessage = message => transport.send(JSON.stringify(message));
|
||||||
|
transport.onmessage = message => connection.dispatch(JSON.parse(message));
|
||||||
|
const playwrightObject = await connection.waitForObjectWithKnownName('Playwright');
|
||||||
|
await runTest(playwrightObject);
|
||||||
|
spawnedProcess.removeListener('exit', onExit);
|
||||||
|
spawnedProcess.stdin.destroy();
|
||||||
|
spawnedProcess.stdout.destroy();
|
||||||
|
spawnedProcess.stderr.destroy();
|
||||||
|
await teardownCoverage();
|
||||||
|
} else {
|
||||||
|
const playwright = require('../index');
|
||||||
|
await runTest(playwright);
|
||||||
|
await teardownCoverage();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function teardownCoverage() {
|
||||||
|
uninstall();
|
||||||
|
const coveragePath = path.join(__dirname, 'coverage-report', testWorkerIndex + '.json');
|
||||||
|
const coverageJSON = [...coverage.keys()].filter(key => coverage.get(key));
|
||||||
|
await fs.promises.mkdir(path.dirname(coveragePath), { recursive: true });
|
||||||
|
await fs.promises.writeFile(coveragePath, JSON.stringify(coverageJSON, undefined, 2), 'utf8');
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
fixtures.defineTestFixture('createUserDataDir', async ({}, runTest) => {
|
fixtures.overrideTestFixtures({
|
||||||
const dirs: string[] = [];
|
testParametersPathSegment: async ({ browserName }, runTest) => {
|
||||||
async function createUserDataDir() {
|
await runTest(browserName);
|
||||||
// We do not put user data dir in testOutputPath,
|
|
||||||
// because we do not want to upload them as test result artifacts.
|
|
||||||
//
|
|
||||||
// Additionally, it is impossible to upload user data dir after test run:
|
|
||||||
// - Firefox removes lock file later, presumably from another watchdog process?
|
|
||||||
// - WebKit has circular symlinks that makes CI go crazy.
|
|
||||||
const dir = await mkdtempAsync(path.join(os.tmpdir(), 'playwright-test-'));
|
|
||||||
dirs.push(dir);
|
|
||||||
return dir;
|
|
||||||
}
|
}
|
||||||
await runTest(createUserDataDir);
|
|
||||||
await Promise.all(dirs.map(dir => removeFolderAsync(dir).catch(e => {})));
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineTestFixture('launchPersistent', async ({createUserDataDir, defaultBrowserOptions, browserType}, test) => {
|
|
||||||
let context;
|
|
||||||
async function launchPersistent(options) {
|
|
||||||
if (context)
|
|
||||||
throw new Error('can only launch one persitent context');
|
|
||||||
const userDataDir = await createUserDataDir();
|
|
||||||
context = await browserType.launchPersistentContext(userDataDir, {...defaultBrowserOptions, ...options});
|
|
||||||
const page = context.pages()[0];
|
|
||||||
return {context, page};
|
|
||||||
}
|
|
||||||
await test(launchPersistent);
|
|
||||||
if (context)
|
|
||||||
await context.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.overrideTestFixture('testParametersArtifactsPath', async ({ browserName }, runTest) => {
|
|
||||||
await runTest(browserName);
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -29,40 +29,39 @@ type HttpTestFixtures = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fixtures = baseFixtures
|
export const fixtures = baseFixtures
|
||||||
.declareWorkerFixtures<HttpWorkerFixtures>()
|
.defineWorkerFixtures<HttpWorkerFixtures>({
|
||||||
.declareTestFixtures<HttpTestFixtures>();
|
httpService: async ({ testWorkerIndex }, test) => {
|
||||||
const { defineTestFixture, defineWorkerFixture } = fixtures;
|
const assetsPath = path.join(__dirname, 'assets');
|
||||||
|
const cachedPath = path.join(__dirname, 'assets', 'cached');
|
||||||
|
|
||||||
defineWorkerFixture('httpService', async ({ testWorkerIndex }, test) => {
|
const port = 8907 + testWorkerIndex * 2;
|
||||||
const assetsPath = path.join(__dirname, 'assets');
|
const server = await TestServer.create(assetsPath, port);
|
||||||
const cachedPath = path.join(__dirname, 'assets', 'cached');
|
server.enableHTTPCache(cachedPath);
|
||||||
|
|
||||||
const port = 8907 + testWorkerIndex * 2;
|
const httpsPort = port + 1;
|
||||||
const server = await TestServer.create(assetsPath, port);
|
const httpsServer = await TestServer.createHTTPS(assetsPath, httpsPort);
|
||||||
server.enableHTTPCache(cachedPath);
|
httpsServer.enableHTTPCache(cachedPath);
|
||||||
|
|
||||||
const httpsPort = port + 1;
|
await test({ server, httpsServer });
|
||||||
const httpsServer = await TestServer.createHTTPS(assetsPath, httpsPort);
|
|
||||||
httpsServer.enableHTTPCache(cachedPath);
|
|
||||||
|
|
||||||
await test({server, httpsServer});
|
await Promise.all([
|
||||||
|
server.stop(),
|
||||||
|
httpsServer.stop(),
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
|
||||||
await Promise.all([
|
asset: async ({ }, test) => {
|
||||||
server.stop(),
|
await test(p => path.join(__dirname, `assets`, p));
|
||||||
httpsServer.stop(),
|
},
|
||||||
]);
|
})
|
||||||
});
|
.defineTestFixtures<HttpTestFixtures>({
|
||||||
|
server: async ({ httpService }, test) => {
|
||||||
|
httpService.server.reset();
|
||||||
|
await test(httpService.server);
|
||||||
|
},
|
||||||
|
|
||||||
defineTestFixture('server', async ({httpService}, test) => {
|
httpsServer: async ({ httpService }, test) => {
|
||||||
httpService.server.reset();
|
httpService.httpsServer.reset();
|
||||||
await test(httpService.server);
|
await test(httpService.httpsServer);
|
||||||
});
|
},
|
||||||
|
});
|
||||||
defineTestFixture('httpsServer', async ({httpService}, test) => {
|
|
||||||
httpService.httpsServer.reset();
|
|
||||||
await test(httpService.httpsServer);
|
|
||||||
});
|
|
||||||
|
|
||||||
defineWorkerFixture('asset', async ({}, test) => {
|
|
||||||
await test(p => path.join(__dirname, `assets`, p));
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,8 @@ type ImplWorkerFixtures = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fixtures = playwrightFixtures
|
export const fixtures = playwrightFixtures
|
||||||
.declareWorkerFixtures<ImplWorkerFixtures>();
|
.defineWorkerFixtures<ImplWorkerFixtures>({
|
||||||
const { defineWorkerFixture } = fixtures;
|
toImpl: async ({ playwright }, test) => {
|
||||||
|
await test((playwright as any)._toImpl);
|
||||||
defineWorkerFixture('toImpl', async ({ playwright }, test) => {
|
}
|
||||||
await test((playwright as any)._toImpl);
|
});
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -217,9 +217,8 @@ describe('page screenshot', (suite, { browserName, headful }) => {
|
||||||
expect(screenshot).toMatchImage('screenshot-canvas.png', { threshold: 0.3 });
|
expect(screenshot).toMatchImage('screenshot-canvas.png', { threshold: 0.3 });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work for webgl', (test, { browserName, platform }) => {
|
it('should work for webgl', (test, { browserName }) => {
|
||||||
test.fixme(browserName === 'firefox');
|
test.fixme(browserName === 'firefox' || browserName === 'webkit');
|
||||||
test.fixme(browserName === 'webkit' && platform === 'linux');
|
|
||||||
}, async ({page, server}) => {
|
}, async ({page, server}) => {
|
||||||
await page.setViewportSize({width: 640, height: 480});
|
await page.setViewportSize({width: 640, height: 480});
|
||||||
await page.goto(server.PREFIX + '/screenshots/webgl.html');
|
await page.goto(server.PREFIX + '/screenshots/webgl.html');
|
||||||
|
|
@ -262,26 +261,26 @@ describe('page screenshot', (suite, { browserName, headful }) => {
|
||||||
expect(await page.screenshot()).toMatchImage('screenshot-iframe.png');
|
expect(await page.screenshot()).toMatchImage('screenshot-iframe.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('path option should work', async ({page, server, testOutputPath}) => {
|
it('path option should work', async ({page, server, testInfo}) => {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
const outputPath = testOutputPath('screenshot.png');
|
const outputPath = testInfo.outputPath('screenshot.png');
|
||||||
await page.screenshot({path: outputPath});
|
await page.screenshot({path: outputPath});
|
||||||
expect(await fs.promises.readFile(outputPath)).toMatchImage('screenshot-sanity.png');
|
expect(await fs.promises.readFile(outputPath)).toMatchImage('screenshot-sanity.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('path option should create subdirectories', async ({page, server, testOutputPath}) => {
|
it('path option should create subdirectories', async ({page, server, testInfo}) => {
|
||||||
await page.setViewportSize({width: 500, height: 500});
|
await page.setViewportSize({width: 500, height: 500});
|
||||||
await page.goto(server.PREFIX + '/grid.html');
|
await page.goto(server.PREFIX + '/grid.html');
|
||||||
const outputPath = testOutputPath(path.join('these', 'are', 'directories', 'screenshot.png'));
|
const outputPath = testInfo.outputPath(path.join('these', 'are', 'directories', 'screenshot.png'));
|
||||||
await page.screenshot({path: outputPath});
|
await page.screenshot({path: outputPath});
|
||||||
expect(await fs.promises.readFile(outputPath)).toMatchImage('screenshot-sanity.png');
|
expect(await fs.promises.readFile(outputPath)).toMatchImage('screenshot-sanity.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('path option should detect jpeg', async ({page, server, testOutputPath}) => {
|
it('path option should detect jpeg', async ({page, server, testInfo}) => {
|
||||||
await page.setViewportSize({ width: 100, height: 100 });
|
await page.setViewportSize({ width: 100, height: 100 });
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
const outputPath = testOutputPath('screenshot.jpg');
|
const outputPath = testInfo.outputPath('screenshot.jpg');
|
||||||
const screenshot = await page.screenshot({omitBackground: true, path: outputPath});
|
const screenshot = await page.screenshot({omitBackground: true, path: outputPath});
|
||||||
expect(await fs.promises.readFile(outputPath)).toMatchImage('white.jpg');
|
expect(await fs.promises.readFile(outputPath)).toMatchImage('white.jpg');
|
||||||
expect(screenshot).toMatchImage('white.jpg');
|
expect(screenshot).toMatchImage('white.jpg');
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import fs from 'fs';
|
||||||
|
|
||||||
it('should be able to save file', (test, { browserName, headful }) => {
|
it('should be able to save file', (test, { browserName, headful }) => {
|
||||||
test.skip(headful || browserName !== 'chromium', 'Printing to pdf is currently only supported in headless chromium.');
|
test.skip(headful || browserName !== 'chromium', 'Printing to pdf is currently only supported in headless chromium.');
|
||||||
}, async ({page, testOutputPath}) => {
|
}, async ({page, testInfo}) => {
|
||||||
const outputFile = testOutputPath('output.pdf');
|
const outputFile = testInfo.outputPath('output.pdf');
|
||||||
await page.pdf({path: outputFile});
|
await page.pdf({path: outputFile});
|
||||||
expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0);
|
expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,27 +18,6 @@ import { config, fixtures as baseFixtures } from '@playwright/test-runner';
|
||||||
import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, LaunchOptions, Page } from '../index';
|
import type { Browser, BrowserContext, BrowserContextOptions, BrowserType, LaunchOptions, Page } from '../index';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
// Parameter declarations ------------------------------------------------------
|
|
||||||
|
|
||||||
type PlaywrightParameters = {
|
|
||||||
// Browser name, one of 'chromium', 'webkit' and 'firefox', can be specified via
|
|
||||||
// environment BROWSER=webkit or via command line, --browser-name=webkit
|
|
||||||
browserName: 'chromium' | 'firefox' | 'webkit';
|
|
||||||
// Run tests in a headful mode, can be specified via environment HEADFUL=1 or via
|
|
||||||
// command line, --headful. Defaults to false.
|
|
||||||
headful: boolean;
|
|
||||||
// Slows down Playwright operations by the specified amount of milliseconds.
|
|
||||||
// Useful so that you can see what is going on. Defaults to 0.
|
|
||||||
slowMo: number;
|
|
||||||
// Whether to take screenshots on failure, --screenshot-on-failure. Defaults to false.
|
|
||||||
screenshotOnFailure: boolean;
|
|
||||||
// Whether to record the execution trace
|
|
||||||
trace: boolean;
|
|
||||||
// Host platform
|
|
||||||
platform: 'win32' | 'linux' | 'darwin';
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Worker fixture declarations -------------------------------------------------
|
// Worker fixture declarations -------------------------------------------------
|
||||||
// ... these live as long as the worker process.
|
// ... these live as long as the worker process.
|
||||||
|
|
||||||
|
|
@ -49,8 +28,6 @@ type PlaywrightWorkerFixtures = {
|
||||||
browserType: BrowserType<Browser>;
|
browserType: BrowserType<Browser>;
|
||||||
// Default browserType.launch() options.
|
// Default browserType.launch() options.
|
||||||
defaultBrowserOptions: LaunchOptions;
|
defaultBrowserOptions: LaunchOptions;
|
||||||
// Factory for creating a browser with given additional options.
|
|
||||||
browserFactory: (options?: LaunchOptions) => Promise<Browser>;
|
|
||||||
// Browser instance, shared for the worker.
|
// Browser instance, shared for the worker.
|
||||||
browser: Browser;
|
browser: Browser;
|
||||||
// True iff browserName is Chromium
|
// True iff browserName is Chromium
|
||||||
|
|
@ -82,121 +59,116 @@ type PlaywrightTestFixtures = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fixtures = baseFixtures
|
export const fixtures = baseFixtures
|
||||||
.declareParameters<PlaywrightParameters>()
|
.defineParameter<'browserName', 'chromium' | 'firefox' | 'webkit'>('browserName', 'Browser type name', process.env.BROWSER || 'chromium' as any)
|
||||||
.declareWorkerFixtures<PlaywrightWorkerFixtures>()
|
.defineParameter<'headful', boolean>('headful', 'Whether to run tests headless or headful', process.env.HEADFUL ? true : false)
|
||||||
.declareTestFixtures<PlaywrightTestFixtures>();
|
.defineParameter<'platform', 'win32' | 'linux' | 'darwin'>('platform', 'Operating system', process.platform as ('win32' | 'linux' | 'darwin'))
|
||||||
|
.defineParameter<'screenshotOnFailure', boolean>('screenshotOnFailure', 'Generate screenshot on failure', false)
|
||||||
|
.defineParameter<'slowMo', number>('slowMo', 'Slows down Playwright operations by the specified amount of milliseconds', 0)
|
||||||
|
.defineParameter<'trace', boolean>('trace', 'Whether to record the execution trace', !!process.env.TRACING || false)
|
||||||
|
.defineWorkerFixtures<PlaywrightWorkerFixtures>({
|
||||||
|
defaultBrowserOptions: async ({ headful, slowMo }, runTest) => {
|
||||||
|
await runTest({
|
||||||
|
handleSIGINT: false,
|
||||||
|
slowMo,
|
||||||
|
headless: !headful,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// Parameter and matrix definitions --------------------------------------------
|
playwright: async ({ }, runTest) => {
|
||||||
|
const playwright = require('../index');
|
||||||
|
await runTest(playwright);
|
||||||
|
},
|
||||||
|
|
||||||
fixtures.defineParameter('browserName', 'Browser type name', process.env.BROWSER || 'chromium' as any);
|
browserType: async ({ playwright, browserName }, runTest) => {
|
||||||
fixtures.defineParameter('headful', 'Whether to run tests headless or headful', process.env.HEADFUL ? true : false);
|
const browserType = (playwright as any)[browserName];
|
||||||
fixtures.defineParameter('platform', 'Operating system', process.platform as ('win32' | 'linux' | 'darwin'));
|
await runTest(browserType);
|
||||||
fixtures.defineParameter('screenshotOnFailure', 'Generate screenshot on failure', false);
|
},
|
||||||
fixtures.defineParameter('slowMo', 'Slows down Playwright operations by the specified amount of milliseconds', 0);
|
|
||||||
fixtures.defineParameter('trace', 'Whether to record the execution trace', !!process.env.TRACING || false);
|
browser: async ({ browserType, defaultBrowserOptions }, runTest) => {
|
||||||
|
const browser = await browserType.launch(defaultBrowserOptions);
|
||||||
|
await runTest(browser);
|
||||||
|
await browser.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
isChromium: async ({ browserName }, runTest) => {
|
||||||
|
await runTest(browserName === 'chromium');
|
||||||
|
},
|
||||||
|
|
||||||
|
isFirefox: async ({ browserName }, runTest) => {
|
||||||
|
await runTest(browserName === 'firefox');
|
||||||
|
},
|
||||||
|
|
||||||
|
isWebKit: async ({ browserName }, runTest) => {
|
||||||
|
await runTest(browserName === 'webkit');
|
||||||
|
},
|
||||||
|
|
||||||
|
isWindows: async ({ platform }, test) => {
|
||||||
|
await test(platform === 'win32');
|
||||||
|
},
|
||||||
|
|
||||||
|
isMac: async ({ platform }, test) => {
|
||||||
|
await test(platform === 'darwin');
|
||||||
|
},
|
||||||
|
|
||||||
|
isLinux: async ({ platform }, test) => {
|
||||||
|
await test(platform === 'linux');
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.defineTestFixtures<PlaywrightTestFixtures>({
|
||||||
|
defaultContextOptions: async ({ trace, testInfo }, runTest) => {
|
||||||
|
if (trace || testInfo.retry) {
|
||||||
|
await runTest({
|
||||||
|
_traceResourcesPath: path.join(config.outputDir, 'trace-resources'),
|
||||||
|
_tracePath: testInfo.outputPath('playwright.trace'),
|
||||||
|
videosPath: testInfo.outputPath(''),
|
||||||
|
} as any);
|
||||||
|
} else {
|
||||||
|
await runTest({});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
contextFactory: async ({ browser, defaultContextOptions, testInfo, screenshotOnFailure }, runTest) => {
|
||||||
|
const contexts: BrowserContext[] = [];
|
||||||
|
async function contextFactory(options: BrowserContextOptions = {}) {
|
||||||
|
const context = await browser.newContext({ ...defaultContextOptions, ...options });
|
||||||
|
contexts.push(context);
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
await runTest(contextFactory);
|
||||||
|
|
||||||
|
if (screenshotOnFailure && (testInfo.status !== testInfo.expectedStatus)) {
|
||||||
|
let ordinal = 0;
|
||||||
|
for (const context of contexts) {
|
||||||
|
for (const page of context.pages())
|
||||||
|
await page.screenshot({ timeout: 5000, path: testInfo.outputPath + `-test-failed-${++ordinal}.png` });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const context of contexts)
|
||||||
|
await context.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
context: async ({ contextFactory }, runTest) => {
|
||||||
|
const context = await contextFactory();
|
||||||
|
await runTest(context);
|
||||||
|
// Context factory is taking care of closing the context,
|
||||||
|
// so that it could capture a screenshot on failure.
|
||||||
|
},
|
||||||
|
|
||||||
|
page: async ({ context }, runTest) => {
|
||||||
|
// Always create page off context so that they matched.
|
||||||
|
await runTest(await context.newPage());
|
||||||
|
// Context fixture is taking care of closing the page.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// If browser is not specified, we are running tests against all three browsers.
|
// If browser is not specified, we are running tests against all three browsers.
|
||||||
fixtures.generateParametrizedTests(
|
fixtures.generateParametrizedTests(
|
||||||
'browserName',
|
'browserName',
|
||||||
process.env.BROWSER ? [process.env.BROWSER] as any : ['chromium', 'webkit', 'firefox']);
|
process.env.BROWSER ? [process.env.BROWSER] as any : ['chromium', 'webkit', 'firefox']);
|
||||||
|
|
||||||
// Worker fixtures definitions -------------------------------------------------
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('defaultBrowserOptions', async ({ headful, slowMo }, runTest) => {
|
fixtures.overrideTestFixtures({
|
||||||
await runTest({
|
testParametersPathSegment: async ({ browserName, platform }, runTest) => {
|
||||||
handleSIGINT: false,
|
await runTest(browserName + '-' + platform);
|
||||||
slowMo,
|
|
||||||
headless: !headful,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('playwright', async ({}, runTest) => {
|
|
||||||
const playwright = require('../index');
|
|
||||||
await runTest(playwright);
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('browserType', async ({playwright, browserName}, runTest) => {
|
|
||||||
const browserType = playwright[browserName];
|
|
||||||
await runTest(browserType);
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, runTest) => {
|
|
||||||
const browser = await browserType.launch(defaultBrowserOptions);
|
|
||||||
await runTest(browser);
|
|
||||||
await browser.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('isChromium', async ({browserName}, runTest) => {
|
|
||||||
await runTest(browserName === 'chromium');
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('isFirefox', async ({browserName}, runTest) => {
|
|
||||||
await runTest(browserName === 'firefox');
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('isWebKit', async ({browserName}, runTest) => {
|
|
||||||
await runTest(browserName === 'webkit');
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('isWindows', async ({platform}, test) => {
|
|
||||||
await test(platform === 'win32');
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('isMac', async ({platform}, test) => {
|
|
||||||
await test(platform === 'darwin');
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineWorkerFixture('isLinux', async ({platform}, test) => {
|
|
||||||
await test(platform === 'linux');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Test fixtures definitions ---------------------------------------------------
|
|
||||||
|
|
||||||
fixtures.defineTestFixture('defaultContextOptions', async ({ testOutputPath, trace, testInfo }, runTest) => {
|
|
||||||
if (trace || testInfo.retry) {
|
|
||||||
await runTest({
|
|
||||||
_traceResourcesPath: path.join(config.outputDir, 'trace-resources'),
|
|
||||||
_tracePath: testOutputPath('playwright.trace'),
|
|
||||||
videosPath: testOutputPath(''),
|
|
||||||
} as any);
|
|
||||||
} else {
|
|
||||||
await runTest({});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
fixtures.defineTestFixture('contextFactory', async ({ browser, defaultContextOptions, testInfo, screenshotOnFailure, testOutputPath }, runTest) => {
|
|
||||||
const contexts: BrowserContext[] = [];
|
|
||||||
async function contextFactory(options: BrowserContextOptions = {}) {
|
|
||||||
const context = await browser.newContext({ ...defaultContextOptions, ...options });
|
|
||||||
contexts.push(context);
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
await runTest(contextFactory);
|
|
||||||
|
|
||||||
if (screenshotOnFailure && (testInfo.status !== testInfo.expectedStatus)) {
|
|
||||||
let ordinal = 0;
|
|
||||||
for (const context of contexts) {
|
|
||||||
for (const page of context.pages())
|
|
||||||
await page.screenshot({ timeout: 5000, path: testOutputPath + `-test-failed-${++ordinal}.png` });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const context of contexts)
|
|
||||||
await context.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineTestFixture('context', async ({ contextFactory }, runTest) => {
|
|
||||||
const context = await contextFactory();
|
|
||||||
await runTest(context);
|
|
||||||
// Context factory is taking care of closing the context,
|
|
||||||
// so that it could capture a screenshot on failure.
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.defineTestFixture('page', async ({context}, runTest) => {
|
|
||||||
// Always create page off context so that they matched.
|
|
||||||
await runTest(await context.newPage());
|
|
||||||
// Context fixture is taking care of closing the page.
|
|
||||||
});
|
|
||||||
|
|
||||||
fixtures.overrideTestFixture('testParametersArtifactsPath', async ({ browserName, platform }, runTest) => {
|
|
||||||
await runTest(browserName + '-' + platform);
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,22 @@ type ServerFixtures = {
|
||||||
remoteServer: RemoteServer;
|
remoteServer: RemoteServer;
|
||||||
stallingRemoteServer: RemoteServer;
|
stallingRemoteServer: RemoteServer;
|
||||||
};
|
};
|
||||||
export const serverFixtures = baseFixtures.declareTestFixtures<ServerFixtures>();
|
|
||||||
const { defineTestFixture } = serverFixtures;
|
export const serverFixtures = baseFixtures.defineTestFixtures<ServerFixtures>({
|
||||||
|
remoteServer: async ({ browserType, defaultBrowserOptions }, test) => {
|
||||||
|
const remoteServer = new RemoteServer();
|
||||||
|
await remoteServer._start(browserType, defaultBrowserOptions);
|
||||||
|
await test(remoteServer);
|
||||||
|
await remoteServer.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
stallingRemoteServer: async ({ browserType, defaultBrowserOptions }, test) => {
|
||||||
|
const remoteServer = new RemoteServer();
|
||||||
|
await remoteServer._start(browserType, defaultBrowserOptions, { stallOnClose: true });
|
||||||
|
await test(remoteServer);
|
||||||
|
await remoteServer.close();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const playwrightPath = path.join(__dirname, '..');
|
const playwrightPath = path.join(__dirname, '..');
|
||||||
|
|
||||||
|
|
@ -115,17 +129,3 @@ export class RemoteServer {
|
||||||
return await this.childExitCode();
|
return await this.childExitCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineTestFixture('remoteServer', async ({browserType, defaultBrowserOptions}, test) => {
|
|
||||||
const remoteServer = new RemoteServer();
|
|
||||||
await remoteServer._start(browserType, defaultBrowserOptions);
|
|
||||||
await test(remoteServer);
|
|
||||||
await remoteServer.close();
|
|
||||||
});
|
|
||||||
|
|
||||||
defineTestFixture('stallingRemoteServer', async ({browserType, defaultBrowserOptions}, test) => {
|
|
||||||
const remoteServer = new RemoteServer();
|
|
||||||
await remoteServer._start(browserType, defaultBrowserOptions, { stallOnClose: true });
|
|
||||||
await test(remoteServer);
|
|
||||||
await remoteServer.close();
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,8 @@ describe('screencast', suite => {
|
||||||
|
|
||||||
it('should capture static page', (test, { browserName }) => {
|
it('should capture static page', (test, { browserName }) => {
|
||||||
test.fixme(browserName === 'firefox', 'Always clips to square');
|
test.fixme(browserName === 'firefox', 'Always clips to square');
|
||||||
}, async ({browser, testOutputPath}) => {
|
}, async ({browser, testInfo}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const size = { width: 320, height: 240 };
|
const size = { width: 320, height: 240 };
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
videosPath,
|
videosPath,
|
||||||
|
|
@ -182,8 +182,8 @@ describe('screencast', suite => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should capture navigation', async ({browser, server, testOutputPath}) => {
|
it('should capture navigation', async ({browser, server, testInfo}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
videosPath,
|
videosPath,
|
||||||
videoSize: { width: 1280, height: 720 }
|
videoSize: { width: 1280, height: 720 }
|
||||||
|
|
@ -214,8 +214,8 @@ describe('screencast', suite => {
|
||||||
|
|
||||||
it('should capture css transformation', (test, { browserName, platform, headful }) => {
|
it('should capture css transformation', (test, { browserName, platform, headful }) => {
|
||||||
test.fixme(headful, 'Fails on headful');
|
test.fixme(headful, 'Fails on headful');
|
||||||
}, async ({browser, server, testOutputPath}) => {
|
}, async ({browser, server, testInfo}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const size = { width: 320, height: 240 };
|
const size = { width: 320, height: 240 };
|
||||||
// Set viewport equal to screencast frame size to avoid scaling.
|
// Set viewport equal to screencast frame size to avoid scaling.
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
|
|
@ -240,8 +240,8 @@ describe('screencast', suite => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work for popups', async ({browser, testOutputPath, server}) => {
|
it('should work for popups', async ({browser, testInfo, server}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
videosPath,
|
videosPath,
|
||||||
videoSize: { width: 320, height: 240 }
|
videoSize: { width: 320, height: 240 }
|
||||||
|
|
@ -262,8 +262,8 @@ describe('screencast', suite => {
|
||||||
|
|
||||||
it('should scale frames down to the requested size ', (test, parameters) => {
|
it('should scale frames down to the requested size ', (test, parameters) => {
|
||||||
test.fixme(parameters.headful, 'Fails on headful');
|
test.fixme(parameters.headful, 'Fails on headful');
|
||||||
}, async ({browser, testOutputPath, server}) => {
|
}, async ({browser, testInfo, server}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
videosPath,
|
videosPath,
|
||||||
viewport: {width: 640, height: 480},
|
viewport: {width: 640, height: 480},
|
||||||
|
|
@ -307,8 +307,8 @@ describe('screencast', suite => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use viewport as default size', async ({browser, testOutputPath}) => {
|
it('should use viewport as default size', async ({browser, testInfo}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const size = {width: 800, height: 600};
|
const size = {width: 800, height: 600};
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
videosPath,
|
videosPath,
|
||||||
|
|
@ -325,8 +325,8 @@ describe('screencast', suite => {
|
||||||
expect(await videoPlayer.videoHeight).toBe(size.height);
|
expect(await videoPlayer.videoHeight).toBe(size.height);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be 1280x720 by default', async ({browser, testOutputPath}) => {
|
it('should be 1280x720 by default', async ({browser, testInfo}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const context = await browser.newContext({
|
const context = await browser.newContext({
|
||||||
videosPath,
|
videosPath,
|
||||||
});
|
});
|
||||||
|
|
@ -341,8 +341,8 @@ describe('screencast', suite => {
|
||||||
expect(await videoPlayer.videoHeight).toBe(720);
|
expect(await videoPlayer.videoHeight).toBe(720);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should capture static page in persistent context', async ({launchPersistent, testOutputPath}) => {
|
it('should capture static page in persistent context', async ({launchPersistent, testInfo}) => {
|
||||||
const videosPath = testOutputPath('');
|
const videosPath = testInfo.outputPath('');
|
||||||
const size = { width: 320, height: 240 };
|
const size = { width: 320, height: 240 };
|
||||||
const { context, page } = await launchPersistent({
|
const { context, page } = await launchPersistent({
|
||||||
videosPath,
|
videosPath,
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ import type * as trace from '../types/trace';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
|
|
||||||
it('should record trace', async ({browser, testOutputPath, server}) => {
|
it('should record trace', async ({browser, testInfo, server}) => {
|
||||||
const artifactsPath = testOutputPath('');
|
const artifactsPath = testInfo.outputPath('');
|
||||||
const tracePath = path.join(artifactsPath, 'playwright.trace');
|
const tracePath = path.join(artifactsPath, 'playwright.trace');
|
||||||
const context = await browser.newContext({ _tracePath: tracePath } as any);
|
const context = await browser.newContext({ _tracePath: tracePath } as any);
|
||||||
const page = await context.newPage();
|
const page = await context.newPage();
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,15 @@ const Source = require('../../Source');
|
||||||
const mdBuilder = require('../MDBuilder');
|
const mdBuilder = require('../MDBuilder');
|
||||||
const jsBuilder = require('../JSBuilder');
|
const jsBuilder = require('../JSBuilder');
|
||||||
const { fixtures } = require('@playwright/test-runner');
|
const { fixtures } = require('@playwright/test-runner');
|
||||||
const { defineWorkerFixture, describe, it, expect } = fixtures;
|
const { defineWorkerFixtures, describe, it, expect } = fixtures;
|
||||||
|
|
||||||
defineWorkerFixture('page', async({}, test) => {
|
defineWorkerFixtures({
|
||||||
const browser = await playwright.chromium.launch();
|
page: async({}, test) => {
|
||||||
const page = await browser.newPage();
|
const browser = await playwright.chromium.launch();
|
||||||
await test(page);
|
const page = await browser.newPage();
|
||||||
await browser.close();
|
await test(page);
|
||||||
|
await browser.close();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('checkPublicAPI', function() {
|
describe('checkPublicAPI', function() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue