From 7d6ee3a5bdc8b80f9bd4d9c71625487e6fec7fd9 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 11:33:56 +0100 Subject: [PATCH 01/15] No need to prepend adminUrl --- assets/src/js/commands/admin-commands.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/assets/src/js/commands/admin-commands.js b/assets/src/js/commands/admin-commands.js index 9dcb6013..c4ae1ee6 100644 --- a/assets/src/js/commands/admin-commands.js +++ b/assets/src/js/commands/admin-commands.js @@ -36,7 +36,6 @@ const registerAdminCommands = () => { } const commandStore = dispatch( 'core/commands' ); - const adminUrl = window.acf?.data?.admin_url || ''; const viewCommands = [ { @@ -205,8 +204,8 @@ const registerAdminCommands = () => { keywords: command.keywords, callback: ( { close } ) => { document.location = command.urlArgs - ? addQueryArgs( adminUrl + command.url, command.urlArgs ) - : adminUrl + command.url; + ? addQueryArgs( command.url, command.urlArgs ) + : command.url; close(); }, } ); From ee408f1d5486f24b2fdf3b607c0380bbd98052b5 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 11:57:33 +0100 Subject: [PATCH 02/15] Remove command descriptions They're not supported by the Commands API: https://github.com/WordPress/gutenberg/blob/924fe383e22b25748e1c9292089bba007ef3c475/packages/commands/README.md#types-of-commands --- assets/src/js/commands/admin-commands.js | 45 ------------------------ 1 file changed, 45 deletions(-) diff --git a/assets/src/js/commands/admin-commands.js b/assets/src/js/commands/admin-commands.js index c4ae1ee6..96670d80 100644 --- a/assets/src/js/commands/admin-commands.js +++ b/assets/src/js/commands/admin-commands.js @@ -44,10 +44,6 @@ const registerAdminCommands = () => { url: 'edit.php', urlArgs: { post_type: 'acf-field-group' }, icon: layout, - description: __( - 'SCF: View and manage custom field groups', - 'secure-custom-fields' - ), keywords: [ 'acf', 'custom fields', @@ -61,10 +57,6 @@ const registerAdminCommands = () => { url: 'edit.php', urlArgs: { post_type: 'acf-post-type' }, icon: postList, - description: __( - 'SCF: Manage custom post types', - 'secure-custom-fields' - ), keywords: [ 'cpt', 'content types', 'manage post types' ], }, { @@ -73,10 +65,6 @@ const registerAdminCommands = () => { url: 'edit.php', urlArgs: { post_type: 'acf-taxonomy' }, icon: category, - description: __( - 'SCF: Manage custom taxonomies for organizing content', - 'secure-custom-fields' - ), keywords: [ 'categories', 'tags', 'terms', 'custom taxonomies' ], }, { @@ -85,10 +73,6 @@ const registerAdminCommands = () => { url: 'edit.php', urlArgs: { post_type: 'acf-ui-options-page' }, icon: settings, - description: __( - 'SCF: Manage custom options pages for global settings', - 'secure-custom-fields' - ), keywords: [ 'settings', 'global options', 'site options' ], }, { @@ -97,10 +81,6 @@ const registerAdminCommands = () => { url: 'admin.php', urlArgs: { page: 'acf-tools' }, icon: tool, - description: __( - 'SCF: Access SCF utility tools', - 'secure-custom-fields' - ), keywords: [ 'utilities', 'import export', 'json' ], }, { @@ -109,10 +89,6 @@ const registerAdminCommands = () => { url: 'admin.php', urlArgs: { page: 'acf-tools', tool: 'import' }, icon: upload, - description: __( - 'SCF: Import field groups, post types, taxonomies, and options pages', - 'secure-custom-fields' - ), keywords: [ 'upload', 'json', 'migration', 'transfer' ], }, { @@ -121,10 +97,6 @@ const registerAdminCommands = () => { url: 'admin.php', urlArgs: { page: 'acf-tools', tool: 'export' }, icon: download, - description: __( - 'SCF: Export field groups, post types, taxonomies, and options pages', - 'secure-custom-fields' - ), keywords: [ 'download', 'json', 'backup', 'migration' ], }, ]; @@ -137,10 +109,6 @@ const registerAdminCommands = () => { url: 'post-new.php', urlArgs: { post_type: 'acf-field-group' }, icon: plus, - description: __( - 'SCF: Create a new field group to organize custom fields', - 'secure-custom-fields' - ), keywords: [ 'add', 'new', @@ -155,10 +123,6 @@ const registerAdminCommands = () => { url: 'post-new.php', urlArgs: { post_type: 'acf-post-type' }, icon: plus, - description: __( - 'SCF: Create a new custom post type', - 'secure-custom-fields' - ), keywords: [ 'add', 'new', 'create', 'cpt', 'content type' ], }, { @@ -167,10 +131,6 @@ const registerAdminCommands = () => { url: 'post-new.php', urlArgs: { post_type: 'acf-taxonomy' }, icon: plus, - description: __( - 'SCF: Create a new custom taxonomy', - 'secure-custom-fields' - ), keywords: [ 'add', 'new', @@ -186,10 +146,6 @@ const registerAdminCommands = () => { url: 'post-new.php', urlArgs: { post_type: 'acf-ui-options-page' }, icon: plus, - description: __( - 'SCF: Create a new custom options page', - 'secure-custom-fields' - ), keywords: [ 'add', 'new', 'create', 'options', 'settings page' ], }, ]; @@ -200,7 +156,6 @@ const registerAdminCommands = () => { label: command.label, icon: createElement( Icon, { icon: command.icon } ), context: 'admin', - description: command.description, keywords: command.keywords, callback: ( { close } ) => { document.location = command.urlArgs From a9c6c4fd66d80889499e47a070d76b6f643de806 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 13:16:55 +0100 Subject: [PATCH 03/15] No need for tertiary, addQueryArgs falls back gracefully --- assets/src/js/commands/admin-commands.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/assets/src/js/commands/admin-commands.js b/assets/src/js/commands/admin-commands.js index 96670d80..a1670552 100644 --- a/assets/src/js/commands/admin-commands.js +++ b/assets/src/js/commands/admin-commands.js @@ -158,9 +158,10 @@ const registerAdminCommands = () => { context: 'admin', keywords: command.keywords, callback: ( { close } ) => { - document.location = command.urlArgs - ? addQueryArgs( command.url, command.urlArgs ) - : command.url; + document.location = addQueryArgs( + command.url, + command.urlArgs + ); close(); }, } ); From a3906908af8496e063aa704d5b68b420957faf21 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 13:32:25 +0100 Subject: [PATCH 04/15] No need to wrap icon in createElement() --- assets/src/js/commands/admin-commands.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assets/src/js/commands/admin-commands.js b/assets/src/js/commands/admin-commands.js index a1670552..f924e874 100644 --- a/assets/src/js/commands/admin-commands.js +++ b/assets/src/js/commands/admin-commands.js @@ -12,8 +12,6 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { createElement } from '@wordpress/element'; -import { Icon } from '@wordpress/components'; import { dispatch } from '@wordpress/data'; import { addQueryArgs } from '@wordpress/url'; import { @@ -154,7 +152,7 @@ const registerAdminCommands = () => { commandStore.registerCommand( { name: 'scf/' + command.name, label: command.label, - icon: createElement( Icon, { icon: command.icon } ), + icon: command.icon, context: 'admin', keywords: command.keywords, callback: ( { close } ) => { From 08127b7a438ff890562be93dde129cef14a257b3 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 14:51:39 +0100 Subject: [PATCH 05/15] Fix command palette --- assets/src/js/commands/admin-commands.js | 26 ++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/assets/src/js/commands/admin-commands.js b/assets/src/js/commands/admin-commands.js index f924e874..1dedcfc5 100644 --- a/assets/src/js/commands/admin-commands.js +++ b/assets/src/js/commands/admin-commands.js @@ -12,7 +12,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { dispatch } from '@wordpress/data'; +import { dispatch, select } from '@wordpress/data'; import { addQueryArgs } from '@wordpress/url'; import { layout, @@ -29,10 +29,11 @@ import { * Register admin commands for SCF */ const registerAdminCommands = () => { - if ( ! dispatch( 'core/commands' ) || ! window.acf?.data ) { + if ( ! select( 'core/commands') || ! dispatch( 'core/commands' ) ) { return; } + const registeredCommands = select( 'core/commands' ).getCommands(); const commandStore = dispatch( 'core/commands' ); const viewCommands = [ @@ -166,13 +167,22 @@ const registerAdminCommands = () => { }; // WordPress 6.9+ adds Command Palette commands for all admin menu items. - const wpVersion = window.acf.data.wp_version; - const isWp69Plus = - wpVersion.localeCompare( '6.9', undefined, { numeric: true } ) >= 0; + // For older versions, we need to register them manually. The most reliable way to + // detect this is to check if the commands are already registered. + viewCommands.forEach( ( command ) => { + const commandUrl = addQueryArgs( command.url, command.urlArgs ); + // WordPress stores destination URLs in the command *name*, appended to + // the menu slug (which is also a relative URL), resulting in somewhat + // peculiar naming, e.g. + // edit.php?post_type=acf-field-group-edit.php?post_type=acf-ui-options-page + if ( registeredCommands.some( ( cmd ) => cmd.name.endsWith( commandUrl ) ) ) { + return; + } + registerCommand( command ); + } ); - if ( ! isWp69Plus ) { - viewCommands.forEach( registerCommand ); - } + // "Create New" commands are not automatically registered by WordPress, + // so we always register them. createCommands.forEach( registerCommand ); }; From bc1b69d7eda4bb21cb86d55136df37224a91bb8c Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 15:13:38 +0100 Subject: [PATCH 06/15] Add e2e test coverage --- tests/e2e/command-palette.spec.ts | 78 +++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 tests/e2e/command-palette.spec.ts diff --git a/tests/e2e/command-palette.spec.ts b/tests/e2e/command-palette.spec.ts new file mode 100644 index 00000000..5053b208 --- /dev/null +++ b/tests/e2e/command-palette.spec.ts @@ -0,0 +1,78 @@ +/** + * Internal dependencies + */ +const { test, expect } = require( './fixtures' ); + +test.describe( 'Command Palette', () => { + test.beforeAll( async ( { requestUtils } ) => { + await requestUtils.activatePlugin( 'secure-custom-fields' ); + } ); + + test.afterAll( async ( { requestUtils } ) => { + await requestUtils.deactivatePlugin( 'secure-custom-fields' ); + } ); + + test( 'should register SCF create commands', async ( { page, admin } ) => { + await admin.visitAdminPage( 'index.php' ); + + // Open the command palette via keyboard shortcut. + await page.keyboard.press( 'Meta+k' ); + + const input = page.getByRole( 'combobox', { + name: 'Search commands and settings', + } ); + await expect( input ).toBeVisible(); + + // Search for a create command — these are always registered by SCF. + await input.fill( 'Create New Field Group' ); + await expect( + page.getByRole( 'option', { name: /Create New Field Group/ } ) + ).toBeVisible(); + } ); + + test( 'should register SCF view commands without duplicates', async ( { + page, + admin, + } ) => { + await admin.visitAdminPage( 'index.php' ); + + await page.keyboard.press( 'Meta+k' ); + + const input = page.getByRole( 'combobox', { + name: 'Search commands and settings', + } ); + + // Search for a view command that exists in both WP's auto-registered + // admin menu commands and SCF's view commands list. + await input.fill( 'Field Groups' ); + + const options = page.getByRole( 'option', { + name: /Field Groups/, + } ); + + // There should be exactly one match, not two (no duplicate). + await expect( options ).toHaveCount( 1 ); + } ); + + test( 'should navigate to field groups via command palette', async ( { + page, + admin, + } ) => { + await admin.visitAdminPage( 'index.php' ); + + await page.keyboard.press( 'Meta+k' ); + + const input = page.getByRole( 'combobox', { + name: 'Search commands and settings', + } ); + + await input.fill( 'Field Groups' ); + await page + .getByRole( 'option', { name: /Field Groups/ } ) + .click(); + + await expect( page ).toHaveURL( + /edit\.php\?post_type=acf-field-group/ + ); + } ); +} ); From ef6daf8d557f245204819de63e26c3d1d56f00c3 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 15:27:23 +0100 Subject: [PATCH 07/15] Remove admin-commands unit tests --- tests/js/commands/admin-commands.test.js | 86 ------------------------ 1 file changed, 86 deletions(-) delete mode 100644 tests/js/commands/admin-commands.test.js diff --git a/tests/js/commands/admin-commands.test.js b/tests/js/commands/admin-commands.test.js deleted file mode 100644 index 8e5d8d9f..00000000 --- a/tests/js/commands/admin-commands.test.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Unit tests for admin commands version-based registration - */ - -let mockCommandStore = null; - -jest.mock( '@wordpress/data', () => ( { - dispatch: jest.fn( () => mockCommandStore ), -} ) ); - -jest.mock( '@wordpress/i18n', () => ( { __: ( str ) => str } ) ); -jest.mock( '@wordpress/element', () => ( { createElement: jest.fn() } ) ); -jest.mock( '@wordpress/components', () => ( { Icon: 'Icon' } ) ); -jest.mock( '@wordpress/url', () => ( { addQueryArgs: jest.fn() } ) ); -jest.mock( '@wordpress/icons', () => ( { - layout: 'icon', - plus: 'icon', - postList: 'icon', - category: 'icon', - settings: 'icon', - tool: 'icon', - upload: 'icon', - download: 'icon', -} ) ); - -describe( 'Admin Commands', () => { - let mockRegisterCommand; - let capturedCallback; - - beforeEach( () => { - jest.clearAllMocks(); - jest.resetModules(); - mockRegisterCommand = jest.fn(); - mockCommandStore = { registerCommand: mockRegisterCommand }; - window.requestIdleCallback = jest.fn( ( cb ) => { - capturedCallback = cb; - } ); - } ); - - // 7 viewCommands + 4 createCommands = 11 on WP < 6.9 - // 4 createCommands only on WP 6.9+ (viewCommands skipped) - it.each( [ - [ '6.8', 11 ], - [ '6.8.1', 11 ], - [ '6.9', 4 ], - [ '6.9-beta1', 4 ], - [ '6.9.1', 4 ], - [ '7.0', 4 ], - ] )( 'WP %s registers %i commands', async ( wpVersion, expectedCount ) => { - window.acf = { - data: { - admin_url: 'http://example.com/wp-admin/', - wp_version: wpVersion, - }, - }; - - await import( '../../../assets/src/js/commands/admin-commands.js' ); - capturedCallback(); - - expect( mockRegisterCommand ).toHaveBeenCalledTimes( expectedCount ); - } ); - - it( 'WP 6.9+ skips view commands but keeps create commands', async () => { - window.acf = { - data: { - admin_url: 'http://example.com/wp-admin/', - wp_version: '6.9', - }, - }; - - await import( '../../../assets/src/js/commands/admin-commands.js' ); - capturedCallback(); - - const names = mockRegisterCommand.mock.calls.map( - ( c ) => c[ 0 ].name - ); - - // View commands should NOT be registered - expect( names ).not.toContain( 'scf/field-groups' ); - expect( names ).not.toContain( 'scf/post-types' ); - - // Create commands should be registered - expect( names ).toContain( 'scf/new-field-group' ); - expect( names ).toContain( 'scf/new-post-type' ); - } ); -} ); From 88e0ad03750e652585f1a6e9279f90fae930aaa3 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 15:28:09 +0100 Subject: [PATCH 08/15] TEMPORARY: Include WP 6.2 in test matrix --- .github/workflows/e2e.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 2b113193..8691a8ef 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -35,8 +35,6 @@ jobs: # On trunk: full matrix with node 24 and minimum WP version - event: 'pull_request' node: '24' - - event: 'pull_request' - wp: '6.2' env: WP_ENV_CORE: ${{ matrix.wp == 'trunk' && 'WordPress/WordPress' || (matrix.wp != 'latest' && format('WordPress/WordPress#{0}', matrix.wp) || null) }} From 980289b414ee31acbd3e5c91098553e7122da564 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 15:34:56 +0100 Subject: [PATCH 09/15] No need to prepend adminUrl --- assets/src/js/commands/custom-post-type-commands.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/assets/src/js/commands/custom-post-type-commands.js b/assets/src/js/commands/custom-post-type-commands.js index 1240996b..03470a5b 100644 --- a/assets/src/js/commands/custom-post-type-commands.js +++ b/assets/src/js/commands/custom-post-type-commands.js @@ -34,7 +34,6 @@ const registerPostTypeCommands = () => { } const commandStore = dispatch( 'core/commands' ); - const adminUrl = window.acf.data.admin_url || ''; const postTypes = window.acf.data.customPostTypes; // WordPress 6.9+ adds Command Palette commands for all admin menu items. @@ -69,7 +68,7 @@ const registerPostTypeCommands = () => { postType.label, ].filter( Boolean ), callback: ( { close } ) => { - document.location = addQueryArgs( adminUrl + 'edit.php', { + document.location = addQueryArgs( 'edit.php', { post_type: postType.name, } ); close(); @@ -93,7 +92,7 @@ const registerPostTypeCommands = () => { ], callback: ( { close } ) => { document.location = addQueryArgs( - adminUrl + 'post-new.php', + 'post-new.php', { post_type: postType.name, } @@ -128,7 +127,7 @@ const registerPostTypeCommands = () => { postType.label, ], callback: ( { close } ) => { - document.location = addQueryArgs( adminUrl + 'post.php', { + document.location = addQueryArgs( 'post.php', { post: postType.id, action: 'edit', } ); From 84088dcfc77ba19da1f4c83ce51419534ec91cb4 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 15:36:40 +0100 Subject: [PATCH 10/15] Remove description field --- assets/src/js/commands/custom-post-type-commands.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/assets/src/js/commands/custom-post-type-commands.js b/assets/src/js/commands/custom-post-type-commands.js index 03470a5b..666fdc68 100644 --- a/assets/src/js/commands/custom-post-type-commands.js +++ b/assets/src/js/commands/custom-post-type-commands.js @@ -59,7 +59,6 @@ const registerPostTypeCommands = () => { label: postType.all_items, icon: createElement( Icon, { icon: page } ), context: 'admin', - description: postType.all_items, keywords: [ 'post type', 'content', @@ -81,7 +80,6 @@ const registerPostTypeCommands = () => { label: postType.add_new_item, icon: createElement( Icon, { icon: plus } ), context: 'admin', - description: postType.add_new_item, keywords: [ 'add', 'new', @@ -112,11 +110,6 @@ const registerPostTypeCommands = () => { ), icon: createElement( Icon, { icon: edit } ), context: 'admin', - description: sprintf( - /* translators: %s: post type label */ - __( 'Edit the %s post type settings', 'secure-custom-fields' ), - postType.label - ), keywords: [ 'edit', 'modify', From 3b6b1f379568222ac6f2924d93dc68d291b3ac36 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 15:37:48 +0100 Subject: [PATCH 11/15] No need for createElement --- assets/src/js/commands/custom-post-type-commands.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/assets/src/js/commands/custom-post-type-commands.js b/assets/src/js/commands/custom-post-type-commands.js index 666fdc68..8f4a611c 100644 --- a/assets/src/js/commands/custom-post-type-commands.js +++ b/assets/src/js/commands/custom-post-type-commands.js @@ -15,8 +15,6 @@ * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; -import { createElement } from '@wordpress/element'; -import { Icon } from '@wordpress/components'; import { dispatch } from '@wordpress/data'; import { addQueryArgs } from '@wordpress/url'; import { page, plus, edit } from '@wordpress/icons'; @@ -57,7 +55,7 @@ const registerPostTypeCommands = () => { commandStore.registerCommand( { name: `scf/cpt-${ postType.name }`, label: postType.all_items, - icon: createElement( Icon, { icon: page } ), + icon: page, context: 'admin', keywords: [ 'post type', @@ -78,7 +76,7 @@ const registerPostTypeCommands = () => { commandStore.registerCommand( { name: `scf/new-${ postType.name }`, label: postType.add_new_item, - icon: createElement( Icon, { icon: plus } ), + icon: plus, context: 'admin', keywords: [ 'add', @@ -108,7 +106,7 @@ const registerPostTypeCommands = () => { __( 'Edit post type: %s', 'secure-custom-fields' ), postType.label ), - icon: createElement( Icon, { icon: edit } ), + icon: edit, context: 'admin', keywords: [ 'edit', From 7d3e8aab7f3f1b178554a1bc2d9663e5674f8df6 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 17:40:38 +0100 Subject: [PATCH 12/15] Fix command palette shortcut in e2e tests --- tests/e2e/command-palette.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/command-palette.spec.ts b/tests/e2e/command-palette.spec.ts index 5053b208..79e23af3 100644 --- a/tests/e2e/command-palette.spec.ts +++ b/tests/e2e/command-palette.spec.ts @@ -16,7 +16,7 @@ test.describe( 'Command Palette', () => { await admin.visitAdminPage( 'index.php' ); // Open the command palette via keyboard shortcut. - await page.keyboard.press( 'Meta+k' ); + await page.keyboard.press( 'ControlOrMeta+k' ); const input = page.getByRole( 'combobox', { name: 'Search commands and settings', @@ -36,7 +36,7 @@ test.describe( 'Command Palette', () => { } ) => { await admin.visitAdminPage( 'index.php' ); - await page.keyboard.press( 'Meta+k' ); + await page.keyboard.press( 'ControlOrMeta+k' ); const input = page.getByRole( 'combobox', { name: 'Search commands and settings', @@ -60,7 +60,7 @@ test.describe( 'Command Palette', () => { } ) => { await admin.visitAdminPage( 'index.php' ); - await page.keyboard.press( 'Meta+k' ); + await page.keyboard.press( 'ControlOrMeta+k' ); const input = page.getByRole( 'combobox', { name: 'Search commands and settings', From bc39aad81cd0252092b014895816d7d3bfcd7744 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 20:23:32 +0100 Subject: [PATCH 13/15] Fix wpVersionAtLeast test util --- tests/e2e/fixtures.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e/fixtures.js b/tests/e2e/fixtures.js index 8674f328..7c93e076 100644 --- a/tests/e2e/fixtures.js +++ b/tests/e2e/fixtures.js @@ -177,13 +177,13 @@ const test = wpTest.extend( { async function wpVersionAtLeast( page, major, minor ) { return page.evaluate( ( [ maj, min ] ) => { - const branchClass = [ ...document.body.classList ].find( ( c ) => - c.startsWith( 'branch-' ) + const versionClass = [ ...document.body.classList ].find( ( c ) => + c.startsWith( 'version-' ) ); - if ( ! branchClass ) { + if ( ! versionClass ) { return true; } - const match = branchClass.match( /branch-(\d+)-(\d+)/ ); + const match = versionClass.match( /version-(\d+)-(\d+)/ ); if ( ! match ) { return true; } From ebf97f3ef47f3b6ab849a638ab498c149ecaa8ec Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 20:24:23 +0100 Subject: [PATCH 14/15] Skip command palette tests on WP < 6.9 --- tests/e2e/command-palette.spec.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/e2e/command-palette.spec.ts b/tests/e2e/command-palette.spec.ts index 79e23af3..e082786e 100644 --- a/tests/e2e/command-palette.spec.ts +++ b/tests/e2e/command-palette.spec.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -const { test, expect } = require( './fixtures' ); +const { test, expect, wpVersionAtLeast } = require( './fixtures' ); test.describe( 'Command Palette', () => { test.beforeAll( async ( { requestUtils } ) => { @@ -14,6 +14,10 @@ test.describe( 'Command Palette', () => { test( 'should register SCF create commands', async ( { page, admin } ) => { await admin.visitAdminPage( 'index.php' ); + test.skip( + ! ( await wpVersionAtLeast( page, 6, 3 ) ), + 'Command Palette requires WordPress 6.3+' + ); // Open the command palette via keyboard shortcut. await page.keyboard.press( 'ControlOrMeta+k' ); @@ -35,6 +39,10 @@ test.describe( 'Command Palette', () => { admin, } ) => { await admin.visitAdminPage( 'index.php' ); + test.skip( + ! ( await wpVersionAtLeast( page, 6, 3 ) ), + 'Command Palette requires WordPress 6.3+' + ); await page.keyboard.press( 'ControlOrMeta+k' ); @@ -59,6 +67,11 @@ test.describe( 'Command Palette', () => { admin, } ) => { await admin.visitAdminPage( 'index.php' ); + // Command Palette was introduced in WordPress 6.3 + test.skip( + ! ( await wpVersionAtLeast( page, 6, 3 ) ), + 'Command Palette requires WordPress 6.3+' + ); await page.keyboard.press( 'ControlOrMeta+k' ); From 6b2802372c6ddf6ba16539503d8ef79a91a07ab1 Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 26 Mar 2026 20:24:59 +0100 Subject: [PATCH 15/15] TEMPORARY: Extend test matrix --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 8691a8ef..cce9aa34 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -29,7 +29,7 @@ jobs: event: ['${{ github.event_name }}'] shard: [1, 2, 3, 4] node: ['22', '24'] - wp: ['6.2', 'latest', 'trunk'] + wp: ['6.2', '6.3', '6.8', 'latest', 'trunk'] exclude: # On PRs: only test Node 22 + WP latest and trunk for fast feedback # On trunk: full matrix with node 24 and minimum WP version