diff --git a/.env.example b/.env.example old mode 100644 new mode 100755 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml old mode 100644 new mode 100755 index 98f8a2a..859d246 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,127 +1,13 @@ # .github/workflows/playwright-daily.yml # Runs Playwright test shards every day at **11 : 42 AM IST** (06 : 12 UTC) -# plus anytime you trigger it manually from the Actions tab. - -name: Run Playwright tests - -on: - push: # runs on every push - pull_request: # runs on new PRs or PR updates - schedule: - - cron: '30 3 * * 1-5' - workflow_dispatch: - -jobs: - run-tests: - name: Run shard ${{ matrix.shardIndex }}/5 - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - shardIndex: [1,2,3,4,5] - shardTotal: [5] - - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js 18.x - uses: actions/setup-node@v3 - with: - node-version: '18' - - - name: Create .env file - run: | - echo "USERNAME=${{ secrets.USERNAME }}" >> .env - echo "PASSWORD=${{ secrets.PASSWORD }}" >> .env - echo "NEW_PASSWORD=${{ secrets.NEW_PASSWORD }}" >> .env - echo "FIRST_NAME=${{ secrets.FIRST_NAME }}" >> .env - echo "STREET_NAME=${{ secrets.STREET_NAME }}" >> .env - echo "CITY=${{ secrets.CITY }}" >> .env - echo "STATE=${{ secrets.STATE }}" >> .env - echo "COUNTRY=${{ secrets.COUNTRY }}" >> .env - echo "ZIP_CODE=${{ secrets.ZIP_CODE }}" >> .env - - - name: Cache npm dependencies - uses: actions/cache@v3 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - name: Install deps + browsers - run: | - npm ci - npx playwright install --with-deps chromium firefox webkit - - name: List Playwright projects (debug) - run: npx playwright list --projects | cat - - - name: Run shard ${{ matrix.shardIndex }} - run: npx playwright test --grep="@chromium|@firefox|@webkit|@android|@ios|@api" --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - - - name: Upload blob report - if: ${{ !cancelled() }} - uses: actions/upload-artifact@v4 - with: - name: blob-report-${{ matrix.shardIndex }} - path: ./blob-report - retention-days: 1 - - merge-reports: - name: Merge Reports - needs: run-tests - if: always() # run even if some shards fail - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Setup Node.js 18.x - uses: actions/setup-node@v3 - with: - node-version: '18' - - - name: Cache npm dependencies - uses: actions/cache@v3 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - - name: Install deps + browsers - run: | - npm ci - npx playwright install --with-deps - - name: Download all blob reports - uses: actions/download-artifact@v4 - with: - path: ./all-blob-reports - pattern: blob-report-* - merge-multiple: true - - - name: Merge HTML & JSON reports - run: npx playwright merge-reports --reporter=html ./all-blob-reports - - - name: Upload combined report - uses: actions/upload-artifact@v4 - with: - name: Playwright Test Report - path: ./playwright-report - retention-days: 14 - - - name: Send TestDino report - run: | - npx --yes tdpw ./playwright-report \ - --token="${{ secrets.TESTDINO_TOKEN }}" \ - --upload-html \ - --verbose - # name: Run Playwright tests # on: -# push: -# pull_request: +# push: # runs on every push +# pull_request: # runs on new PRs or PR updates +# schedule: +# - cron: '30 3 * * 1-5' # workflow_dispatch: # jobs: @@ -132,20 +18,17 @@ jobs: # strategy: # fail-fast: false # matrix: -# shardIndex: [1, 2, 3, 4, 5] +# shardIndex: [1,2,3,4,5] # shardTotal: [5] # steps: -# - name: Checkout repo -# uses: actions/checkout@v4 +# - uses: actions/checkout@v4 -# # ✅ Required Node version -# - name: Setup Node.js 20.x -# uses: actions/setup-node@v4 +# - name: Setup Node.js 18.x +# uses: actions/setup-node@v3 # with: -# node-version: '20' +# node-version: '18' -# # ✅ Required env variables for tests # - name: Create .env file # run: | # echo "USERNAME=${{ secrets.USERNAME }}" >> .env @@ -157,8 +40,7 @@ jobs: # echo "STATE=${{ secrets.STATE }}" >> .env # echo "COUNTRY=${{ secrets.COUNTRY }}" >> .env # echo "ZIP_CODE=${{ secrets.ZIP_CODE }}" >> .env - -# # ✅ Cache npm dependencies + # - name: Cache npm dependencies # uses: actions/cache@v3 # with: @@ -166,28 +48,148 @@ jobs: # key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} # restore-keys: | # ${{ runner.os }}-node- - -# # ✅ Install dependencies + TestDino (.tgz) + Playwright browsers -# - name: Install dependencies & browsers +# - name: Install deps + browsers # run: | -# npm install -# npm install --save-dev @testdino/playwright@latest +# npm ci # npx playwright install --with-deps chromium firefox webkit +# - name: List Playwright projects (debug) +# run: npx playwright list --projects | cat -# # ✅ Run Playwright shard with TestDino -# - name: Run Playwright shard with TestDino -# env: -# TESTDINO_TOKEN: ${{ secrets.TESTDINO_TOKEN }} -# run: | -# npx playwright test \ -# --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} \ -# --grep "@chromium|@firefox|@webkit|@android|@ios|@api" \ +# - name: Run shard ${{ matrix.shardIndex }} +# run: npx playwright test --grep="@chromium|@firefox|@webkit|@android|@ios|@api" --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} -# # ✅ Upload blob report (needed for merge) # - name: Upload blob report # if: ${{ !cancelled() }} # uses: actions/upload-artifact@v4 # with: # name: blob-report-${{ matrix.shardIndex }} # path: ./blob-report -# retention-days: 1 \ No newline at end of file +# retention-days: 1 + +# merge-reports: +# name: Merge Reports +# needs: run-tests +# if: always() # run even if some shards fail +# runs-on: ubuntu-latest + +# steps: +# - uses: actions/checkout@v4 + +# - name: Setup Node.js 18.x +# uses: actions/setup-node@v3 +# with: +# node-version: '18' + +# - name: Cache npm dependencies +# uses: actions/cache@v3 +# with: +# path: ~/.npm +# key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} +# restore-keys: | +# ${{ runner.os }}-node- +# - name: Install deps + browsers +# run: | +# npm ci +# npx playwright install --with-deps +# - name: Download all blob reports +# uses: actions/download-artifact@v4 +# with: +# path: ./all-blob-reports +# pattern: blob-report-* +# merge-multiple: true + +# - name: Merge HTML & JSON reports +# run: npx playwright merge-reports --reporter=html ./all-blob-reports + +# - name: Upload combined report +# uses: actions/upload-artifact@v4 +# with: +# name: Playwright Test Report +# path: ./playwright-report +# retention-days: 14 + + +name: Run Playwright tests + +on: + workflow_dispatch: + inputs: + test_count: + description: 'Number of TC- tests to generate (max 5000)' + required: false + default: '5' + +jobs: + run-tests: + name: Run shard ${{ matrix.shardIndex }}/15 + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + shardIndex: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + shardTotal: [15] + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + # ✅ Required Node version + - name: Setup Node.js 20.x + uses: actions/setup-node@v4 + with: + node-version: '20' + + # ✅ Required env variables for tests + - name: Create .env file + run: | + echo "USERNAME=${{ secrets.USERNAME }}" >> .env + echo "PASSWORD=${{ secrets.PASSWORD }}" >> .env + echo "NEW_PASSWORD=${{ secrets.NEW_PASSWORD }}" >> .env + echo "FIRST_NAME=${{ secrets.FIRST_NAME }}" >> .env + echo "STREET_NAME=${{ secrets.STREET_NAME }}" >> .env + echo "CITY=${{ secrets.CITY }}" >> .env + echo "STATE=${{ secrets.STATE }}" >> .env + echo "COUNTRY=${{ secrets.COUNTRY }}" >> .env + echo "ZIP_CODE=${{ secrets.ZIP_CODE }}" >> .env + # ✅ Cache npm dependencies + - name: Cache npm dependencies + uses: actions/cache@v3 + with: + path: ~/.npm + key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + # ✅ Install dependencies + TestDino (.tgz) + Playwright browsers + - name: Install dependencies & browsers + run: | + npm install + npx playwright install --with-deps chromium + # ✅ Run Playwright shard with real-time TestDino streaming + - name: Run Playwright shard with TestDino + env: + TESTDINO_TOKEN: ${{ secrets.TESTDINO_TOKEN }} + TESTDINO_SERVER_URL: https://stg-analytics.testdino.com + TC_COUNT: ${{ github.event.inputs.test_count || '5' }} + run: | + npx playwright test \ + --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} \ + --workers=7 \ + --pass-with-no-tests \ + --grep="@chromium|@firefox|@webkit|@android|@ios|@api" + # ✅ Upload test results to BuildPulse (runs even when tests fail) + - name: Upload test results to BuildPulse + if: always() + uses: BuildPulseLLC/test-reporter-action@v3 + with: + api-token: ${{ secrets.BUILDPULSE_API_TOKEN }} + path: junit.xml + + # ✅ Upload blob report (needed for merge) + - name: Upload blob report + if: ${{ !cancelled() }} + uses: actions/upload-artifact@v4 + with: + name: blob-report-${{ matrix.shardIndex }} + path: ./blob-report + retention-days: 1 diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/LICENCE b/LICENCE new file mode 100755 index 0000000..6c5b4dc --- /dev/null +++ b/LICENCE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 TestDino + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 620a189..729981e --- a/README.md +++ b/README.md @@ -3,6 +3,13 @@ Automated end-to-end tests for Ecommerce Demo store using [Playwright](https://playwright.dev/). --- +
+ ## Project Structure @@ -45,32 +52,41 @@ npx playwright show-report ## Testdino Integration -[Testdino](https://testdino.com/) enables cloud-based Playwright reporting. - -### Local Execution +[Testdino](https://testdino.com/) enables cloud-based Playwright reporting with real-time streaming via the [`@testdino/playwright`](https://www.npmjs.com/package/@testdino/playwright) reporter. -After your tests complete and the report is generated in `playwright-report`, upload it to Testdino: +The reporter is already configured in `playwright.config.js`: +```js +reporter: [ + ['@testdino/playwright', { token: process.env.TESTDINO_TOKEN }], +], +``` +### Local Execution -Replace the token above with your own Testdino API key. +Set your API token (from the TestDino dashboard) and run tests as usual — results stream to TestDino in real time: -See all available commands: ```sh -npx tdpw --help +export TESTDINO_TOKEN=YOUR_API_TOKEN +npx playwright test ``` +You can also put the token in `.env` (see `.env.example`); it is loaded automatically. + --- ## CI/CD Pipeline Integration ### GitHub Actions -Add the following step to your workflow after tests and report generation: - +Add `TESTDINO_TOKEN` as a repository secret and expose it to the test step: - -Ensure your API key is correctly placed in the command. +```yaml +- name: Run Playwright tests + run: npx playwright test + env: + TESTDINO_TOKEN: ${{ secrets.TESTDINO_TOKEN }} +``` --- diff --git a/__screenshots__/visual.spec.js-snapshots/github-login-after-typing-chromium-darwin.png b/__screenshots__/visual.spec.js-snapshots/github-login-after-typing-chromium-darwin.png old mode 100644 new mode 100755 diff --git a/__screenshots__/visual.spec.js-snapshots/github-login-changed-chromium-darwin.png b/__screenshots__/visual.spec.js-snapshots/github-login-changed-chromium-darwin.png old mode 100644 new mode 100755 diff --git a/__screenshots__/visual.spec.js-snapshots/github-login-chromium-darwin.png b/__screenshots__/visual.spec.js-snapshots/github-login-chromium-darwin.png old mode 100644 new mode 100755 diff --git a/__screenshots__/visual.spec.js-snapshots/github-login-filled-chromium-darwin.png b/__screenshots__/visual.spec.js-snapshots/github-login-filled-chromium-darwin.png old mode 100644 new mode 100755 diff --git a/__screenshots__/visual.spec.js-snapshots/github-login-initial-chromium-darwin.png b/__screenshots__/visual.spec.js-snapshots/github-login-initial-chromium-darwin.png old mode 100644 new mode 100755 diff --git a/__screenshots__/visual.spec.js-snapshots/github-login-username-chromium-darwin.png b/__screenshots__/visual.spec.js-snapshots/github-login-username-chromium-darwin.png old mode 100644 new mode 100755 diff --git a/__screenshots__/visual.spec.js-snapshots/username-input-chromium-darwin.png b/__screenshots__/visual.spec.js-snapshots/username-input-chromium-darwin.png old mode 100644 new mode 100755 diff --git a/github-login.png b/github-login.png old mode 100644 new mode 100755 diff --git a/package-lock.json b/package-lock.json old mode 100644 new mode 100755 index 461940b..5e77396 --- a/package-lock.json +++ b/package-lock.json @@ -10,22 +10,22 @@ "license": "ISC", "dependencies": { "dotenv": "^17.2.1", - "playwright": "^1.55.0" + "playwright": "1.59.0" }, "devDependencies": { - "@playwright/test": "^1.54.1", - "@testdino/playwright": "^1.0.7", + "@playwright/test": "1.59.0", + "@testdino/playwright": "file:vendor/testdino-playwright-2.0.0.tgz", "@types/node": "^24.1.0" } }, "node_modules/@playwright/test": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.2.tgz", - "integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==", + "version": "1.59.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.59.0.tgz", + "integrity": "sha512-TOA5sTLd49rTDaZpYpvCQ9hGefHQq/OYOyCVnGqS2mjMfX+lGZv2iddIJd0I48cfxqSPttS9S3OuLKyylHcO1w==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.58.2" + "playwright": "1.59.0" }, "bin": { "playwright": "cli.js" @@ -55,18 +55,22 @@ } }, "node_modules/@testdino/playwright": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@testdino/playwright/-/playwright-1.0.7.tgz", - "integrity": "sha512-ayFZ7T6BFBTxS5coYPGmANEhmBVRf0nX8CZEBPnTIUpqY5mrM2gtxSpOwEct86aRW/wo5FnchjyxN1wEc0C2Mg==", + "version": "2.0.0", + "resolved": "file:vendor/testdino-playwright-2.0.0.tgz", + "integrity": "sha512-wVBcmAQ7Bbyi/YkFIHFzNGwxIIFn23uZOsvVz/mve5c2gP0vP7bgWsX0rye77SNEmP6IJxpM3WAl2aAGhKNKzQ==", "dev": true, "dependencies": { - "axios": "^1.13.4", + "axios": "^1.18.1", "chalk": "^5.6.2", - "commander": "^14.0.3", - "dotenv": "^17.2.3", + "commander": "^15.0.0", + "dotenv": "^17.4.2", "execa": "^9.6.1", - "jiti": "^2.6.1", - "ws": "^8.19.0" + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "jiti": "^2.7.0", + "kafkajs": "^2.2.4", + "picomatch": "^4.0.4" }, "bin": { "tdpw": "bin/tdpw.js" @@ -88,6 +92,19 @@ "undici-types": "~7.16.0" } }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -96,15 +113,16 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", + "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", "dev": true, "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", + "follow-redirects": "^1.16.0", "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" } }, "node_modules/call-bind-apply-helpers": { @@ -148,13 +166,13 @@ } }, "node_modules/commander": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", - "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-15.0.0.tgz", + "integrity": "sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==", "dev": true, "license": "MIT", "engines": { - "node": ">=20" + "node": ">=22.12.0" } }, "node_modules/cross-spawn": { @@ -172,6 +190,24 @@ "node": ">= 8" } }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -183,9 +219,9 @@ } }, "node_modules/dotenv": { - "version": "17.2.4", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.4.tgz", - "integrity": "sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==", + "version": "17.4.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz", + "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -230,9 +266,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "dev": true, "license": "MIT", "dependencies": { @@ -302,9 +338,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "dev": true, "funding": [ { @@ -323,17 +359,17 @@ } }, "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -432,6 +468,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -462,9 +508,9 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "dev": true, "license": "MIT", "dependencies": { @@ -474,6 +520,27 @@ "node": ">= 0.4" } }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", @@ -530,16 +597,81 @@ "dev": true, "license": "ISC" }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/jiti": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/kafkajs": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/kafkajs/-/kafkajs-2.2.4.tgz", + "integrity": "sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -573,6 +705,13 @@ "node": ">= 0.6" } }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, "node_modules/npm-run-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", @@ -626,13 +765,26 @@ "node": ">=8" } }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/playwright": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.2.tgz", - "integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==", + "version": "1.59.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.59.0.tgz", + "integrity": "sha512-wihGScriusvATUxmhfENxg0tj1vHEFeIwxlnPFKQTOQVd7aG08mUfvvniRP/PtQOC+2Bs52kBOC/Up1jTXeIbw==", "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.58.2" + "playwright-core": "1.59.0" }, "bin": { "playwright": "cli.js" @@ -645,9 +797,9 @@ } }, "node_modules/playwright-core": { - "version": "1.58.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.2.tgz", - "integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==", + "version": "1.59.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.59.0.tgz", + "integrity": "sha512-PW/X/IoZ6BMUUy8rpwHEZ8Kc0IiLIkgKYGNFaMs5KmQhcfLILNx9yCQD0rnWeWfz1PNeqcFP1BsihQhDOBCwZw==", "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" @@ -673,11 +825,27 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, "node_modules/shebang-command": { "version": "2.0.0", @@ -728,6 +896,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", @@ -764,28 +945,6 @@ "node": ">= 8" } }, - "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/yoctocolors": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", diff --git a/package.json b/package.json old mode 100644 new mode 100755 index 0e8ba2a..8b80885 --- a/package.json +++ b/package.json @@ -7,12 +7,12 @@ "license": "ISC", "description": "", "devDependencies": { - "@playwright/test": "^1.54.1", - "@testdino/playwright": "^1.0.7", + "@playwright/test": "1.59.0", + "@testdino/playwright": "file:vendor/testdino-playwright-2.0.0.tgz", "@types/node": "^24.1.0" }, "dependencies": { "dotenv": "^17.2.1", - "playwright": "^1.55.0" + "playwright": "1.59.0" } } diff --git a/pages/AllPages.js b/pages/AllPages.js old mode 100644 new mode 100755 diff --git a/pages/AllProductsPage.js b/pages/AllProductsPage.js old mode 100644 new mode 100755 diff --git a/pages/BasePage.js b/pages/BasePage.js old mode 100644 new mode 100755 diff --git a/pages/CartPage.js b/pages/CartPage.js old mode 100644 new mode 100755 diff --git a/pages/CheckoutPage.js b/pages/CheckoutPage.js old mode 100644 new mode 100755 diff --git a/pages/ContactUsPage.js b/pages/ContactUsPage.js old mode 100644 new mode 100755 diff --git a/pages/HomePage.js b/pages/HomePage.js old mode 100644 new mode 100755 diff --git a/pages/InventoryPage.js b/pages/InventoryPage.js old mode 100644 new mode 100755 diff --git a/pages/LoginPage.js b/pages/LoginPage.js old mode 100644 new mode 100755 diff --git a/pages/OrderDetailsPage.js b/pages/OrderDetailsPage.js old mode 100644 new mode 100755 diff --git a/pages/OrderPage.js b/pages/OrderPage.js old mode 100644 new mode 100755 diff --git a/pages/ProductDetailsPage.js b/pages/ProductDetailsPage.js old mode 100644 new mode 100755 diff --git a/pages/SignupPage.js b/pages/SignupPage.js old mode 100644 new mode 100755 diff --git a/pages/UserPage.js b/pages/UserPage.js old mode 100644 new mode 100755 diff --git a/playwright.config.js b/playwright.config.js old mode 100644 new mode 100755 index 3496e92..358bade --- a/playwright.config.js +++ b/playwright.config.js @@ -9,11 +9,14 @@ const isCI = !!process.env.CI; export default defineConfig({ testDir: './tests', + testMatch: ['bulk-tc.spec.js'], snapshotDir: './__screenshots__', // ✅ Baseline image storage fullyParallel: true, forbidOnly: isCI, - retries: isCI ? 1 : 1, // Enable retries for flaky test behavior - workers: isCI ? 5 : 5, + // 1 retry in CI so intentionally-flaky tests register as "flaky" (pass on + // retry) instead of failing the shard outright. + retries: isCI ? 1 : 0, + workers: 3, timeout: 60 * 1000, expect: { @@ -27,15 +30,21 @@ export default defineConfig({ }], ['blob', { outputDir: 'blob-report' }], // Blob reporter for merging ['json', { outputFile: './playwright-report/report.json' }], - // ['@testdino/playwright', { token: process.env.TESTDINO_TOKEN }], + ['junit', { outputFile: 'junit.xml' }], // JUnit XML for BuildPulse + + // NOTE: ciRunId (shard grouping) intentionally NOT set — runs streamed with + // ciRunId are ingested but never appear on the staging dashboard (backend bug). + // Re-add `ciRunId: process.env.GITHUB_RUN_ID` once server-side grouping is fixed. + ['@testdino/playwright', { token: process.env.TESTDINO_TOKEN }], // Real-time streaming to TestDino ], use: { baseURL: 'https://storedemo.testdino.com/products', headless: true, - trace: 'retain-on-failure', - screenshot: 'only-on-failure', - video: 'retain-on-failure', + // Always record so every artifact reaches TestDino + trace: 'on', + screenshot: 'on', + video: 'on', actionTimeout: 15 * 1000, navigationTimeout: 30 * 1000, }, @@ -44,33 +53,6 @@ export default defineConfig({ { name: 'chromium', use: { ...devices['Desktop Chrome'] }, - grep: /@chromium/, // only run tests tagged @chromium - }, - { - name: 'firefox', - use: { ...devices['Desktop Firefox'] }, - grep: /@firefox/, // only run tests tagged @firefox - }, - { - name: 'webkit', - use: { ...devices['Desktop Safari'] }, - grep: /@webkit/, // only run tests tagged @webkit - }, - { - name: 'android', - use: { ...devices['Pixel 5'] }, - grep: /@android/, // only run tests tagged @android - }, - { - name: 'ios', - use: { ...devices['iPhone 12'] }, - grep: /@ios/, // only run tests tagged @ios - }, - - { - name: 'api', - use: { ...devices['API'] }, - grep: /@api/, // only run tests tagged @api }, ], }); diff --git a/tests/bulk-tc.spec.js b/tests/bulk-tc.spec.js new file mode 100644 index 0000000..4526c73 --- /dev/null +++ b/tests/bulk-tc.spec.js @@ -0,0 +1,41 @@ +// @ts-check +// Bulk-generated suite: one loop, TOTAL_TESTS test cases. +// Each iteration registers an independent test titled TC-