From 425063bf0ead2bec65747733093638b4eee4553e Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:42:33 +0800 Subject: [PATCH 01/82] Use composite actions in API tests job --- .github/workflows/smoke-test-daily.yml | 38 ++++++++------------------ 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 95fb70dbf6a..5e65ff5b1cf 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -41,38 +41,24 @@ jobs: install-filters: woocommerce build: false - - name: Download and install Chromium browser. - working-directory: plugins/woocommerce - run: pnpm exec playwright install chromium - - - name: Run 'Update WooCommerce' test. - working-directory: plugins/woocommerce + - name: Update site to nightly version + uses: ./.github/actions/tests/run-e2e-tests + with: + report-name: ${{ env.API_ARTIFACT }} + tests: update-woocommerce.spec.js env: + GITHUB_TOKEN: ${{ secrets.E2E_GH_TOKEN }} UPDATE_WC: nightly - run: pnpm exec playwright test --config=tests/e2e-pw/playwright.config.js update-woocommerce.spec.js - - name: Run API tests. - working-directory: plugins/woocommerce + - name: Run API tests + id: run-api-composite-action + uses: ./.github/actions/tests/run-api-tests + with: + report-name: ${{ env.API_ARTIFACT }} + tests: hello.test.js # mytodo: remove env: USER_KEY: ${{ secrets.SMOKE_TEST_ADMIN_USER }} USER_SECRET: ${{ secrets.SMOKE_TEST_ADMIN_PASSWORD }} - run: pnpm exec playwright test --config=tests/api-core-tests/playwright.config.js - - - name: Generate API Test report. - if: success() || failure() - working-directory: plugins/woocommerce - run: pnpm exec allure generate --clean ${{ env.ALLURE_RESULTS_DIR }} --output ${{ env.ALLURE_REPORT_DIR }} - - - name: Archive API test report - if: success() || failure() - uses: actions/upload-artifact@v3 - with: - name: ${{ env.API_ARTIFACT }} - path: | - ${{ env.ALLURE_RESULTS_DIR }} - ${{ env.ALLURE_REPORT_DIR }} - if-no-files-found: ignore - retention-days: 5 e2e-tests: name: E2E tests on nightly build From c40b6e7e7eed6021180b97be6a8b8f1953b5a14d Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:44:12 +0800 Subject: [PATCH 02/82] Use composite actions in E2E test job --- .github/workflows/smoke-test-daily.yml | 48 ++++++++------------------ 1 file changed, 15 insertions(+), 33 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 5e65ff5b1cf..fd44b390f24 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -66,16 +66,6 @@ jobs: permissions: contents: read needs: [api-tests] - env: - ADMIN_PASSWORD: ${{ secrets.SMOKE_TEST_ADMIN_PASSWORD }} - ADMIN_USER: ${{ secrets.SMOKE_TEST_ADMIN_USER }} - ADMIN_USER_EMAIL: ${{ secrets.SMOKE_TEST_ADMIN_USER_EMAIL }} - ALLURE_REPORT_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/test-results/allure-report - ALLURE_RESULTS_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/test-results/allure-results - BASE_URL: ${{ secrets.SMOKE_TEST_URL }} - CUSTOMER_PASSWORD: ${{ secrets.SMOKE_TEST_CUSTOMER_PASSWORD }} - CUSTOMER_USER: ${{ secrets.SMOKE_TEST_CUSTOMER_USER }} - DEFAULT_TIMEOUT_OVERRIDE: 120000 steps: - uses: actions/checkout@v3 @@ -86,33 +76,25 @@ jobs: install-filters: woocommerce build: false - - name: Download and install Chromium browser. - working-directory: plugins/woocommerce - run: pnpm exec playwright install chromium - - - name: Run E2E tests. + - name: Run E2E tests + id: run-e2e-composite-action timeout-minutes: 60 - working-directory: plugins/woocommerce + uses: ./.github/actions/tests/run-e2e-tests + with: + report-name: ${{ env.E2E_ARTIFACT }} + tests: basic.spec.js # mytodo: remove env: + ADMIN_PASSWORD: ${{ secrets.SMOKE_TEST_ADMIN_PASSWORD }} + ADMIN_USER: ${{ secrets.SMOKE_TEST_ADMIN_USER }} + ADMIN_USER_EMAIL: ${{ secrets.SMOKE_TEST_ADMIN_USER_EMAIL }} + ALLURE_REPORT_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/test-results/allure-report + ALLURE_RESULTS_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/test-results/allure-results + BASE_URL: ${{ secrets.SMOKE_TEST_URL }} + CUSTOMER_PASSWORD: ${{ secrets.SMOKE_TEST_CUSTOMER_PASSWORD }} + CUSTOMER_USER: ${{ secrets.SMOKE_TEST_CUSTOMER_USER }} + DEFAULT_TIMEOUT_OVERRIDE: 120000 E2E_MAX_FAILURES: 25 RESET_SITE: true - run: pnpm exec playwright test --config=tests/e2e-pw/playwright.config.js - - - name: Generate Playwright E2E Test report. - if: success() || failure() - working-directory: plugins/woocommerce - run: pnpm exec allure generate --clean ${{ env.ALLURE_RESULTS_DIR }} --output ${{ env.ALLURE_REPORT_DIR }} - - - name: Archive E2E test report - if: success() || failure() - uses: actions/upload-artifact@v3 - with: - name: ${{ env.E2E_ARTIFACT }} - path: | - ${{ env.ALLURE_RESULTS_DIR }} - ${{ env.ALLURE_REPORT_DIR }} - if-no-files-found: ignore - retention-days: 5 k6-tests: name: k6 tests on nightly build From 92e15b9def102b7f5da7446faf3595a4265425f1 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:44:50 +0800 Subject: [PATCH 03/82] Use composite actions in k6 job --- .github/workflows/smoke-test-daily.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index fd44b390f24..a00072159d8 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -112,23 +112,22 @@ jobs: install-filters: woocommerce build: false - - name: Download and install Chromium browser. - working-directory: plugins/woocommerce - run: pnpm exec playwright install chromium - - name: Update performance test site with E2E test - working-directory: plugins/woocommerce + id: update-perf-site + continue-on-error: true + uses: ./.github/actions/tests/run-e2e-tests + with: + report-name: k6-daily-update-site--run-${{ github.run_number }} + tests: update-woocommerce.spec.js env: BASE_URL: ${{ secrets.SMOKE_TEST_PERF_URL }}/ ADMIN_USER: ${{ secrets.SMOKE_TEST_PERF_ADMIN_USER }} ADMIN_PASSWORD: ${{ secrets.SMOKE_TEST_PERF_ADMIN_PASSWORD }} CUSTOMER_USER: ${{ secrets.SMOKE_TEST_PERF_ADMIN_USER }} CUSTOMER_PASSWORD: ${{ secrets.SMOKE_TEST_PERF_ADMIN_PASSWORD }} - UPDATE_WC: nightly DEFAULT_TIMEOUT_OVERRIDE: 120000 - run: | - pnpm exec playwright test --config=tests/e2e-pw/playwright.config.js update-woocommerce.spec.js - continue-on-error: true + GITHUB_TOKEN: ${{ secrets.E2E_GH_TOKEN }} + UPDATE_WC: nightly - name: Install k6 run: | From a6039aa1b6f7ef20f12f2b5ad2846145fa5b429c Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:47:20 +0800 Subject: [PATCH 04/82] Use composite actions in plugin tests job --- .github/workflows/smoke-test-daily.yml | 27 +++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index a00072159d8..c1d32556752 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -180,27 +180,32 @@ jobs: with: build-filters: woocommerce - - name: Launch wp-env e2e environment - working-directory: plugins/woocommerce - run: pnpm env:test --filter=woocommerce - - - name: Download and install Chromium browser. - working-directory: plugins/woocommerce - run: pnpm exec playwright install chromium + - name: Setup local test environment + uses: ./.github/actions/tests/setup-local-test-environment + with: + test-type: e2e - name: Run 'Upload plugin' test - working-directory: plugins/woocommerce + id: run-upload-plugin-test + uses: ./.github/actions/tests/run-e2e-tests + with: + report-name: Smoke tests on trunk with ${{ matrix.plugin }} plugin installed (run ${{ github.run_number }}) + tests: upload-plugin.spec.js env: PLUGIN_REPOSITORY: ${{ matrix.private && secrets[matrix.repo] || matrix.repo }} PLUGIN_NAME: ${{ matrix.plugin }} GITHUB_TOKEN: ${{ secrets.E2E_GH_TOKEN }} - run: pnpm test:e2e-pw upload-plugin.spec.js - name: Run the rest of E2E tests - working-directory: plugins/woocommerce + id: run-e2e-composite-action + timeout-minutes: 60 + uses: ./.github/actions/tests/run-e2e-tests + with: + playwright-config: ignore-plugin-tests.playwright.config.js + report-name: Smoke tests on trunk with ${{ matrix.plugin }} plugin installed (run ${{ github.run_number }}) + tests: basic.spec.js # mytodo: remove env: E2E_MAX_FAILURES: 15 - run: pnpm test:e2e-pw - name: Generate E2E Test report. if: success() || failure() From 58af912bfaa832a1fc0dc1605b6b5f017d8d515e Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:48:22 +0800 Subject: [PATCH 05/82] Specify job outputs --- .github/workflows/smoke-test-daily.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index c1d32556752..7b3e6c6e094 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -21,6 +21,8 @@ jobs: runs-on: ubuntu-20.04 permissions: contents: read + outputs: + test-result: ${{ steps.run-api-composite-action.outputs.result }} env: ALLURE_RESULTS_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/api-core-tests/test-results/allure-results ALLURE_REPORT_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/api-core-tests/test-results/allure-report @@ -66,7 +68,8 @@ jobs: permissions: contents: read needs: [api-tests] - + outputs: + test-result: ${{ steps.run-e2e-composite-action.outputs.result }} steps: - uses: actions/checkout@v3 @@ -103,6 +106,8 @@ jobs: contents: read needs: [api-tests] if: success() || failure() + outputs: + test-result: ${{ steps.run-k6-tests.conclusion }} steps: - uses: actions/checkout@v3 @@ -134,6 +139,7 @@ jobs: curl https://github.com/grafana/k6/releases/download/v0.33.0/k6-v0.33.0-linux-amd64.tar.gz -L | tar xvz --strip-components 1 - name: Run k6 smoke tests + id: run-k6-tests env: URL: ${{ secrets.SMOKE_TEST_PERF_URL }} HOST: ${{ secrets.SMOKE_TEST_PERF_HOST }} From 4211c1424f7180213dc290e7ad66b9064ce66e03 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:51:06 +0800 Subject: [PATCH 06/82] Add step to create and archive plugin test slack blocks --- .github/workflows/smoke-test-daily.yml | 34 +++++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 7b3e6c6e094..05d991550ec 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -8,6 +8,7 @@ env: API_ARTIFACT: api-daily--run-${{ github.run_number }} E2E_ARTIFACT: e2e-daily--run-${{ github.run_number }} FORCE_COLOR: 1 + PLUGIN_SLACK_BLOCKS_ARTIFACT: plugin-blocks concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -167,17 +168,23 @@ jobs: include: - plugin: 'WooCommerce Payments' repo: 'automattic/woocommerce-payments' + slug: woocommerce-payments - plugin: 'WooCommerce PayPal Payments' repo: 'woocommerce/woocommerce-paypal-payments' + slug: woocommerce-paypal-payments - plugin: 'WooCommerce Shipping & Tax' repo: 'automattic/woocommerce-services' + slug: woocommerce-services - plugin: 'WooCommerce Subscriptions' repo: WC_SUBSCRIPTIONS_REPO private: true + slug: woocommerce-subscriptions - plugin: 'Gutenberg' repo: 'WordPress/gutenberg' + slug: gutenberg - plugin: 'Gutenberg - Nightly' repo: 'bph/gutenberg' + slug: gutenberg-nightly steps: - uses: actions/checkout@v3 @@ -213,21 +220,24 @@ jobs: env: E2E_MAX_FAILURES: 15 - - name: Generate E2E Test report. - if: success() || failure() - working-directory: plugins/woocommerce - run: pnpm exec allure generate --clean ${{ env.ALLURE_RESULTS_DIR }} --output ${{ env.ALLURE_REPORT_DIR }} + - name: Create context block and save as JSON file + id: create-block-json + uses: actions/github-script@v6 + with: + script: | + const script = require( './.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js' ) + script( { core } ); + env: + UPLOAD_RESULT: ${{ steps.run-upload-plugin-test.outputs.result }} + E2E_RESULT: ${{ steps.run-e2e-composite-action.outputs.result }} + PLUGIN_NAME: ${{ matrix.plugin }} + PLUGIN_SLUG: ${{ matrix.slug }} - - name: Archive E2E test report - if: success() || failure() + - name: Upload JSON file as artifact uses: actions/upload-artifact@v3 with: - name: Smoke tests on trunk with ${{ matrix.plugin }} plugin installed (run ${{ github.run_number }}) - path: | - ${{ env.ALLURE_RESULTS_DIR }} - ${{ env.ALLURE_REPORT_DIR }} - if-no-files-found: ignore - retention-days: 5 + name: ${{ matrix.plugin }} + path: ${{ steps.create-block-json.outputs.path }} trunk-results: name: Publish report on smoke tests on nightly build From eb458bbdf333437fd14e7402a78f01712c7e70a9 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:51:24 +0800 Subject: [PATCH 07/82] Remove unnecessary env var --- .github/workflows/smoke-test-daily.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 05d991550ec..eb669311ccb 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -159,7 +159,6 @@ jobs: contents: read needs: [api-tests] env: - USE_WP_ENV: 1 ALLURE_RESULTS_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/allure-results ALLURE_REPORT_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/allure-report strategy: From 2932e11ae2f5bc41026d0428b03e64c0355dbd99 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:52:20 +0800 Subject: [PATCH 08/82] Add job to send slack summary --- .github/workflows/smoke-test-daily.yml | 47 ++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index eb669311ccb..186bfa1dbf2 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -337,3 +337,50 @@ jobs: -f slug="${{ matrix.slug }}" \ -f s3_root=public \ --repo woocommerce/woocommerce-test-reports + + post-slack-summary: + name: Post Slack summary + runs-on: ubuntu-20.04 + permissions: + contents: read + if: | + success() || ( + failure() && contains( needs.*.result, 'failure' ) + ) + needs: + - api-tests + - e2e-tests + - k6-tests + - test-plugins + steps: + - uses: actions/checkout@v3 + + - name: Download Slack blocks from plugin tests + id: download-plugin-blocks + uses: actions/download-artifact@v3 + with: + name: ${{ env.PLUGIN_SLACK_BLOCKS_ARTIFACT }} + path: /tmp/plugin-blocks + + - name: Construct Slack payload + id: construct-slack-payload + uses: actions/github-script@v6 + with: + script: | + const script = require('./.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js'); + script( { core } ); + env: + API_RESULT: ${{ needs.api-tests.outputs.test-result }} + E2E_RESULT: ${{ needs.e2e-tests.outputs.test-result }} + k6_RESULT: ${{ needs.k6-tests.outputs.test-result }} + PLUGINS_BLOCKS_PATH: ${{ steps.download-plugin-blocks.outputs.download-path }} + + - name: Send Slack message # mytodo: DAILY_TEST_SLACK_CHANNEL + id: send-slack-message + uses: slackapi/slack-github-action@v1.23.0 + with: + channel-id: ${{ secrets.SMOKE_TEST_SLACK_CHANNEL }} + payload: ${{ steps.construct-slack-payload.outputs.payload }} + env: + SLACK_BOT_TOKEN: ${{ secrets.E2E_SLACK_TOKEN }} + \ No newline at end of file From 7317e60bbe233c601c71b97133d032a09c0d7159 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:53:05 +0800 Subject: [PATCH 09/82] Minor spacing fix --- .github/workflows/smoke-test-daily.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 186bfa1dbf2..e728633402c 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -231,13 +231,13 @@ jobs: E2E_RESULT: ${{ steps.run-e2e-composite-action.outputs.result }} PLUGIN_NAME: ${{ matrix.plugin }} PLUGIN_SLUG: ${{ matrix.slug }} - + - name: Upload JSON file as artifact uses: actions/upload-artifact@v3 with: name: ${{ matrix.plugin }} path: ${{ steps.create-block-json.outputs.path }} - + trunk-results: name: Publish report on smoke tests on nightly build if: | From bbfa6c06445b5df7ae0e896599b5f19d5c31bbdf Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Tue, 15 Aug 2023 16:53:29 +0800 Subject: [PATCH 10/82] Add supporting scripts --- .../scripts/construct-slack-payload.js | 55 +++++++++++++++++++ .../scripts/create-blocks-plugin-tests.js | 38 +++++++++++++ .../scripts/utils/get-context-blocks.js | 22 ++++++++ .../scripts/utils/index.js | 7 +++ .../scripts/utils/select-emoji.js | 26 +++++++++ 5 files changed, 148 insertions(+) create mode 100644 .github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js create mode 100644 .github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js create mode 100644 .github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js create mode 100644 .github/actions/tests/slack-summary-daily/scripts/utils/index.js create mode 100644 .github/actions/tests/slack-summary-daily/scripts/utils/select-emoji.js diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js new file mode 100644 index 00000000000..606d8d8e8f4 --- /dev/null +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -0,0 +1,55 @@ +const { API_RESULT, E2E_RESULT, k6_RESULT, PLUGINS_BLOCKS_PATH } = process.env; +const { selectEmoji, readContextBlocksFromJsonFiles } = require( './utils' ); + +const block_header = { + type: 'header', + text: { + type: 'plain_text', + text: 'Daily test results', + emoji: true, + }, +}; + +const emoji_API = selectEmoji( API_RESULT ); +const emoji_E2E = selectEmoji( E2E_RESULT ); +const emoji_k6 = selectEmoji( k6_RESULT ); + +const block_nightlySite = { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: '*Smoke tests on daily build*', + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: `API ${ emoji_API }`, + }, + { + type: 'mrkdwn', + text: `E2E ${ emoji_E2E }`, + }, + { + type: 'mrkdwn', + text: `k6 ${ emoji_k6 }`, + }, + ], +}; + +const blocks_plugins = readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); + +const payload = { + blocks: [ block_header, block_nightlySite, ...blocks_plugins ], +}; + +const payload_stringified = JSON.stringify( payload ); + +core.setOuput( 'payload', payload_stringified ); diff --git a/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js new file mode 100644 index 00000000000..fe317d18171 --- /dev/null +++ b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js @@ -0,0 +1,38 @@ +const { UPLOAD_RESULT, E2E_RESULT, PLUGIN_NAME, PLUGIN_SLUG } = process.env; +const { selectEmoji } = require( './utils' ); +const fs = require( 'fs' ); + +const emoji_UPLOAD = selectEmoji( UPLOAD_RESULT ); +const emoji_E2E = selectEmoji( E2E_RESULT ); + +const block = { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: PLUGIN_NAME, + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: `Upload test ${ emoji_UPLOAD }`, + }, + { + type: 'mrkdwn', + text: `E2E ${ emoji_E2E }`, + }, + ], +}; +const block_stringified = JSON.stringify( block ); + +const path = `/tmp/${ PLUGIN_SLUG }.json`; +fs.writeFileSync( path, block_stringified ); + +core.setOutput( 'path', path ); diff --git a/.github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js b/.github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js new file mode 100644 index 00000000000..78919007236 --- /dev/null +++ b/.github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js @@ -0,0 +1,22 @@ +const fs = require( 'fs' ); +const path = require( 'path' ); + +const readContextBlocksFromJsonFiles = ( blocksDir ) => { + const jsonsDir = path.resolve( blocksDir ); + const jsons = fs.readdirSync( jsonsDir ); + + let contextBlocks = []; + + for ( const json of jsons ) { + const jsonPath = path.resolve( jsonsDir, json ); + const contextBlock = require( jsonPath ); + + contextBlocks.push( contextBlock ); + } + + return contextBlocks; +}; + +module.exports = { + readContextBlocksFromJsonFiles, +}; diff --git a/.github/actions/tests/slack-summary-daily/scripts/utils/index.js b/.github/actions/tests/slack-summary-daily/scripts/utils/index.js new file mode 100644 index 00000000000..24ea196b9f6 --- /dev/null +++ b/.github/actions/tests/slack-summary-daily/scripts/utils/index.js @@ -0,0 +1,7 @@ +const { readContextBlocksFromJsonFiles } = require( './get-context-blocks' ); +const { selectEmoji } = require( './select-emoji' ); + +module.exports = { + readContextBlocksFromJsonFiles, + selectEmoji, +}; diff --git a/.github/actions/tests/slack-summary-daily/scripts/utils/select-emoji.js b/.github/actions/tests/slack-summary-daily/scripts/utils/select-emoji.js new file mode 100644 index 00000000000..a9ba564fe09 --- /dev/null +++ b/.github/actions/tests/slack-summary-daily/scripts/utils/select-emoji.js @@ -0,0 +1,26 @@ +const emojis = { + PASSED: ':workflow-passed:', + FAILED: ':workflow-failed:', + SKIPPED: ':workflow-skipped:', + CANCELLED: ':workflow-cancelled:', + UNKNOWN: ':grey_question:', +}; + +const selectEmoji = ( result ) => { + switch ( result ) { + case 'success': + return emojis.PASSED; + case 'failure': + return emojis.FAILED; + case 'skipped': + return emojis.SKIPPED; + case 'cancelled': + return emojis.CANCELLED; + default: + return emojis.UNKNOWN; + } +}; + +module.exports = { + selectEmoji, +}; From d351853bc108eb8d2cdc2b74c8028ce324b75a43 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 16 Aug 2023 08:14:22 +0800 Subject: [PATCH 11/82] Fix function export --- .../scripts/construct-slack-payload.js | 113 ++++++++++-------- .../scripts/create-blocks-plugin-tests.js | 72 +++++------ 2 files changed, 97 insertions(+), 88 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 606d8d8e8f4..602a232e3eb 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -1,55 +1,62 @@ -const { API_RESULT, E2E_RESULT, k6_RESULT, PLUGINS_BLOCKS_PATH } = process.env; -const { selectEmoji, readContextBlocksFromJsonFiles } = require( './utils' ); +module.exports = ( { core } ) => { + const { API_RESULT, E2E_RESULT, k6_RESULT, PLUGINS_BLOCKS_PATH } = + process.env; + const { + selectEmoji, + readContextBlocksFromJsonFiles, + } = require( './utils' ); -const block_header = { - type: 'header', - text: { - type: 'plain_text', - text: 'Daily test results', - emoji: true, - }, + const block_header = { + type: 'header', + text: { + type: 'plain_text', + text: 'Daily test results', + emoji: true, + }, + }; + + const emoji_API = selectEmoji( API_RESULT ); + const emoji_E2E = selectEmoji( E2E_RESULT ); + const emoji_k6 = selectEmoji( k6_RESULT ); + + const block_nightlySite = { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: '*Smoke tests on daily build*', + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: `API ${ emoji_API }`, + }, + { + type: 'mrkdwn', + text: `E2E ${ emoji_E2E }`, + }, + { + type: 'mrkdwn', + text: `k6 ${ emoji_k6 }`, + }, + ], + }; + + const blocks_plugins = + readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); + + const payload = { + blocks: [ block_header, block_nightlySite, ...blocks_plugins ], + }; + + const payload_stringified = JSON.stringify( payload ); + + core.setOuput( 'payload', payload_stringified ); }; - -const emoji_API = selectEmoji( API_RESULT ); -const emoji_E2E = selectEmoji( E2E_RESULT ); -const emoji_k6 = selectEmoji( k6_RESULT ); - -const block_nightlySite = { - type: 'context', - elements: [ - { - type: 'mrkdwn', - text: '*Smoke tests on daily build*', - }, - { - type: 'mrkdwn', - text: ' ', - }, - { - type: 'mrkdwn', - text: ' ', - }, - { - type: 'mrkdwn', - text: `API ${ emoji_API }`, - }, - { - type: 'mrkdwn', - text: `E2E ${ emoji_E2E }`, - }, - { - type: 'mrkdwn', - text: `k6 ${ emoji_k6 }`, - }, - ], -}; - -const blocks_plugins = readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); - -const payload = { - blocks: [ block_header, block_nightlySite, ...blocks_plugins ], -}; - -const payload_stringified = JSON.stringify( payload ); - -core.setOuput( 'payload', payload_stringified ); diff --git a/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js index fe317d18171..c3a1c6247df 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js +++ b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js @@ -1,38 +1,40 @@ -const { UPLOAD_RESULT, E2E_RESULT, PLUGIN_NAME, PLUGIN_SLUG } = process.env; -const { selectEmoji } = require( './utils' ); -const fs = require( 'fs' ); +module.exports = ( { core } ) => { + const { UPLOAD_RESULT, E2E_RESULT, PLUGIN_NAME, PLUGIN_SLUG } = process.env; + const { selectEmoji } = require( './utils' ); + const fs = require( 'fs' ); -const emoji_UPLOAD = selectEmoji( UPLOAD_RESULT ); -const emoji_E2E = selectEmoji( E2E_RESULT ); + const emoji_UPLOAD = selectEmoji( UPLOAD_RESULT ); + const emoji_E2E = selectEmoji( E2E_RESULT ); -const block = { - type: 'context', - elements: [ - { - type: 'mrkdwn', - text: PLUGIN_NAME, - }, - { - type: 'mrkdwn', - text: ' ', - }, - { - type: 'mrkdwn', - text: ' ', - }, - { - type: 'mrkdwn', - text: `Upload test ${ emoji_UPLOAD }`, - }, - { - type: 'mrkdwn', - text: `E2E ${ emoji_E2E }`, - }, - ], + const block = { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: PLUGIN_NAME, + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: ' ', + }, + { + type: 'mrkdwn', + text: `Upload test ${ emoji_UPLOAD }`, + }, + { + type: 'mrkdwn', + text: `E2E ${ emoji_E2E }`, + }, + ], + }; + const block_stringified = JSON.stringify( block ); + + const path = `/tmp/${ PLUGIN_SLUG }.json`; + fs.writeFileSync( path, block_stringified ); + + core.setOutput( 'path', path ); }; -const block_stringified = JSON.stringify( block ); - -const path = `/tmp/${ PLUGIN_SLUG }.json`; -fs.writeFileSync( path, block_stringified ); - -core.setOutput( 'path', path ); From d14d63114bca8270b8d975fa6e8408a6d96af7c4 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 16 Aug 2023 08:43:49 +0800 Subject: [PATCH 12/82] Fix artifact name --- .github/workflows/smoke-test-daily.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index e728633402c..79394b082ce 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -235,7 +235,7 @@ jobs: - name: Upload JSON file as artifact uses: actions/upload-artifact@v3 with: - name: ${{ matrix.plugin }} + name: ${{ env.PLUGIN_SLACK_BLOCKS_ARTIFACT }} path: ${{ steps.create-block-json.outputs.path }} trunk-results: From 8195c0286cfa00c0941e7dffa3d9212f22681bee Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 16 Aug 2023 09:07:56 +0800 Subject: [PATCH 13/82] Fix syntax error --- .../slack-summary-daily/scripts/construct-slack-payload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 602a232e3eb..0da7f9ae4dd 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -58,5 +58,5 @@ module.exports = ( { core } ) => { const payload_stringified = JSON.stringify( payload ); - core.setOuput( 'payload', payload_stringified ); + core.setOutput( 'payload', payload_stringified ); }; From 6af36053442424ebfc1da1a2d8f4aa3c988cebe5 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 16 Aug 2023 12:47:25 +0800 Subject: [PATCH 14/82] Change slack message formatting --- .../scripts/construct-slack-payload.js | 85 +++++++++++++------ .../scripts/create-blocks-plugin-tests.js | 46 +++++----- 2 files changed, 79 insertions(+), 52 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 0da7f9ae4dd..b1f70f5c512 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -1,6 +1,11 @@ module.exports = ( { core } ) => { - const { API_RESULT, E2E_RESULT, k6_RESULT, PLUGINS_BLOCKS_PATH } = - process.env; + const { + API_RESULT, + E2E_RESULT, + k6_RESULT, + PLUGINS_BLOCKS_PATH, + GITHUB_RUN_ID, + } = process.env; const { selectEmoji, readContextBlocksFromJsonFiles, @@ -18,42 +23,68 @@ module.exports = ( { core } ) => { const emoji_API = selectEmoji( API_RESULT ); const emoji_E2E = selectEmoji( E2E_RESULT ); const emoji_k6 = selectEmoji( k6_RESULT ); - - const block_nightlySite = { - type: 'context', - elements: [ - { + const blockGroup_nightlySite = [ + { + type: 'section', + text: { type: 'mrkdwn', text: '*Smoke tests on daily build*', }, + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `API ${ emoji_API }\tE2E ${ emoji_E2E }\tk6 ${ emoji_k6 }`, + }, + ], + }, + { + type: 'divider', + }, + ]; + + const blockGroups_plugins = + readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); + + const block_github = { + type: 'actions', + elements: [ { - type: 'mrkdwn', - text: ' ', + type: 'button', + text: { + type: 'plain_text', + text: 'View GitHub run logs :github:', + emoji: true, + }, + url: `https://github.com/woocommerce/woocommerce/actions/runs/${ GITHUB_RUN_ID }`, }, + ], + }; + const block_dashboard = { + type: 'actions', + elements: [ { - type: 'mrkdwn', - text: ' ', - }, - { - type: 'mrkdwn', - text: `API ${ emoji_API }`, - }, - { - type: 'mrkdwn', - text: `E2E ${ emoji_E2E }`, - }, - { - type: 'mrkdwn', - text: `k6 ${ emoji_k6 }`, + type: 'button', + text: { + type: 'plain_text', + text: 'Open test reports dashboard :colorful-bar-chart:', + emoji: true, + }, + url: 'https://woocommerce.github.io/woocommerce-test-reports/daily/', }, ], }; - const blocks_plugins = - readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); - const payload = { - blocks: [ block_header, block_nightlySite, ...blocks_plugins ], + blocks: [ + block_header, + ...blockGroup_nightlySite, + ...blockGroups_plugins.flat(), + block_github, + block_dashboard, + ], }; const payload_stringified = JSON.stringify( payload ); diff --git a/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js index c3a1c6247df..d23cb9b072a 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js +++ b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js @@ -6,35 +6,31 @@ module.exports = ( { core } ) => { const emoji_UPLOAD = selectEmoji( UPLOAD_RESULT ); const emoji_E2E = selectEmoji( E2E_RESULT ); - const block = { - type: 'context', - elements: [ - { + const blockGroup = [ + { + type: 'section', + text: { type: 'mrkdwn', - text: PLUGIN_NAME, + text: `*${ PLUGIN_NAME }*`, }, - { - type: 'mrkdwn', - text: ' ', - }, - { - type: 'mrkdwn', - text: ' ', - }, - { - type: 'mrkdwn', - text: `Upload test ${ emoji_UPLOAD }`, - }, - { - type: 'mrkdwn', - text: `E2E ${ emoji_E2E }`, - }, - ], - }; - const block_stringified = JSON.stringify( block ); + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `"Upload plugin" test ${ emoji_UPLOAD }\tOther E2E tests ${ emoji_E2E }`, + }, + ], + }, + { + type: 'divider', + }, + ]; + const blockGroup_stringified = JSON.stringify( blockGroup ); const path = `/tmp/${ PLUGIN_SLUG }.json`; - fs.writeFileSync( path, block_stringified ); + fs.writeFileSync( path, blockGroup_stringified ); core.setOutput( 'path', path ); }; From c092494c1e073d44efe93e8dfc24199978db579c Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 16 Aug 2023 16:41:12 +0800 Subject: [PATCH 15/82] Remove comments --- .github/workflows/smoke-test-daily.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 79394b082ce..e3fe09ee5ab 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -58,7 +58,6 @@ jobs: uses: ./.github/actions/tests/run-api-tests with: report-name: ${{ env.API_ARTIFACT }} - tests: hello.test.js # mytodo: remove env: USER_KEY: ${{ secrets.SMOKE_TEST_ADMIN_USER }} USER_SECRET: ${{ secrets.SMOKE_TEST_ADMIN_PASSWORD }} @@ -86,7 +85,6 @@ jobs: uses: ./.github/actions/tests/run-e2e-tests with: report-name: ${{ env.E2E_ARTIFACT }} - tests: basic.spec.js # mytodo: remove env: ADMIN_PASSWORD: ${{ secrets.SMOKE_TEST_ADMIN_PASSWORD }} ADMIN_USER: ${{ secrets.SMOKE_TEST_ADMIN_USER }} @@ -215,7 +213,6 @@ jobs: with: playwright-config: ignore-plugin-tests.playwright.config.js report-name: Smoke tests on trunk with ${{ matrix.plugin }} plugin installed (run ${{ github.run_number }}) - tests: basic.spec.js # mytodo: remove env: E2E_MAX_FAILURES: 15 @@ -375,7 +372,7 @@ jobs: k6_RESULT: ${{ needs.k6-tests.outputs.test-result }} PLUGINS_BLOCKS_PATH: ${{ steps.download-plugin-blocks.outputs.download-path }} - - name: Send Slack message # mytodo: DAILY_TEST_SLACK_CHANNEL + - name: Send Slack message id: send-slack-message uses: slackapi/slack-github-action@v1.23.0 with: From 77277cdfbf522fec252c366bee0a7384e0e1f229 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 16 Aug 2023 16:44:11 +0800 Subject: [PATCH 16/82] Change slack channel id --- .github/workflows/smoke-test-daily.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index e3fe09ee5ab..d78e6771244 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -376,7 +376,7 @@ jobs: id: send-slack-message uses: slackapi/slack-github-action@v1.23.0 with: - channel-id: ${{ secrets.SMOKE_TEST_SLACK_CHANNEL }} + channel-id: ${{ secrets.DAILY_TEST_SLACK_CHANNEL }} payload: ${{ steps.construct-slack-payload.outputs.payload }} env: SLACK_BOT_TOKEN: ${{ secrets.E2E_SLACK_TOKEN }} From dbbb2fb6ca1c0427a979183c41bb76f6b2e61f6f Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 16 Aug 2023 18:02:06 +0800 Subject: [PATCH 17/82] Allow Slack block steps to run on e2e failure --- .github/workflows/smoke-test-daily.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index d78e6771244..032b7d563a0 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -217,19 +217,21 @@ jobs: E2E_MAX_FAILURES: 15 - name: Create context block and save as JSON file + if: success() || failure() id: create-block-json uses: actions/github-script@v6 with: - script: | - const script = require( './.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js' ) - script( { core } ); + script: | + const script = require( './.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js' ) + script( { core } ); env: - UPLOAD_RESULT: ${{ steps.run-upload-plugin-test.outputs.result }} - E2E_RESULT: ${{ steps.run-e2e-composite-action.outputs.result }} - PLUGIN_NAME: ${{ matrix.plugin }} - PLUGIN_SLUG: ${{ matrix.slug }} + UPLOAD_RESULT: ${{ steps.run-upload-plugin-test.outputs.result }} + E2E_RESULT: ${{ steps.run-e2e-composite-action.outputs.result }} + PLUGIN_NAME: ${{ matrix.plugin }} + PLUGIN_SLUG: ${{ matrix.slug }} - name: Upload JSON file as artifact + if: success() || failure() uses: actions/upload-artifact@v3 with: name: ${{ env.PLUGIN_SLACK_BLOCKS_ARTIFACT }} From 0d6f1969ed62ebaae19192c5e21ad1a148dbcda9 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 08:51:49 +0800 Subject: [PATCH 18/82] More slack message formatting changes --- .../scripts/construct-slack-payload.js | 158 +++++++++++------- 1 file changed, 93 insertions(+), 65 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index b1f70f5c512..e4383939d75 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -4,6 +4,7 @@ module.exports = ( { core } ) => { E2E_RESULT, k6_RESULT, PLUGINS_BLOCKS_PATH, + GITHUB_REF_NAME, GITHUB_RUN_ID, } = process.env; const { @@ -11,82 +12,109 @@ module.exports = ( { core } ) => { readContextBlocksFromJsonFiles, } = require( './utils' ); - const block_header = { - type: 'header', - text: { - type: 'plain_text', - text: 'Daily test results', - emoji: true, - }, + const create_blockGroup_header = () => { + const date = new Intl.DateTimeFormat( 'en-US', { + dateStyle: 'full', + } ).format( Date.now() ); + + const block = [ + { + type: 'divider', + }, + { + type: 'header', + text: { + type: 'plain_text', + text: 'Daily test results', + emoji: true, + }, + }, + , + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `*Date:* ${ date }`, + }, + ], + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `*Branch:* \`${ GITHUB_REF_NAME }\``, + }, + ], + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `*GitHub run logs:* `, + }, + ], + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: '*Test reports dashboard:* ', + }, + ], + }, + { + type: 'divider', + }, + ]; + + return block; }; - const emoji_API = selectEmoji( API_RESULT ); - const emoji_E2E = selectEmoji( E2E_RESULT ); - const emoji_k6 = selectEmoji( k6_RESULT ); - const blockGroup_nightlySite = [ - { - type: 'section', - text: { - type: 'mrkdwn', - text: '*Smoke tests on daily build*', - }, - }, - { - type: 'context', - elements: [ - { - type: 'mrkdwn', - text: `API ${ emoji_API }\tE2E ${ emoji_E2E }\tk6 ${ emoji_k6 }`, - }, - ], - }, - { - type: 'divider', - }, - ]; + const create_blockGroup_nightlySite = () => { + const emoji_API = selectEmoji( API_RESULT ); + const emoji_E2E = selectEmoji( E2E_RESULT ); + const emoji_k6 = selectEmoji( k6_RESULT ); + const block = [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: '*Smoke tests on daily build*', + }, + }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `API ${ emoji_API }\tE2E ${ emoji_E2E }\tk6 ${ emoji_k6 }`, + }, + ], + }, + { + type: 'divider', + }, + ]; + + return block; + }; + + const blockGroup_header = create_blockGroup_header(); + const blockGroup_nightlySite = create_blockGroup_nightlySite(); const blockGroups_plugins = readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); - - const block_github = { - type: 'actions', - elements: [ - { - type: 'button', - text: { - type: 'plain_text', - text: 'View GitHub run logs :github:', - emoji: true, - }, - url: `https://github.com/woocommerce/woocommerce/actions/runs/${ GITHUB_RUN_ID }`, - }, - ], - }; - const block_dashboard = { - type: 'actions', - elements: [ - { - type: 'button', - text: { - type: 'plain_text', - text: 'Open test reports dashboard :colorful-bar-chart:', - emoji: true, - }, - url: 'https://woocommerce.github.io/woocommerce-test-reports/daily/', - }, - ], - }; - const payload = { blocks: [ - block_header, + ...blockGroup_header, ...blockGroup_nightlySite, ...blockGroups_plugins.flat(), - block_github, - block_dashboard, ], }; - const payload_stringified = JSON.stringify( payload ); core.setOutput( 'payload', payload_stringified ); From 6511664ba376dbf1285dafa34c0a67c8113aab00 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 08:54:21 +0800 Subject: [PATCH 19/82] Minor variable naming change --- .../scripts/construct-slack-payload.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index e4383939d75..0a238a954aa 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -17,7 +17,7 @@ module.exports = ( { core } ) => { dateStyle: 'full', } ).format( Date.now() ); - const block = [ + const blocks = [ { type: 'divider', }, @@ -71,7 +71,7 @@ module.exports = ( { core } ) => { }, ]; - return block; + return blocks; }; const create_blockGroup_nightlySite = () => { @@ -79,7 +79,7 @@ module.exports = ( { core } ) => { const emoji_E2E = selectEmoji( E2E_RESULT ); const emoji_k6 = selectEmoji( k6_RESULT ); - const block = [ + const blocks = [ { type: 'section', text: { @@ -101,7 +101,7 @@ module.exports = ( { core } ) => { }, ]; - return block; + return blocks; }; const blockGroup_header = create_blockGroup_header(); From 56a90d950515e9073fee9a793a5dec350330bba0 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 09:56:46 +0800 Subject: [PATCH 20/82] Remove unnecessary comma --- .../tests/slack-summary-daily/scripts/construct-slack-payload.js | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 0a238a954aa..058cc6ec2c8 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -29,7 +29,6 @@ module.exports = ( { core } ) => { emoji: true, }, }, - , { type: 'context', elements: [ From 7ef6f1c30ac818b2a30ac17b287ed4cce8851b6b Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 10:30:23 +0800 Subject: [PATCH 21/82] Move divider location --- .../slack-summary-daily/scripts/construct-slack-payload.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 058cc6ec2c8..073ca4e97ec 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -18,9 +18,6 @@ module.exports = ( { core } ) => { } ).format( Date.now() ); const blocks = [ - { - type: 'divider', - }, { type: 'header', text: { @@ -29,6 +26,9 @@ module.exports = ( { core } ) => { emoji: true, }, }, + { + type: 'divider', + }, { type: 'context', elements: [ From c1771cb372ec7b303b7c5ffb997c43603eeef79a Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 10:42:13 +0800 Subject: [PATCH 22/82] Add missing required env vars --- .github/workflows/smoke-test-daily.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 032b7d563a0..94f07cbbc4c 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -124,6 +124,8 @@ jobs: report-name: k6-daily-update-site--run-${{ github.run_number }} tests: update-woocommerce.spec.js env: + ALLURE_RESULTS_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/allure-results + ALLURE_REPORT_DIR: ${{ github.workspace }}/plugins/woocommerce/tests/e2e-pw/allure-report BASE_URL: ${{ secrets.SMOKE_TEST_PERF_URL }}/ ADMIN_USER: ${{ secrets.SMOKE_TEST_PERF_ADMIN_USER }} ADMIN_PASSWORD: ${{ secrets.SMOKE_TEST_PERF_ADMIN_PASSWORD }} From 876a0eb6b9d86d09d8328769303556a41e41db6e Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 11:37:42 +0800 Subject: [PATCH 23/82] Get actual run date --- .../scripts/construct-slack-payload.js | 21 ++++++++++++++----- .github/workflows/smoke-test-daily.yml | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 073ca4e97ec..86f95d8ab44 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -1,4 +1,4 @@ -module.exports = ( { core } ) => { +module.exports = async ( { context, core, github } ) => { const { API_RESULT, E2E_RESULT, @@ -12,10 +12,21 @@ module.exports = ( { core } ) => { readContextBlocksFromJsonFiles, } = require( './utils' ); - const create_blockGroup_header = () => { - const date = new Intl.DateTimeFormat( 'en-US', { + const create_blockGroup_header = async () => { + const response = await github.rest.actions.getWorkflowRun( { + owner: context.repo.owner, + repo: context.repo.repo, + run_id: GITHUB_RUN_ID, + } ); + const runStartedAt = new Date( response.data.run_started_at ); + const intlDateTimeFormatOptions = { dateStyle: 'full', - } ).format( Date.now() ); + timeStyle: 'long', + }; + const date = new Intl.DateTimeFormat( + 'en-US', + intlDateTimeFormatOptions + ).format( runStartedAt ); const blocks = [ { @@ -103,7 +114,7 @@ module.exports = ( { core } ) => { return blocks; }; - const blockGroup_header = create_blockGroup_header(); + const blockGroup_header = await create_blockGroup_header(); const blockGroup_nightlySite = create_blockGroup_nightlySite(); const blockGroups_plugins = readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 94f07cbbc4c..0e70dab2839 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -369,7 +369,7 @@ jobs: with: script: | const script = require('./.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js'); - script( { core } ); + await script( { context, core, github } ); env: API_RESULT: ${{ needs.api-tests.outputs.test-result }} E2E_RESULT: ${{ needs.e2e-tests.outputs.test-result }} From ce6a9e2b26462e494f83c2694ed0cd58bbf4ca02 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 11:39:47 +0800 Subject: [PATCH 24/82] Minor text update --- .../slack-summary-daily/scripts/construct-slack-payload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 86f95d8ab44..fe4219ea4aa 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -45,7 +45,7 @@ module.exports = async ( { context, core, github } ) => { elements: [ { type: 'mrkdwn', - text: `*Date:* ${ date }`, + text: `*Run started:* ${ date }`, }, ], }, From 8fe91cf71453b6f89c65e889caf41086ea4d00f0 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 11:51:02 +0800 Subject: [PATCH 25/82] Minor function scoping --- .../scripts/construct-slack-payload.js | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index fe4219ea4aa..9319ea81d9b 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -13,20 +13,26 @@ module.exports = async ( { context, core, github } ) => { } = require( './utils' ); const create_blockGroup_header = async () => { - const response = await github.rest.actions.getWorkflowRun( { - owner: context.repo.owner, - repo: context.repo.repo, - run_id: GITHUB_RUN_ID, - } ); - const runStartedAt = new Date( response.data.run_started_at ); - const intlDateTimeFormatOptions = { - dateStyle: 'full', - timeStyle: 'long', + const getRunStartDate = async () => { + const response = await github.rest.actions.getWorkflowRun( { + owner: context.repo.owner, + repo: context.repo.repo, + run_id: GITHUB_RUN_ID, + } ); + const runStartedAt = new Date( response.data.run_started_at ); + const intlDateTimeFormatOptions = { + dateStyle: 'full', + timeStyle: 'long', + }; + const date = new Intl.DateTimeFormat( + 'en-US', + intlDateTimeFormatOptions + ).format( runStartedAt ); + + return date; }; - const date = new Intl.DateTimeFormat( - 'en-US', - intlDateTimeFormatOptions - ).format( runStartedAt ); + + const readableDate = await getRunStartDate(); const blocks = [ { @@ -45,7 +51,7 @@ module.exports = async ( { context, core, github } ) => { elements: [ { type: 'mrkdwn', - text: `*Run started:* ${ date }`, + text: `*Run started:* ${ readableDate }`, }, ], }, From af2d4b8daacbb5439e27b47e93a7212a93925580 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 17 Aug 2023 11:51:16 +0800 Subject: [PATCH 26/82] Minor doc addition --- .../slack-summary-daily/scripts/utils/get-context-blocks.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js b/.github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js index 78919007236..f09e614bb11 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js +++ b/.github/actions/tests/slack-summary-daily/scripts/utils/get-context-blocks.js @@ -1,6 +1,10 @@ const fs = require( 'fs' ); const path = require( 'path' ); +/** + * @param {string} blocksDir + * @returns {any[][]} + */ const readContextBlocksFromJsonFiles = ( blocksDir ) => { const jsonsDir = path.resolve( blocksDir ); const jsons = fs.readdirSync( jsonsDir ); From 0573492a74ff3b34a75b042ab9e222fb142f0b79 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 23 Aug 2023 08:45:58 +0800 Subject: [PATCH 27/82] Minor spacing corrections --- .github/workflows/smoke-test-daily.yml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 0e70dab2839..a8fae464492 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -223,22 +223,22 @@ jobs: id: create-block-json uses: actions/github-script@v6 with: - script: | - const script = require( './.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js' ) - script( { core } ); + script: | + const script = require( './.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js' ) + script( { core } ); env: - UPLOAD_RESULT: ${{ steps.run-upload-plugin-test.outputs.result }} - E2E_RESULT: ${{ steps.run-e2e-composite-action.outputs.result }} - PLUGIN_NAME: ${{ matrix.plugin }} - PLUGIN_SLUG: ${{ matrix.slug }} - + UPLOAD_RESULT: ${{ steps.run-upload-plugin-test.outputs.result }} + E2E_RESULT: ${{ steps.run-e2e-composite-action.outputs.result }} + PLUGIN_NAME: ${{ matrix.plugin }} + PLUGIN_SLUG: ${{ matrix.slug }} + - name: Upload JSON file as artifact if: success() || failure() uses: actions/upload-artifact@v3 with: name: ${{ env.PLUGIN_SLACK_BLOCKS_ARTIFACT }} path: ${{ steps.create-block-json.outputs.path }} - + trunk-results: name: Publish report on smoke tests on nightly build if: | @@ -368,8 +368,8 @@ jobs: uses: actions/github-script@v6 with: script: | - const script = require('./.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js'); - await script( { context, core, github } ); + const script = require('./.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js'); + await script( { context, core, github } ); env: API_RESULT: ${{ needs.api-tests.outputs.test-result }} E2E_RESULT: ${{ needs.e2e-tests.outputs.test-result }} @@ -384,4 +384,3 @@ jobs: payload: ${{ steps.construct-slack-payload.outputs.payload }} env: SLACK_BOT_TOKEN: ${{ secrets.E2E_SLACK_TOKEN }} - \ No newline at end of file From 073a250bd51332ae43aca802e2ef54b4d60c2e2b Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 23 Aug 2023 08:46:17 +0800 Subject: [PATCH 28/82] Add links --- .../scripts/construct-slack-payload.js | 23 +++++++++++++------ .../scripts/create-blocks-plugin-tests.js | 3 ++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index 9319ea81d9b..b4934a68b34 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -12,6 +12,8 @@ module.exports = async ( { context, core, github } ) => { readContextBlocksFromJsonFiles, } = require( './utils' ); + const URL_GITHUB_RUN_LOG = `https://github.com/woocommerce/woocommerce/actions/runs/${ GITHUB_RUN_ID }`; + const create_blockGroup_header = async () => { const getRunStartDate = async () => { const response = await github.rest.actions.getWorkflowRun( { @@ -69,7 +71,7 @@ module.exports = async ( { context, core, github } ) => { elements: [ { type: 'mrkdwn', - text: `*GitHub run logs:* `, + text: `*GitHub run logs:* <${ URL_GITHUB_RUN_LOG }|${ GITHUB_RUN_ID }>`, }, ], }, @@ -94,6 +96,11 @@ module.exports = async ( { context, core, github } ) => { const emoji_API = selectEmoji( API_RESULT ); const emoji_E2E = selectEmoji( E2E_RESULT ); const emoji_k6 = selectEmoji( k6_RESULT ); + const url_API = + 'https://woocommerce.github.io/woocommerce-test-reports/daily/nightly-site/api'; + const url_E2E = + 'https://woocommerce.github.io/woocommerce-test-reports/daily/nightly-site/e2e'; + const url_k6 = URL_GITHUB_RUN_LOG; const blocks = [ { @@ -108,7 +115,7 @@ module.exports = async ( { context, core, github } ) => { elements: [ { type: 'mrkdwn', - text: `API ${ emoji_API }\tE2E ${ emoji_E2E }\tk6 ${ emoji_k6 }`, + text: `<${ url_API }|API> ${ emoji_API }\t<${ url_E2E }|E2E> ${ emoji_E2E }\t<${ url_k6 }|k6> ${ emoji_k6 }`, }, ], }, @@ -124,12 +131,14 @@ module.exports = async ( { context, core, github } ) => { const blockGroup_nightlySite = create_blockGroup_nightlySite(); const blockGroups_plugins = readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); + const blocks_payload = [ + ...blockGroup_header, + ...blockGroup_nightlySite, + ...blockGroups_plugins.flat(), + ]; const payload = { - blocks: [ - ...blockGroup_header, - ...blockGroup_nightlySite, - ...blockGroups_plugins.flat(), - ], + text: 'Daily test results', + blocks: blocks_payload, }; const payload_stringified = JSON.stringify( payload ); diff --git a/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js index d23cb9b072a..e2e99712e32 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js +++ b/.github/actions/tests/slack-summary-daily/scripts/create-blocks-plugin-tests.js @@ -5,13 +5,14 @@ module.exports = ( { core } ) => { const emoji_UPLOAD = selectEmoji( UPLOAD_RESULT ); const emoji_E2E = selectEmoji( E2E_RESULT ); + const reportURL = `https://woocommerce.github.io/woocommerce-test-reports/daily/${ PLUGIN_SLUG }/e2e`; const blockGroup = [ { type: 'section', text: { type: 'mrkdwn', - text: `*${ PLUGIN_NAME }*`, + text: `<${ reportURL }|*${ PLUGIN_NAME }*>`, }, }, { From d096619ef4f2034633e67d374b09f3f8136036d6 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Wed, 23 Aug 2023 09:09:17 +0800 Subject: [PATCH 29/82] Add header link --- .../slack-summary-daily/scripts/construct-slack-payload.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index b4934a68b34..d747d90768b 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -107,7 +107,7 @@ module.exports = async ( { context, core, github } ) => { type: 'section', text: { type: 'mrkdwn', - text: '*Smoke tests on daily build*', + text: '', }, }, { @@ -131,14 +131,14 @@ module.exports = async ( { context, core, github } ) => { const blockGroup_nightlySite = create_blockGroup_nightlySite(); const blockGroups_plugins = readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); - const blocks_payload = [ + const blocks_all = [ ...blockGroup_header, ...blockGroup_nightlySite, ...blockGroups_plugins.flat(), ]; const payload = { text: 'Daily test results', - blocks: blocks_payload, + blocks: blocks_all, }; const payload_stringified = JSON.stringify( payload ); From 0207bbff970d32e137e1c24e4bff5552e055366d Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Fri, 1 Sep 2023 11:35:37 +0800 Subject: [PATCH 30/82] Handle skipped plugin tests --- .../scripts/construct-slack-payload.js | 22 +++++++++++++++++-- .github/workflows/smoke-test-daily.yml | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index d747d90768b..ef88808d92b 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -127,10 +127,28 @@ module.exports = async ( { context, core, github } ) => { return blocks; }; + const create_blockGroups_plugins = () => { + const blocks_pluginTestsNotRun = [ + { + type: 'section', + text: { + type: 'mrkdwn', + text: ':warning: *Plugin tests were not run!*', + }, + }, + { + type: 'divider', + }, + ]; + + return PLUGINS_BLOCKS_PATH + ? readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ) + : blocks_pluginTestsNotRun; + }; + const blockGroup_header = await create_blockGroup_header(); const blockGroup_nightlySite = create_blockGroup_nightlySite(); - const blockGroups_plugins = - readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); + const blockGroups_plugins = create_blockGroups_plugins(); const blocks_all = [ ...blockGroup_header, ...blockGroup_nightlySite, diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index a8fae464492..72accab4e1d 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -357,6 +357,7 @@ jobs: - uses: actions/checkout@v3 - name: Download Slack blocks from plugin tests + if: ! contains(fromJSON('["skipped", "cancelled"]'), needs.test-plugins.result) id: download-plugin-blocks uses: actions/download-artifact@v3 with: From 08eab1046cdcee76fc9aefc2bb4435680b6f8911 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Fri, 1 Sep 2023 11:39:10 +0800 Subject: [PATCH 31/82] Additional skip check --- .github/workflows/smoke-test-daily.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 72accab4e1d..30fdcdf2907 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -299,7 +299,8 @@ jobs: plugins-results: name: Publish report on Smoke tests on trunk with plugins if: | - ( success() || failure() ) && + ( success() || failure() ) && + ( needs.test-plugins.result != 'skipped' ) && ! github.event.pull_request.head.repo.fork runs-on: ubuntu-20.04 needs: [e2e-tests, test-plugins, k6-tests] From 2aefd9a301c6f2aa21eda45db8e59f31de6d1179 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Fri, 1 Sep 2023 12:12:36 +0800 Subject: [PATCH 32/82] Modify if condition --- .github/workflows/smoke-test-daily.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 30fdcdf2907..84e4e636100 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -358,7 +358,7 @@ jobs: - uses: actions/checkout@v3 - name: Download Slack blocks from plugin tests - if: ! contains(fromJSON('["skipped", "cancelled"]'), needs.test-plugins.result) + if: needs.test-plugins.result != 'skipped' id: download-plugin-blocks uses: actions/download-artifact@v3 with: From 15f260f35ed7fa23b1986f7f690e87ead172862c Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Fri, 1 Sep 2023 13:13:08 +0800 Subject: [PATCH 33/82] Set alternative value for env vars to make them more accurate --- .github/workflows/smoke-test-daily.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index 84e4e636100..e2ed104779c 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -374,8 +374,8 @@ jobs: await script( { context, core, github } ); env: API_RESULT: ${{ needs.api-tests.outputs.test-result }} - E2E_RESULT: ${{ needs.e2e-tests.outputs.test-result }} - k6_RESULT: ${{ needs.k6-tests.outputs.test-result }} + E2E_RESULT: ${{ needs.e2e-tests.outputs.test-result || needs.e2e-tests.result }} + k6_RESULT: ${{ needs.k6-tests.outputs.test-result || needs.k6-tests.result }} PLUGINS_BLOCKS_PATH: ${{ steps.download-plugin-blocks.outputs.download-path }} - name: Send Slack message From 910f8cf583e45f7b3c856d94bcf4e76b920e5ce9 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Fri, 1 Sep 2023 13:13:46 +0800 Subject: [PATCH 34/82] Handle skipped plugin tests more gracefully --- .../scripts/construct-slack-payload.js | 19 +++++++++++++++---- .github/workflows/smoke-test-daily.yml | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index ef88808d92b..d34525d4cd3 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -4,6 +4,7 @@ module.exports = async ( { context, core, github } ) => { E2E_RESULT, k6_RESULT, PLUGINS_BLOCKS_PATH, + PLUGIN_TESTS_RESULT, GITHUB_REF_NAME, GITHUB_RUN_ID, } = process.env; @@ -128,7 +129,8 @@ module.exports = async ( { context, core, github } ) => { }; const create_blockGroups_plugins = () => { - const blocks_pluginTestsNotRun = [ + const pluginTestsSkipped = PLUGIN_TESTS_RESULT === 'skipped'; + const blocks_pluginTestsSkipped = [ { type: 'section', text: { @@ -136,14 +138,23 @@ module.exports = async ( { context, core, github } ) => { text: ':warning: *Plugin tests were not run!*', }, }, + { + type: 'context', + elements: [ + { + type: 'mrkdwn', + text: `Head over to the <${ URL_GITHUB_RUN_LOG }|GitHub workflow run log> to see what went wrong.`, + }, + ], + }, { type: 'divider', }, ]; - return PLUGINS_BLOCKS_PATH - ? readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ) - : blocks_pluginTestsNotRun; + return pluginTestsSkipped + ? blocks_pluginTestsSkipped + : readContextBlocksFromJsonFiles( PLUGINS_BLOCKS_PATH ); }; const blockGroup_header = await create_blockGroup_header(); diff --git a/.github/workflows/smoke-test-daily.yml b/.github/workflows/smoke-test-daily.yml index e2ed104779c..07148b364af 100644 --- a/.github/workflows/smoke-test-daily.yml +++ b/.github/workflows/smoke-test-daily.yml @@ -377,6 +377,7 @@ jobs: E2E_RESULT: ${{ needs.e2e-tests.outputs.test-result || needs.e2e-tests.result }} k6_RESULT: ${{ needs.k6-tests.outputs.test-result || needs.k6-tests.result }} PLUGINS_BLOCKS_PATH: ${{ steps.download-plugin-blocks.outputs.download-path }} + PLUGIN_TESTS_RESULT: ${{ needs.test-plugins.result }} - name: Send Slack message id: send-slack-message From d8a07b030b15afe4d16f100a3895965070865c9a Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Fri, 1 Sep 2023 14:04:56 +0800 Subject: [PATCH 35/82] Add changelog --- .../woocommerce/changelog/e2e-add-plugin-tests-slack-summary | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 plugins/woocommerce/changelog/e2e-add-plugin-tests-slack-summary diff --git a/plugins/woocommerce/changelog/e2e-add-plugin-tests-slack-summary b/plugins/woocommerce/changelog/e2e-add-plugin-tests-slack-summary new file mode 100644 index 00000000000..a38627d6592 --- /dev/null +++ b/plugins/woocommerce/changelog/e2e-add-plugin-tests-slack-summary @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Add job to post Slack summary of plugin test results in "Smoke test daily" workflow. From e76fe48a8924c63d606fb7a49351b3912127193b Mon Sep 17 00:00:00 2001 From: Dan Q Date: Tue, 5 Sep 2023 13:14:48 +0100 Subject: [PATCH 36/82] Move top padding of Marketplace Extensions content to instead be top margin of Marketplace Extensions page This mitigates the issue whereby notifications push page content down a LONG way, and is a more-correct way to lay out the content. --- .../client/marketplace/components/content/content.scss | 4 ++-- .../woocommerce-admin/client/marketplace/marketplace.scss | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/plugins/woocommerce-admin/client/marketplace/components/content/content.scss b/plugins/woocommerce-admin/client/marketplace/components/content/content.scss index c9456d07c4a..bbd1b83ce4f 100644 --- a/plugins/woocommerce-admin/client/marketplace/components/content/content.scss +++ b/plugins/woocommerce-admin/client/marketplace/components/content/content.scss @@ -4,11 +4,11 @@ box-sizing: content-box; margin: auto; max-width: $content-max-width; - padding: $header-height-mobile $content-spacing-small $content-spacing-small; + padding: 0 $content-spacing-small $content-spacing-small; } @media screen and (min-width: $breakpoint-medium) { .woocommerce-marketplace__content { - padding: $header-height-desktop $content-spacing-large $content-spacing-large; + padding: 0 $content-spacing-large $content-spacing-large; } } diff --git a/plugins/woocommerce-admin/client/marketplace/marketplace.scss b/plugins/woocommerce-admin/client/marketplace/marketplace.scss index c019a031525..5c329b28f90 100644 --- a/plugins/woocommerce-admin/client/marketplace/marketplace.scss +++ b/plugins/woocommerce-admin/client/marketplace/marketplace.scss @@ -4,7 +4,11 @@ background: #fff; .woocommerce-layout__primary { - margin: 0; + margin: $header-height-mobile 0 0; + + @media (min-width: $breakpoint-medium) { + margin-top: $header-height-desktop; + } } .woocommerce-layout__main { From b430015d083d24963289ce1b239460bf0cfe3208 Mon Sep 17 00:00:00 2001 From: Dan Q Date: Tue, 5 Sep 2023 13:15:51 +0100 Subject: [PATCH 37/82] Reposition alert boxes WooCommerce store alerts shown on the Marketplace page are mis-aligned on account of the CSS that applies to the Marketplace. This change re-positions them and, as a bonus, aligns their left and right edges with the rest of the page content, improving the design. --- .../client/marketplace/marketplace.scss | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plugins/woocommerce-admin/client/marketplace/marketplace.scss b/plugins/woocommerce-admin/client/marketplace/marketplace.scss index 5c329b28f90..45360a11c99 100644 --- a/plugins/woocommerce-admin/client/marketplace/marketplace.scss +++ b/plugins/woocommerce-admin/client/marketplace/marketplace.scss @@ -14,4 +14,15 @@ .woocommerce-layout__main { padding: 0; } + + /* On marketplace pages, reposition store alerts so they don't collide with other components */ + .woocommerce-store-alerts { + margin-left: 16px; + margin-right: 16px; + + @media (min-width: $breakpoint-medium) { + margin-left: 32px; + margin-right: 32px; + } + } } From 702b768570cee832bd378636344737e9190dbb33 Mon Sep 17 00:00:00 2001 From: Dan Q Date: Tue, 5 Sep 2023 14:33:27 +0100 Subject: [PATCH 38/82] Suppress second scrollbar on WooCommerce > Extensions pages This is necessary because the layout of WooCommerce > Extensions pages adjusts the page height (to compensate for the larger header). On systems with scrollbars set to always-visible, this results in a ~1px overflow of the inner content and double-scrollbars are visible. This CSS mitigates that. --- .../woocommerce-admin/client/marketplace/marketplace.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/woocommerce-admin/client/marketplace/marketplace.scss b/plugins/woocommerce-admin/client/marketplace/marketplace.scss index c019a031525..baed0b4e80b 100644 --- a/plugins/woocommerce-admin/client/marketplace/marketplace.scss +++ b/plugins/woocommerce-admin/client/marketplace/marketplace.scss @@ -3,6 +3,11 @@ .woocommerce-admin-page__extensions { background: #fff; + #wpbody-content { + /* Prevent double-scrollbar issue on WooCommerce > Extension pages */ + overflow: hidden; + } + .woocommerce-layout__primary { margin: 0; } From 7b8056c301cd787b85b4be54b0a30f9ca167e7bb Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 8 Sep 2023 15:54:15 +0000 Subject: [PATCH 39/82] Add changefile(s) from automation for the following project(s): woocommerce --- .../changelog/fix-wccom-17944-reposition-notifications | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 plugins/woocommerce/changelog/fix-wccom-17944-reposition-notifications diff --git a/plugins/woocommerce/changelog/fix-wccom-17944-reposition-notifications b/plugins/woocommerce/changelog/fix-wccom-17944-reposition-notifications new file mode 100644 index 00000000000..a9dc043f793 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-wccom-17944-reposition-notifications @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: #### Message \r\n\r\n#### Comment \r\n\r\nImproved visibility/layout of store alerts on WooCommerce > Extensions pages. + + From 46dd6369e43fd818259374fef19888fb6e752986 Mon Sep 17 00:00:00 2001 From: Rodel Calasagsag Date: Thu, 14 Sep 2023 15:32:50 +0800 Subject: [PATCH 40/82] Fix "Smoke tests on daily build" link --- .../slack-summary-daily/scripts/construct-slack-payload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js index d34525d4cd3..3d561ad1f8b 100644 --- a/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js +++ b/.github/actions/tests/slack-summary-daily/scripts/construct-slack-payload.js @@ -108,7 +108,7 @@ module.exports = async ( { context, core, github } ) => { type: 'section', text: { type: 'mrkdwn', - text: '', + text: `<${ URL_GITHUB_RUN_LOG }|*Smoke tests on daily build*>`, }, }, { From 0e88160fa355e5b60fbd040a251f88ac6d5248c7 Mon Sep 17 00:00:00 2001 From: Dan Q Date: Mon, 18 Sep 2023 13:44:02 +0100 Subject: [PATCH 42/82] Manually add changelog entry (don't know why this didn't get created from the PR) --- .../changelog/fix-wccom-18029-suppress-double-scrollbar | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar diff --git a/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar b/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar new file mode 100644 index 00000000000..e50e7fd98e3 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar @@ -0,0 +1,3 @@ +Significance: patch +Type: fix +Comment: Fixed a bug that caused redundant extra scrollbars to appear on WooCommerce > Extensions pages for some browser/OS/configuration combinations. From e057e142397e797856b767fd9c76e8da0c2eb59c Mon Sep 17 00:00:00 2001 From: Dan Q Date: Mon, 18 Sep 2023 13:48:38 +0100 Subject: [PATCH 43/82] Edit changelog file to match format of that seen elsewhere --- .../changelog/fix-wccom-18029-suppress-double-scrollbar | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar b/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar index e50e7fd98e3..e682c6ee327 100644 --- a/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar +++ b/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar @@ -1,3 +1,4 @@ Significance: patch Type: fix Comment: Fixed a bug that caused redundant extra scrollbars to appear on WooCommerce > Extensions pages for some browser/OS/configuration combinations. + From cddf65ad1f0409ca144b7ed860caffdd336d993a Mon Sep 17 00:00:00 2001 From: Dan Q Date: Mon, 18 Sep 2023 14:17:41 +0100 Subject: [PATCH 44/82] Attempt to trigger auto changelog again --- .../changelog/fix-wccom-18029-suppress-double-scrollbar | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar diff --git a/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar b/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar deleted file mode 100644 index e682c6ee327..00000000000 --- a/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar +++ /dev/null @@ -1,4 +0,0 @@ -Significance: patch -Type: fix -Comment: Fixed a bug that caused redundant extra scrollbars to appear on WooCommerce > Extensions pages for some browser/OS/configuration combinations. - From 606f0ebaad11dca1b7919af3b3c2d27c18b547a4 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 18 Sep 2023 13:26:04 +0000 Subject: [PATCH 45/82] Add changefile(s) from automation for the following project(s): woocommerce --- .../changelog/fix-wccom-18029-suppress-double-scrollbar | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar diff --git a/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar b/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar new file mode 100644 index 00000000000..711132b3016 --- /dev/null +++ b/plugins/woocommerce/changelog/fix-wccom-18029-suppress-double-scrollbar @@ -0,0 +1,5 @@ +Significance: patch +Type: fix +Comment: Fixed a bug that caused redundant extra scrollbars to appear on WooCommerce > Extensions pages for some browser/OS/configuration combinations. + + From debb07d64d0ff5d13284195cbd5c6f0a9fc795a0 Mon Sep 17 00:00:00 2001 From: Veljko V Date: Mon, 18 Sep 2023 22:44:05 +0200 Subject: [PATCH 46/82] Add new E2E test to cover Shopper My Account Addresses (#40114) Add new E2E test to cover my account addresses --- .../add-new-e2e-test-myaccount-addreses | 4 + .../shopper/my-account-addresses.spec.js | 125 ++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 plugins/woocommerce/changelog/add-new-e2e-test-myaccount-addreses create mode 100644 plugins/woocommerce/tests/e2e-pw/tests/shopper/my-account-addresses.spec.js diff --git a/plugins/woocommerce/changelog/add-new-e2e-test-myaccount-addreses b/plugins/woocommerce/changelog/add-new-e2e-test-myaccount-addreses new file mode 100644 index 00000000000..178c5ef8730 --- /dev/null +++ b/plugins/woocommerce/changelog/add-new-e2e-test-myaccount-addreses @@ -0,0 +1,4 @@ +Significance: patch +Type: add + +Add new e2e test to cover My Account Addresses section diff --git a/plugins/woocommerce/tests/e2e-pw/tests/shopper/my-account-addresses.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/shopper/my-account-addresses.spec.js new file mode 100644 index 00000000000..c0a7163c9e5 --- /dev/null +++ b/plugins/woocommerce/tests/e2e-pw/tests/shopper/my-account-addresses.spec.js @@ -0,0 +1,125 @@ +const { test, expect } = require( '@playwright/test' ); +const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default; + +const randomNum = new Date().getTime().toString(); +const customer = { + username: `customer${ randomNum }`, + password: 'password', + email: `customer${ randomNum }@woocommercecoree2etestsuite.com`, +}; + +test.describe( 'Customer can manage addresses in My Account > Addresses page', () => { + test.beforeAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + // create customer + await api + .post( 'customers', customer ) + .then( ( response ) => ( customer.id = response.data.id ) ); + } ); + + test.afterAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + await api.delete( `customers/${ customer.id }`, { force: true } ); + } ); + + test( 'can add billing address from my account', async ( { page } ) => { + await page.goto( 'my-account/edit-address/' ); + // sign in as the "customer" user + await page.locator( '#username' ).fill( customer.username ); + await page.locator( '#password' ).fill( customer.password ); + await page.locator( 'text=Log in' ).click(); + + // verify that the page exists and that there are no added addresses + await expect( page.locator( 'h1.entry-title' ) ).toContainText( + 'Addresses' + ); + await expect( + page.locator( '.woocommerce-Address' ).first() + ).toContainText( 'You have not set up this type of address yet.' ); + + // go to add billing address + await page.goto( 'my-account/edit-address/billing' ); + await expect( page.locator( 'h3' ) ).toContainText( 'Billing address' ); + await page.locator( '#billing_first_name' ).fill( 'John' ); + await page.locator( '#billing_last_name' ).fill( 'Doe Billing' ); + await page + .locator( '#billing_address_1' ) + .fill( '123 Evergreen Terrace' ); + await page.locator( '#billing_city' ).fill( 'Frisco' ); + await page.locator( '#billing_country' ).selectOption( 'US' ); + await page.locator( '#billing_state' ).selectOption( 'CA' ); + await page.locator( '#billing_postcode' ).fill( '97403' ); + await page.locator( '#billing_phone' ).fill( '555 555-5555' ); + await page.locator( 'text=Save address' ).click(); + + // verify billing address has been applied + await expect( page.locator( '.woocommerce-message' ) ).toContainText( + 'Address changed successfully.' + ); + await expect( + page.locator( `:text("John Doe Billing")` ) + ).toBeVisible(); + await expect( + page.locator( `:text("123 Evergreen Terrace")` ) + ).toBeVisible(); + await expect( + page.locator( `:text("Frisco, CA 97403")` ) + ).toBeVisible(); + } ); + + test( 'can add shipping address from my account', async ( { page } ) => { + await page.goto( 'my-account/edit-address/' ); + // sign in as the "customer" user + await page.locator( '#username' ).fill( customer.username ); + await page.locator( '#password' ).fill( customer.password ); + await page.locator( 'text=Log in' ).click(); + + // verify that the page exists and that there are no added addresses + await expect( page.locator( 'h1.entry-title' ) ).toContainText( + 'Addresses' + ); + await expect( + page.locator( '.woocommerce-Address' ).nth( 1 ) + ).toContainText( 'You have not set up this type of address yet.' ); + + // go to add shipping address + await page.goto( 'my-account/edit-address/shipping' ); + await expect( page.locator( 'h3' ) ).toContainText( + 'Shipping address' + ); + await page.locator( '#shipping_first_name' ).fill( 'John' ); + await page.locator( '#shipping_last_name' ).fill( 'Doe Shipping' ); + await page + .locator( '#shipping_address_1' ) + .fill( '456 Nevergreen Terrace' ); + await page.locator( '#shipping_city' ).fill( 'New York' ); + await page.locator( '#shipping_country' ).selectOption( 'US' ); + await page.locator( '#shipping_state' ).selectOption( 'NY' ); + await page.locator( '#shipping_postcode' ).fill( '10010' ); + await page.locator( 'text=Save address' ).click(); + + // verify shipping address has been applied + await expect( page.locator( '.woocommerce-message' ) ).toContainText( + 'Address changed successfully.' + ); + await expect( + page.locator( `:text("John Doe Shipping")` ) + ).toBeVisible(); + await expect( + page.locator( `:text("456 Nevergreen Terrace")` ) + ).toBeVisible(); + await expect( + page.locator( `:text("New York, NY 10010")` ) + ).toBeVisible(); + } ); +} ); From a23e975eaa1925e7da73a69269fa9923dc9efbfd Mon Sep 17 00:00:00 2001 From: Veljko V Date: Mon, 18 Sep 2023 23:18:29 +0200 Subject: [PATCH 47/82] Add new E2E test for Shopper Product-related flows (#40132) * Add new E2E test to cover Shopper Product page * Make product-related tests granular --- .../e2e-add-new-test-shopper-product | 4 + .../tests/shopper/product-grouped.spec.js | 120 +++++++ .../tests/shopper/product-simple.spec.js | 223 ++++++++++++ ...dates.spec.js => product-variable.spec.js} | 145 +++++++- .../tests/shopper/single-product.spec.js | 326 ------------------ 5 files changed, 485 insertions(+), 333 deletions(-) create mode 100644 plugins/woocommerce/changelog/e2e-add-new-test-shopper-product create mode 100644 plugins/woocommerce/tests/e2e-pw/tests/shopper/product-grouped.spec.js create mode 100644 plugins/woocommerce/tests/e2e-pw/tests/shopper/product-simple.spec.js rename plugins/woocommerce/tests/e2e-pw/tests/shopper/{variable-product-updates.spec.js => product-variable.spec.js} (65%) delete mode 100644 plugins/woocommerce/tests/e2e-pw/tests/shopper/single-product.spec.js diff --git a/plugins/woocommerce/changelog/e2e-add-new-test-shopper-product b/plugins/woocommerce/changelog/e2e-add-new-test-shopper-product new file mode 100644 index 00000000000..d3d8827ff09 --- /dev/null +++ b/plugins/woocommerce/changelog/e2e-add-new-test-shopper-product @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Add new E2E test covering shopper product page and make Product-related tests granular (separated test files) diff --git a/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-grouped.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-grouped.spec.js new file mode 100644 index 00000000000..72e02d8e4fe --- /dev/null +++ b/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-grouped.spec.js @@ -0,0 +1,120 @@ +const { test, expect } = require( '@playwright/test' ); +const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default; + +const productPrice = '18.16'; +const simpleProductName = 'Simple single product'; +const groupedProductName = 'Grouped single product'; + +let simpleProductId, simpleProduct2Id, groupedProductId; + +test.describe( 'Grouped Product Page', () => { + const slug = groupedProductName.replace( / /gi, '-' ).toLowerCase(); + const simpleProduct1 = simpleProductName + ' 1'; + const simpleProduct2 = simpleProductName + ' 2'; + + test.beforeAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + // add products + await api + .post( 'products', { + name: simpleProduct1, + type: 'simple', + regular_price: productPrice, + } ) + .then( ( response ) => { + simpleProductId = response.data.id; + } ); + await api + .post( 'products', { + name: simpleProduct2, + type: 'simple', + regular_price: productPrice, + } ) + .then( ( response ) => { + simpleProduct2Id = response.data.id; + } ); + await api + .post( 'products', { + name: groupedProductName, + type: 'grouped', + grouped_products: [ simpleProductId, simpleProduct2Id ], + } ) + .then( ( response ) => { + groupedProductId = response.data.id; + } ); + } ); + + test.beforeEach( async ( { context } ) => { + // Shopping cart is very sensitive to cookies, so be explicit + await context.clearCookies(); + } ); + + test.afterAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + await api.delete( `products/${ simpleProductId }`, { + force: true, + } ); + await api.delete( `products/${ simpleProduct2Id }`, { + force: true, + } ); + await api.delete( `products/${ groupedProductId }`, { + force: true, + } ); + } ); + + test( 'should be able to add grouped products to the cart', async ( { + page, + } ) => { + await page.goto( `product/${ slug }` ); + + await page.getByRole( 'button', { name: 'Add to cart' } ).click(); + await expect( page.locator( '.woocommerce-error' ) ).toContainText( + 'Please choose the quantity of items you wish to add to your cartā€¦' + ); + + await page.locator( 'div.quantity input.qty >> nth=0' ).fill( '5' ); + await page.locator( 'div.quantity input.qty >> nth=1' ).fill( '5' ); + await page.getByRole( 'button', { name: 'Add to cart' } ).click(); + await expect( page.locator( '.woocommerce-message' ) ).toContainText( + `ā€œ${ simpleProduct1 }ā€ and ā€œ${ simpleProduct2 }ā€ have been added to your cart.` + ); + + await page.goto( 'cart/' ); + await expect( + page.locator( 'td.product-name >> nth=0' ) + ).toContainText( simpleProduct1 ); + await expect( + page.locator( 'td.product-name >> nth=1' ) + ).toContainText( simpleProduct2 ); + await expect( page.locator( 'tr.order-total > td' ) ).toContainText( + ( +productPrice * 10 ).toString() + ); + } ); + + test( 'should be able to remove grouped products from the cart', async ( { + page, + } ) => { + await page.goto( `product/${ slug }` ); + await page.locator( 'div.quantity input.qty >> nth=0' ).fill( '1' ); + await page.locator( 'div.quantity input.qty >> nth=1' ).fill( '1' ); + await page.getByRole( 'button', { name: 'Add to cart' } ).click(); + + await page.goto( 'cart/' ); + await page.locator( 'a.remove >> nth=1' ).click(); + await page.locator( 'a.remove >> nth=0' ).click(); + + await expect( page.locator( '.cart-empty' ) ).toContainText( + 'Your cart is currently empty.' + ); + } ); +} ); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-simple.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-simple.spec.js new file mode 100644 index 00000000000..1f4a32e1cd6 --- /dev/null +++ b/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-simple.spec.js @@ -0,0 +1,223 @@ +const { test, expect } = require( '@playwright/test' ); +const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default; + +const productPrice = '18.16'; +const simpleProductName = 'Simple single product'; + +let simpleProductId, + simpleProduct1Id, + simpleProduct2Id, + productCategory1Id, + productCategory2Id; + +test.describe( 'Single Product Page', () => { + const simpleProduct1 = simpleProductName + ' Related'; + const simpleProduct2 = simpleProductName + ' Upsell'; + const productCategoryName1 = 'Hoodies'; + const productCategoryName2 = 'Jumpers'; + const productDescription = 'Lorem ipsum dolor sit amet.'; + + test.beforeAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + + // add product categories + await api + .post( 'products/categories', { + name: productCategoryName1, + } ) + .then( ( response ) => { + productCategory1Id = response.data.id; + } ); + await api + .post( 'products/categories', { + name: productCategoryName2, + } ) + .then( ( response ) => { + productCategory2Id = response.data.id; + } ); + + // add products + await api + .post( 'products', { + name: simpleProduct1, + type: 'simple', + categories: [ + { + id: productCategory1Id, + name: productCategoryName1, + }, + ], + regular_price: productPrice, + } ) + .then( ( response ) => { + simpleProduct1Id = response.data.id; + } ); + await api + .post( 'products', { + name: simpleProduct2, + type: 'simple', + categories: [ + { + id: productCategory2Id, + name: productCategoryName2, + }, + ], + regular_price: productPrice, + } ) + .then( ( response ) => { + simpleProduct2Id = response.data.id; + } ); + await api + .post( 'products', { + name: simpleProductName, + description: productDescription, + type: 'simple', + categories: [ + { + id: productCategory1Id, + name: productCategoryName1, + }, + ], + regular_price: productPrice, + related_ids: simpleProduct1Id, + upsell_ids: simpleProduct2Id, + } ) + .then( ( response ) => { + simpleProductId = response.data.id; + } ); + } ); + + test.beforeEach( async ( { context } ) => { + // Shopping cart is very sensitive to cookies, so be explicit + await context.clearCookies(); + } ); + + test.afterAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + await api.delete( `products/${ simpleProductId }`, { + force: true, + } ); + await api.delete( `products/${ simpleProduct1Id }`, { + force: true, + } ); + await api.delete( `products/${ simpleProduct2Id }`, { + force: true, + } ); + await api.post( 'products/categories/batch', { + delete: [ productCategory1Id, productCategory2Id ], + } ); + } ); + + test( 'should be able to see upsell and related products', async ( { + page, + } ) => { + const slug = simpleProductName.replace( / /gi, '-' ).toLowerCase(); + await page.goto( `product/${ slug }` ); + + await expect( page.locator( '.upsells > h2' ) ).toContainText( + 'You may also likeā€¦' + ); + await expect( page.locator( '.related > h2' ) ).toContainText( + 'Related products' + ); + await expect( + page.locator( + '.upsells > .products > li > a > .woocommerce-loop-product__title' + ) + ).toContainText( simpleProduct2 ); + await expect( + page.locator( + '.related > .products > li > a > .woocommerce-loop-product__title' + ) + ).toContainText( simpleProduct1 ); + } ); + + test( 'should be able to post a review and see it after', async ( { + page, + } ) => { + await page.goto( 'my-account' ); + await page.locator( '#username' ).fill( 'admin' ); + await page.locator( '#password' ).fill( 'password' ); + await page.locator( 'text=Log in' ).click(); + + const slug = simpleProductName.replace( / /gi, '-' ).toLowerCase(); + await page.goto( `product/${ slug }` ); + + await expect( page.locator( '.reviews_tab' ) ).toContainText( + 'Reviews (0)' + ); + await page.locator( '.reviews_tab' ).click(); + await page.locator( '.star-4' ).click(); + await page.locator( '#comment' ).fill( 'This product is great!' ); + await page.locator( 'text=Submit' ).click(); + await expect( + page.locator( '.woocommerce-Reviews-title' ) + ).toContainText( `1 review for ${ simpleProductName }` ); + await expect( page.locator( '.reviews_tab' ) ).toContainText( + 'Reviews (1)' + ); + } ); + + test( 'should be able to see product description and image', async ( { + page, + } ) => { + const slug = simpleProductName.replace( / /gi, '-' ).toLowerCase(); + await page.goto( `product/${ slug }` ); + + await expect( page.locator( '#tab-description > p' ) ).toContainText( + productDescription + ); + await expect( + page.locator( + '.woocommerce-product-gallery__image--placeholder > .wp-post-image' + ) + ).toBeVisible(); + } ); + + test( 'should be able to add simple products to the cart', async ( { + page, + } ) => { + const slug = simpleProductName.replace( / /gi, '-' ).toLowerCase(); + await page.goto( `product/${ slug }` ); + + await page.locator( 'input.qty' ).fill( '5' ); + await page.getByRole( 'button', { name: 'Add to cart' } ).click(); + + await expect( page.locator( '.woocommerce-message' ) ).toContainText( + 'have been added to your cart.' + ); + + await page.goto( 'cart/' ); + await expect( page.locator( 'td.product-name' ) ).toContainText( + simpleProductName + ); + await expect( page.locator( 'input.qty' ) ).toHaveValue( '5' ); + await expect( page.locator( 'td.product-subtotal' ) ).toContainText( + ( 5 * +productPrice ).toString() + ); + } ); + + test( 'should be able to remove simple products from the cart', async ( { + page, + } ) => { + await page.goto( `/shop/?add-to-cart=${ simpleProductId }` ); + await page.waitForLoadState( 'networkidle' ); + + await page.goto( 'cart/' ); + await page.locator( 'a.remove' ).click(); + + await expect( page.locator( '.cart-empty' ) ).toContainText( + 'Your cart is currently empty.' + ); + } ); +} ); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/shopper/variable-product-updates.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-variable.spec.js similarity index 65% rename from plugins/woocommerce/tests/e2e-pw/tests/shopper/variable-product-updates.spec.js rename to plugins/woocommerce/tests/e2e-pw/tests/shopper/product-variable.spec.js index b987fae5afc..815823157b2 100644 --- a/plugins/woocommerce/tests/e2e-pw/tests/shopper/variable-product-updates.spec.js +++ b/plugins/woocommerce/tests/e2e-pw/tests/shopper/product-variable.spec.js @@ -1,9 +1,49 @@ const { test, expect } = require( '@playwright/test' ); const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default; -const variableProductName = 'Variable Product Updates'; -const productPrice = '11.16'; -const variations = [ +const productPrice = '18.16'; +const variableProductName = 'Variable single product'; +const cartDialogMessage = + 'Please select some product options before adding this product to your cart.'; +const variations1 = [ + { + regular_price: productPrice, + attributes: [ + { + name: 'Size', + option: 'Small', + }, + ], + }, + { + regular_price: ( +productPrice * 2 ).toString(), + attributes: [ + { + name: 'Size', + option: 'Medium', + }, + ], + }, + { + regular_price: ( +productPrice * 3 ).toString(), + attributes: [ + { + name: 'Size', + option: 'Large', + }, + ], + }, + { + regular_price: ( +productPrice * 4 ).toString(), + attributes: [ + { + name: 'Size', + option: 'XLarge', + }, + ], + }, +]; +const variations2 = [ { attributes: [ { @@ -90,8 +130,99 @@ const variations = [ }, ]; -const cartDialogMessage = - 'Please select some product options before adding this product to your cart.'; +let variableProductId; + +test.describe( 'Variable Product Page', () => { + const slug = variableProductName.replace( / /gi, '-' ).toLowerCase(); + + test.beforeAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + // add product + await api + .post( 'products', { + name: variableProductName, + type: 'variable', + attributes: [ + { + name: 'Size', + options: [ 'Small', 'Medium', 'Large', 'XLarge' ], + visible: true, + variation: true, + }, + ], + } ) + .then( async ( response ) => { + variableProductId = response.data.id; + for ( const key in variations1 ) { + await api.post( + `products/${ variableProductId }/variations`, + variations1[ key ] + ); + } + } ); + } ); + + test.beforeEach( async ( { context } ) => { + // Shopping cart is very sensitive to cookies, so be explicit + await context.clearCookies(); + } ); + + test.afterAll( async ( { baseURL } ) => { + const api = new wcApi( { + url: baseURL, + consumerKey: process.env.CONSUMER_KEY, + consumerSecret: process.env.CONSUMER_SECRET, + version: 'wc/v3', + } ); + await api.delete( `products/${ variableProductId }`, { + force: true, + } ); + } ); + + test( 'should be able to add variation products to the cart', async ( { + page, + } ) => { + await page.goto( `product/${ slug }` ); + + for ( const attr of variations1 ) { + await page + .locator( '#size' ) + .selectOption( attr.attributes[ 0 ].option ); + await page.getByRole( 'button', { name: 'Add to cart' } ).click(); + await expect( + page.locator( '.woocommerce-message' ) + ).toContainText( 'has been added to your cart.' ); + } + + await page.goto( 'cart/' ); + await expect( + page.locator( 'td.product-name >> nth=0' ) + ).toContainText( variableProductName ); + await expect( page.locator( 'tr.order-total > td' ) ).toContainText( + ( +productPrice * 10 ).toString() + ); + } ); + + test( 'should be able to remove variation products from the cart', async ( { + page, + } ) => { + await page.goto( `product/${ slug }` ); + await page.locator( '#size' ).selectOption( 'Large' ); + await page.getByRole( 'button', { name: 'Add to cart' } ).click(); + + await page.goto( 'cart/' ); + await page.locator( 'a.remove' ).click(); + + await expect( page.locator( '.cart-empty' ) ).toContainText( + 'Your cart is currently empty.' + ); + } ); +} ); test.describe( 'Shopper > Update variable product', () => { let variableProductId; @@ -125,10 +256,10 @@ test.describe( 'Shopper > Update variable product', () => { } ) .then( async ( response ) => { variableProductId = response.data.id; - for ( const key in variations ) { + for ( const key in variations2 ) { await api.post( `products/${ variableProductId }/variations`, - variations[ key ] + variations2[ key ] ); } } ); diff --git a/plugins/woocommerce/tests/e2e-pw/tests/shopper/single-product.spec.js b/plugins/woocommerce/tests/e2e-pw/tests/shopper/single-product.spec.js deleted file mode 100644 index 8f9b5447881..00000000000 --- a/plugins/woocommerce/tests/e2e-pw/tests/shopper/single-product.spec.js +++ /dev/null @@ -1,326 +0,0 @@ -const { test, expect } = require( '@playwright/test' ); -const wcApi = require( '@woocommerce/woocommerce-rest-api' ).default; - -const productPrice = '18.16'; -const simpleProductName = 'Simple single product'; -const variableProductName = 'Variable single product'; -const variations = [ - { - regular_price: productPrice, - attributes: [ - { - name: 'Size', - option: 'Small', - }, - ], - }, - { - regular_price: ( +productPrice * 2 ).toString(), - attributes: [ - { - name: 'Size', - option: 'Medium', - }, - ], - }, - { - regular_price: ( +productPrice * 3 ).toString(), - attributes: [ - { - name: 'Size', - option: 'Large', - }, - ], - }, - { - regular_price: ( +productPrice * 4 ).toString(), - attributes: [ - { - name: 'Size', - option: 'XLarge', - }, - ], - }, -]; -const groupedProductName = 'Grouped single product'; - -let simpleProductId, simpleProduct2Id, variableProductId, groupedProductId; - -test.describe( 'Single Product Page', () => { - test.beforeAll( async ( { baseURL } ) => { - const api = new wcApi( { - url: baseURL, - consumerKey: process.env.CONSUMER_KEY, - consumerSecret: process.env.CONSUMER_SECRET, - version: 'wc/v3', - } ); - // add product - await api - .post( 'products', { - name: simpleProductName, - type: 'simple', - regular_price: productPrice, - } ) - .then( ( response ) => { - simpleProductId = response.data.id; - } ); - } ); - - test.beforeEach( async ( { context } ) => { - // Shopping cart is very sensitive to cookies, so be explicit - await context.clearCookies(); - } ); - - test.afterAll( async ( { baseURL } ) => { - const api = new wcApi( { - url: baseURL, - consumerKey: process.env.CONSUMER_KEY, - consumerSecret: process.env.CONSUMER_SECRET, - version: 'wc/v3', - } ); - await api.delete( `products/${ simpleProductId }`, { - force: true, - } ); - } ); - - test( 'should be able to add simple products to the cart', async ( { - page, - } ) => { - const slug = simpleProductName.replace( / /gi, '-' ).toLowerCase(); - await page.goto( `product/${ slug }` ); - - await page.locator( 'input.qty' ).fill( '5' ); - await page.getByRole( 'button', { name: 'Add to cart' } ).click(); - - await expect( page.locator( '.woocommerce-message' ) ).toContainText( - 'have been added to your cart.' - ); - - await page.goto( 'cart/' ); - await expect( page.locator( 'td.product-name' ) ).toContainText( - simpleProductName - ); - await expect( page.locator( 'input.qty' ) ).toHaveValue( '5' ); - await expect( page.locator( 'td.product-subtotal' ) ).toContainText( - ( 5 * +productPrice ).toString() - ); - } ); - - test( 'should be able to remove simple products from the cart', async ( { - page, - } ) => { - await page.goto( `/shop/?add-to-cart=${ simpleProductId }` ); - await page.waitForLoadState( 'networkidle' ); - - await page.goto( 'cart/' ); - await page.locator( 'a.remove' ).click(); - - await expect( page.locator( '.cart-empty' ) ).toContainText( - 'Your cart is currently empty.' - ); - } ); -} ); - -test.describe( 'Variable Product Page', () => { - const slug = variableProductName.replace( / /gi, '-' ).toLowerCase(); - - test.beforeAll( async ( { baseURL } ) => { - const api = new wcApi( { - url: baseURL, - consumerKey: process.env.CONSUMER_KEY, - consumerSecret: process.env.CONSUMER_SECRET, - version: 'wc/v3', - } ); - // add product - await api - .post( 'products', { - name: variableProductName, - type: 'variable', - attributes: [ - { - name: 'Size', - options: [ 'Small', 'Medium', 'Large', 'XLarge' ], - visible: true, - variation: true, - }, - ], - } ) - .then( async ( response ) => { - variableProductId = response.data.id; - for ( const key in variations ) { - await api.post( - `products/${ variableProductId }/variations`, - variations[ key ] - ); - } - } ); - } ); - - test.beforeEach( async ( { context } ) => { - // Shopping cart is very sensitive to cookies, so be explicit - await context.clearCookies(); - } ); - - test.afterAll( async ( { baseURL } ) => { - const api = new wcApi( { - url: baseURL, - consumerKey: process.env.CONSUMER_KEY, - consumerSecret: process.env.CONSUMER_SECRET, - version: 'wc/v3', - } ); - await api.delete( `products/${ variableProductId }`, { - force: true, - } ); - } ); - - test( 'should be able to add variation products to the cart', async ( { - page, - } ) => { - await page.goto( `product/${ slug }` ); - - for ( const attr of variations ) { - await page - .locator( '#size' ) - .selectOption( attr.attributes[ 0 ].option ); - await page.getByRole( 'button', { name: 'Add to cart' } ).click(); - await expect( - page.locator( '.woocommerce-message' ) - ).toContainText( 'has been added to your cart.' ); - } - - await page.goto( 'cart/' ); - await expect( - page.locator( 'td.product-name >> nth=0' ) - ).toContainText( variableProductName ); - await expect( page.locator( 'tr.order-total > td' ) ).toContainText( - ( +productPrice * 10 ).toString() - ); - } ); - - test( 'should be able to remove variation products from the cart', async ( { - page, - } ) => { - await page.goto( `product/${ slug }` ); - await page.locator( '#size' ).selectOption( 'Large' ); - await page.getByRole( 'button', { name: 'Add to cart' } ).click(); - - await page.goto( 'cart/' ); - await page.locator( 'a.remove' ).click(); - - await expect( page.locator( '.cart-empty' ) ).toContainText( - 'Your cart is currently empty.' - ); - } ); -} ); - -test.describe( 'Grouped Product Page', () => { - const slug = groupedProductName.replace( / /gi, '-' ).toLowerCase(); - const simpleProduct1 = simpleProductName + ' 1'; - const simpleProduct2 = simpleProductName + ' 2'; - - test.beforeAll( async ( { baseURL } ) => { - const api = new wcApi( { - url: baseURL, - consumerKey: process.env.CONSUMER_KEY, - consumerSecret: process.env.CONSUMER_SECRET, - version: 'wc/v3', - } ); - // add products - await api - .post( 'products', { - name: simpleProduct1, - type: 'simple', - regular_price: productPrice, - } ) - .then( ( response ) => { - simpleProductId = response.data.id; - } ); - await api - .post( 'products', { - name: simpleProduct2, - type: 'simple', - regular_price: productPrice, - } ) - .then( ( response ) => { - simpleProduct2Id = response.data.id; - } ); - await api - .post( 'products', { - name: groupedProductName, - type: 'grouped', - grouped_products: [ simpleProductId, simpleProduct2Id ], - } ) - .then( ( response ) => { - groupedProductId = response.data.id; - } ); - } ); - - test.beforeEach( async ( { context } ) => { - // Shopping cart is very sensitive to cookies, so be explicit - await context.clearCookies(); - } ); - - test.afterAll( async ( { baseURL } ) => { - const api = new wcApi( { - url: baseURL, - consumerKey: process.env.CONSUMER_KEY, - consumerSecret: process.env.CONSUMER_SECRET, - version: 'wc/v3', - } ); - await api.delete( `products/${ simpleProductId }`, { - force: true, - } ); - await api.delete( `products/${ simpleProduct2Id }`, { - force: true, - } ); - await api.delete( `products/${ groupedProductId }`, { - force: true, - } ); - } ); - - test( 'should be able to add grouped products to the cart', async ( { - page, - } ) => { - await page.goto( `product/${ slug }` ); - - await page.getByRole( 'button', { name: 'Add to cart' } ).click(); - await expect( page.locator( '.woocommerce-error' ) ).toContainText( - 'Please choose the quantity of items you wish to add to your cartā€¦' - ); - - await page.locator( 'div.quantity input.qty >> nth=0' ).fill( '5' ); - await page.locator( 'div.quantity input.qty >> nth=1' ).fill( '5' ); - await page.getByRole( 'button', { name: 'Add to cart' } ).click(); - await expect( page.locator( '.woocommerce-message' ) ).toContainText( - `ā€œ${ simpleProduct1 }ā€ and ā€œ${ simpleProduct2 }ā€ have been added to your cart.` - ); - - await page.goto( 'cart/' ); - await expect( - page.locator( 'td.product-name >> nth=0' ) - ).toContainText( simpleProduct1 ); - await expect( - page.locator( 'td.product-name >> nth=1' ) - ).toContainText( simpleProduct2 ); - await expect( page.locator( 'tr.order-total > td' ) ).toContainText( - ( +productPrice * 10 ).toString() - ); - } ); - - test( 'should be able to remove grouped products from the cart', async ( { - page, - } ) => { - await page.goto( `product/${ slug }` ); - await page.locator( 'div.quantity input.qty >> nth=0' ).fill( '1' ); - await page.locator( 'div.quantity input.qty >> nth=1' ).fill( '1' ); - await page.getByRole( 'button', { name: 'Add to cart' } ).click(); - - await page.goto( 'cart/' ); - await page.locator( 'a.remove >> nth=1' ).click(); - await page.locator( 'a.remove >> nth=0' ).click(); - - await expect( page.locator( '.cart-empty' ) ).toContainText( - 'Your cart is currently empty.' - ); - } ); -} ); From aad835a4979eadb16e5337fa92132bda58b9581c Mon Sep 17 00:00:00 2001 From: David Anderson Date: Mon, 18 Sep 2023 21:51:53 +0000 Subject: [PATCH 48/82] Make is_checkout() description more accurate --- plugins/woocommerce/includes/wc-conditional-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce/includes/wc-conditional-functions.php b/plugins/woocommerce/includes/wc-conditional-functions.php index c5fc0c261e8..622d4ed19f2 100644 --- a/plugins/woocommerce/includes/wc-conditional-functions.php +++ b/plugins/woocommerce/includes/wc-conditional-functions.php @@ -102,7 +102,7 @@ if ( ! function_exists( 'is_cart' ) ) { if ( ! function_exists( 'is_checkout' ) ) { /** - * Is_checkout - Returns true when viewing the checkout page. + * Is_checkout - Returns true when viewing the checkout page, or when processing AJAX requests for updating or processing the checkout. * * @return bool */ From e1f9264bb6b9bb3fd779243bf8419acb3a916221 Mon Sep 17 00:00:00 2001 From: Chi-Hsuan Huang Date: Tue, 19 Sep 2023 11:37:46 +0800 Subject: [PATCH 49/82] Add tracks to CYS assembler-hub and hide pages sidebar screen (#40156) * Add tracks to assembler-hub and hide add pages menu * Add changefile(s) from automation for the following project(s): woocommerce * Track sidebar menu item click event * Update tour tracks --------- Co-authored-by: github-actions --- .../assembler-hub/onboarding-tour/index.tsx | 22 +++- .../onboarding-tour/test/index.tsx | 106 ++++++++++++++++++ .../assembler-hub/sidebar/index.tsx | 7 +- .../assembler-hub/sidebar/save-hub.tsx | 12 ++ ...idebar-navigation-screen-color-palette.tsx | 33 +++++- .../sidebar-navigation-screen-footer.tsx | 17 ++- .../sidebar-navigation-screen-header.tsx | 17 ++- .../sidebar-navigation-screen-homepage.tsx | 18 ++- .../sidebar-navigation-screen-main.tsx | 71 +++++++++++- .../sidebar-navigation-screen-pages.tsx | 17 ++- .../sidebar-navigation-screen-typography.tsx | 33 +++++- .../changelog/add-cys-assembler-hub-tracks | 4 + 12 files changed, 332 insertions(+), 25 deletions(-) create mode 100644 plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/test/index.tsx create mode 100644 plugins/woocommerce/changelog/add-cys-assembler-hub-tracks diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx index 90173f8b785..345adc4a99f 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/index.tsx @@ -4,6 +4,7 @@ import { __ } from '@wordpress/i18n'; import { useState } from '@wordpress/element'; import { TourKit, TourKitTypes } from '@woocommerce/components'; +import { recordEvent } from '@woocommerce/tracks'; export * from './use-onboarding-tour'; type OnboardingTourProps = { @@ -83,8 +84,15 @@ export const OnboardingTour = ( { ], closeHandler: ( _steps, _currentStepIndex, source ) => { if ( source === 'done-btn' ) { + // Click on "Take a tour" button + recordEvent( + 'customize_your_store_assembler_hub_tour_start' + ); setShowWelcomeTour( false ); } else { + recordEvent( + 'customize_your_store_assembler_hub_tour_skip' + ); onClose(); } }, @@ -196,7 +204,19 @@ export const OnboardingTour = ( { }, }, ], - closeHandler: onClose, + closeHandler: ( _steps, _currentStepIndex, source ) => { + if ( source === 'done-btn' ) { + recordEvent( + 'customize_your_store_assembler_hub_tour_complete' + ); + } else { + recordEvent( + 'customize_your_store_assembler_hub_tour_close' + ); + } + + onClose(); + }, } } > ); diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/test/index.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/test/index.tsx new file mode 100644 index 00000000000..b7fd92b3c69 --- /dev/null +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/onboarding-tour/test/index.tsx @@ -0,0 +1,106 @@ +/** + * External dependencies + */ +import { render, screen } from '@testing-library/react'; +import { recordEvent } from '@woocommerce/tracks'; + +/** + * Internal dependencies + */ +import { OnboardingTour } from '../index'; + +jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) ); + +describe( 'OnboardingTour', () => { + let props: { + onClose: jest.Mock; + setShowWelcomeTour: jest.Mock; + showWelcomeTour: boolean; + }; + + beforeEach( () => { + props = { + onClose: jest.fn(), + setShowWelcomeTour: jest.fn(), + showWelcomeTour: true, + }; + } ); + + it( 'should render welcome tour', () => { + render( ); + + expect( + screen.getByText( /Welcome to your AI-generated store!/i ) + ).toBeInTheDocument(); + } ); + + it( 'should render step 1', () => { + render( ); + + expect( + screen.getByText( /View your changes in real time/i ) + ).toBeInTheDocument(); + } ); + + it( 'should record an event when clicking on "Take a tour" button', () => { + render( ); + + screen + .getByRole( 'button', { + name: /Take a tour/i, + } ) + .click(); + + expect( recordEvent ).toHaveBeenCalledWith( + 'customize_your_store_assembler_hub_tour_start' + ); + } ); + + it( 'should record an event when clicking on "Skip" button', () => { + render( ); + + screen + .getByRole( 'button', { + name: /Skip/i, + } ) + .click(); + + expect( recordEvent ).toHaveBeenCalledWith( + 'customize_your_store_assembler_hub_tour_skip' + ); + } ); + + it( 'should record an event when clicking on "Skip" button', () => { + render( ); + + screen + .getByRole( 'button', { + name: 'Close Tour', + } ) + .click(); + + expect( recordEvent ).toHaveBeenCalledWith( + 'customize_your_store_assembler_hub_tour_close' + ); + } ); + + it( 'should record an event when complete the tour', () => { + render( ); + + screen + .getByRole( 'button', { + name: 'Next', + } ) + .click(); + + screen + .getByRole( 'button', { + name: 'Done', + } ) + .click(); + + expect( recordEvent ).toHaveBeenCalledWith( + 'customize_your_store_assembler_hub_tour_complete' + ); + } ); +} ); diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/index.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/index.tsx index 2478b41814b..38e214133dc 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/index.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/index.tsx @@ -23,7 +23,7 @@ import { SidebarNavigationScreenTypography } from './sidebar-navigation-screen-t import { SidebarNavigationScreenHeader } from './sidebar-navigation-screen-header'; import { SidebarNavigationScreenHomepage } from './sidebar-navigation-screen-homepage'; import { SidebarNavigationScreenFooter } from './sidebar-navigation-screen-footer'; -import { SidebarNavigationScreenPages } from './sidebar-navigation-screen-pages'; +// import { SidebarNavigationScreenPages } from './sidebar-navigation-screen-pages'; import { SidebarNavigationScreenLogo } from './sidebar-navigation-screen-logo'; import { SaveHub } from './save-hub'; @@ -124,9 +124,10 @@ function SidebarScreens() { - + { /* TODO: Implement pages sidebar in Phrase 2 */ } + { /* - + */ } diff --git a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx index b380ce609b8..882b1df989e 100644 --- a/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx +++ b/plugins/woocommerce-admin/client/customize-store/assembler-hub/sidebar/save-hub.tsx @@ -22,6 +22,7 @@ import { store as blockEditorStore } from '@wordpress/block-editor'; import { store as noticesStore } from '@wordpress/notices'; // @ts-ignore No types for this exist yet. import { useEntitiesSavedStatesIsDirty as useIsDirty } from '@wordpress/editor'; +import { recordEvent } from '@woocommerce/tracks'; /** * Internal dependencies @@ -142,6 +143,13 @@ export const SaveHub = () => { }, [ urlParams.path ] ); const save = async () => { + const source = `${ urlParams.path.replace( + '/customize-store/assembler-hub/', + '' + ) }`; + recordEvent( 'customize_your_store_assembler_hub_save_click', { + source, + } ); removeNotice( saveNoticeId ); try { @@ -185,6 +193,10 @@ export const SaveHub = () => {