test: roll test runner to 0.9.20 (#4062)

This commit is contained in:
Pavel Feldman 2020-10-05 17:03:24 -07:00 коммит произвёл GitHub
Родитель 2df6425254
Коммит 0db09f8ed4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
21 изменённых файлов: 480 добавлений и 516 удалений

166
package-lock.json сгенерированный
Просмотреть файл

@ -1096,9 +1096,9 @@
}
},
"@jest/types": {
"version": "26.3.0",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz",
"integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==",
"version": "26.5.0",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.0.tgz",
"integrity": "sha512-nH9DFLqaIhB+RVgjivemvMiFSWw/BKwbZGxBAMv8CCTvUyFoK8RwHhAlmlXIvMBrf5Z3YQ4p9cq3Qh9EDctGvA==",
"dev": true,
"requires": {
"@types/istanbul-lib-coverage": "^2.0.0",
@ -1109,12 +1109,11 @@
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -1161,22 +1160,19 @@
}
},
"@playwright/test": {
"version": "0.9.7",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-0.9.7.tgz",
"integrity": "sha512-llqV967KlRZ5mWNm0DpEkqi/42UBIssM/JzZ83KbTQdbmGhmx8L4hcJ6c1ExeFe/qq5uvL0mae1yuKfqxPBrPg==",
"version": "0.9.9",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-0.9.9.tgz",
"integrity": "sha512-JcpesJZG1EEdqlWllRHlprQ7v7IxL9IujwuIK/YcGpeeihEgZCyacL55Zg9i45n+0BWzXnOPQURCdWL4VnXySw==",
"dev": true,
"requires": {
"jpeg-js": "^0.4.2",
"pixelmatch": "^5.2.1",
"playwright": "1.4.0-next.1601161680085",
"pngjs": "^5.0.0",
"rimraf": "^3.0.2"
}
},
"@playwright/test-runner": {
"version": "0.9.17",
"resolved": "https://registry.npmjs.org/@playwright/test-runner/-/test-runner-0.9.17.tgz",
"integrity": "sha512-9d0b99Rir+Vck8r1Zak17QB6vG/AzabURLXv9nlvVFFDRqmttRVPfnGgvlQ7Ae4lkUhYk2JSHX2ETq/nvMfwlg==",
"version": "0.9.20",
"resolved": "https://registry.npmjs.org/@playwright/test-runner/-/test-runner-0.9.20.tgz",
"integrity": "sha512-3en4cjeWn2JgrHTJEmPVrYmEBkYegSu3uML49mcmQLpNyozyGy4EKysoeUuyXRoZQz4ptWY6AzFtFPyt34KLCw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.10.4",
@ -1188,9 +1184,13 @@
"commander": "^6.1.0",
"debug": "^4.1.5",
"expect": "^26.4.2",
"jpeg-js": "^0.4.2",
"micromatch": "^4.0.2",
"ms": "^2.1.2",
"pirates": "^4.0.1",
"pixelmatch": "^5.2.1",
"pngjs": "^5.0.0",
"pretty-format": "^26.4.2",
"rimraf": "^3.0.2",
"source-map-support": "^0.5.19",
"stack-utils": "^2.0.2"
@ -1211,12 +1211,6 @@
"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": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
@ -1346,9 +1340,9 @@
}
},
"@types/stack-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz",
"integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==",
"dev": true
},
"@types/ws": {
@ -1667,9 +1661,9 @@
"dev": true
},
"acorn": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
"dev": true
},
"acorn-jsx": {
@ -2231,9 +2225,9 @@
"dev": true
},
"caniuse-lite": {
"version": "1.0.30001141",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001141.tgz",
"integrity": "sha512-EHfInJHoQTmlMdVZrEc5gmwPc0zyN/hVufmGHPbVNQwlk7tJfCmQ2ysRZMY2MeleBivALUTyyxXnQjK18XrVpA==",
"version": "1.0.30001143",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001143.tgz",
"integrity": "sha512-p/PO5YbwmCpBJPxjOiKBvAlUPgF8dExhfEpnsH+ys4N/791WHrYrGg0cyHiAURl5hSbx5vIcjKmQAP6sHDYH3w==",
"dev": true
},
"chalk": {
@ -2760,9 +2754,9 @@
"optional": true
},
"diff-sequences": {
"version": "26.3.0",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz",
"integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==",
"version": "26.5.0",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.5.0.tgz",
"integrity": "sha512-ZXx86srb/iYy6jG71k++wBN9P9J05UNQ5hQHQd9MtMPvcqXPx/vKU69jfHV637D00Q2gSgPk2D+jSx3l1lDW/Q==",
"dev": true
},
"diffie-hellman": {
@ -2818,9 +2812,9 @@
}
},
"electron": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-9.3.1.tgz",
"integrity": "sha512-DScrhqBT4a54KfdF0EoipALpHmdQTn3m7SSCtbpTcEcG+UDUiXad2cOfW6DHeVH7N+CVDKDG12q2PhVJjXkFAA==",
"version": "9.3.2",
"resolved": "https://registry.npmjs.org/electron/-/electron-9.3.2.tgz",
"integrity": "sha512-0lleEf9msAXGDi2GukAuiGdw3VDgSTlONOnJgqDEz1fuSEVsXz5RX+hNPKDsVDerLTFg/C34RuJf4LwHvkKcBA==",
"dev": true,
"requires": {
"@electron/get": "^1.0.1",
@ -3056,12 +3050,11 @@
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -3303,26 +3296,25 @@
}
},
"expect": {
"version": "26.4.2",
"resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz",
"integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==",
"version": "26.5.0",
"resolved": "https://registry.npmjs.org/expect/-/expect-26.5.0.tgz",
"integrity": "sha512-oIOy3mHWjnF5ZICuaui5kdtJZQ+D7XHWyUQDxk1WhIRCkcIYc24X23bOfikgCNU6i9wcSqLQhwPOqeRp09naxg==",
"dev": true,
"requires": {
"@jest/types": "^26.3.0",
"@jest/types": "^26.5.0",
"ansi-styles": "^4.0.0",
"jest-get-type": "^26.3.0",
"jest-matcher-utils": "^26.4.2",
"jest-message-util": "^26.3.0",
"jest-matcher-utils": "^26.5.0",
"jest-message-util": "^26.5.0",
"jest-regex-util": "^26.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -4376,24 +4368,23 @@
"dev": true
},
"jest-diff": {
"version": "26.4.2",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz",
"integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==",
"version": "26.5.0",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.5.0.tgz",
"integrity": "sha512-CmDMMPkVMxrrh0Dv/4M9kh1tsYsZnYTQMMTvIFpePBSk9wMVfcyfg30TCq+oR9AzGbw8vsI50Gk1HmlMMlhoJg==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"diff-sequences": "^26.3.0",
"diff-sequences": "^26.5.0",
"jest-get-type": "^26.3.0",
"pretty-format": "^26.4.2"
"pretty-format": "^26.5.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -4446,24 +4437,23 @@
"dev": true
},
"jest-matcher-utils": {
"version": "26.4.2",
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.2.tgz",
"integrity": "sha512-KcbNqWfWUG24R7tu9WcAOKKdiXiXCbMvQYT6iodZ9k1f7065k0keUOW6XpJMMvah+hTfqkhJhRXmA3r3zMAg0Q==",
"version": "26.5.0",
"resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.5.0.tgz",
"integrity": "sha512-QgbbxqFT8wiTi4o/7MWj2vHlcmMjACG8vnJ9pJ7svVDmkzEnTUGdHXWLKB1aZhbnyXetMNRF+TSMcDS9aGfuzA==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"jest-diff": "^26.4.2",
"jest-diff": "^26.5.0",
"jest-get-type": "^26.3.0",
"pretty-format": "^26.4.2"
"pretty-format": "^26.5.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -4510,14 +4500,14 @@
}
},
"jest-message-util": {
"version": "26.3.0",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz",
"integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==",
"version": "26.5.0",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.5.0.tgz",
"integrity": "sha512-UEOqdoTfX0AFyReL4q5N3CfDBWt+AtQzeszZuuGapU39vwEk90rTSBghCA/3FFEZzvGfH2LE4+0NaBI81Cu2Ow==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@jest/types": "^26.3.0",
"@types/stack-utils": "^1.0.1",
"@jest/types": "^26.5.0",
"@types/stack-utils": "^2.0.0",
"chalk": "^4.0.0",
"graceful-fs": "^4.2.4",
"micromatch": "^4.0.2",
@ -4526,12 +4516,11 @@
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -5458,24 +5447,23 @@
"dev": true
},
"pretty-format": {
"version": "26.4.2",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz",
"integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==",
"version": "26.5.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.0.tgz",
"integrity": "sha512-NcgRuuTutUJ9+Br4P19DFThpJYnYBiugfRmZEA6pXrUeG+IcMSmppb88rU+iPA+XAJcjTYlCb5Ed6miHg/Qqqw==",
"dev": true,
"requires": {
"@jest/types": "^26.3.0",
"@jest/types": "^26.5.0",
"ansi-regex": "^5.0.0",
"ansi-styles": "^4.0.0",
"react-is": "^16.12.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
@ -7214,9 +7202,9 @@
},
"dependencies": {
"acorn": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
"version": "6.4.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
"integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
"dev": true
},
"braces": {

Просмотреть файл

@ -50,8 +50,8 @@
"ws": "^7.3.1"
},
"devDependencies": {
"@playwright/test": "^0.9.7",
"@playwright/test-runner": "^0.9.17",
"@playwright/test": "0.9.9",
"@playwright/test-runner": "0.9.20",
"@types/debug": "^4.1.5",
"@types/extract-zip": "^1.6.2",
"@types/mime": "^2.0.3",

Просмотреть файл

@ -234,9 +234,11 @@ describe('connect', (suite, { wire }) => {
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 videosPath = testOutputPath();
const videosPath = testInfo.outputPath();
const context = await remote.newContext({
videosPath,
videoSize: { width: 320, height: 240 },

Просмотреть файл

@ -23,8 +23,8 @@ type DomainFixtures = {
domain: any;
};
const fixtures = baseFixtures.declareWorkerFixtures<DomainFixtures>();
fixtures.defineWorkerFixture('domain', async ({ }, test) => {
const fixtures = baseFixtures.defineWorkerFixtures<DomainFixtures>({
domain: async ({ }, test) => {
const local = domain.create();
local.run(() => { });
let err;
@ -32,6 +32,7 @@ fixtures.defineWorkerFixture('domain', async ({ }, test) => {
await test(null);
if (err)
throw err;
}
});
const { it, expect } = fixtures;

Просмотреть файл

@ -15,15 +15,17 @@
*/
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({
browser: async ({browserType, defaultBrowserOptions}, test) => {
const browser = await browserType.launch({
...defaultBrowserOptions,
args: (defaultBrowserOptions.args || []).concat(['--site-per-process'])
});
await test(browser);
await browser.close();
}
});
describe('oopif', (suite, { browserName }) => {

Просмотреть файл

@ -22,13 +22,14 @@ import type { ChromiumBrowser } from '../..';
type TestState = {
outputTraceFile: string;
};
const fixtures = playwrightFixtures.declareTestFixtures<TestState>();
const { it, expect, describe, defineTestFixture } = fixtures;
defineTestFixture('outputTraceFile', async ({testOutputPath}, test) => {
await test(testOutputPath(path.join(`trace.json`)));
const fixtures = playwrightFixtures.defineTestFixtures<TestState>({
outputTraceFile: async ({ testInfo }, test) => {
await test(testInfo.outputPath(path.join(`trace.json`)));
}
});
const { it, expect, describe } = fixtures;
describe('oopif', (suite, { browserName }) => {
suite.skip(browserName !== 'chromium');
}, () => {
@ -39,8 +40,8 @@ describe('oopif', (suite, { browserName }) => {
expect(fs.existsSync(outputTraceFile)).toBe(true);
});
it('should create directories as needed', async ({browser, page, server, testOutputPath}) => {
const filePath = testOutputPath(path.join('these', 'are', 'directories', 'trace.json'));
it('should create directories as needed', async ({browser, page, server, testInfo}) => {
const filePath = testInfo.outputPath(path.join('these', 'are', 'directories', 'trace.json'));
await (browser as ChromiumBrowser).startTracing(page, {screenshots: true, path: filePath});
await page.goto(server.PREFIX + '/grid.html');
await (browser as ChromiumBrowser).stopTracing();

Просмотреть файл

@ -61,28 +61,28 @@ it('should report downloads with acceptDownloads: true', async ({browser, server
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
page.waitForEvent('download'),
page.click('a')
]);
const userPath = testOutputPath('download.txt');
const userPath = testInfo.outputPath('download.txt');
await download.saveAs(userPath);
expect(fs.existsSync(userPath)).toBeTruthy();
expect(fs.readFileSync(userPath).toString()).toBe('Hello world');
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
page.waitForEvent('download'),
page.click('a')
]);
const userPath = testOutputPath('download.txt');
const userPath = testInfo.outputPath('download.txt');
await download.saveAs(userPath);
expect(fs.existsSync(userPath)).toBeTruthy();
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();
});
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
page.waitForEvent('download'),
page.click('a')
]);
const userPath = testOutputPath('download.txt');
const userPath = testInfo.outputPath('download.txt');
await download.saveAs(userPath);
expect(fs.existsSync(userPath)).toBeTruthy();
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);
expect(fs.existsSync(anotherUserPath)).toBeTruthy();
expect(fs.readFileSync(anotherUserPath).toString()).toBe('Hello world');
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
page.waitForEvent('download'),
page.click('a')
]);
const dir = testOutputPath('downloads');
const dir = testInfo.outputPath('downloads');
const userPath = path.join(dir, 'download.txt');
await download.saveAs(userPath);
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();
});
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
page.waitForEvent('download'),
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);
expect(fs.existsSync(nestedPath)).toBeTruthy();
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 }) => {
test.skip(wire);
}, async ({testOutputPath, server, browserType, remoteServer}) => {
}, async ({testInfo, server, browserType, remoteServer}) => {
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
const page = await browser.newPage({ acceptDownloads: true });
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.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);
expect(fs.existsSync(nestedPath)).toBeTruthy();
expect(fs.readFileSync(nestedPath).toString()).toBe('Hello world');
@ -163,27 +163,27 @@ it('should save when connected remotely', (test, { wire }) => {
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
page.waitForEvent('download'),
page.click('a')
]);
const userPath = testOutputPath('download.txt');
const userPath = testInfo.outputPath('download.txt');
const { message } = await download.saveAs(userPath).catch(e => e);
expect(message).toContain('Pass { acceptDownloads: true } when you are creating your browser context');
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
page.waitForEvent('download'),
page.click('a')
]);
const userPath = testOutputPath('download.txt');
const userPath = testInfo.outputPath('download.txt');
await download.delete();
const { message } = await download.saveAs(userPath).catch(e => e);
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 }) => {
test.skip(wire);
}, async ({testOutputPath, server, browserType, remoteServer}) => {
}, async ({testInfo, server, browserType, remoteServer}) => {
const browser = await browserType.connect({ wsEndpoint: remoteServer.wsEndpoint() });
const page = await browser.newPage({ acceptDownloads: true });
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.click('a')
]);
const userPath = testOutputPath('download.txt');
const userPath = testInfo.outputPath('download.txt');
await download.delete();
const { message } = await download.saveAs(userPath).catch(e => e);
expect(message).toContain('Download already deleted. Save before deleting.');

Просмотреть файл

@ -23,10 +23,8 @@ type TestState = {
downloadsBrowser: Browser;
persistentDownloadsContext: BrowserContext;
};
const fixtures = baseFixtures.declareTestFixtures<TestState>();
const { it, expect, defineTestFixture } = fixtures;
defineTestFixture('downloadsBrowser', async ({server, browserType, defaultBrowserOptions, testOutputPath}, test) => {
const fixtures = baseFixtures.defineTestFixtures<TestState>({
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');
@ -34,13 +32,13 @@ defineTestFixture('downloadsBrowser', async ({server, browserType, defaultBrowse
});
const browser = await browserType.launch({
...defaultBrowserOptions,
downloadsPath: testOutputPath(''),
downloadsPath: testInfo.outputPath(''),
});
await test(browser);
await browser.close();
});
},
defineTestFixture('persistentDownloadsContext', async ({server, launchPersistent, testOutputPath}, test) => {
persistentDownloadsContext: async ({ server, launchPersistent, testInfo }, test) => {
server.setRoute('/download', (req, res) => {
res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader('Content-Disposition', 'attachment; filename=file.txt');
@ -48,16 +46,19 @@ defineTestFixture('persistentDownloadsContext', async ({server, launchPersistent
});
const { context, page } = await launchPersistent(
{
downloadsPath: testOutputPath(''),
downloadsPath: testInfo.outputPath(''),
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}) => {
const { it, expect } = fixtures;
it('should keep downloadsPath folder', async ({downloadsBrowser, testInfo, server}) => {
const page = await downloadsBrowser.newPage();
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
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 page.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}) => {
@ -85,7 +86,7 @@ it('should delete downloads when context closes', async ({downloadsBrowser, serv
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 });
await page.setContent(`<a href="${server.PREFIX}/download">download</a>`);
const [ download ] = await Promise.all([
@ -93,11 +94,11 @@ it('should report downloads in downloadsPath folder', async ({downloadsBrowser,
page.click('a')
]);
const path = await download.path();
expect(path.startsWith(testOutputPath(''))).toBeTruthy();
expect(path.startsWith(testInfo.outputPath(''))).toBeTruthy();
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 [ download ] = await Promise.all([
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.suggestedFilename()).toBe(`file.txt`);
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}) => {

Просмотреть файл

@ -15,7 +15,7 @@
*/
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';
const electronName = process.platform === 'win32' ? 'electron.cmd' : 'electron';
@ -25,24 +25,23 @@ type TestState = {
window: ElectronPage;
};
export const electronFixtures = baseFixtures.declareTestFixtures<TestState>();
const { defineTestFixture } = electronFixtures;
declare module '../../index' {
const electron: ElectronLauncher;
}
defineTestFixture('application', async ({playwright}, test) => {
export const electronFixtures = baseFixtures.defineTestFixtures<TestState>({
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) => {
window: async ({ application }, test) => {
const page = await application.newBrowserWindow({ width: 800, height: 600 });
await test(page);
await page.close();
},
});
declare module '../../index' {
const electron: ElectronLauncher;
}

Просмотреть файл

@ -384,12 +384,12 @@ describe('element screenshot', (suite, parameters) => {
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.goto(server.PREFIX + '/grid.html');
await page.evaluate(() => window.scrollBy(50, 100));
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});
expect(await fs.promises.readFile(outputPath)).toMatchImage('screenshot-element-bounding-box.png');
});

Просмотреть файл

@ -25,25 +25,26 @@ export type FixturesFixtures = {
stallingConnectedRemoteServer: RemoteServer;
};
const fixturesFixtures = serverFixtures.declareTestFixtures<FixturesFixtures>();
const { it, describe, expect, defineTestFixture } = fixturesFixtures;
defineTestFixture('connectedRemoteServer', async ({browserType, remoteServer, server}, test) => {
const fixturesFixtures = serverFixtures.defineTestFixtures<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('stallingConnectedRemoteServer', async ({browserType, stallingRemoteServer, server}, test) => {
stallingConnectedRemoteServer: async ({browserType, stallingRemoteServer, server}, test) => {
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();
},
});
const { it, describe, expect } = fixturesFixtures;
it('should close the browser when the node process closes', test => {
test.slow();
test.flaky('Flakes at least on WebKit Linux');

Просмотреть файл

@ -27,26 +27,53 @@ import { installCoverageHooks } from './coverage';
import { fixtures as httpFixtures } from './http.fixtures';
import { fixtures as implFixtures } from './impl.fixtures';
import { fixtures as playwrightFixtures } from './playwright.fixtures';
export { expect } from '@playwright/test/out/matcher.fixtures';
export { config } from '@playwright/test-runner';
export { expect, config } from '@playwright/test-runner';
const removeFolderAsync = util.promisify(require('rimraf'));
const mkdtempAsync = util.promisify(fs.mkdtemp);
type AllParameters = {
wire: boolean;
};
type AllTestFixtures = {
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
.union(httpFixtures)
.union(implFixtures)
.declareParameters<AllParameters>()
.declareTestFixtures<AllTestFixtures>();
.defineParameter('wire', 'Wire testing mode', !!process.env.PWWIRE || false)
.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 fit = fixtures.fit;
@ -59,7 +86,6 @@ export const afterEach = fixtures.afterEach;
export const beforeAll = fixtures.beforeAll;
export const afterAll = fixtures.afterAll;
fixtures.defineParameter('wire', 'Wire testing mode', !!process.env.PWWIRE || false);
fixtures.generateParametrizedTests(
'platform',
@ -74,7 +100,8 @@ const getExecutablePath = browserName => {
return process.env.WKPATH;
};
fixtures.overrideWorkerFixture('defaultBrowserOptions', async ({ browserName, headful, slowMo }, runTest) => {
fixtures.overrideWorkerFixtures({
defaultBrowserOptions: async ({ browserName, headful, slowMo }, runTest) => {
const executablePath = getExecutablePath(browserName);
if (executablePath)
console.error(`Using executable at ${executablePath}`);
@ -84,11 +111,11 @@ fixtures.overrideWorkerFixture('defaultBrowserOptions', async ({ browserName, he
slowMo,
headless: !headful,
});
});
},
fixtures.overrideWorkerFixture('playwright', async ({ browserName, testWorkerIndex, platform, wire }, runTest) => {
playwright: async ({ browserName, testWorkerIndex, platform, wire }, runTest) => {
assert(platform); // Depend on platform to generate all tests.
const {coverage, uninstall} = installCoverageHooks(browserName);
const { coverage, uninstall } = installCoverageHooks(browserName);
if (wire) {
require('../lib/utils/utils').setUnderTest();
const connection = new Connection();
@ -124,40 +151,11 @@ fixtures.overrideWorkerFixture('playwright', async ({ browserName, testWorkerInd
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) => {
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 => {})));
});
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) => {
fixtures.overrideTestFixtures({
testParametersPathSegment: async ({ browserName }, runTest) => {
await runTest(browserName);
}
});

Просмотреть файл

@ -29,11 +29,8 @@ type HttpTestFixtures = {
};
export const fixtures = baseFixtures
.declareWorkerFixtures<HttpWorkerFixtures>()
.declareTestFixtures<HttpTestFixtures>();
const { defineTestFixture, defineWorkerFixture } = fixtures;
defineWorkerFixture('httpService', async ({ testWorkerIndex }, test) => {
.defineWorkerFixtures<HttpWorkerFixtures>({
httpService: async ({ testWorkerIndex }, test) => {
const assetsPath = path.join(__dirname, 'assets');
const cachedPath = path.join(__dirname, 'assets', 'cached');
@ -45,24 +42,26 @@ defineWorkerFixture('httpService', async ({ testWorkerIndex }, test) => {
const httpsServer = await TestServer.createHTTPS(assetsPath, httpsPort);
httpsServer.enableHTTPCache(cachedPath);
await test({server, httpsServer});
await test({ server, httpsServer });
await Promise.all([
server.stop(),
httpsServer.stop(),
]);
});
},
defineTestFixture('server', async ({httpService}, test) => {
asset: async ({ }, test) => {
await test(p => path.join(__dirname, `assets`, p));
},
})
.defineTestFixtures<HttpTestFixtures>({
server: async ({ httpService }, test) => {
httpService.server.reset();
await test(httpService.server);
});
},
defineTestFixture('httpsServer', async ({httpService}, test) => {
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
.declareWorkerFixtures<ImplWorkerFixtures>();
const { defineWorkerFixture } = fixtures;
defineWorkerFixture('toImpl', async ({ playwright }, test) => {
.defineWorkerFixtures<ImplWorkerFixtures>({
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 });
});
it('should work for webgl', (test, { browserName, platform }) => {
test.fixme(browserName === 'firefox');
test.fixme(browserName === 'webkit' && platform === 'linux');
it('should work for webgl', (test, { browserName }) => {
test.fixme(browserName === 'firefox' || browserName === 'webkit');
}, async ({page, server}) => {
await page.setViewportSize({width: 640, height: 480});
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');
});
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.goto(server.PREFIX + '/grid.html');
const outputPath = testOutputPath('screenshot.png');
const outputPath = testInfo.outputPath('screenshot.png');
await page.screenshot({path: outputPath});
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.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});
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.goto(server.EMPTY_PAGE);
const outputPath = testOutputPath('screenshot.jpg');
const outputPath = testInfo.outputPath('screenshot.jpg');
const screenshot = await page.screenshot({omitBackground: true, path: outputPath});
expect(await fs.promises.readFile(outputPath)).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 }) => {
test.skip(headful || browserName !== 'chromium', 'Printing to pdf is currently only supported in headless chromium.');
}, async ({page, testOutputPath}) => {
const outputFile = testOutputPath('output.pdf');
}, async ({page, testInfo}) => {
const outputFile = testInfo.outputPath('output.pdf');
await page.pdf({path: outputFile});
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 * 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 -------------------------------------------------
// ... these live as long as the worker process.
@ -49,8 +28,6 @@ type PlaywrightWorkerFixtures = {
browserType: BrowserType<Browser>;
// Default browserType.launch() options.
defaultBrowserOptions: LaunchOptions;
// Factory for creating a browser with given additional options.
browserFactory: (options?: LaunchOptions) => Promise<Browser>;
// Browser instance, shared for the worker.
browser: Browser;
// True iff browserName is Chromium
@ -82,89 +59,75 @@ type PlaywrightTestFixtures = {
};
export const fixtures = baseFixtures
.declareParameters<PlaywrightParameters>()
.declareWorkerFixtures<PlaywrightWorkerFixtures>()
.declareTestFixtures<PlaywrightTestFixtures>();
// Parameter and matrix definitions --------------------------------------------
fixtures.defineParameter('browserName', 'Browser type name', process.env.BROWSER || 'chromium' as any);
fixtures.defineParameter('headful', 'Whether to run tests headless or headful', process.env.HEADFUL ? true : false);
fixtures.defineParameter('platform', 'Operating system', process.platform as ('win32' | 'linux' | 'darwin'));
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);
// If browser is not specified, we are running tests against all three browsers.
fixtures.generateParametrizedTests(
'browserName',
process.env.BROWSER ? [process.env.BROWSER] as any : ['chromium', 'webkit', 'firefox']);
// Worker fixtures definitions -------------------------------------------------
fixtures.defineWorkerFixture('defaultBrowserOptions', async ({ headful, slowMo }, runTest) => {
.defineParameter<'browserName', 'chromium' | 'firefox' | 'webkit'>('browserName', 'Browser type name', process.env.BROWSER || 'chromium' as any)
.defineParameter<'headful', boolean>('headful', 'Whether to run tests headless or headful', process.env.HEADFUL ? true : false)
.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,
});
});
},
fixtures.defineWorkerFixture('playwright', async ({}, runTest) => {
playwright: async ({ }, runTest) => {
const playwright = require('../index');
await runTest(playwright);
});
},
fixtures.defineWorkerFixture('browserType', async ({playwright, browserName}, runTest) => {
const browserType = playwright[browserName];
browserType: async ({ playwright, browserName }, runTest) => {
const browserType = (playwright as any)[browserName];
await runTest(browserType);
});
},
fixtures.defineWorkerFixture('browser', async ({browserType, defaultBrowserOptions}, runTest) => {
browser: async ({ browserType, defaultBrowserOptions }, runTest) => {
const browser = await browserType.launch(defaultBrowserOptions);
await runTest(browser);
await browser.close();
});
},
fixtures.defineWorkerFixture('isChromium', async ({browserName}, runTest) => {
isChromium: async ({ browserName }, runTest) => {
await runTest(browserName === 'chromium');
});
},
fixtures.defineWorkerFixture('isFirefox', async ({browserName}, runTest) => {
isFirefox: async ({ browserName }, runTest) => {
await runTest(browserName === 'firefox');
});
},
fixtures.defineWorkerFixture('isWebKit', async ({browserName}, runTest) => {
isWebKit: async ({ browserName }, runTest) => {
await runTest(browserName === 'webkit');
});
},
fixtures.defineWorkerFixture('isWindows', async ({platform}, test) => {
isWindows: async ({ platform }, test) => {
await test(platform === 'win32');
});
},
fixtures.defineWorkerFixture('isMac', async ({platform}, test) => {
isMac: async ({ platform }, test) => {
await test(platform === 'darwin');
});
},
fixtures.defineWorkerFixture('isLinux', async ({platform}, test) => {
isLinux: async ({ platform }, test) => {
await test(platform === 'linux');
});
// Test fixtures definitions ---------------------------------------------------
fixtures.defineTestFixture('defaultContextOptions', async ({ testOutputPath, trace, testInfo }, runTest) => {
},
})
.defineTestFixtures<PlaywrightTestFixtures>({
defaultContextOptions: async ({ trace, testInfo }, runTest) => {
if (trace || testInfo.retry) {
await runTest({
_traceResourcesPath: path.join(config.outputDir, 'trace-resources'),
_tracePath: testOutputPath('playwright.trace'),
videosPath: testOutputPath(''),
_tracePath: testInfo.outputPath('playwright.trace'),
videosPath: testInfo.outputPath(''),
} as any);
} else {
await runTest({});
}
});
},
fixtures.defineTestFixture('contextFactory', async ({ browser, defaultContextOptions, testInfo, screenshotOnFailure, testOutputPath }, runTest) => {
contextFactory: async ({ browser, defaultContextOptions, testInfo, screenshotOnFailure }, runTest) => {
const contexts: BrowserContext[] = [];
async function contextFactory(options: BrowserContextOptions = {}) {
const context = await browser.newContext({ ...defaultContextOptions, ...options });
@ -177,26 +140,35 @@ fixtures.defineTestFixture('contextFactory', async ({ browser, defaultContextOpt
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` });
await page.screenshot({ timeout: 5000, path: testInfo.outputPath + `-test-failed-${++ordinal}.png` });
}
}
for (const context of contexts)
await context.close();
});
},
fixtures.defineTestFixture('context', async ({ contextFactory }, runTest) => {
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) => {
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) => {
// If browser is not specified, we are running tests against all three browsers.
fixtures.generateParametrizedTests(
'browserName',
process.env.BROWSER ? [process.env.BROWSER] as any : ['chromium', 'webkit', 'firefox']);
fixtures.overrideTestFixtures({
testParametersPathSegment: async ({ browserName, platform }, runTest) => {
await runTest(browserName + '-' + platform);
}
});

Просмотреть файл

@ -24,8 +24,22 @@ type ServerFixtures = {
remoteServer: 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, '..');
@ -115,17 +129,3 @@ export class RemoteServer {
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 }) => {
test.fixme(browserName === 'firefox', 'Always clips to square');
}, async ({browser, testOutputPath}) => {
const videosPath = testOutputPath('');
}, async ({browser, testInfo}) => {
const videosPath = testInfo.outputPath('');
const size = { width: 320, height: 240 };
const context = await browser.newContext({
videosPath,
@ -182,8 +182,8 @@ describe('screencast', suite => {
}
});
it('should capture navigation', async ({browser, server, testOutputPath}) => {
const videosPath = testOutputPath('');
it('should capture navigation', async ({browser, server, testInfo}) => {
const videosPath = testInfo.outputPath('');
const context = await browser.newContext({
videosPath,
videoSize: { width: 1280, height: 720 }
@ -214,8 +214,8 @@ describe('screencast', suite => {
it('should capture css transformation', (test, { browserName, platform, headful }) => {
test.fixme(headful, 'Fails on headful');
}, async ({browser, server, testOutputPath}) => {
const videosPath = testOutputPath('');
}, async ({browser, server, testInfo}) => {
const videosPath = testInfo.outputPath('');
const size = { width: 320, height: 240 };
// Set viewport equal to screencast frame size to avoid scaling.
const context = await browser.newContext({
@ -240,8 +240,8 @@ describe('screencast', suite => {
}
});
it('should work for popups', async ({browser, testOutputPath, server}) => {
const videosPath = testOutputPath('');
it('should work for popups', async ({browser, testInfo, server}) => {
const videosPath = testInfo.outputPath('');
const context = await browser.newContext({
videosPath,
videoSize: { width: 320, height: 240 }
@ -262,8 +262,8 @@ describe('screencast', suite => {
it('should scale frames down to the requested size ', (test, parameters) => {
test.fixme(parameters.headful, 'Fails on headful');
}, async ({browser, testOutputPath, server}) => {
const videosPath = testOutputPath('');
}, async ({browser, testInfo, server}) => {
const videosPath = testInfo.outputPath('');
const context = await browser.newContext({
videosPath,
viewport: {width: 640, height: 480},
@ -307,8 +307,8 @@ describe('screencast', suite => {
}
});
it('should use viewport as default size', async ({browser, testOutputPath}) => {
const videosPath = testOutputPath('');
it('should use viewport as default size', async ({browser, testInfo}) => {
const videosPath = testInfo.outputPath('');
const size = {width: 800, height: 600};
const context = await browser.newContext({
videosPath,
@ -325,8 +325,8 @@ describe('screencast', suite => {
expect(await videoPlayer.videoHeight).toBe(size.height);
});
it('should be 1280x720 by default', async ({browser, testOutputPath}) => {
const videosPath = testOutputPath('');
it('should be 1280x720 by default', async ({browser, testInfo}) => {
const videosPath = testInfo.outputPath('');
const context = await browser.newContext({
videosPath,
});
@ -341,8 +341,8 @@ describe('screencast', suite => {
expect(await videoPlayer.videoHeight).toBe(720);
});
it('should capture static page in persistent context', async ({launchPersistent, testOutputPath}) => {
const videosPath = testOutputPath('');
it('should capture static page in persistent context', async ({launchPersistent, testInfo}) => {
const videosPath = testInfo.outputPath('');
const size = { width: 320, height: 240 };
const { context, page } = await launchPersistent({
videosPath,

Просмотреть файл

@ -19,8 +19,8 @@ import type * as trace from '../types/trace';
import * as path from 'path';
import * as fs from 'fs';
it('should record trace', async ({browser, testOutputPath, server}) => {
const artifactsPath = testOutputPath('');
it('should record trace', async ({browser, testInfo, server}) => {
const artifactsPath = testInfo.outputPath('');
const tracePath = path.join(artifactsPath, 'playwright.trace');
const context = await browser.newContext({ _tracePath: tracePath } as any);
const page = await context.newPage();

Просмотреть файл

@ -22,13 +22,15 @@ const Source = require('../../Source');
const mdBuilder = require('../MDBuilder');
const jsBuilder = require('../JSBuilder');
const { fixtures } = require('@playwright/test-runner');
const { defineWorkerFixture, describe, it, expect } = fixtures;
const { defineWorkerFixtures, describe, it, expect } = fixtures;
defineWorkerFixture('page', async({}, test) => {
defineWorkerFixtures({
page: async({}, test) => {
const browser = await playwright.chromium.launch();
const page = await browser.newPage();
await test(page);
await browser.close();
}
});
describe('checkPublicAPI', function() {