Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@
{
"files": [ "**/test/**/*.js" ],
"extends": [ "plugin:@wordpress/eslint-plugin/test-unit" ]
},
{
"files": [ "specs/**/*.js" ],
"rules": {
"import/no-extraneous-dependencies": [
"error",
{
"peerDependencies": true,
"devDependencies": true
}
]
}
}
]
}
35 changes: 35 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,38 @@ jobs:

- name: Run PHP tests
run: npm run test:unit:php:base
e2e:
name: E2E Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: npm

- name: Install Node Dependencies
run: npm i

- name: Build JavaScript
run: npm run build

- name: Install Playwright browsers
run: npx playwright install --with-deps chromium

- name: Start wp-env
run: npm run test:unit:php:setup

- name: Run E2E tests
run: npm run test:e2e

- name: Upload test artifacts on failure
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-artifacts
path: artifacts/
if-no-files-found: ignore
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ build/
*.result.*

dev-env/

# Playwright e2e test artifacts (screenshots, traces, test results)
artifacts/
65 changes: 65 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
"devDependencies": {
"@actions/core": "^3.0.0",
"@emotion/babel-plugin": "^11.13.5",
"@playwright/test": "^1.58.2",
"@wordpress/base-styles": "^6.16.0",
"@wordpress/e2e-test-utils-playwright": "^1.40.0",
"@wordpress/env": "^10.0.0",
"@wordpress/scripts": "^31.5.0",
Comment thread
mikachan marked this conversation as resolved.
"babel-plugin-inline-json-import": "^0.3.2",
Expand Down Expand Up @@ -57,7 +59,9 @@
"update-version": "node update-version-and-changelog.js",
"prepare": "husky",
"wp-env": "wp-env",
"test:unit": "wp-scripts test-unit-js --config test/unit/jest.config.js"
"test:unit": "wp-scripts test-unit-js --config test/unit/jest.config.js",
"test:e2e": "wp-scripts test-playwright",
"test:e2e:debug": "wp-scripts test-playwright --ui"
},
"lint-staged": {
"*.{js,json,yml}": [
Expand Down
2 changes: 2 additions & 0 deletions playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
process.env.WP_BASE_URL ??= 'http://localhost:8989';
module.exports = require( '@wordpress/scripts/config/playwright.config' );
29 changes: 29 additions & 0 deletions specs/editor-sidebar.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* WordPress dependencies
*/
const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );

test.describe( 'Create Block Theme — Site Editor Sidebar', () => {
test( 'plugin sidebar button is present in the editor toolbar', async ( {
admin,
page,
} ) => {
await admin.visitSiteEditor( { canvas: 'edit' } );
await expect(
page.getByRole( 'button', { name: 'Create Block Theme' } )
).toBeVisible();
Comment thread
mikachan marked this conversation as resolved.
} );

test( 'clicking the toolbar button opens the plugin sidebar', async ( {
admin,
page,
} ) => {
await admin.visitSiteEditor( { canvas: 'edit' } );
await page
.getByRole( 'button', { name: 'Create Block Theme' } )
.click();
await expect(
page.getByRole( 'button', { name: 'Save Changes to Theme' } )
).toBeVisible();
} );
} );
112 changes: 112 additions & 0 deletions specs/landing-page.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* External dependencies
*/
const { execSync } = require( 'child_process' );

/**
* WordPress dependencies
*/
const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );

const E2E_THEME_SLUG = 'e2e-test-theme';

test.describe( 'Create Block Theme — Admin Landing Page', () => {
let originalThemeSlug;

test.beforeAll( async ( { requestUtils } ) => {
const themes = await requestUtils.rest( { path: '/wp/v2/themes' } );
const active = themes.find( ( { status } ) => status === 'active' );
originalThemeSlug = active?.stylesheet;

if (
themes.some( ( { stylesheet } ) => stylesheet === E2E_THEME_SLUG )
) {
execSync(
`npx wp-env run tests-cli wp theme delete ${ E2E_THEME_SLUG }`,
{ stdio: 'ignore' }
);
}
} );

test.afterAll( async ( { requestUtils } ) => {
if ( originalThemeSlug ) {
await requestUtils.activateTheme( originalThemeSlug );
}

const themes = await requestUtils.rest( { path: '/wp/v2/themes' } );
if (
themes.some( ( { stylesheet } ) => stylesheet === E2E_THEME_SLUG )
) {
execSync(
`npx wp-env run tests-cli wp theme delete ${ E2E_THEME_SLUG }`,
{ stdio: 'ignore' }
Comment on lines +40 to +42
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen a need for this before. Could you explain why this is needed? Is there a precedence for this in Gutenberg already?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no deleteTheme() method available in @wordpress/e2e-test-utils-playwright, and the REST API doesn't support theme deletion (/wp/v2/themes is read-only). Because we're testing this plugin creating a theme, I think WP-CLI is the best way to clean them up.

wp-env is already running at this point, so npx wp-env run cli should be OK to use here.

);
}
} );

test( 'page loads and shows main heading', async ( { admin, page } ) => {
await admin.visitAdminPage(
'themes.php',
'page=create-block-theme-landing'
);
await expect(
page.getByRole( 'heading', { name: 'What would you like to do?' } )
).toBeVisible();
} );

test( 'clicking export downloads a zip file', async ( { admin, page } ) => {
await admin.visitAdminPage(
'themes.php',
'page=create-block-theme-landing'
);
const [ download ] = await Promise.all( [
page.waitForEvent( 'download' ),
page.getByRole( 'button', { name: /Export/ } ).click(),
] );
expect( download.suggestedFilename() ).toMatch( /\.zip$/ );
} );

test( 'create blank theme modal opens with name field', async ( {
admin,
page,
} ) => {
await admin.visitAdminPage(
'themes.php',
'page=create-block-theme-landing'
);
await page
.getByRole( 'button', { name: /Create a new Blank Theme/i } )
.click();
await expect( page.getByLabel( /Theme name/i ) ).toBeVisible();
} );

test( 'create blank theme end-to-end', async ( {
admin,
page,
requestUtils,
} ) => {
await admin.visitAdminPage(
'themes.php',
'page=create-block-theme-landing'
);

// Accept the alert dialog that fires on successful theme creation.
page.once( 'dialog', ( dialog ) => dialog.accept() );

await page
.getByRole( 'button', { name: /Create a new Blank Theme/i } )
.click();
await page.getByLabel( /Theme name/i ).fill( 'E2E Test Theme' );
await page
.getByRole( 'button', {
name: 'Create and Activate Blank Theme',
} )
.click();

await page.waitForURL( /site-editor/, { waitUntil: 'commit' } );

const themes = await requestUtils.rest( { path: '/wp/v2/themes' } );
const active = themes.find( ( { status } ) => status === 'active' );
expect( active?.stylesheet ).toBe( E2E_THEME_SLUG );
} );
} );
Loading