diff --git a/.github/workflows/blocks-playwright.yml b/.github/workflows/blocks-playwright.yml index 78317a6321b..9d24157a4b8 100644 --- a/.github/workflows/blocks-playwright.yml +++ b/.github/workflows/blocks-playwright.yml @@ -1,4 +1,4 @@ -name: Run Blocks Playwright Tests +name: Blocks Playwright Tests on: pull_request: @@ -11,13 +11,12 @@ on: # Allow manually triggering the workflow. workflow_dispatch: - env: FORCE_COLOR: 1 jobs: - e2e: - name: ${{ matrix.config.name }} [${{ matrix.shards.name }}] + blocks-playwright-tests: + name: Shard ${{ matrix.shardIndex }} of ${{ matrix.shardTotal }} timeout-minutes: 60 runs-on: ubuntu-latest defaults: @@ -26,27 +25,11 @@ jobs: strategy: fail-fast: false matrix: - config: - - name: Default (Block) Theme - file: playwright.config.ts - resultPath: test-results - - name: Classic Theme - file: playwright.classic-theme.config.ts - resultPath: test-results-classic-theme - - name: Side Effects - file: playwright.side-effects.config.ts - resultPath: test-results-side-effects - - name: Block Theme With Templates - file: playwright.block-theme-with-templates.config.ts - resultPath: test-results-block-theme-with-templates - shards: - - name: 1/5 - - name: 2/5 - - name: 3/5 - - name: 4/5 - - name: 5/5 + shardIndex: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + shardTotal: [10] + steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup WooCommerce Monorepo uses: ./.github/actions/setup-woocommerce-monorepo @@ -54,19 +37,36 @@ jobs: install: '@woocommerce/plugin-woocommerce...' build: '@woocommerce/plugin-woocommerce' - - name: Install Playwright - run: pnpm --filter='@woocommerce/block-library' exec playwright install --with-deps + - name: Install Playwright dependencies + run: pnpm exec playwright install chromium --with-deps - - name: Start wp-env - run: pnpm --filter='@woocommerce/block-library' env:start + - name: Setup testing environment and start the server + run: pnpm env:start - name: Run Playwright tests - working-directory: plugins/woocommerce-blocks - run: pnpm playwright test --config=tests/e2e/${{ matrix.config.file }} --shard ${{ matrix.shards.name }} + run: pnpm test:e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - - uses: actions/upload-artifact@v3 - if: ${{ failure() }} + - name: Archive debug artifacts (screenshots, traces) + uses: actions/upload-artifact@v4 + if: ${{ !cancelled() }} with: - name: playwright-report-${{ matrix.config.name }} - path: plugins/woocommerce-blocks/tests/e2e/artifacts/${{ matrix.config.resultPath }} - if-no-files-found: error # 'warn' or 'ignore' are also available, defaults to `warn` + name: failures-artifacts-shard-${{ matrix.shardIndex }} + path: plugins/woocommerce-blocks/tests/e2e/artifacts/test-results + if-no-files-found: ignore + + merge-artifacts: + # Merges all artifacts from all shards into a single zip and + # deletes the parts. In case of a rerun, artifacts from the + # previous run will be retained by merging them with the new ones. + name: Merge Artifacts + if: ${{ !cancelled() }} + needs: [blocks-playwright-tests] + runs-on: ubuntu-latest + steps: + - name: Merge Artifacts + uses: actions/upload-artifact/merge@v4 + # Don't fail the job if there aren't any artifacts to merge. + continue-on-error: true + with: + name: failures-artifacts + delete-merged: true diff --git a/plugins/woocommerce-blocks/package.json b/plugins/woocommerce-blocks/package.json index 7775ceb64ef..1c4a052d3c5 100644 --- a/plugins/woocommerce-blocks/package.json +++ b/plugins/woocommerce-blocks/package.json @@ -86,13 +86,9 @@ "test:js": "wp-scripts test-unit-js --config tests/js/jest.config.json", "test:debug": "ndb .", "test:e2e": "sh ./bin/check-env.sh && pnpm playwright test --config=tests/e2e/playwright.config.ts", - "test:e2e:report": "sh ./bin/check-env.sh && npx playwright test --config=tests/e2e/playwright.config.ts --reporter=html", - "test:e2e:side-effects": "pnpm run test:e2e --config=tests/e2e/playwright.side-effects.config.ts", - "test:e2e:side-effects:report": "pnpm run test:e2e:report --config=tests/e2e/playwright.side-effects.config.ts --reporter=html", - "test:e2e:classic-theme": "pnpm run test:e2e --config=tests/e2e/playwright.classic-theme.config.ts", - "test:e2e:classic-theme:report": "pnpm run test:e2e:report --config=tests/e2e/playwright.classic-theme.config.ts", - "test:e2e:block-theme-with-templates": "pnpm run test:e2e --config=tests/e2e/playwright.block-theme-with-templates.config.ts", - "test:e2e:block-theme-with-templates:report": "pnpm run test:e2e:report --config=tests/e2e/playwright.block-theme-with-templates.config.ts", + "test:e2e:block-theme": "pnpm run test:e2e block_theme", + "test:e2e:classic-theme": "pnpm run test:e2e classic_theme", + "test:e2e:block-theme-with-templates": "pnpm run test:e2e block_theme_with_templates", "test:e2e:jest": "pnpm run wp-env:config && cross-env JEST_PUPPETEER_CONFIG=tests/e2e-jest/config/jest-puppeteer.config.js NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js", "test:e2e:jest:dev": "pnpm run wp-env:config && cross-env JEST_PUPPETEER_CONFIG=tests/e2e-jest/config/jest-puppeteer.config-dev.js NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js", "test:e2e:jest:dev-watch": "pnpm run wp-env:config && cross-env JEST_PUPPETEER_CONFIG=tests/e2e-jest/config/jest-puppeteer.config-dev.js NODE_CONFIG_DIR=tests/e2e-jest/config wp-scripts test-e2e --config tests/e2e-jest/config/jest.config.js --watch", diff --git a/plugins/woocommerce-blocks/tests/e2e/block-theme-with-templates.setup.ts b/plugins/woocommerce-blocks/tests/e2e/block-theme-with-templates.setup.ts deleted file mode 100644 index 8c26b4a04ee..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/block-theme-with-templates.setup.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * External dependencies - */ -import { - BLOCK_THEME_WITH_TEMPLATES_SLUG, - DB_EXPORT_FILE, - cli, -} from '@woocommerce/e2e-utils'; -import { test as setup, expect } from '@woocommerce/e2e-playwright-utils'; - -setup( 'Sets up the block theme with templates', async ( { requestUtils } ) => { - await requestUtils.activateTheme( BLOCK_THEME_WITH_TEMPLATES_SLUG ); - - const cliOutput = await cli( - `npm run wp-env run tests-cli wp db export ${ DB_EXPORT_FILE }` - ); - // eslint-disable-next-line playwright/no-standalone-expect - expect( cliOutput.stdout ).toContain( 'Success: Exported' ); -} ); diff --git a/plugins/woocommerce-blocks/tests/e2e/block-theme.setup.ts b/plugins/woocommerce-blocks/tests/e2e/block-theme.setup.ts deleted file mode 100644 index 940d5e76a2d..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/block-theme.setup.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint-disable playwright/no-standalone-expect */ -/** - * External dependencies - */ -import { BLOCK_THEME_SLUG, DB_EXPORT_FILE, cli } from '@woocommerce/e2e-utils'; -import { test as setup, expect } from '@woocommerce/e2e-playwright-utils'; - -setup( 'Sets up the block theme', async () => { - let cliOutput = await cli( - `npm run wp-env run tests-cli -- wp theme install ${ BLOCK_THEME_SLUG } --activate` - ); - - expect( - cliOutput.stdout, - `Could not install and/or activate ${ BLOCK_THEME_SLUG }` - ).toContain( 'Success' ); - - // Enable permalinks and perform a hard flush. - cliOutput = await cli( - `npm run wp-env run tests-cli -- wp rewrite structure /%postname%/ --hard` - ); - - expect( cliOutput.stdout ).toContain( 'Success: Rewrite structure set' ); - expect( cliOutput.stdout ).toContain( 'Success: Rewrite rules flushed' ); - - cliOutput = await cli( - `npm run wp-env run tests-cli wp db export ${ DB_EXPORT_FILE }` - ); - expect( cliOutput.stdout ).toContain( 'Success: Exported' ); -} ); diff --git a/plugins/woocommerce-blocks/tests/e2e/classic-theme.setup.ts b/plugins/woocommerce-blocks/tests/e2e/classic-theme.setup.ts deleted file mode 100644 index 93a74319f79..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/classic-theme.setup.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable playwright/no-standalone-expect */ -/** - * External dependencies - */ -import { - CLASSIC_THEME_NAME, - CLASSIC_THEME_SLUG, - DB_EXPORT_FILE, - cli, -} from '@woocommerce/e2e-utils'; -import { test as setup, expect } from '@woocommerce/e2e-playwright-utils'; - -setup( 'Sets up the classic theme', async ( { admin } ) => { - await cli( - `npm run wp-env run tests-cli -- wp theme install ${ CLASSIC_THEME_SLUG } --activate` - ); - await admin.page.goto( '/wp-admin/themes.php' ); - await expect( - admin.page.getByText( `Active: ${ CLASSIC_THEME_NAME }` ) - ).toBeVisible(); - - const cliOutput = await cli( - `npm run wp-env run tests-cli wp db export ${ DB_EXPORT_FILE }` - ); - expect( cliOutput.stdout ).toContain( 'Success: Exported' ); -} ); diff --git a/plugins/woocommerce-blocks/tests/e2e/global-setup.ts b/plugins/woocommerce-blocks/tests/e2e/global-setup.ts index 3a46c6a9fa5..72958cf5b95 100644 --- a/plugins/woocommerce-blocks/tests/e2e/global-setup.ts +++ b/plugins/woocommerce-blocks/tests/e2e/global-setup.ts @@ -5,7 +5,14 @@ */ import { chromium, request } from '@playwright/test'; import { RequestUtils } from '@wordpress/e2e-test-utils-playwright'; -import { BASE_URL, adminFile, cli, customerFile } from '@woocommerce/e2e-utils'; +import { + BASE_URL, + adminFile, + cli, + customerFile, + BLOCK_THEME_SLUG, + DB_EXPORT_FILE, +} from '@woocommerce/e2e-utils'; /** * Internal dependencies @@ -53,36 +60,51 @@ const prepareAttributes = async () => { }; async function globalSetup() { - const timers = { - total: '└ Total time', - authentication: '├ Authentication time', - attributes: '├ Attributes preparation time', - }; + console.log( 'Running global setup:' ); + console.time( '└ Total time' ); - console.log( 'Running global setup...' ); - console.time( timers.total ); + let databaseImported = false; + + try { + console.log( '├ Attempting database import…' ); + await cli( + `npm run wp-env run tests-cli wp db import ${ DB_EXPORT_FILE }` + ); + databaseImported = true; + } catch ( _error ) { + // noop + } const requestContext = await request.newContext( { baseURL: BASE_URL, } ); - console.time( timers.authentication ); - await new RequestUtils( requestContext, { - user: admin, - storageStatePath: adminFile, - } ).setupRest(); + console.log( '├ Pre-authenticating users…' ); await new RequestUtils( requestContext, { user: customer, storageStatePath: customerFile, } ).setupRest(); - console.timeEnd( timers.authentication ); + const requestUtils = new RequestUtils( requestContext, { + user: admin, + storageStatePath: adminFile, + } ); + await requestUtils.setupRest(); - console.time( timers.attributes ); - await prepareAttributes(); - console.timeEnd( timers.attributes ); + if ( ! databaseImported ) { + console.log( '├ Activating default theme…' ); + await requestUtils.activateTheme( BLOCK_THEME_SLUG ); + + console.log( '├ Preparing product attributes…' ); + await prepareAttributes(); + } + + console.log( '├ Exporting database…' ); + await cli( + `npm run wp-env run tests-cli wp db export ${ DB_EXPORT_FILE }` + ); await requestContext.dispose(); - console.timeEnd( timers.total ); + console.timeEnd( '└ Total time' ); } export default globalSetup; diff --git a/plugins/woocommerce-blocks/tests/e2e/global-teardown.ts b/plugins/woocommerce-blocks/tests/e2e/global-teardown.ts deleted file mode 100644 index 8c6fef834b0..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/global-teardown.ts +++ /dev/null @@ -1,3 +0,0 @@ -/* eslint-disable no-console, @typescript-eslint/no-empty-function */ - -module.exports = async () => {}; diff --git a/plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts b/plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts index ece2f02e473..c9dd31f2e1e 100644 --- a/plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts +++ b/plugins/woocommerce-blocks/tests/e2e/playwright-utils/test.ts @@ -161,12 +161,9 @@ const test = base.extend< window.localStorage.clear(); } ); - const cliOutput = await cli( + await cli( `npm run wp-env run tests-cli wp db import ${ DB_EXPORT_FILE }` ); - if ( ! cliOutput.stdout.includes( 'Success: Imported ' ) ) { - throw new Error( `Failed to import ${ DB_EXPORT_FILE }` ); - } }, pageUtils: async ( { page }, use ) => { await use( new PageUtils( { page } ) ); diff --git a/plugins/woocommerce-blocks/tests/e2e/playwright.block-theme-with-templates.config.ts b/plugins/woocommerce-blocks/tests/e2e/playwright.block-theme-with-templates.config.ts deleted file mode 100644 index 15bfd99bbde..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/playwright.block-theme-with-templates.config.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * External dependencies - */ -import { defineConfig } from '@playwright/test'; - -/** - * Internal dependencies - */ -import config from './playwright.config'; - -export default defineConfig( { - ...config, - outputDir: 'artifacts/test-results-block-theme-with-templates', - fullyParallel: true, - workers: 1, - projects: [ - { - name: 'blockThemeWithTemplatesConfiguration', - testDir: '.', - testMatch: /block-theme-with-templates.setup.ts/, - }, - { - name: 'blockThemeWithTemplates', - testMatch: /.*.block_theme_with_templates.spec.ts/, - dependencies: [ 'blockThemeWithTemplatesConfiguration' ], - }, - ], -} ); diff --git a/plugins/woocommerce-blocks/tests/e2e/playwright.classic-theme.config.ts b/plugins/woocommerce-blocks/tests/e2e/playwright.classic-theme.config.ts deleted file mode 100644 index 0df3ce51a75..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/playwright.classic-theme.config.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * External dependencies - */ -import { defineConfig } from '@playwright/test'; - -/** - * Internal dependencies - */ -import config from './playwright.config'; - -export default defineConfig( { - ...config, - outputDir: 'artifacts/test-results-classic-theme', - fullyParallel: false, - workers: 1, - projects: [ - { - name: 'classicThemeConfiguration', - testDir: '.', - testMatch: /classic-theme.setup.ts/, - }, - { - name: 'classicTheme', - testMatch: /.*.classic_theme.spec.ts/, - dependencies: [ 'classicThemeConfiguration' ], - }, - ], -} ); diff --git a/plugins/woocommerce-blocks/tests/e2e/playwright.config.ts b/plugins/woocommerce-blocks/tests/e2e/playwright.config.ts index e4317b8d3b7..66275559cfb 100644 --- a/plugins/woocommerce-blocks/tests/e2e/playwright.config.ts +++ b/plugins/woocommerce-blocks/tests/e2e/playwright.config.ts @@ -1,43 +1,30 @@ /** * External dependencies */ -import { defineConfig, PlaywrightTestConfig } from '@playwright/test'; -import { BASE_URL, STORAGE_STATE_PATH } from '@woocommerce/e2e-utils'; - import { fileURLToPath } from 'url'; +import { BASE_URL, STORAGE_STATE_PATH } from '@woocommerce/e2e-utils'; +import { PlaywrightTestConfig, defineConfig, devices } from '@playwright/test'; -// eslint-disable-next-line @typescript-eslint/no-var-requires -require( 'dotenv' ).config(); -interface ExtendedPlaywrightTestConfig extends PlaywrightTestConfig { - use: { - stateDir?: string; - } & PlaywrightTestConfig[ 'use' ]; -} +const { CI, DEFAULT_TIMEOUT_OVERRIDE } = process.env; -const { CI, DEFAULT_TIMEOUT_OVERRIDE, E2E_MAX_FAILURES } = process.env; - -const config: ExtendedPlaywrightTestConfig = { +const config: PlaywrightTestConfig = { + maxFailures: 0, timeout: parseInt( DEFAULT_TIMEOUT_OVERRIDE || '', 10 ) || 100_000, // Defaults to 100s. - outputDir: 'artifacts/test-results', + outputDir: './artifacts/test-results', globalSetup: fileURLToPath( new URL( 'global-setup.ts', 'file:' + __filename ).href ), - globalTeardown: require.resolve( './global-teardown' ), - testDir: 'tests', + testDir: './tests', retries: CI ? 2 : 0, + // We're running our tests in serial, so we only need one worker. workers: 1, + fullyParallel: false, // Don't report slow test "files", as we're running our tests in serial. reportSlowTests: null, - reporter: process.env.CI - ? [ [ 'github' ], [ 'list' ], [ 'html' ] ] - : 'list', - maxFailures: E2E_MAX_FAILURES ? Number( E2E_MAX_FAILURES ) : 0, - snapshotPathTemplate: - '{testDir}/{testFileDir}/__screenshots__/{arg}{testName}{ext}', + reporter: process.env.CI ? [ [ 'github' ], [ 'list' ] ] : 'list', use: { baseURL: BASE_URL, screenshot: 'only-on-failure', - stateDir: 'tests/e2e/test-results/storage/', trace: 'retain-on-failure', video: 'on-first-retry', viewport: { width: 1280, height: 720 }, @@ -47,14 +34,8 @@ const config: ExtendedPlaywrightTestConfig = { }, projects: [ { - name: 'blockThemeConfiguration', - testDir: '.', - testMatch: /block-theme.setup.ts/, - }, - { - name: 'blockTheme', - testMatch: /.*.block_theme.spec.ts/, - dependencies: [ 'blockThemeConfiguration' ], + name: 'chromium', + use: { ...devices[ 'Desktop Chrome' ] }, }, ], }; diff --git a/plugins/woocommerce-blocks/tests/e2e/playwright.side-effects.config.ts b/plugins/woocommerce-blocks/tests/e2e/playwright.side-effects.config.ts deleted file mode 100644 index a6e28f8a1ab..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/playwright.side-effects.config.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * External dependencies - */ -import { defineConfig } from '@playwright/test'; - -/** - * Internal dependencies - */ -import config from './playwright.config'; - -export default defineConfig( { - ...config, - outputDir: 'artifacts/test-results-side-effects', - fullyParallel: false, - workers: 1, - projects: [ - { - name: 'blockThemeConfiguration', - testDir: '.', - testMatch: /block-theme.setup.ts/, - }, - { - name: 'blockThemeWithGlobalSideEffects', - testMatch: /.*.block_theme.side_effects.spec.ts/, - dependencies: [ 'blockThemeConfiguration' ], - }, - ], -} ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts index 9c762201fdf..6d6f2423a4b 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/basic.block_theme.spec.ts @@ -20,6 +20,7 @@ test.describe( 'Basic role-based functionality tests', () => { test.use( { storageState: customerFile, } ); + test( 'Load My Account page', async ( { page } ) => { await page.goto( '/my-account' ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts index 34adb03e3ac..fbf6c227028 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.merchant.classic_theme.spec.ts @@ -1,9 +1,14 @@ /** * External dependencies */ +import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; import { test, expect } from '@woocommerce/e2e-playwright-utils'; test.describe( 'Merchant → Cart', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.activateTheme( CLASSIC_THEME_SLUG ); + } ); + test.describe( 'in widget editor', () => { test( "can't be inserted in a widget area", async ( { editorUtils, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-block.shopper.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts index 8e18e928786..e4859030bc5 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-notices.shopper.classic_theme.spec.ts @@ -26,7 +26,9 @@ const test = base.extend< { checkoutPageObject: CheckoutPage } >( { } ); test.describe( 'Shopper → Notice Templates', () => { - test.beforeEach( async ( { wpCliUtils, frontendUtils } ) => { + test.beforeEach( async ( { requestUtils, wpCliUtils, frontendUtils } ) => { + await requestUtils.activateTheme( CLASSIC_THEME_SLUG ); + const cartShortcodeID = await wpCliUtils.getPostIDByTitle( 'Cart Shortcode' ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-shipping.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.spec.ts similarity index 99% rename from plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.spec.ts index 130deccc1d5..61f41393183 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.side_effects.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/cart/cart-checkout-block-translations.shopper.block_theme.spec.ts @@ -69,7 +69,6 @@ test.describe( 'Shopper → Translations', () => { const beanieAddToCartButton = page.getByLabel( 'Toevoegen aan winkelwagen: “Beanie“' ); - await beanieAddToCartButton.click(); await page.getByLabel( 'Toevoegen aan winkelwagen: “Beanie“' ).click(); @@ -117,7 +116,6 @@ test.describe( 'Shopper → Translations', () => { ).toBeVisible(); await expect( page.getByText( 'Subtotaal' ) ).toBeVisible(); - await expect( page.getByText( 'Verzending' ) ).toBeVisible(); await expect( diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.guest-shopper.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.merchant.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/checkout/additional-fields.shopper.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts index ca3d8bfa3c1..d49fc184eaf 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.merchant.classic_theme.spec.ts @@ -1,9 +1,14 @@ /** * External dependencies */ +import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; import { test, expect } from '@woocommerce/e2e-playwright-utils'; test.describe( 'Merchant → Checkout', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.activateTheme( CLASSIC_THEME_SLUG ); + } ); + test.describe( 'in widget editor', () => { test( "can't be inserted in a widget area", async ( { editorUtils, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.spec.ts similarity index 97% rename from plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.spec.ts index 3f45ce18953..92f962217a8 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.side_effects.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/checkout-block.shopper.block_theme.spec.ts @@ -64,16 +64,17 @@ test.describe( 'Shopper → Account (guest user)', () => { requestUtils, checkoutPageObject, page, + baseURL, } ) => { //Get the login link from checkout page. - const loginLink = page.getByText( 'Log in.' ); - const loginLinkHref = await loginLink.getAttribute( 'href' ); + const loginLink = page.getByRole( 'link', { name: 'Log in.' } ); - //Confirm login link is correct. - expect( loginLinkHref ).toContain( - `${ process.env.WORDPRESS_BASE_URL }/my-account/?redirect_to` + await expect( loginLink ).toHaveAttribute( + 'href', + baseURL + + '/my-account/?redirect_to=' + + encodeURIComponent( baseURL + '/checkout/' ) ); - expect( loginLinkHref ).toContain( `checkout` ); await requestUtils.rest( { method: 'PUT', @@ -85,7 +86,8 @@ test.describe( 'Shopper → Account (guest user)', () => { const createAccount = page.getByLabel( 'Create an account?' ); await createAccount.check(); - const testEmail = `test${ Math.random() * 10 }@example.com`; + + const testEmail = `test-${ Date.now() }@example.com`; await checkoutPageObject.fillInCheckoutWithTestData( { email: testEmail, } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/checkout/order-confirmation.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/classic-template/classic-template.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.side_effects.spec.ts deleted file mode 100644 index dc43f1d4007..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.side_effects.spec.ts +++ /dev/null @@ -1,94 +0,0 @@ -/** - * External dependencies - */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; - -/** - * Internal dependencies - */ -import { REGULAR_PRICED_PRODUCT_NAME } from '../checkout/constants'; - -test.describe( 'Merchant → Local Pickup Settings', () => { - test.beforeEach( async ( { localPickupUtils } ) => { - await localPickupUtils.deleteLocations(); - await localPickupUtils.addPickupLocation( { - location: { - name: 'Automattic, Inc.', - address: '60 29th Street, Suite 343', - city: 'San Francisco', - postcode: '94110', - state: 'US:CA', - details: 'American entity', - }, - } ); - await localPickupUtils.disableLocalPickupCosts(); - await localPickupUtils.enableLocalPickup(); - } ); - - test( 'Updating the title in WC Settings updates the local pickup text in the block and vice/versa', async ( { - page, - localPickupUtils, - admin, - editor, - editorUtils, - frontendUtils, - } ) => { - // First update the title via the site editor then check the local pickup settings. - await admin.visitSiteEditor( { - postId: 'woocommerce/woocommerce//page-checkout', - postType: 'wp_template', - } ); - await editorUtils.enterEditMode(); - - const block = await editorUtils.getBlockByName( - 'woocommerce/checkout-shipping-method-block' - ); - await editor.selectBlocks( block ); - const fakeInput = editor.canvas.getByLabel( 'Pickup', { exact: true } ); - await fakeInput.click(); - - const isMacOS = process.platform === 'darwin'; // darwin is macOS - - // eslint-disable-next-line playwright/no-conditional-in-test - if ( isMacOS ) { - await fakeInput.press( 'Meta+a' ); - } else { - await fakeInput.press( 'Control+a' ); - } - await fakeInput.press( 'Backspace' ); - await fakeInput.pressSequentially( 'This is a test' ); - await editor.canvas.getByText( 'This is a test' ).isVisible(); - await editor.saveSiteEditorEntities(); - - // Now check if it's visible in the local pickup settings. - await localPickupUtils.openLocalPickupSettings(); - await expect( page.getByLabel( 'Title' ) ).toHaveValue( - 'This is a test' - ); - - // Now update the title via local pickup settings and check it reflects in the site editor and front end. - await localPickupUtils.setLocalPickupTitle( - 'Edited from settings page' - ); - await localPickupUtils.saveLocalPickupSettings(); - - await admin.visitSiteEditor( { - postId: 'woocommerce/woocommerce//page-checkout', - postType: 'wp_template', - } ); - await editorUtils.enterEditMode(); - - await expect( - editor.canvas.getByText( 'Edited from settings page' ) - ).toBeVisible(); - - await frontendUtils.emptyCart(); - await frontendUtils.goToShop(); - await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME ); - await frontendUtils.goToCheckout(); - - await expect( - page.getByText( 'Edited from settings page' ) - ).toBeVisible(); - } ); -} ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts index 4b3037152e8..26602c9bc52 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/local-pickup/local-pickup.merchant.block_theme.spec.ts @@ -3,9 +3,13 @@ */ import { test, expect } from '@woocommerce/e2e-playwright-utils'; +/** + * Internal dependencies + */ +import { REGULAR_PRICED_PRODUCT_NAME } from '../checkout/constants'; + test.describe( 'Merchant → Local Pickup Settings', () => { test.beforeEach( async ( { localPickupUtils } ) => { - await localPickupUtils.deleteLocations(); await localPickupUtils.disableLocalPickupCosts(); await localPickupUtils.enableLocalPickup(); } ); @@ -96,7 +100,6 @@ test.describe( 'Merchant → Local Pickup Settings', () => { localPickupUtils, } ) => { await localPickupUtils.addPickupLocation( { - page, location: { name: 'Automattic, Inc.', address: '60 29th Street, Suite 343', @@ -116,7 +119,6 @@ test.describe( 'Merchant → Local Pickup Settings', () => { test( 'user can edit a location', async ( { page, localPickupUtils } ) => { await localPickupUtils.addPickupLocation( { - page, location: { name: 'Automattic, Inc.', address: '60 29th Street, Suite 343', @@ -134,7 +136,6 @@ test.describe( 'Merchant → Local Pickup Settings', () => { ).toBeVisible(); await localPickupUtils.editPickupLocation( { - page, location: { name: 'Ministry of Automattic Limited', address: '100 New Bridge Street', @@ -157,7 +158,6 @@ test.describe( 'Merchant → Local Pickup Settings', () => { localPickupUtils, } ) => { await localPickupUtils.addPickupLocation( { - page, location: { name: 'Ausomattic Pty Ltd', address: @@ -183,4 +183,64 @@ test.describe( 'Merchant → Local Pickup Settings', () => { } ) ).toBeVisible(); } ); + + test( 'updating the title in WC Settings updates the local pickup text in the block and vice/versa', async ( { + page, + localPickupUtils, + admin, + editor, + editorUtils, + frontendUtils, + } ) => { + // First update the title via the site editor then check the local pickup settings. + await admin.visitSiteEditor( { + postId: 'woocommerce/woocommerce//page-checkout', + postType: 'wp_template', + } ); + await editorUtils.enterEditMode(); + + const block = await editorUtils.getBlockByName( + 'woocommerce/checkout-shipping-method-block' + ); + await editor.selectBlocks( block ); + + const fakeInput = editor.canvas.getByLabel( 'Pickup', { exact: true } ); + await fakeInput.focus(); + await fakeInput.dblclick(); // Select all text. + await fakeInput.pressSequentially( 'This is a test' ); // We can't use locator.fill() because it's not a valid input element. + + await editor.canvas.getByText( 'This is a test' ).isVisible(); + await editor.saveSiteEditorEntities(); + + // Now check if it's visible in the local pickup settings. + await localPickupUtils.openLocalPickupSettings(); + await expect( page.getByLabel( 'Title' ) ).toHaveValue( + 'This is a test' + ); + + // Now update the title via local pickup settings and check it reflects in the site editor and front end. + await localPickupUtils.setLocalPickupTitle( + 'Edited from settings page' + ); + await localPickupUtils.saveLocalPickupSettings(); + + await admin.visitSiteEditor( { + postId: 'woocommerce/woocommerce//page-checkout', + postType: 'wp_template', + } ); + await editorUtils.enterEditMode(); + + await expect( + editor.canvas.getByText( 'Edited from settings page' ) + ).toBeVisible(); + + await frontendUtils.emptyCart(); + await frontendUtils.goToShop(); + await frontendUtils.addToCart( REGULAR_PRICED_PRODUCT_NAME ); + await frontendUtils.goToCheckout(); + + await expect( + page.getByText( 'Edited from settings page' ) + ).toBeVisible(); + } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts index 36e7e19f74c..8200a9b4417 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.merchant.classic_theme.spec.ts @@ -1,6 +1,7 @@ /** * External dependencies */ +import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; import { expect, test } from '@woocommerce/e2e-playwright-utils'; import { BlockData } from '@woocommerce/e2e-types'; @@ -15,6 +16,10 @@ const blockData: BlockData = { }; test.describe( 'Merchant → Mini Cart', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.activateTheme( CLASSIC_THEME_SLUG ); + } ); + test.describe( 'in widget editor', () => { test( 'can be inserted in a widget area', async ( { editorUtils } ) => { await editorUtils.openWidgetEditor(); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/mini-cart/mini-cart-block.shopper.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/on-sale-badge/on-sale-badge-single-product-template.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/page-content-wrapper/page-content-wrapper.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts index 12b70440d53..21dacd98971 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/product-button/product-button.classic_theme.spec.ts @@ -1,6 +1,7 @@ /** * External dependencies */ +import { CLASSIC_THEME_SLUG } from '@woocommerce/e2e-utils'; import { expect, test as base } from '@woocommerce/e2e-playwright-utils'; /** @@ -25,7 +26,8 @@ const test = base.extend< { productCollectionPage: ProductCollectionPage } >( { }, } ); test.describe( `${ blockData.name } Block`, () => { - test.beforeEach( async ( { page } ) => { + test.beforeEach( async ( { page, requestUtils } ) => { + await requestUtils.activateTheme( CLASSIC_THEME_SLUG ); await page.goto( '/product-collection/' ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-collection/compatibility-layer.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-collection/product-collection.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image-next-previous/product-gallery-large-image-next-previous.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-large-image/product-gallery-large-image.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-pager/product-gallery-pager.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/inner-blocks/product-gallery-thumbnails/product-gallery-thumbnails.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/product-gallery/product-gallery.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.spec.ts similarity index 100% rename from plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.side_effects.spec.ts rename to plugins/woocommerce-blocks/tests/e2e/tests/products/products.block_theme.spec.ts diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts index b02cad43428..bb22f83f99f 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/legacy-templates.block_theme.spec.ts @@ -5,10 +5,6 @@ import { test, expect } from '@woocommerce/e2e-playwright-utils'; import { cli } from '@woocommerce/e2e-utils'; test.describe( 'Legacy templates', () => { - test.beforeEach( async ( { requestUtils } ) => { - await requestUtils.deleteAllTemplates( 'wp_template' ); - } ); - test( 'woocommerce//* slug is supported', async ( { admin, page, @@ -48,15 +44,13 @@ test.describe( 'Legacy templates', () => { } ); await test.step( 'Update created term to legacy format in the DB', async () => { - const cliOutput = await cli( + await cli( `npm run wp-env run tests-cli -- \ wp term update wp_theme woocommerce-woocommerce \ --by="slug" \ --name="woocommerce" \ --slug="woocommerce"` ); - - expect( cliOutput.stdout ).toContain( 'Success: Term updated.' ); } ); await test.step( 'Verify the template can be edited via a legacy ID ', async () => { @@ -88,17 +82,5 @@ test.describe( 'Legacy templates', () => { await expect( page.getByText( template.customText ) ).toBeVisible(); } ); - - await test.step( 'Revert term update', async () => { - const cliOutput = await cli( - `npm run wp-env run tests-cli -- \ - wp term update wp_theme woocommerce \ - --by="slug" \ - --name="woocommerce/woocommerce" \ - --slug="woocommerce-woocommerce"` - ); - - expect( cliOutput.stdout ).toContain( 'Success: Term updated.' ); - } ); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts index c6fc2cbf97e..4ee32982f35 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/single-product-template.block_theme_with_templates.spec.ts @@ -1,6 +1,7 @@ /** * External dependencies */ +import { BLOCK_THEME_WITH_TEMPLATES_SLUG } from '@woocommerce/e2e-utils'; import { test, expect } from '@woocommerce/e2e-playwright-utils'; /** @@ -19,6 +20,10 @@ const userText = 'Hello World in the Belt template'; const themeTemplateText = 'Single Product Belt template loaded from theme'; test.describe( 'Single Product Template', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.activateTheme( BLOCK_THEME_WITH_TEMPLATES_SLUG ); + } ); + test( 'loads the theme template for a specific product using the product slug and it can be customized', async ( { admin, editor, diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.side_effects.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.side_effects.spec.ts deleted file mode 100644 index fef99109dcb..00000000000 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.side_effects.spec.ts +++ /dev/null @@ -1,89 +0,0 @@ -/** - * External dependencies - */ -import { test, expect } from '@woocommerce/e2e-playwright-utils'; -import { - BLOCK_THEME_SLUG, - BLOCK_THEME_WITH_TEMPLATES_SLUG, -} from '@woocommerce/e2e-utils'; - -/** - * Internal dependencies - */ -import { CUSTOMIZABLE_WC_TEMPLATES } from './constants'; - -const testToRun = CUSTOMIZABLE_WC_TEMPLATES.filter( - ( data ) => data.canBeOverriddenByThemes -); - -for ( const testData of testToRun ) { - const userText = `Hello World in the ${ testData.templateName } template`; - const woocommerceTemplateUserText = `Hello World in the WooCommerce ${ testData.templateName } template`; - - test.describe( `${ testData.templateName } template`, () => { - test( `user-modified ${ testData.templateName } template based on the theme template has priority over the user-modified template based on the default WooCommerce template`, async ( { - page, - admin, - editor, - requestUtils, - editorUtils, - frontendUtils, - } ) => { - // Edit the WooCommerce default template - await editorUtils.visitTemplateEditor( - testData.templateName, - testData.templateType - ); - await editor.insertBlock( { - name: 'core/paragraph', - attributes: { content: woocommerceTemplateUserText }, - } ); - await editor.saveSiteEditorEntities(); - - await requestUtils.activateTheme( BLOCK_THEME_WITH_TEMPLATES_SLUG ); - - // Edit the theme template. The theme template is not - // directly available from the UI, because the customized - // one takes priority, so we go directly to its URL. - await admin.visitSiteEditor( { - postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`, - postType: testData.templateType, - } ); - await editorUtils.enterEditMode(); - await editorUtils.waitForSiteEditorFinishLoading(); - await editorUtils.editor.insertBlock( { - name: 'core/paragraph', - attributes: { content: userText }, - } ); - await editor.saveSiteEditorEntities(); - - // Verify the template is the one modified by the user based on the theme. - await testData.visitPage( { frontendUtils, page } ); - await expect( page.getByText( userText ).first() ).toBeVisible(); - await expect( - page.getByText( woocommerceTemplateUserText ) - ).toHaveCount( 0 ); - - // Revert edition and verify the user-modified WC template is used. - // Note: we need to revert it from the admin (instead of calling - // `deleteAllTemplates()`). This way, we verify there are no - // duplicate templates with the same name. - // See: https://github.com/woocommerce/woocommerce/issues/42220 - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( - testData.templateName - ); - - await testData.visitPage( { frontendUtils, page } ); - - await expect( - page.getByText( woocommerceTemplateUserText ).first() - ).toBeVisible(); - await expect( page.getByText( userText ) ).toHaveCount( 0 ); - - await requestUtils.activateTheme( BLOCK_THEME_SLUG ); - } ); - } ); -} diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts index ec878d3cb95..c3c77397920 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme.spec.ts @@ -2,81 +2,54 @@ * External dependencies */ import { test, expect } from '@woocommerce/e2e-playwright-utils'; +import { + BLOCK_THEME_SLUG, + BLOCK_THEME_WITH_TEMPLATES_SLUG, +} from '@woocommerce/e2e-utils'; /** * Internal dependencies */ import { CUSTOMIZABLE_WC_TEMPLATES } from './constants'; -CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => { - const userText = `Hello World in the ${ testData.templateName } template`; - const fallbackTemplateUserText = `Hello World in the fallback ${ testData.templateName } template`; - const templateTypeName = - testData.templateType === 'wp_template' ? 'template' : 'template part'; +test.describe( 'Template customization', () => { + CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => { + const userText = `Hello World in the ${ testData.templateName } template`; + const fallbackTemplateUserText = `Hello World in the fallback ${ testData.templateName } template`; + const templateTypeName = + testData.templateType === 'wp_template' + ? 'template' + : 'template part'; - test.describe( `${ testData.templateName } template`, () => { - test( 'can be modified and reverted', async ( { - admin, - frontendUtils, - editor, - editorUtils, - page, - } ) => { - // Verify the template can be edited. - await editorUtils.visitTemplateEditor( - testData.templateName, - testData.templateType - ); - await editor.insertBlock( { - name: 'core/paragraph', - attributes: { content: userText }, - } ); - await editor.saveSiteEditorEntities(); - // Verify template name didn't change. - // See: https://github.com/woocommerce/woocommerce/issues/42221 - await expect( - page.getByRole( 'heading', { - name: `Editing ${ templateTypeName }: ${ testData.templateName }`, - } ) - ).toBeVisible(); - - await testData.visitPage( { frontendUtils, page } ); - await expect( page.getByText( userText ).first() ).toBeVisible(); - - // Verify the edition can be reverted. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( - testData.templateName - ); - await testData.visitPage( { frontendUtils, page } ); - await expect( page.getByText( userText ) ).toHaveCount( 0 ); - } ); - - if ( testData.fallbackTemplate ) { - test( `defaults to the ${ testData.fallbackTemplate.templateName } template`, async ( { + test.describe( `${ testData.templateName } template`, () => { + test( 'can be modified and reverted', async ( { admin, frontendUtils, editor, editorUtils, page, } ) => { - // Edit fallback template and verify changes are visible. + // Verify the template can be edited. await editorUtils.visitTemplateEditor( - testData.fallbackTemplate?.templateName || '', + testData.templateName, testData.templateType ); await editor.insertBlock( { name: 'core/paragraph', - attributes: { - content: fallbackTemplateUserText, - }, + attributes: { content: userText }, } ); await editor.saveSiteEditorEntities(); + // Verify template name didn't change. + // See: https://github.com/woocommerce/woocommerce/issues/42221 + await expect( + page.getByRole( 'heading', { + name: `Editing ${ templateTypeName }: ${ testData.templateName }`, + } ) + ).toBeVisible(); + await testData.visitPage( { frontendUtils, page } ); await expect( - page.getByText( fallbackTemplateUserText ).first() + page.getByText( userText ).first() ).toBeVisible(); // Verify the edition can be reverted. @@ -84,13 +57,130 @@ CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => { path: `/${ testData.templateType }/all`, } ); await editorUtils.revertTemplateCustomizations( - testData.fallbackTemplate?.templateName || '' + testData.templateName ); await testData.visitPage( { frontendUtils, page } ); - await expect( - page.getByText( fallbackTemplateUserText ) - ).toHaveCount( 0 ); + await expect( page.getByText( userText ) ).toHaveCount( 0 ); } ); - } + + if ( testData.fallbackTemplate ) { + test( `defaults to the ${ testData.fallbackTemplate.templateName } template`, async ( { + admin, + frontendUtils, + editor, + editorUtils, + page, + } ) => { + // Edit fallback template and verify changes are visible. + await editorUtils.visitTemplateEditor( + testData.fallbackTemplate?.templateName || '', + testData.templateType + ); + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + content: fallbackTemplateUserText, + }, + } ); + await editor.saveSiteEditorEntities(); + await testData.visitPage( { frontendUtils, page } ); + await expect( + page.getByText( fallbackTemplateUserText ).first() + ).toBeVisible(); + + // Verify the edition can be reverted. + await admin.visitSiteEditor( { + path: `/${ testData.templateType }/all`, + } ); + await editorUtils.revertTemplateCustomizations( + testData.fallbackTemplate?.templateName || '' + ); + await testData.visitPage( { frontendUtils, page } ); + await expect( + page.getByText( fallbackTemplateUserText ) + ).toHaveCount( 0 ); + } ); + } + } ); } ); + + const testToRun = CUSTOMIZABLE_WC_TEMPLATES.filter( + ( data ) => data.canBeOverriddenByThemes + ); + + for ( const testData of testToRun ) { + const userText = `Hello World in the ${ testData.templateName } template`; + const woocommerceTemplateUserText = `Hello World in the WooCommerce ${ testData.templateName } template`; + + test.describe( `${ testData.templateName } template`, () => { + test( `user-modified ${ testData.templateName } template based on the theme template has priority over the user-modified template based on the default WooCommerce template`, async ( { + page, + admin, + editor, + requestUtils, + editorUtils, + frontendUtils, + } ) => { + // Edit the WooCommerce default template + await editorUtils.visitTemplateEditor( + testData.templateName, + testData.templateType + ); + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { content: woocommerceTemplateUserText }, + } ); + await editor.saveSiteEditorEntities(); + + await requestUtils.activateTheme( + BLOCK_THEME_WITH_TEMPLATES_SLUG + ); + + // Edit the theme template. The theme template is not + // directly available from the UI, because the customized + // one takes priority, so we go directly to its URL. + await admin.visitSiteEditor( { + postId: `${ BLOCK_THEME_WITH_TEMPLATES_SLUG }//${ testData.templatePath }`, + postType: testData.templateType, + } ); + await editorUtils.enterEditMode(); + await editorUtils.waitForSiteEditorFinishLoading(); + await editorUtils.editor.insertBlock( { + name: 'core/paragraph', + attributes: { content: userText }, + } ); + await editor.saveSiteEditorEntities(); + + // Verify the template is the one modified by the user based on the theme. + await testData.visitPage( { frontendUtils, page } ); + await expect( + page.getByText( userText ).first() + ).toBeVisible(); + await expect( + page.getByText( woocommerceTemplateUserText ) + ).toHaveCount( 0 ); + + // Revert edition and verify the user-modified WC template is used. + // Note: we need to revert it from the admin (instead of calling + // `deleteAllTemplates()`). This way, we verify there are no + // duplicate templates with the same name. + // See: https://github.com/woocommerce/woocommerce/issues/42220 + await admin.visitSiteEditor( { + path: `/${ testData.templateType }/all`, + } ); + await editorUtils.revertTemplateCustomizations( + testData.templateName + ); + + await testData.visitPage( { frontendUtils, page } ); + + await expect( + page.getByText( woocommerceTemplateUserText ).first() + ).toBeVisible(); + await expect( page.getByText( userText ) ).toHaveCount( 0 ); + + await requestUtils.activateTheme( BLOCK_THEME_SLUG ); + } ); + } ); + } } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts index 0edd26c84ec..9a50287abf3 100644 --- a/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts +++ b/plugins/woocommerce-blocks/tests/e2e/tests/templates/template-customization.block_theme_with_templates.spec.ts @@ -1,6 +1,7 @@ /** * External dependencies */ +import { BLOCK_THEME_WITH_TEMPLATES_SLUG } from '@woocommerce/e2e-utils'; import { test, expect } from '@woocommerce/e2e-playwright-utils'; /** @@ -8,97 +9,107 @@ import { test, expect } from '@woocommerce/e2e-playwright-utils'; */ import { CUSTOMIZABLE_WC_TEMPLATES } from './constants'; -CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => { - if ( ! testData.canBeOverriddenByThemes ) { - return; - } - const userText = `Hello World in the ${ testData.templateName } template`; - const fallbackTemplateUserText = `Hello World in the fallback ${ testData.templateName } template`; - const templateTypeName = - testData.templateType === 'wp_template' ? 'template' : 'template part'; +test.describe( 'Template customization', () => { + test.beforeEach( async ( { requestUtils } ) => { + await requestUtils.activateTheme( BLOCK_THEME_WITH_TEMPLATES_SLUG ); + } ); - test.describe( `${ testData.templateName } template`, () => { - test( "theme template has priority over WooCommerce's and can be modified", async ( { - admin, - editor, - editorUtils, - frontendUtils, - page, - } ) => { - // Edit the theme template. - await editorUtils.visitTemplateEditor( - testData.templateName, - testData.templateType - ); - await editor.insertBlock( { - name: 'core/paragraph', - attributes: { content: userText }, - } ); - await editor.saveSiteEditorEntities(); - // Verify template name didn't change. - // See: https://github.com/woocommerce/woocommerce/issues/42221 - await expect( - page.getByRole( 'heading', { - name: `Editing ${ templateTypeName }: ${ testData.templateName }`, - } ) - ).toBeVisible(); + CUSTOMIZABLE_WC_TEMPLATES.forEach( ( testData ) => { + if ( ! testData.canBeOverriddenByThemes ) { + return; + } + const userText = `Hello World in the ${ testData.templateName } template`; + const fallbackTemplateUserText = `Hello World in the fallback ${ testData.templateName } template`; + const templateTypeName = + testData.templateType === 'wp_template' + ? 'template' + : 'template part'; - // Verify the template is the one modified by the user. - await testData.visitPage( { frontendUtils, page } ); - await expect( page.getByText( userText ).first() ).toBeVisible(); - - // Revert edition and verify the template from the theme is used. - await admin.visitSiteEditor( { - path: `/${ testData.templateType }/all`, - } ); - await editorUtils.revertTemplateCustomizations( - testData.templateName - ); - await testData.visitPage( { frontendUtils, page } ); - - await expect( - page - .getByText( - `${ testData.templateName } template loaded from theme` - ) - .first() - ).toBeVisible(); - await expect( page.getByText( userText ) ).toHaveCount( 0 ); - } ); - - if ( testData.fallbackTemplate ) { - test( `theme template has priority over user-modified ${ testData.fallbackTemplate.templateName } template`, async ( { + test.describe( `${ testData.templateName } template`, () => { + test( "theme template has priority over WooCommerce's and can be modified", async ( { admin, - frontendUtils, editor, editorUtils, + frontendUtils, page, } ) => { - // Edit default template and verify changes are not visible, as the theme template has priority. + // Edit the theme template. await editorUtils.visitTemplateEditor( - testData.fallbackTemplate?.templateName || '', + testData.templateName, testData.templateType ); await editor.insertBlock( { name: 'core/paragraph', - attributes: { - content: fallbackTemplateUserText, - }, + attributes: { content: userText }, } ); await editor.saveSiteEditorEntities(); + // Verify template name didn't change. + // See: https://github.com/woocommerce/woocommerce/issues/42221 + await expect( + page.getByRole( 'heading', { + name: `Editing ${ templateTypeName }: ${ testData.templateName }`, + } ) + ).toBeVisible(); + + // Verify the template is the one modified by the user. await testData.visitPage( { frontendUtils, page } ); await expect( - page.getByText( fallbackTemplateUserText ) - ).toHaveCount( 0 ); + page.getByText( userText ).first() + ).toBeVisible(); - // Revert the edit. + // Revert edition and verify the template from the theme is used. await admin.visitSiteEditor( { path: `/${ testData.templateType }/all`, } ); await editorUtils.revertTemplateCustomizations( - testData.fallbackTemplate?.templateName || '' + testData.templateName ); + await testData.visitPage( { frontendUtils, page } ); + + await expect( + page + .getByText( + `${ testData.templateName } template loaded from theme` + ) + .first() + ).toBeVisible(); + await expect( page.getByText( userText ) ).toHaveCount( 0 ); } ); - } + + if ( testData.fallbackTemplate ) { + test( `theme template has priority over user-modified ${ testData.fallbackTemplate.templateName } template`, async ( { + admin, + frontendUtils, + editor, + editorUtils, + page, + } ) => { + // Edit default template and verify changes are not visible, as the theme template has priority. + await editorUtils.visitTemplateEditor( + testData.fallbackTemplate?.templateName || '', + testData.templateType + ); + await editor.insertBlock( { + name: 'core/paragraph', + attributes: { + content: fallbackTemplateUserText, + }, + } ); + await editor.saveSiteEditorEntities(); + await testData.visitPage( { frontendUtils, page } ); + await expect( + page.getByText( fallbackTemplateUserText ) + ).toHaveCount( 0 ); + + // Revert the edit. + await admin.visitSiteEditor( { + path: `/${ testData.templateType }/all`, + } ); + await editorUtils.revertTemplateCustomizations( + testData.fallbackTemplate?.templateName || '' + ); + } ); + } + } ); } ); } ); diff --git a/plugins/woocommerce-blocks/tests/e2e/utils/cli.ts b/plugins/woocommerce-blocks/tests/e2e/utils/cli.ts index ec375d1f1a3..c5be024ebbd 100644 --- a/plugins/woocommerce-blocks/tests/e2e/utils/cli.ts +++ b/plugins/woocommerce-blocks/tests/e2e/utils/cli.ts @@ -1,25 +1,35 @@ /** * External dependencies */ -import { ExecException, exec } from 'child_process'; +import { exec, ExecException } from 'child_process'; -export function cli( - cmd: string, - args = [] -): Promise< { - code: number; - error: ExecException | null; +interface ExecResult { stdout: string; stderr: string; -} > { - return new Promise( ( resolve ) => { - exec( `${ cmd } ${ args.join( ' ' ) }`, ( error, stdout, stderr ) => { - resolve( { - code: error && error.code ? error.code : 0, - error, - stdout, - stderr, - } ); - } ); +} + +interface ExecError extends ExecResult { + error: ExecException | null; +} + +export function cli( command: string ): Promise< ExecResult > { + return new Promise( ( resolve, reject ) => { + exec( + command, + ( error: ExecException | null, stdout: string, stderr: string ) => { + if ( error ) { + reject( { + error, + stdout, + stderr, + } as ExecError ); + } else { + resolve( { + stdout, + stderr, + } as ExecResult ); + } + } + ); } ); } diff --git a/plugins/woocommerce/changelog/refactor-e2e-playwright-configs b/plugins/woocommerce/changelog/refactor-e2e-playwright-configs new file mode 100644 index 00000000000..1878545c6f6 --- /dev/null +++ b/plugins/woocommerce/changelog/refactor-e2e-playwright-configs @@ -0,0 +1,4 @@ +Significance: patch +Type: dev + +Blocks E2E: Refactor Playwright configs and CI workflow