Blocks E2E: Refactor configs and workflow (#46409)
This commit is contained in:
parent
4840af874a
commit
30756f74e3
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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' );
|
||||
} );
|
|
@ -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' );
|
||||
} );
|
|
@ -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' );
|
||||
} );
|
|
@ -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;
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
/* eslint-disable no-console, @typescript-eslint/no-empty-function */
|
||||
|
||||
module.exports = async () => {};
|
|
@ -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 } ) );
|
||||
|
|
|
@ -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' ],
|
||||
},
|
||||
],
|
||||
} );
|
|
@ -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' ],
|
||||
},
|
||||
],
|
||||
} );
|
|
@ -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' ] },
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -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' ],
|
||||
},
|
||||
],
|
||||
} );
|
|
@ -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' );
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'
|
||||
);
|
||||
|
|
|
@ -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(
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
} );
|
|
@ -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();
|
||||
} );
|
||||
} );
|
|
@ -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();
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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/' );
|
||||
} );
|
||||
|
||||
|
|
|
@ -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.' );
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 );
|
||||
} );
|
||||
} );
|
||||
}
|
|
@ -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 );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
|
|
@ -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 || ''
|
||||
);
|
||||
} );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
);
|
||||
} );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: dev
|
||||
|
||||
Blocks E2E: Refactor Playwright configs and CI workflow
|
Loading…
Reference in New Issue