From 0db09f8ed463bda134eb56fa364af263a9191a3e Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Mon, 5 Oct 2020 17:03:24 -0700 Subject: [PATCH] test: roll test runner to 0.9.20 (#4062) --- package-lock.json | 166 +++++++------- package.json | 4 +- test/browsertype-connect.spec.ts | 6 +- test/channels.spec.ts | 19 +- test/chromium/oopif.spec.ts | 18 +- test/chromium/tracing.spec.ts | 15 +- test/download.spec.ts | 38 ++-- test/downloads-path.spec.ts | 73 +++--- test/electron/electron.fixture.ts | 35 ++- test/elementhandle-screenshot.spec.ts | 4 +- test/fixtures.spec.ts | 31 +-- test/fixtures.ts | 180 ++++++++------- test/http.fixtures.ts | 61 +++-- test/impl.fixtures.ts | 11 +- test/page-screenshot.spec.ts | 17 +- test/pdf.spec.ts | 4 +- test/playwright.fixtures.ts | 232 +++++++++----------- test/remoteServer.fixture.ts | 32 +-- test/screencast.spec.ts | 32 +-- test/trace.spec.ts | 4 +- utils/doclint/check_public_api/test/test.js | 14 +- 21 files changed, 480 insertions(+), 516 deletions(-) diff --git a/package-lock.json b/package-lock.json index 959d4e453b..11216cf925 100644 --- a/package-lock.json +++ b/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": { diff --git a/package.json b/package.json index 1a06c7bad6..7700eddb27 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/test/browsertype-connect.spec.ts b/test/browsertype-connect.spec.ts index f1b81150ca..ed1d044381 100644 --- a/test/browsertype-connect.spec.ts +++ b/test/browsertype-connect.spec.ts @@ -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 }, diff --git a/test/channels.spec.ts b/test/channels.spec.ts index 67b7559683..54ca034330 100644 --- a/test/channels.spec.ts +++ b/test/channels.spec.ts @@ -23,15 +23,16 @@ type DomainFixtures = { domain: any; }; -const fixtures = baseFixtures.declareWorkerFixtures(); -fixtures.defineWorkerFixture('domain', async ({ }, test) => { - const local = domain.create(); - local.run(() => { }); - let err; - local.on('error', e => err = e); - await test(null); - if (err) - throw err; +const fixtures = baseFixtures.defineWorkerFixtures({ + domain: async ({ }, test) => { + const local = domain.create(); + local.run(() => { }); + let err; + local.on('error', e => err = e); + await test(null); + if (err) + throw err; + } }); const { it, expect } = fixtures; diff --git a/test/chromium/oopif.spec.ts b/test/chromium/oopif.spec.ts index 5048b60654..eec022419b 100644 --- a/test/chromium/oopif.spec.ts +++ b/test/chromium/oopif.spec.ts @@ -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) => { - const browser = await browserType.launch({ - ...defaultBrowserOptions, - args: (defaultBrowserOptions.args || []).concat(['--site-per-process']) - }); - await test(browser); - await browser.close(); +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 }) => { diff --git a/test/chromium/tracing.spec.ts b/test/chromium/tracing.spec.ts index b4c9749dc7..dc107597f2 100644 --- a/test/chromium/tracing.spec.ts +++ b/test/chromium/tracing.spec.ts @@ -22,13 +22,14 @@ import type { ChromiumBrowser } from '../..'; type TestState = { outputTraceFile: string; }; -const fixtures = playwrightFixtures.declareTestFixtures(); -const { it, expect, describe, defineTestFixture } = fixtures; - -defineTestFixture('outputTraceFile', async ({testOutputPath}, test) => { - await test(testOutputPath(path.join(`trace.json`))); +const fixtures = playwrightFixtures.defineTestFixtures({ + 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(); diff --git a/test/download.spec.ts b/test/download.spec.ts index 2f62d72179..fcf6070160 100644 --- a/test/download.spec.ts +++ b/test/download.spec.ts @@ -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(`download`); 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(`download`); 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(`download`); 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(`download`); 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(`download`); 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(`download`); @@ -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(`download`); 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(`download`); 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(`download`); @@ -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.'); diff --git a/test/downloads-path.spec.ts b/test/downloads-path.spec.ts index 77f55e2e83..2d461bf720 100644 --- a/test/downloads-path.spec.ts +++ b/test/downloads-path.spec.ts @@ -23,41 +23,42 @@ type TestState = { downloadsBrowser: Browser; persistentDownloadsContext: BrowserContext; }; -const fixtures = baseFixtures.declareTestFixtures(); -const { it, expect, defineTestFixture } = fixtures; +const fixtures = baseFixtures.defineTestFixtures({ + 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) => { - 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: testOutputPath(''), - }); - await test(browser); - await browser.close(); + 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'); + res.end(`Hello world`); + }); + const { context, page } = await launchPersistent( + { + downloadsPath: testInfo.outputPath(''), + acceptDownloads: true + } + ); + await page.setContent(`download`); + await test(context); + await context.close(); + }, }); -defineTestFixture('persistentDownloadsContext', async ({server, launchPersistent, testOutputPath}, 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 { context, page } = await launchPersistent( - { - downloadsPath: testOutputPath(''), - acceptDownloads: true - } - ); - await page.setContent(`download`); - await test(context); - await context.close(); -}); +const { it, expect } = fixtures; -it('should keep downloadsPath folder', async ({downloadsBrowser, testOutputPath, server}) => { +it('should keep downloadsPath folder', async ({downloadsBrowser, testInfo, server}) => { const page = await downloadsBrowser.newPage(); await page.setContent(`download`); 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(`download`); 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}) => { diff --git a/test/electron/electron.fixture.ts b/test/electron/electron.fixture.ts index 2bcbcc7ee7..4685e7a3aa 100644 --- a/test/electron/electron.fixture.ts +++ b/test/electron/electron.fixture.ts @@ -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(); -const { defineTestFixture } = electronFixtures; +export const electronFixtures = baseFixtures.defineTestFixtures({ + 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' { 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(); -}); diff --git a/test/elementhandle-screenshot.spec.ts b/test/elementhandle-screenshot.spec.ts index 761b77d29f..0a7de8976c 100644 --- a/test/elementhandle-screenshot.spec.ts +++ b/test/elementhandle-screenshot.spec.ts @@ -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'); }); diff --git a/test/fixtures.spec.ts b/test/fixtures.spec.ts index 55375687f2..b55333b86f 100644 --- a/test/fixtures.spec.ts +++ b/test/fixtures.spec.ts @@ -25,24 +25,25 @@ export type FixturesFixtures = { stallingConnectedRemoteServer: RemoteServer; }; -const fixturesFixtures = serverFixtures.declareTestFixtures(); -const { it, describe, expect, defineTestFixture } = fixturesFixtures; +const fixturesFixtures = serverFixtures.defineTestFixtures({ + 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) => { - 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(); + 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(); + }, }); -defineTestFixture('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(); diff --git a/test/fixtures.ts b/test/fixtures.ts index b70847e4c8..f0db339325 100644 --- a/test/fixtures.ts +++ b/test/fixtures.ts @@ -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; - launchPersistent: (options?: Parameters['launchPersistentContext']>[1]) => Promise<{context: BrowserContext, page: Page}>; + launchPersistent: (options?: Parameters['launchPersistentContext']>[1]) => Promise<{ context: BrowserContext, page: Page }>; }; export const fixtures = playwrightFixtures .union(httpFixtures) .union(implFixtures) - .declareParameters() - .declareTestFixtures(); + .defineParameter('wire', 'Wire testing mode', !!process.env.PWWIRE || false) + .defineTestFixtures({ + 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,90 +100,62 @@ const getExecutablePath = browserName => { return process.env.WKPATH; }; -fixtures.overrideWorkerFixture('defaultBrowserOptions', async ({ browserName, headful, slowMo }, runTest) => { - const executablePath = getExecutablePath(browserName); - if (executablePath) - console.error(`Using executable at ${executablePath}`); - await runTest({ - executablePath, - handleSIGINT: false, - 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, +fixtures.overrideWorkerFixtures({ + defaultBrowserOptions: async ({ browserName, headful, slowMo }, runTest) => { + const executablePath = getExecutablePath(browserName); + if (executablePath) + console.error(`Using executable at ${executablePath}`); + await runTest({ + executablePath, + handleSIGINT: false, + slowMo, + headless: !headful, }); - 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'); - } + 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() { + 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) => { - 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; +fixtures.overrideTestFixtures({ + testParametersPathSegment: async ({ browserName }, runTest) => { + await runTest(browserName); } - 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); }); diff --git a/test/http.fixtures.ts b/test/http.fixtures.ts index 988161453b..bebddc8a39 100644 --- a/test/http.fixtures.ts +++ b/test/http.fixtures.ts @@ -29,40 +29,39 @@ type HttpTestFixtures = { }; export const fixtures = baseFixtures - .declareWorkerFixtures() - .declareTestFixtures(); -const { defineTestFixture, defineWorkerFixture } = fixtures; + .defineWorkerFixtures({ + httpService: async ({ testWorkerIndex }, test) => { + const assetsPath = path.join(__dirname, 'assets'); + const cachedPath = path.join(__dirname, 'assets', 'cached'); -defineWorkerFixture('httpService', async ({ testWorkerIndex }, test) => { - const assetsPath = path.join(__dirname, 'assets'); - const cachedPath = path.join(__dirname, 'assets', 'cached'); + const port = 8907 + testWorkerIndex * 2; + const server = await TestServer.create(assetsPath, port); + server.enableHTTPCache(cachedPath); - const port = 8907 + testWorkerIndex * 2; - const server = await TestServer.create(assetsPath, port); - server.enableHTTPCache(cachedPath); + const httpsPort = port + 1; + const httpsServer = await TestServer.createHTTPS(assetsPath, httpsPort); + httpsServer.enableHTTPCache(cachedPath); - const httpsPort = port + 1; - 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(), + ]); + }, - await Promise.all([ - server.stop(), - httpsServer.stop(), - ]); -}); + asset: async ({ }, test) => { + await test(p => path.join(__dirname, `assets`, p)); + }, + }) + .defineTestFixtures({ + server: async ({ httpService }, test) => { + httpService.server.reset(); + await test(httpService.server); + }, -defineTestFixture('server', async ({httpService}, test) => { - httpService.server.reset(); - await test(httpService.server); -}); - -defineTestFixture('httpsServer', async ({httpService}, test) => { - httpService.httpsServer.reset(); - await test(httpService.httpsServer); -}); - -defineWorkerFixture('asset', async ({}, test) => { - await test(p => path.join(__dirname, `assets`, p)); -}); + httpsServer: async ({ httpService }, test) => { + httpService.httpsServer.reset(); + await test(httpService.httpsServer); + }, + }); diff --git a/test/impl.fixtures.ts b/test/impl.fixtures.ts index 8aed0696da..293570a5d5 100644 --- a/test/impl.fixtures.ts +++ b/test/impl.fixtures.ts @@ -21,9 +21,8 @@ type ImplWorkerFixtures = { }; export const fixtures = playwrightFixtures - .declareWorkerFixtures(); -const { defineWorkerFixture } = fixtures; - -defineWorkerFixture('toImpl', async ({ playwright }, test) => { - await test((playwright as any)._toImpl); -}); + .defineWorkerFixtures({ + toImpl: async ({ playwright }, test) => { + await test((playwright as any)._toImpl); + } + }); diff --git a/test/page-screenshot.spec.ts b/test/page-screenshot.spec.ts index 420810c779..c146d55cdd 100644 --- a/test/page-screenshot.spec.ts +++ b/test/page-screenshot.spec.ts @@ -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'); diff --git a/test/pdf.spec.ts b/test/pdf.spec.ts index e96f1da2c3..46b4bc6079 100644 --- a/test/pdf.spec.ts +++ b/test/pdf.spec.ts @@ -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); }); diff --git a/test/playwright.fixtures.ts b/test/playwright.fixtures.ts index 43e08af6e9..2c857f4e0c 100644 --- a/test/playwright.fixtures.ts +++ b/test/playwright.fixtures.ts @@ -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; // Default browserType.launch() options. defaultBrowserOptions: LaunchOptions; - // Factory for creating a browser with given additional options. - browserFactory: (options?: LaunchOptions) => Promise; // Browser instance, shared for the worker. browser: Browser; // True iff browserName is Chromium @@ -82,121 +59,116 @@ type PlaywrightTestFixtures = { }; export const fixtures = baseFixtures - .declareParameters() - .declareWorkerFixtures() - .declareTestFixtures(); + .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({ + 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); -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); + browserType: async ({ playwright, browserName }, runTest) => { + const browserType = (playwright as any)[browserName]; + await runTest(browserType); + }, + + 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({ + 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. fixtures.generateParametrizedTests( 'browserName', process.env.BROWSER ? [process.env.BROWSER] as any : ['chromium', 'webkit', 'firefox']); -// Worker fixtures definitions ------------------------------------------------- -fixtures.defineWorkerFixture('defaultBrowserOptions', async ({ headful, slowMo }, runTest) => { - await runTest({ - handleSIGINT: false, - 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.overrideTestFixtures({ + testParametersPathSegment: async ({ browserName, platform }, runTest) => { + await runTest(browserName + '-' + platform); } }); - -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); -}); diff --git a/test/remoteServer.fixture.ts b/test/remoteServer.fixture.ts index 9d3b7337ab..3d0bb83dd4 100644 --- a/test/remoteServer.fixture.ts +++ b/test/remoteServer.fixture.ts @@ -24,8 +24,22 @@ type ServerFixtures = { remoteServer: RemoteServer; stallingRemoteServer: RemoteServer; }; -export const serverFixtures = baseFixtures.declareTestFixtures(); -const { defineTestFixture } = serverFixtures; + +export const serverFixtures = baseFixtures.defineTestFixtures({ + 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(); -}); diff --git a/test/screencast.spec.ts b/test/screencast.spec.ts index c499c09aac..cec6f1e1c6 100644 --- a/test/screencast.spec.ts +++ b/test/screencast.spec.ts @@ -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, diff --git a/test/trace.spec.ts b/test/trace.spec.ts index 96a8f0f5ad..a2cb8b1fc3 100644 --- a/test/trace.spec.ts +++ b/test/trace.spec.ts @@ -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(); diff --git a/utils/doclint/check_public_api/test/test.js b/utils/doclint/check_public_api/test/test.js index db03c134e3..f081289c5b 100644 --- a/utils/doclint/check_public_api/test/test.js +++ b/utils/doclint/check_public_api/test/test.js @@ -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) => { - const browser = await playwright.chromium.launch(); - const page = await browser.newPage(); - await test(page); - await browser.close(); +defineWorkerFixtures({ + page: async({}, test) => { + const browser = await playwright.chromium.launch(); + const page = await browser.newPage(); + await test(page); + await browser.close(); + } }); describe('checkPublicAPI', function() {