From 19cd96c46a507499f89bb5afefca25ecae209afe Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Wed, 15 Jul 2020 16:52:41 -0700 Subject: [PATCH] test: add the jest-circus experimental runner (#2962) --- .github/workflows/tests.yml | 13 + jest.config.json | 7 +- package-lock.json | 476 +++++------------------------ package.json | 2 +- test/jest-runner.js | 187 ------------ test/jest/index.js | 1 + test/jest/playwrightEnvironment.js | 176 +++++++++++ test/jest/test.spec.js | 25 ++ 8 files changed, 304 insertions(+), 583 deletions(-) delete mode 100644 test/jest-runner.js create mode 100644 test/jest/index.js create mode 100644 test/jest/playwrightEnvironment.js create mode 100644 test/jest/test.spec.js diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4528161fdd..debb79ca4e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,6 +41,10 @@ jobs: env: BROWSER: ${{ matrix.browser }} DEBUG: "*,-pw:wrapped*" + - run: xvfb-run --auto-servernum -- bash -c "ulimit -c unlimited && npm run jest 2>>./testrun.log" + env: + BROWSER: ${{ matrix.browser }} + DEBUG: "*,-pw:wrapped*" - uses: actions/upload-artifact@v1 if: failure() with: @@ -76,6 +80,10 @@ jobs: env: BROWSER: ${{ matrix.browser }} DEBUG: "*,-pw:wrapped*" + - run: npm run jest 2>>./${{ matrix.browser }}-mac-testrun.log + env: + BROWSER: ${{ matrix.browser }} + DEBUG: "*,-pw:wrapped*" - uses: actions/upload-artifact@v1 if: failure() with: @@ -107,6 +115,11 @@ jobs: env: BROWSER: ${{ matrix.browser }} DEBUG: "*,-pw:wrapped*" + - run: npm run jest 2>>./${{ matrix.browser }}-win-testrun.log + shell: bash + env: + BROWSER: ${{ matrix.browser }} + DEBUG: "*,-pw:wrapped*" - uses: actions/upload-artifact@v1 if: failure() with: diff --git a/jest.config.json b/jest.config.json index 1006b2ab45..81b19989be 100644 --- a/jest.config.json +++ b/jest.config.json @@ -1,5 +1,6 @@ { - "runner": "./jest-runner.js", - "rootDir": "./test/", - "testMatch": ["**/?(*.)spec.[jt]s"] + "rootDir": "./test/jest", + "testEnvironment": ".", + "testMatch": ["**/?(*.)spec.[jt]s"], + "testRunner": "jest-circus/runner" } diff --git a/package-lock.json b/package-lock.json index 90bc33f29f..9f62dd8b71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1762,321 +1762,6 @@ } } }, - "@playwright/jest-wrapper": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@playwright/jest-wrapper/-/jest-wrapper-0.0.8.tgz", - "integrity": "sha512-47H3ZDthK8/GXHPj8HJnAXwyBwwir/9DnJysRmEOZtxoxql+qPBI4myyK17fB4INDB59GN0Wxz07aHc2zQhdhA==", - "dev": true, - "requires": { - "@jest/test-result": "^25.2.6", - "@jest/transform": "^25.3.0", - "describers": "0.0.8", - "expect": "^25.2.7", - "jest-message-util": "^25.2.6", - "jest-validate": "^25.5.0", - "playwright": "^1.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", - "dev": true, - "requires": { - "@jest/console": "^25.5.0", - "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/transform": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", - "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.5.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^25.5.1", - "jest-regex-util": "^25.2.6", - "jest-util": "^25.5.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "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==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "expect": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", - "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-styles": "^4.0.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-regex-util": "^25.2.6" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-haste-map": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", - "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "@types/graceful-fs": "^4.1.2", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-serializer": "^25.5.0", - "jest-util": "^25.5.0", - "jest-worker": "^25.5.0", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" - } - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true - }, - "jest-serializer": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", - "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4" - } - }, - "jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" - } - }, - "jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -3959,6 +3644,12 @@ "mimic-response": "^1.0.0" } }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -4043,12 +3734,6 @@ "minimalistic-assert": "^1.0.0" } }, - "describers": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/describers/-/describers-0.0.8.tgz", - "integrity": "sha512-Ir3CVh60KCroib+S/6FF7k2ykZTUjv0kgKnC+s1Ndd5MZWv5eHSskUi+i9z6Vszrcqzw0ihXJU8SYuQBmzzKIg==", - "dev": true - }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -4303,21 +3988,6 @@ "dev": true, "optional": true }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, "escalade": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.0.1.tgz", @@ -6379,6 +6049,84 @@ } } }, + "jest-circus": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-26.1.0.tgz", + "integrity": "sha512-V5h5XJLPf0XXwP92GIOx8n0Q6vdPDcFPBuEVQ9/OPzpsx3gquL8fdxaJGZ5TsvkU3zWM7mDWULAKYJMRkA2e+g==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.1.0", + "@jest/test-result": "^26.1.0", + "@jest/types": "^26.1.0", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^26.1.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.1.0", + "jest-matcher-utils": "^26.1.0", + "jest-message-util": "^26.1.0", + "jest-runtime": "^26.1.0", + "jest-snapshot": "^26.1.0", + "jest-util": "^26.1.0", + "pretty-format": "^26.1.0", + "stack-utils": "^2.0.2", + "throat": "^5.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==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "jest-config": { "version": "26.1.0", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.1.0.tgz", @@ -8700,56 +8448,6 @@ "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=", "dev": true }, - "playwright": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.1.1.tgz", - "integrity": "sha512-abAB/gFdMQueapllosYyEzeKyEu6x/83JykqxmUwSu2foGnLT7E4jPUvbJdOSEpzpDGxN01KmonyskcfXxfcpA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^3.0.0", - "jpeg-js": "^0.3.7", - "mime": "^2.4.4", - "pngjs": "^5.0.0", - "progress": "^2.0.3", - "proxy-from-env": "^1.1.0", - "rimraf": "^3.0.2", - "ws": "^6.1.0" - }, - "dependencies": { - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "https-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", - "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", - "dev": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - } - } - }, "pngjs": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", @@ -9076,12 +8774,6 @@ "picomatch": "^2.2.1" } }, - "realpath-native": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", - "dev": true - }, "regenerate": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", diff --git a/package.json b/package.json index e4407deb16..9163965180 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "@babel/core": "^7.10.3", "@babel/preset-env": "^7.10.3", "@babel/preset-typescript": "^7.10.1", - "@playwright/jest-wrapper": "0.0.8", "@types/debug": "0.0.31", "@types/extract-zip": "^1.6.2", "@types/mime": "^2.0.1", @@ -83,6 +82,7 @@ "esprima": "^4.0.0", "formidable": "^1.2.1", "jest": "^26.1.0", + "jest-circus": "^26.1.0", "ncp": "^2.0.0", "node-stream-zip": "^1.8.2", "pirates": "^4.0.1", diff --git a/test/jest-runner.js b/test/jest-runner.js deleted file mode 100644 index 35a5dbcd7f..0000000000 --- a/test/jest-runner.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Copyright (c) Microsoft Corporation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const path = require('path'); -const wrapper = require('@playwright/jest-wrapper'); -const DefaultTestRunner = require('../utils/testrunner'); -const {TestRunner, TestRun} = require('../utils/testrunner/TestRunner'); -const { PlaywrightEnvironment, BrowserTypeEnvironment, BrowserEnvironment, PageEnvironment} = require('./environments.js'); -const fs = require('fs'); -const pirates = require('pirates'); -const babel = require('@babel/core'); -const testRunnerInfo = makeTestRunnerInfo(); - - -module.exports = wrapper.createJestRunner(async ({path: filePath}) => { - const config = require('./test.config'); - const spec = config.specs.find(spec => { - return spec.files.some(f => path.join(__dirname, f) === filePath); - }); - if (!spec) { - console.error('cannot find spec for', filePath); - return []; - } - const {testRunner, browserInfo} = testRunnerInfo; - testRunner.collector()._tests = []; - for (const [key, value] of Object.entries(testRunner.api())) - global[key] = value; - for (const {browserEnvironment, browserTypeEnvironment, browserName, browserType, pageEnvironment, launchOptions} of browserInfo) { - const suiteName = { 'chromium': 'Chromium', 'firefox': 'Firefox', 'webkit': 'WebKit' }[browserName]; - describe(suiteName, () => { - // In addition to state, expose these two on global so that describes can access them. - global.browserType = browserType; - global.HEADLESS = !!launchOptions.headless; - - testRunner.collector().useEnvironment(browserTypeEnvironment); - const skip = spec.browsers && !spec.browsers.includes(browserName); - (skip ? xdescribe : describe)(spec.title || '', () => { - for (const e of spec.environments || ['page']) { - if (e === 'browser') { - testRunner.collector().useEnvironment(browserEnvironment); - } else if (e === 'page') { - testRunner.collector().useEnvironment(browserEnvironment); - testRunner.collector().useEnvironment(pageEnvironment); - } else { - testRunner.collector().useEnvironment(e); - } - } - const revert = pirates.addHook((code, filename) => { - const result = babel.transformFileSync(filename, { - presets: [ - ['@babel/preset-env', {targets: {node: 'current'}}], - '@babel/preset-typescript'] - }); - return result.code; - }, { - exts: ['.ts'] - }); - require(filePath); - revert(); - delete require.cache[require.resolve(filePath)]; - }); - - delete global.HEADLESS; - delete global.browserType; - }); - } - for (const key of Object.keys(testRunner.api())) { - // expect is used when running tests, while the rest of api is not. - if (key !== 'expect') - delete global[key]; - } - - return testRunner._filter.filter(testRunner.collector().tests()).map(test => { - return { - titles: test.titles(), - test - }; - }); -}, async (tests, options, onStart, onResult) => { - const parallel = Math.min(options.workers, 30); - require('events').defaultMaxListeners *= parallel; - const runner = new TestRunner(); - const runs = tests.map(test => { - const run = new TestRun(test.test); - run.__test__ = test; - return run; - }); - await runner.run(runs, { - parallel, - breakOnFailure: false, - hookTimeout: options.timeout, - totalTimeout: options.timeout, - // onStarted = async (testRuns) => {}, - // onFinished = async (result) => {}, - onTestRunStarted: async testRun => { - onStart(testRun.__test__); - }, - onTestRunFinished: async testRun => { - let status = 'skip'; - if (testRun.isFailure()) - status = 'fail'; - else if (testRun.result() === 'ok') - status = 'pass'; - else if (testRun.test().expectation() === 'fail') - status = 'todo'; - onResult(testRun.__test__, { - status, - error: testRun.error(), - }); - } - }); -}); - -function makeTestRunnerInfo() { - const parallel = 1; - const timeout = process.env.CI ? 30 * 1000 : 10 * 1000; - const config = require('./test.config'); - const testRunner = new DefaultTestRunner({ - timeout, - totalTimeout: process.env.CI ? 30 * 60 * 1000 * browserNames.length : 0, // 30 minutes per browser on CI - parallel, - breakOnFailure: process.argv.indexOf('--break-on-failure') !== -1, - verbose: process.argv.includes('--verbose'), - summary: !process.argv.includes('--verbose'), - showSlowTests: process.env.CI ? 5 : 0, - showMarkedAsFailingTests: 10, - }); - if (config.setupTestRunner) - config.setupTestRunner(testRunner); - - // TODO: this should be a preinstalled playwright by default. - const playwrightPath = config.playwrightPath; - const playwright = require('..'); - const { setUnderTest } = require(require('path').join(playwrightPath, 'lib/helper.js')); - setUnderTest(); - - const playwrightEnvironment = new PlaywrightEnvironment(playwright); - - testRunner.collector().useEnvironment(playwrightEnvironment); - for (const e of config.globalEnvironments || []) - testRunner.collector().useEnvironment(e); - - global.playwright = playwright; - const browserNames = ['chromium']; - const browserInfo = browserNames.map(browserName => { - const browserType = playwright[browserName]; - - const browserTypeEnvironment = new BrowserTypeEnvironment(browserName); - - // TODO: maybe launch options per browser? - const launchOptions = { - ...(config.launchOptions || {}), - handleSIGINT: false, - }; - if (launchOptions.executablePath) - launchOptions.executablePath = launchOptions.executablePath[browserName]; - if (launchOptions.executablePath) { - const YELLOW_COLOR = '\x1b[33m'; - const RESET_COLOR = '\x1b[0m'; - console.warn(`${YELLOW_COLOR}WARN: running ${browserName} tests with ${launchOptions.executablePath}${RESET_COLOR}`); - browserType._executablePath = launchOptions.executablePath; - delete launchOptions.executablePath; - } else { - if (!fs.existsSync(browserType.executablePath())) - throw new Error(`Browser is not downloaded. Run 'npm install' and try to re-run tests`); - } - - const browserEnvironment = new BrowserEnvironment(launchOptions, config.dumpLogOnFailure); - - const pageEnvironment = new PageEnvironment(); - return {browserName, browserType, browserEnvironment, browserTypeEnvironment, pageEnvironment, launchOptions}; - }); - return {testRunner, browserInfo}; -} \ No newline at end of file diff --git a/test/jest/index.js b/test/jest/index.js new file mode 100644 index 0000000000..4fd9211de1 --- /dev/null +++ b/test/jest/index.js @@ -0,0 +1 @@ +module.exports = require('./playwrightEnvironment').default diff --git a/test/jest/playwrightEnvironment.js b/test/jest/playwrightEnvironment.js new file mode 100644 index 0000000000..f9058fd012 --- /dev/null +++ b/test/jest/playwrightEnvironment.js @@ -0,0 +1,176 @@ +/** + * Copyright Microsoft Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const NodeEnvironment = require('jest-environment-node'); +const path = require('path'); +const playwright = require('../../index'); + +class PlaywrightEnvironment extends NodeEnvironment { + constructor(config, context) { + super(config, context); + this.fixturePool = new FixturePool(); + + this.global.registerFixture = (name, fn) => { + this.fixturePool.registerFixture(name, 'test', fn); + }; + + this.global.registerWorkerFixture = (name, fn) => { + this.fixturePool.registerFixture(name, 'worker', fn); + }; + + this.global.registerWorkerFixture('browser', async (test) => { + const browser = await playwright[process.env.BROWSER || 'chromium'].launch(); + await test(browser); + await browser.close(); + }); + + this.global.registerFixture('context', async (browser, test) => { + const context = await browser.newContext(); + await test(context); + await context.close(); + }); + + this.global.registerFixture('page', async (context, test) => { + const page = await context.newPage(); + await test(page); + }); + } + + async setup() { + await super.setup(); + } + + async teardown() { + await this.fixturePool.teardownScope('worker'); + await super.teardown(); + } + + runScript(script) { + return super.runScript(script); + } + + async handleTestEvent(event, state) { + if (event.name === 'test_start') { + const fn = event.test.fn; + event.test.fn = async () => { + try { + return await this.fixturePool.resolveParametersAndRun(fn); + } finally { + await this.fixturePool.teardownScope('test'); + } + }; + } + } +} + +class Fixture { + constructor(pool, name, scope, fn) { + this.pool = pool; + this.name = name; + this.scope = scope; + this.fn = fn; + this.deps = fixtureParameterNames(this.fn); + this.usages = new Set(); + this.value = null; + } + + async setup() { + for (const name of this.deps) { + await this.pool.setupFixture(name); + this.pool.instances.get(name).usages.add(this.name); + } + + const params = this.deps.map(n => this.pool.instances.get(n).value); + let setupFenceCallback; + const setupFence = new Promise(f => setupFenceCallback = f); + const teardownFence = new Promise(f => this._teardownFenceCallback = f); + this._tearDownComplete = this.fn(...params, async value => { + this.value = value; + setupFenceCallback(); + await teardownFence; + }); + await setupFence; + } + + async teardown() { + if (this._teardown) + return; + this._teardown = true; + for (const name of this.usages) { + const fixture = this.pool.instances.get(name); + if (!fixture) + continue; + await fixture.teardown(); + } + this._teardownFenceCallback(); + await this._tearDownComplete; + this.pool.instances.delete(this.name); + } +} + +class FixturePool { + constructor() { + this.registrations = new Map(); + this.instances = new Map(); + } + + registerFixture(name, scope, fn) { + this.registrations.set(name, { scope, fn }); + } + + async setupFixture(name) { + let fixture = this.instances.get(name); + if (fixture) + return fixture; + + const { scope, fn } = this.registrations.get(name); + fixture = new Fixture(this, name, scope, fn); + this.instances.set(name, fixture); + await fixture.setup(); + return fixture; + } + + async teardownScope(scope) { + for (const [name, fixture] of this.instances) { + if (fixture.scope === scope) + await fixture.teardown(); + } + } + + async resolveParametersAndRun(fn) { + const names = fixtureParameterNames(fn); + for (const name of names) + await this.setupFixture(name); + await fn(...names.map(n => this.instances.get(n).value)); + } +} + +exports.getPlaywrightEnv = () => PlaywrightEnvironment; +exports.default = exports.getPlaywrightEnv(); + +function fixtureParameterNames(fn) { + const text = fn.toString(); + const match = text.match(/async\ (.*) =>/); + if (!match) + return []; + let signature = match[1]; + if (signature.startsWith('(') && signature.endsWith(')')) + signature = signature.substring(1, signature.length - 1); + if (!signature.trim()) + return []; + const result = signature.split(',').map(t => t.trim()); + return result.filter(s => s !== 'test'); +} diff --git a/test/jest/test.spec.js b/test/jest/test.spec.js new file mode 100644 index 0000000000..a870fbb70e --- /dev/null +++ b/test/jest/test.spec.js @@ -0,0 +1,25 @@ +/** + * Copyright Microsoft Corporation. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +test('test 1', async (page, context) => { + expect(page.url()).toBe('about:blank'); + expect(page.context()).toEqual(context); +}); + +test('test 2', async (page, context) => { + expect(page.url()).toBe('about:blank'); + expect(page.context()).toEqual(context); +});