diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b37d689fdb..07d1c1ecf4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,7 +34,7 @@ jobs: - run: node lib/cli/cli install-deps ${{ matrix.browser }} chromium # XVFB-RUN merges both STDOUT and STDERR, whereas we need only STDERR # Wrap `npm run` in a subshell to redirect STDERR to file. - - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- bash -c "npm run test -- --tag=${{ matrix.browser }}" + - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- bash -c "npm run test -- --project=${{ matrix.browser }}" - run: node tests/config/checkCoverage.js ${{ matrix.browser }} - run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json if: always() @@ -62,7 +62,7 @@ jobs: DEBUG: extract-zip - run: npm run build - run: node lib/cli/cli install-deps ${{ matrix.browser }} chromium - - run: npm run test -- --tag=${{ matrix.browser }} + - run: npm run test -- --project=${{ matrix.browser }} - run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json if: always() - uses: actions/upload-artifact@v1 @@ -91,7 +91,7 @@ jobs: DEBUG: extract-zip - run: npm run build - run: node lib/cli/cli install-deps - - run: npm run test -- --tag=${{ matrix.browser }} + - run: npm run test -- --project=${{ matrix.browser }} shell: bash - run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json if: always() @@ -140,7 +140,7 @@ jobs: - run: node lib/cli/cli install-deps ${{ matrix.browser }} chromium # XVFB-RUN merges both STDOUT and STDERR, whereas we need only STDERR # Wrap `npm run` in a subshell to redirect STDERR to file. - - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- bash -c "npm run test -- --tag=${{ matrix.browser }}" + - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- bash -c "npm run test -- --project=${{ matrix.browser }}" if: ${{ always() }} env: HEADFUL: 1 @@ -197,7 +197,7 @@ jobs: - run: node lib/cli/cli install-deps ${{ matrix.browser }} chromium # XVFB-RUN merges both STDOUT and STDERR, whereas we need only STDERR # Wrap `npm run` in a subshell to redirect STDERR to file. - - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- bash -c "npm run test -- --tag=${{ matrix.browser }}" + - run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" -- bash -c "npm run test -- --project=${{ matrix.browser }}" env: PWTEST_VIDEO: 1 - run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json diff --git a/package-lock.json b/package-lock.json index 90948e1667..7436a3e55a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -658,6 +658,200 @@ "@babel/helper-plugin-utils": "^7.10.4" } }, + "@babel/plugin-proposal-private-property-in-object": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz", + "integrity": "sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-create-class-features-plugin": "^7.14.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-private-property-in-object": "^7.14.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/generator": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz", + "integrity": "sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "dev": true + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", + "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.0", + "@babel/types": "^7.14.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, "@babel/plugin-proposal-unicode-property-regex": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", @@ -835,6 +1029,23 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz", + "integrity": "sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0" + }, + "dependencies": { + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + } + } + }, "@babel/plugin-syntax-top-level-await": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", @@ -8140,16 +8351,28 @@ } }, "folio": { - "version": "0.4.0-alpha6", - "resolved": "https://registry.npmjs.org/folio/-/folio-0.4.0-alpha6.tgz", - "integrity": "sha512-UzL9iFvumPbcsrfObkQX0AbGUNGRzgFY+IyRluHlVzhF2aaa5jEoq/ZPDNPgJwDBvKdyO026+qQ2rNzHv5KnaA==", + "version": "0.4.0-alpha10", + "resolved": "https://registry.npmjs.org/folio/-/folio-0.4.0-alpha10.tgz", + "integrity": "sha512-UnmWFIgYP/NaU9nVFzbBP5Uj473miWj3K3XpmpVIa42TFePSRdyeogFAAbhdb60C8h5E32NkTQbquGDaMGabLg==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/core": "^7.11.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/preset-env": "^7.11.0", - "@babel/preset-typescript": "^7.10.4", + "@babel/code-frame": "^7.12.13", + "@babel/core": "^7.14.0", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-dynamic-import": "^7.13.8", + "@babel/plugin-proposal-export-namespace-from": "^7.12.13", + "@babel/plugin-proposal-logical-assignment-operators": "^7.13.8", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-numeric-separator": "^7.12.13", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-proposal-private-methods": "^7.13.0", + "@babel/plugin-proposal-private-property-in-object": "^7.14.0", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.14.0", + "@babel/preset-typescript": "^7.13.0", "colors": "^1.4.0", "commander": "^6.1.0", "debug": "^4.1.5", @@ -8164,6 +8387,410 @@ "rimraf": "^3.0.2", "source-map-support": "^0.5.19", "stack-utils": "^2.0.2" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/compat-data": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", + "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", + "dev": true + }, + "@babel/core": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", + "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-compilation-targets": "^7.13.16", + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helpers": "^7.14.0", + "@babel/parser": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz", + "integrity": "sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.1.tgz", + "integrity": "sha512-r8rsUahG4ywm0QpGcCrLaUSOuNAISR3IZCg4Fx05Ozq31aCUrQsTLH6KPxy0N5ULoQ4Sn9qjNdGNtbPWAC6hYg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.12.13", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", + "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz", + "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==", + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", + "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", + "dev": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "dev": true + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz", + "integrity": "sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz", + "integrity": "sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.13.tgz", + "integrity": "sha512-INAgtFo4OnLN3Y/j0VwAgw3HDXcDtX+C/erMvWzuV9v71r7urb6iyMXu7eM9IgLr1ElLlOkaHjJ0SbCmdOQ3Iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz", + "integrity": "sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.13.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz", + "integrity": "sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.13.tgz", + "integrity": "sha512-O1jFia9R8BUCl3ZGB7eitaAPu62TXJRHn7rh+ojNERCFyqRwJMTmhz+tJ+k0CwI6CLjX/ee4qW74FSqlq9I35w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.12.tgz", + "integrity": "sha512-fcEdKOkIB7Tf4IxrgEVeFC4zeJSTr78no9wTdBuZZbqF64kzllU0ybo2zrzm7gUQfxGhBgq4E39oRs8Zx/RMYQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz", + "integrity": "sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.13.tgz", + "integrity": "sha512-cHP3u1JiUiG2LFDKbXnwVad81GvfyIOmCD6HIEId6ojrY0Drfy2q1jw7BwN7dE84+kTnBjLkXoL3IEy/3JPu2w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz", + "integrity": "sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-simple-access": "^7.13.12", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.13.0.tgz", + "integrity": "sha512-elQEwluzaU8R8dbVuW2Q2Y8Nznf7hnjM7+DSCd14Lo5fF63C9qNLbwZYbmZrtV9/ySpSUpkRpQXvJb6xyu4hCQ==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.13.0", + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/plugin-syntax-typescript": "^7.12.13" + } + }, + "@babel/preset-typescript": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.13.0.tgz", + "integrity": "sha512-LXJwxrHy0N3f6gIJlYbLta1D9BDtHpQeqwzM0LIfjDlr6UE/D5Mc7W4iDiQzaE+ks0sTjT26ArcHWnJVt0QiHw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.13.0", + "@babel/helper-validator-option": "^7.12.17", + "@babel/plugin-transform-typescript": "^7.13.0" + } + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", + "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.0", + "@babel/types": "^7.14.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "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.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "for-in": { diff --git a/package.json b/package.json index 1a1959e57c..abd1cb9885 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "node": ">=12" }, "scripts": { - "ctest": "folio --config=tests/config/default.config.ts --tag=chromium", - "ftest": "folio --config=tests/config/default.config.ts --tag=firefox", - "wtest": "folio --config=tests/config/default.config.ts --tag=webkit", + "ctest": "folio --config=tests/config/default.config.ts --project=chromium", + "ftest": "folio --config=tests/config/default.config.ts --project=firefox", + "wtest": "folio --config=tests/config/default.config.ts --project=webkit", "atest": "folio --config=tests/config/android.config.ts", "etest": "folio --config=tests/config/electron.config.ts", "test": "folio --config=tests/config/default.config.ts", @@ -87,7 +87,7 @@ "eslint-plugin-notice": "^0.9.10", "eslint-plugin-react-hooks": "^4.2.0", "file-loader": "^6.1.0", - "folio": "=0.4.0-alpha6", + "folio": "=0.4.0-alpha10", "formidable": "^1.2.2", "html-webpack-plugin": "^4.4.1", "ncp": "^2.0.0", diff --git a/tests/browsercontext-add-cookies.spec.ts b/tests/browsercontext-add-cookies.spec.ts index 7048e7520e..8c0017ed0c 100644 --- a/tests/browsercontext-add-cookies.spec.ts +++ b/tests/browsercontext-add-cookies.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { contextTest as it, slowPlaywrightTest, expect } from './config/browserTest'; +import { contextTest as it, playwrightTest, expect } from './config/browserTest'; it('should work', async ({context, page, server}) => { await page.goto(server.EMPTY_PAGE); @@ -157,7 +157,9 @@ it('should isolate send cookie header', async ({server, context, browser}) => { } }); -slowPlaywrightTest('should isolate cookies between launches', async ({browserType, server, browserOptions}) => { +playwrightTest('should isolate cookies between launches', async ({browserType, server, browserOptions}) => { + playwrightTest.slow(); + const browser1 = await browserType.launch(browserOptions); const context1 = await browser1.newContext(); await context1.addCookies([{url: server.EMPTY_PAGE, name: 'cookie-in-context-1', value: 'value', expires: Date.now() / 1000 + 10000}]); diff --git a/tests/browsercontext-pages.spec.ts b/tests/browsercontext-pages.spec.ts index ab08116f45..48f5602626 100644 --- a/tests/browsercontext-pages.spec.ts +++ b/tests/browsercontext-pages.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { browserTest as it, expect, slowBrowserTest } from './config/browserTest'; +import { browserTest as it, expect } from './config/browserTest'; import { attachFrame, chromiumVersionLessThan } from './config/utils'; it('should not be visible in context.pages', async ({contextFactory}) => { @@ -108,8 +108,9 @@ it('should click the button with offset with page scale', async ({browser, serve await context.close(); }); -// We open 20 pages here! -slowBrowserTest('should not leak listeners during navigation of 20 pages', async ({contextFactory, server}) => { +it('should not leak listeners during navigation of 20 pages', async ({contextFactory, server}) => { + it.slow('We open 20 pages here!'); + const context = await contextFactory(); let warning = null; const warningHandler = w => warning = w; diff --git a/tests/browsertype-connect.spec.ts b/tests/browsertype-connect.spec.ts index 15d8e5ad43..e0e528a291 100644 --- a/tests/browsertype-connect.spec.ts +++ b/tests/browsertype-connect.spec.ts @@ -15,10 +15,12 @@ * limitations under the License. */ -import { slowPlaywrightTest as test, expect } from './config/browserTest'; +import { playwrightTest as test, expect } from './config/browserTest'; import fs from 'fs'; import * as path from 'path'; +test.slow('All connect tests are slow'); + test('should be able to reconnect to a browser', async ({browserType, startRemoteServer, server}) => { const remoteServer = await startRemoteServer(); { diff --git a/tests/browsertype-launch.spec.ts b/tests/browsertype-launch.spec.ts index 19ef7d9e48..ab7fbedf9b 100644 --- a/tests/browsertype-launch.spec.ts +++ b/tests/browsertype-launch.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { playwrightTest as it, slowPlaywrightTest as slowTest, expect } from './config/browserTest'; +import { playwrightTest as it, expect } from './config/browserTest'; it('should reject all promises when browser is closed', async ({browserType, browserOptions}) => { const browser = await browserType.launch(browserOptions); @@ -105,7 +105,7 @@ it('should report launch log', async ({browserType, browserOptions, mode}) => { expect(error.message).toContain(''); }); -slowTest('should accept objects as options', async ({browserType, browserOptions}) => { +it('should accept objects as options', async ({browserType, browserOptions}) => { // @ts-expect-error process is not a real option. const browser = await browserType.launch({ ...browserOptions, process }); await browser.close(); diff --git a/tests/config/android.config.ts b/tests/config/android.config.ts index 964efd09b4..f78eed7de4 100644 --- a/tests/config/android.config.ts +++ b/tests/config/android.config.ts @@ -17,28 +17,10 @@ import * as folio from 'folio'; import * as path from 'path'; import { test as pageTest } from '../page/pageTest'; -import { AndroidEnv, androidTest } from './androidTest'; +import { AndroidEnv } from './androidTest'; import type { BrowserContext } from '../../index'; - -const config: folio.Config = { - testDir: path.join(__dirname, '..'), - outputDir: path.join(__dirname, '..', '..', 'test-results'), - timeout: 120000, - globalTimeout: 7200000, - workers: 1, -}; -if (process.env.CI) { - config.forbidOnly = true; - config.retries = 1; // Multiple retries are too slow on Android. -} -folio.setConfig(config); - -if (process.env.CI) { - folio.setReporters([ - new folio.reporters.dot(), - new folio.reporters.json({ outputFile: path.join(__dirname, '..', '..', 'test-results', 'report.json') }), - ]); -} +import { PlaywrightEnvOptions } from './browserTest'; +import { CommonOptions } from './baseTest'; class AndroidPageEnv extends AndroidEnv { private _context?: BrowserContext; @@ -60,14 +42,40 @@ class AndroidPageEnv extends AndroidEnv { } } -const envConfig = { - tag: 'android', - options: { - mode: 'default' as const, - browserName: 'chromium' as const, - loopback: '10.0.2.2', - } +type AllOptions = PlaywrightEnvOptions & CommonOptions; + +const outputDir = path.join(__dirname, '..', '..', 'test-results'); +const testDir = path.join(__dirname, '..'); +const config: folio.Config = { + testDir, + outputDir, + timeout: 120000, + globalTimeout: 7200000, + workers: 1, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 1 : 0, + reporter: process.env.CI ? [ + 'dot', + { name: 'json', outputFile: path.join(outputDir, 'report.json') }, + ] : 'line', + projects: [], }; -pageTest.runWith(envConfig, new AndroidPageEnv()); -androidTest.runWith(envConfig); +config.projects.push({ + name: 'android', + options: { + loopback: '10.0.2.2', + }, + testDir: path.join(testDir, 'android'), +}); + +config.projects.push({ + name: 'android', + options: { + loopback: '10.0.2.2', + }, + testDir: path.join(testDir, 'page'), + define: { test: pageTest, env: new AndroidPageEnv() }, +}); + +export default config; diff --git a/tests/config/baseTest.ts b/tests/config/baseTest.ts index e99f058ce2..3be720daeb 100644 --- a/tests/config/baseTest.ts +++ b/tests/config/baseTest.ts @@ -45,14 +45,6 @@ type BaseWorkerArgs = { isLinux: boolean; }; -type BaseOptions = { - mode: Mode; - browserName: BrowserName; - channel?: string; - video?: boolean; - headful?: boolean; -}; - class DriverMode { private _playwrightObject: any; @@ -111,49 +103,59 @@ class DefaultMode { } } +type BaseOptions = { + mode?: Mode; + browserName?: BrowserName; + channel?: string; + video?: boolean; + headful?: boolean; +}; + class BaseEnv { private _mode: DriverMode | ServiceMode | DefaultMode; + private _browserName: BrowserName; private _options: BaseOptions; private _playwright: typeof import('../../index'); - optionsType(): BaseOptions { - return {} as any; + hasBeforeAllOptions(options: BaseOptions) { + return 'mode' in options || 'browserName' in options || 'channel' in options || 'video' in options || 'headful' in options; } async beforeAll(options: BaseOptions, workerInfo: folio.WorkerInfo): Promise { this._options = options; + this._browserName = options.browserName || 'chromium'; this._mode = { default: new DefaultMode(), service: new ServiceMode(), driver: new DriverMode(), - }[this._options.mode]; + }[this._options.mode || 'default']; require('../../lib/utils/utils').setUnderTest(); this._playwright = await this._mode.setup(workerInfo); return { playwright: this._playwright, - browserName: this._options.browserName, + browserName: this._browserName, browserChannel: this._options.channel, - isChromium: this._options.browserName === 'chromium', - isFirefox: this._options.browserName === 'firefox', - isWebKit: this._options.browserName === 'webkit', + isChromium: this._browserName === 'chromium', + isFirefox: this._browserName === 'firefox', + isWebKit: this._browserName === 'webkit', isWindows: process.platform === 'win32', isMac: process.platform === 'darwin', isLinux: process.platform === 'linux', headful: !!this._options.headful, video: !!this._options.video, - mode: this._options.mode, + mode: this._options.mode || 'default', platform: process.platform as ('win32' | 'darwin' | 'linux'), toImpl: (this._playwright as any)._toImpl, }; } async beforeEach({}, testInfo: folio.TestInfo) { - testInfo.snapshotPathSegment = this._options.browserName; - testInfo.data = { browserName: this._options.browserName }; + testInfo.snapshotPathSegment = this._browserName; + testInfo.data = { browserName: this._browserName }; if (this._options.headful) testInfo.data.headful = true; - if (this._options.mode !== 'default') - testInfo.data.mode = this._options.mode; + if ((this._options.mode || 'default') !== 'default') + testInfo.data.mode = this._options.mode || 'default'; if (this._options.video) testInfo.data.video = true; return {}; @@ -181,8 +183,8 @@ class ServerEnv { private _socksServer: any; private _socksPort: number; - optionsType(): ServerOptions { - return {}; + hasBeforeAllOptions(options: ServerOptions) { + return 'loopback' in options; } async beforeAll(options: ServerOptions, workerInfo: folio.WorkerInfo) { @@ -246,8 +248,8 @@ type CoverageOptions = { class CoverageEnv { private _coverage: ReturnType | undefined; - optionsType(): CoverageOptions { - return {}; + hasBeforeAllOptions(options: CoverageOptions) { + return 'coverageName' in options; } async beforeAll(options: CoverageOptions, workerInfo: folio.WorkerInfo) { @@ -268,7 +270,7 @@ class CoverageEnv { } } -export type CommonOptions = BaseOptions; +export type CommonOptions = BaseOptions & ServerOptions & CoverageOptions; export type CommonArgs = BaseWorkerArgs & ServerWorkerArgs; export const baseTest = folio.test.extend(new CoverageEnv()).extend(new ServerEnv()).extend(new BaseEnv()); diff --git a/tests/config/browserTest.ts b/tests/config/browserTest.ts index 776c39fd3b..17a53dfcdc 100644 --- a/tests/config/browserTest.ts +++ b/tests/config/browserTest.ts @@ -32,7 +32,7 @@ type PlaywrightTestArgs = { startRemoteServer: (options?: RemoteServerOptions) => Promise; }; -type PlaywrightEnvOptions = { +export type PlaywrightEnvOptions = { launchOptions?: LaunchOptions; traceDir?: string; }; @@ -49,8 +49,8 @@ class PlaywrightEnv { private _persistentContext: BrowserContext | undefined; private _remoteServer: RemoteServer | undefined; - optionsType(): PlaywrightEnvOptions { - return {}; + hasBeforeAllOptions(options: PlaywrightEnvOptions) { + return 'launchOptions' in options || 'traceDir' in options; } async beforeAll(args: CommonArgs & PlaywrightEnvOptions, workerInfo: folio.WorkerInfo): Promise { @@ -137,7 +137,7 @@ class BrowserEnv { } async beforeEach(options: CommonArgs, testInfo: folio.TestInfo): Promise { - const debugName = path.relative(testInfo.config.outputDir, testInfo.outputDir).replace(/[\/\\]/g, '-'); + const debugName = path.relative(testInfo.project.outputDir, testInfo.outputDir).replace(/[\/\\]/g, '-'); const contextOptions = { recordVideo: options.video ? { dir: testInfo.outputPath('') } : undefined, _debugName: debugName, @@ -181,10 +181,7 @@ class ContextEnv { } export const playwrightTest = baseTest.extend(new PlaywrightEnv()); -export const slowPlaywrightTest = baseTest.extend(new PlaywrightEnv()); export const browserTest = playwrightTest.extend(new BrowserEnv()); -export const slowBrowserTest = slowPlaywrightTest.extend(new BrowserEnv()); export const contextTest = browserTest.extend(new ContextEnv()); -export const tracingTest = baseTest.extend(new PlaywrightEnv()).extend(new BrowserEnv()).extend(new ContextEnv()); export { expect } from 'folio'; diff --git a/tests/config/default.config.ts b/tests/config/default.config.ts index d3d7e0087e..711715c991 100644 --- a/tests/config/default.config.ts +++ b/tests/config/default.config.ts @@ -16,31 +16,11 @@ import * as folio from 'folio'; import * as path from 'path'; -import { playwrightTest, slowPlaywrightTest, contextTest, tracingTest } from './browserTest'; +import { PlaywrightEnvOptions } from './browserTest'; import { test as pageTest } from '../page/pageTest'; -import { BrowserName, CommonArgs } from './baseTest'; +import { BrowserName, CommonArgs, CommonOptions } from './baseTest'; import type { Browser, BrowserContext } from '../../index'; -const config: folio.Config = { - testDir: path.join(__dirname, '..'), - outputDir: path.join(__dirname, '..', '..', 'test-results'), - timeout: process.env.PWTEST_VIDEO || process.env.PWTRACE ? 60000 : 30000, - globalTimeout: 5400000, -}; -if (process.env.CI) { - config.workers = 1; - config.forbidOnly = true; - config.retries = 3; -} -folio.setConfig(config); - -if (process.env.CI) { - folio.setReporters([ - new folio.reporters.dot(), - new folio.reporters.json({ outputFile: path.join(__dirname, '..', '..', 'test-results', 'report.json') }), - ]); -} - const getExecutablePath = (browserName: BrowserName) => { if (browserName === 'chromium' && process.env.CRPATH) return process.env.CRPATH; @@ -50,8 +30,7 @@ const getExecutablePath = (browserName: BrowserName) => { return process.env.WKPATH; }; -type WorkerOptionsFor = T extends folio.TestType ? WO : any; -type AllOptions = WorkerOptionsFor; +type AllOptions = PlaywrightEnvOptions & CommonOptions; class PageEnv { private _browser: Browser @@ -99,29 +78,45 @@ class PageEnv { } } -const browsers = ['chromium', 'webkit', 'firefox'] as BrowserName[]; -for (const browserName of browsers) { +const outputDir = path.join(__dirname, '..', '..', 'test-results'); +const testDir = path.join(__dirname, '..'); +const config: folio.Config = { + testDir, + outputDir, + timeout: process.env.PWTEST_VIDEO || process.env.PWTRACE ? 60000 : 30000, + globalTimeout: 5400000, + workers: process.env.CI ? 1 : undefined, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 3 : 0, + reporter: process.env.CI ? [ + 'dot', + { name: 'json', outputFile: path.join(outputDir, 'report.json') }, + ] : 'line', + projects: [], +}; + +for (const browserName of ['chromium', 'webkit', 'firefox'] as BrowserName[]) { const executablePath = getExecutablePath(browserName); if (executablePath && (process.env.FOLIO_WORKER_INDEX === undefined || process.env.FOLIO_WORKER_INDEX === '')) console.error(`Using executable at ${executablePath}`); - const mode = (process.env.PWTEST_MODE || 'default') as ('default' | 'driver' | 'service'); - const envConfig = { + config.projects.push({ + name: browserName, + testDir, + testIgnore: [/android/, /electron/], options: { - mode, + mode: (process.env.PWTEST_MODE || 'default') as ('default' | 'driver' | 'service'), browserName, headful: !!process.env.HEADFUL, channel: process.env.PWTEST_CHANNEL as any, video: !!process.env.PWTEST_VIDEO, - traceDir: process.env.PWTRACE ? path.join(config.outputDir, 'trace') : undefined, + traceDir: process.env.PWTRACE ? path.join(outputDir, 'trace') : undefined, launchOptions: { executablePath, }, coverageName: browserName, }, - tag: browserName, - }; - playwrightTest.runWith(envConfig); - slowPlaywrightTest.runWith({ ...envConfig, timeout: config.timeout * 3 }); - pageTest.runWith(envConfig, new PageEnv()); - tracingTest.runWith({ options: { ...envConfig.options, traceDir: path.join(config.outputDir, 'trace-' + process.env.FOLIO_WORKER_INDEX) }, tag: browserName }); + define: { test: pageTest, env: new PageEnv() }, + }); } + +export default config; diff --git a/tests/config/electron.config.ts b/tests/config/electron.config.ts index 06bdf0932d..6f5cf32343 100644 --- a/tests/config/electron.config.ts +++ b/tests/config/electron.config.ts @@ -16,28 +16,10 @@ import * as folio from 'folio'; import * as path from 'path'; -import { baseElectronTest, ElectronEnv, electronTest } from './electronTest'; +import { ElectronEnv } from './electronTest'; import { test as pageTest } from '../page/pageTest'; - -const config: folio.Config = { - testDir: path.join(__dirname, '..'), - outputDir: path.join(__dirname, '..', '..', 'test-results'), - timeout: 30000, - globalTimeout: 5400000, -}; -if (process.env.CI) { - config.workers = 1; - config.forbidOnly = true; - config.retries = 3; -} -folio.setConfig(config); - -if (process.env.CI) { - folio.setReporters([ - new folio.reporters.dot(), - new folio.reporters.json({ outputFile: path.join(__dirname, '..', '..', 'test-results', 'report.json') }), - ]); -} +import { PlaywrightEnvOptions } from './browserTest'; +import { CommonOptions } from './baseTest'; class ElectronPageEnv extends ElectronEnv { async beforeEach(args: any, testInfo: folio.TestInfo) { @@ -54,15 +36,40 @@ class ElectronPageEnv extends ElectronEnv { } } -const envConfig = { - tag: 'electron', - options: { - mode: 'default' as const, - browserName: 'chromium' as const, - coverageName: 'electron' - } +type AllOptions = PlaywrightEnvOptions & CommonOptions; + +const outputDir = path.join(__dirname, '..', '..', 'test-results'); +const testDir = path.join(__dirname, '..'); +const config: folio.Config = { + testDir, + outputDir, + timeout: 30000, + globalTimeout: 5400000, + workers: process.env.CI ? 1 : undefined, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 3 : 0, + reporter: process.env.CI ? [ + 'dot', + { name: 'json', outputFile: path.join(outputDir, 'report.json') }, + ] : 'line', + projects: [], }; -baseElectronTest.runWith(envConfig); -electronTest.runWith(envConfig); -pageTest.runWith(envConfig, new ElectronPageEnv()); +config.projects.push({ + name: 'electron', + options: { + coverageName: 'electron' + }, + testDir: path.join(testDir, 'electron'), +}); + +config.projects.push({ + name: 'electron', + options: { + coverageName: 'electron' + }, + testDir: path.join(testDir, 'page'), + define: { test: pageTest, env: new ElectronPageEnv() }, +}); + +export default config; diff --git a/tests/config/electronTest.ts b/tests/config/electronTest.ts index 933ee04712..cd749f8827 100644 --- a/tests/config/electronTest.ts +++ b/tests/config/electronTest.ts @@ -79,5 +79,5 @@ export class ElectronEnv { } } -export const baseElectronTest = baseTest.extend({}); +export const baseElectronTest = baseTest; export const electronTest = baseTest.extend(new ElectronEnv()); diff --git a/tests/defaultbrowsercontext-2.spec.ts b/tests/defaultbrowsercontext-2.spec.ts index 2d194dc403..e51bd049ab 100644 --- a/tests/defaultbrowsercontext-2.spec.ts +++ b/tests/defaultbrowsercontext-2.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { playwrightTest as it, slowPlaywrightTest as slowTest, expect } from './config/browserTest'; +import { playwrightTest as it, expect } from './config/browserTest'; import fs from 'fs'; it('should support hasTouch option', async ({server, launchPersistent}) => { @@ -82,7 +82,9 @@ it('should accept userDataDir', async ({createUserDataDir, browserType, browserO expect(fs.readdirSync(userDataDir).length).toBeGreaterThan(0); }); -slowTest('should restore state from userDataDir', async ({browserType, browserOptions, server, createUserDataDir}) => { +it('should restore state from userDataDir', async ({browserType, browserOptions, server, createUserDataDir}) => { + it.slow(); + const userDataDir = await createUserDataDir(); const browserContext = await browserType.launchPersistentContext(userDataDir, browserOptions); const page = await browserContext.newPage(); @@ -104,8 +106,9 @@ slowTest('should restore state from userDataDir', async ({browserType, browserOp await browserContext3.close(); }); -slowTest('should restore cookies from userDataDir', async ({browserType, browserOptions, server, createUserDataDir, platform, browserChannel}) => { - slowTest.fixme(platform === 'win32' && browserChannel === 'chrome'); +it('should restore cookies from userDataDir', async ({browserType, browserOptions, server, createUserDataDir, platform, browserChannel}) => { + it.fixme(platform === 'win32' && browserChannel === 'chrome'); + it.slow(); const userDataDir = await createUserDataDir(); const browserContext = await browserType.launchPersistentContext(userDataDir, browserOptions); diff --git a/tests/headful.spec.ts b/tests/headful.spec.ts index 19813cb991..1ec99a5d29 100644 --- a/tests/headful.spec.ts +++ b/tests/headful.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { playwrightTest as it, slowPlaywrightTest as slowTest, expect } from './config/browserTest'; +import { playwrightTest as it, expect } from './config/browserTest'; it('should have default url when launching browser', async ({browserType, browserOptions, createUserDataDir}) => { const browserContext = await browserType.launchPersistentContext(await createUserDataDir(), {...browserOptions, headless: false }); @@ -23,7 +23,9 @@ it('should have default url when launching browser', async ({browserType, browse await browserContext.close(); }); -slowTest('should close browser with beforeunload page', async ({browserType, browserOptions, server, createUserDataDir}) => { +it('should close browser with beforeunload page', async ({browserType, browserOptions, server, createUserDataDir}) => { + it.slow(); + const browserContext = await browserType.launchPersistentContext(await createUserDataDir(), {...browserOptions, headless: false}); const page = await browserContext.newPage(); await page.goto(server.PREFIX + '/beforeunload.html'); diff --git a/tests/screencast.spec.ts b/tests/screencast.spec.ts index 15c9ea6ec2..75d5f71d2e 100644 --- a/tests/screencast.spec.ts +++ b/tests/screencast.spec.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { slowBrowserTest as it, expect } from './config/browserTest'; +import { browserTest as it, expect } from './config/browserTest'; import fs from 'fs'; import path from 'path'; import { spawnSync } from 'child_process'; @@ -152,6 +152,8 @@ function expectRedFrames(videoFile: string, size: { width: number, height: numbe } it.describe('screencast', () => { + it.slow(); + it('videoSize should require videosPath', async ({browser}) => { const error = await browser.newContext({ videoSize: { width: 100, height: 100 } }).catch(e => e); expect(error.message).toContain('"videoSize" option requires "videosPath" to be specified'); diff --git a/tests/screenshot.spec.ts b/tests/screenshot.spec.ts index c9b32b6f9c..b875a6f81e 100644 --- a/tests/screenshot.spec.ts +++ b/tests/screenshot.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { expect, browserTest, slowBrowserTest } from './config/browserTest'; +import { expect, browserTest } from './config/browserTest'; import { PNG } from 'pngjs'; import { verifyViewport } from './config/utils'; @@ -83,9 +83,9 @@ browserTest.describe('page screenshot', () => { await context.close(); }); - // Large screenshot is slow. - slowBrowserTest('should work with large size', async ({ browserName, headful, platform, contextFactory }) => { - slowBrowserTest.fixme(browserName === 'chromium' && headful === true && platform === 'linux', 'Chromium has gpu problems on linux with large screnshots'); + browserTest('should work with large size', async ({ browserName, headful, platform, contextFactory }) => { + browserTest.fixme(browserName === 'chromium' && headful === true && platform === 'linux', 'Chromium has gpu problems on linux with large screnshots'); + browserTest.slow('Large screenshot is slow'); const context = await contextFactory(); const page = await context.newPage(); diff --git a/tests/signals.spec.ts b/tests/signals.spec.ts index 3cd146ede3..c21d22170a 100644 --- a/tests/signals.spec.ts +++ b/tests/signals.spec.ts @@ -15,9 +15,11 @@ * limitations under the License. */ -import { slowPlaywrightTest as test, expect } from './config/browserTest'; +import { playwrightTest as test, expect } from './config/browserTest'; import { execSync } from 'child_process'; +test.slow('All signal tests are slow'); + test('should close the browser when the node process closes', async ({startRemoteServer, isWindows, server}) => { const remoteServer = await startRemoteServer({ url: server.EMPTY_PAGE }); if (isWindows) diff --git a/tests/tracing.spec.ts b/tests/tracing.spec.ts index 0ad53de094..b0101858e9 100644 --- a/tests/tracing.spec.ts +++ b/tests/tracing.spec.ts @@ -15,13 +15,15 @@ */ import path from 'path'; -import { expect, tracingTest as test } from './config/browserTest'; +import { expect, contextTest as test } from './config/browserTest'; import yauzl from 'yauzl'; import removeFolder from 'rimraf'; -test.beforeEach(async ({}, testInfo) => { - const folder = path.join(testInfo.config.outputDir, 'trace-' + process.env.FOLIO_WORKER_INDEX); - await new Promise(f => removeFolder(folder, f)); +const traceDir = path.join(__dirname, '..', 'test-results', 'trace-' + process.env.FOLIO_WORKER_INDEX); +test.useOptions({ traceDir }); + +test.beforeEach(async () => { + await new Promise(f => removeFolder(traceDir, f)); }); test('should collect trace', async ({ context, page, server, browserName }, testInfo) => {