diff --git a/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap b/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap
deleted file mode 100644
index 9e4a5ac3ad6f6..0000000000000
--- a/packages/e2e-tests/specs/editor/plugins/__snapshots__/plugins-api.test.js.snap
+++ /dev/null
@@ -1,7 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Using Plugins API Document Setting Custom Panel Should render a custom panel inside Document Setting sidebar 1`] = `"My Custom Panel"`;
-
-exports[`Using Plugins API Sidebar Medium screen Should open plugins sidebar using More Menu item and render content 1`] = `"
"`;
-
-exports[`Using Plugins API Sidebar Should open plugins sidebar using More Menu item and render content 1`] = `""`;
diff --git a/packages/e2e-tests/specs/editor/plugins/plugins-api.test.js b/packages/e2e-tests/specs/editor/plugins/plugins-api.test.js
deleted file mode 100644
index 4ad8d0e634204..0000000000000
--- a/packages/e2e-tests/specs/editor/plugins/plugins-api.test.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/**
- * WordPress dependencies
- */
-import {
- activatePlugin,
- clickBlockAppender,
- clickOnMoreMenuItem,
- createNewPost,
- deactivatePlugin,
- openDocumentSettingsSidebar,
- openPublishPanel,
- publishPost,
- setBrowserViewport,
-} from '@wordpress/e2e-test-utils';
-
-describe( 'Using Plugins API', () => {
- beforeAll( async () => {
- await activatePlugin( 'gutenberg-test-plugin-plugins-api' );
- } );
-
- afterAll( async () => {
- await deactivatePlugin( 'gutenberg-test-plugin-plugins-api' );
- } );
-
- beforeEach( async () => {
- await createNewPost();
- } );
-
- describe( 'Post Status Info', () => {
- it( 'Should render post status info inside Document Setting sidebar', async () => {
- await openDocumentSettingsSidebar();
-
- const pluginPostStatusInfoText = await page.$eval(
- '.edit-post-post-status .my-post-status-info-plugin',
- ( el ) => el.innerText
- );
- expect( pluginPostStatusInfoText ).toBe( 'My post status info' );
- } );
- } );
-
- describe( 'Publish Panel', () => {
- beforeEach( async () => {
- // Type something first to activate Publish button.
- await clickBlockAppender();
- await page.keyboard.type( 'First paragraph' );
- } );
-
- it( 'Should render publish panel inside Pre-publish sidebar', async () => {
- await openPublishPanel();
-
- const pluginPublishPanelText = await page.$eval(
- '.editor-post-publish-panel .my-publish-panel-plugin__pre',
- ( el ) => el.innerText
- );
- expect( pluginPublishPanelText ).toMatch( 'My pre publish panel' );
- } );
-
- it( 'Should render publish panel inside Post-publish sidebar', async () => {
- await publishPost();
- const pluginPublishPanel = await page.waitForSelector(
- '.editor-post-publish-panel .my-publish-panel-plugin__post'
- );
- const pluginPublishPanelText = await pluginPublishPanel.evaluate(
- ( node ) => node.innerText
- );
- expect( pluginPublishPanelText ).toMatch( 'My post publish panel' );
- } );
- } );
-
- describe( 'Sidebar', () => {
- const SIDEBAR_PINNED_ITEM_BUTTON =
- '.interface-pinned-items button[aria-label="Plugin title"]';
- const SIDEBAR_PANEL_SELECTOR = '.sidebar-title-plugin-panel';
- it( 'Should open plugins sidebar using More Menu item and render content', async () => {
- await clickOnMoreMenuItem( 'Plugin more menu title' );
-
- const pluginSidebarContent = await page.$eval(
- '.edit-post-sidebar',
- ( el ) => el.innerHTML
- );
- expect( pluginSidebarContent ).toMatchSnapshot();
- } );
-
- it( 'Should be pinned by default and can be opened and closed using pinned items', async () => {
- const sidebarPinnedItem = await page.$(
- SIDEBAR_PINNED_ITEM_BUTTON
- );
- expect( sidebarPinnedItem ).not.toBeNull();
- await sidebarPinnedItem.click();
- expect( await page.$( SIDEBAR_PANEL_SELECTOR ) ).not.toBeNull();
- await sidebarPinnedItem.click();
- expect( await page.$( SIDEBAR_PANEL_SELECTOR ) ).toBeNull();
- } );
-
- it( 'Can be pinned and unpinned', async () => {
- await ( await page.$( SIDEBAR_PINNED_ITEM_BUTTON ) ).click();
- const unpinButton = await page.$(
- 'button[aria-label="Unpin from toolbar"]'
- );
- await unpinButton.click();
- expect( await page.$( SIDEBAR_PINNED_ITEM_BUTTON ) ).toBeNull();
- await page.click(
- '.interface-complementary-area-header button[aria-label="Close plugin"]'
- );
- await page.reload();
- await page.waitForSelector( '.edit-post-layout' );
- expect( await page.$( SIDEBAR_PINNED_ITEM_BUTTON ) ).toBeNull();
- await clickOnMoreMenuItem( 'Plugin more menu title' );
- await page.click( 'button[aria-label="Pin to toolbar"]' );
- expect( await page.$( SIDEBAR_PINNED_ITEM_BUTTON ) ).not.toBeNull();
- await page.reload();
- await page.waitForSelector( '.edit-post-layout' );
- expect( await page.$( SIDEBAR_PINNED_ITEM_BUTTON ) ).not.toBeNull();
- } );
-
- it( 'Should close plugins sidebar using More Menu item', async () => {
- await clickOnMoreMenuItem( 'Plugin more menu title' );
-
- const pluginSidebarOpened = await page.$( '.edit-post-sidebar' );
- expect( pluginSidebarOpened ).not.toBeNull();
-
- await clickOnMoreMenuItem( 'Plugin more menu title' );
-
- const pluginSidebarClosed = await page.$( '.edit-post-sidebar' );
- expect( pluginSidebarClosed ).toBeNull();
- } );
-
- describe( 'Medium screen', () => {
- beforeAll( async () => {
- await setBrowserViewport( 'medium' );
- } );
-
- afterAll( async () => {
- await setBrowserViewport( 'large' );
- } );
-
- it( 'Should open plugins sidebar using More Menu item and render content', async () => {
- await clickOnMoreMenuItem( 'Plugin more menu title' );
-
- const pluginSidebarContent = await page.$eval(
- '.edit-post-sidebar',
- ( el ) => el.innerHTML
- );
- expect( pluginSidebarContent ).toMatchSnapshot();
- } );
- } );
- } );
-
- describe( 'Document Setting Custom Panel', () => {
- it( 'Should render a custom panel inside Document Setting sidebar', async () => {
- await openDocumentSettingsSidebar();
- const pluginDocumentSettingsText = await page.$eval(
- '.edit-post-sidebar .my-document-setting-plugin',
- ( el ) => el.innerText
- );
- expect( pluginDocumentSettingsText ).toMatchSnapshot();
- } );
- } );
-
- describe( 'Error Boundary', () => {
- beforeAll( async () => {
- await activatePlugin(
- 'gutenberg-test-plugin-plugins-error-boundary'
- );
- } );
-
- afterAll( async () => {
- await deactivatePlugin(
- 'gutenberg-test-plugin-plugins-error-boundary'
- );
- } );
-
- it( 'Should create notice using plugin error boundary callback', async () => {
- const noticeContent = await page.waitForSelector(
- '.is-error .components-notice__content'
- );
- expect(
- await page.evaluate(
- ( _noticeContent ) => _noticeContent.firstChild.nodeValue,
- noticeContent
- )
- ).toEqual(
- 'The "my-error-plugin" plugin has encountered an error and cannot be rendered.'
- );
-
- expect( console ).toHaveErrored();
- } );
- } );
-} );
diff --git a/test/e2e/specs/editor/plugins/plugins-api-error-boundary.spec.js b/test/e2e/specs/editor/plugins/plugins-api-error-boundary.spec.js
new file mode 100644
index 0000000000000..25f528be8a008
--- /dev/null
+++ b/test/e2e/specs/editor/plugins/plugins-api-error-boundary.spec.js
@@ -0,0 +1,38 @@
+/**
+ * WordPress dependencies
+ */
+const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
+
+test.describe( 'Plugins API Error Boundary', () => {
+ test.beforeAll( async ( { requestUtils } ) => {
+ await requestUtils.activatePlugin(
+ 'gutenberg-test-plugin-plugins-error-boundary'
+ );
+ } );
+
+ test.afterAll( async ( { requestUtils } ) => {
+ await requestUtils.deactivatePlugin(
+ 'gutenberg-test-plugin-plugins-error-boundary'
+ );
+ } );
+
+ test( 'Should create notice using plugin error boundary callback', async ( {
+ admin,
+ page,
+ } ) => {
+ let hasError = false;
+ page.on( 'console', ( msg ) => {
+ if ( msg.type() === 'error' && msg.text().includes( 'Whoops!' ) )
+ hasError = true;
+ } );
+
+ await admin.createNewPost();
+
+ expect( hasError ).toBe( true );
+ await expect(
+ page.locator( '.is-error .components-notice__content' )
+ ).toContainText(
+ 'The "my-error-plugin" plugin has encountered an error and cannot be rendered.'
+ );
+ } );
+} );
diff --git a/test/e2e/specs/editor/plugins/plugins-api.spec.js b/test/e2e/specs/editor/plugins/plugins-api.spec.js
new file mode 100644
index 0000000000000..c71b49e3c4d81
--- /dev/null
+++ b/test/e2e/specs/editor/plugins/plugins-api.spec.js
@@ -0,0 +1,233 @@
+/**
+ * WordPress dependencies
+ */
+const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );
+
+test.describe( 'Plugins API', () => {
+ test.beforeAll( async ( { requestUtils } ) => {
+ await requestUtils.activatePlugin(
+ 'gutenberg-test-plugin-plugins-api'
+ );
+ } );
+
+ test.beforeEach( async ( { admin } ) => {
+ await admin.createNewPost();
+ } );
+
+ test.afterAll( async ( { requestUtils } ) => {
+ await requestUtils.deactivatePlugin(
+ 'gutenberg-test-plugin-plugins-api'
+ );
+ } );
+
+ test.describe( 'Post Status Info', () => {
+ test( 'Should render post status info inside Document Setting sidebar', async ( {
+ editor,
+ page,
+ } ) => {
+ await editor.openDocumentSettingsSidebar();
+
+ await expect(
+ page
+ .getByRole( 'region', { name: 'Editor settings' } )
+ .locator( '.my-post-status-info-plugin' )
+ ).toHaveText( 'My post status info' );
+ } );
+ } );
+
+ test.describe( 'Publish Panel', () => {
+ test( 'Should render publish panel inside Pre-publish sidebar', async ( {
+ editor,
+ page,
+ } ) => {
+ await editor.canvas
+ .getByRole( 'textbox', { name: 'Add title' } )
+ .fill( 'A post' );
+
+ // Open pre-publish panel.
+ await page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'button', { name: 'Publish' } )
+ .click();
+
+ await expect(
+ page
+ .getByRole( 'region', { name: 'Editor publish' } )
+ .getByRole( 'button', { name: 'My pre publish panel' } )
+ ).toBeVisible();
+ } );
+
+ test( 'Should render publish panel inside Post-publish sidebar', async ( {
+ editor,
+ page,
+ } ) => {
+ await editor.canvas
+ .getByRole( 'textbox', { name: 'Add title' } )
+ .fill( 'A post' );
+ await editor.publishPost();
+
+ await expect(
+ page
+ .getByRole( 'region', { name: 'Editor publish' } )
+ .getByRole( 'button', { name: 'My post publish panel' } )
+ ).toBeVisible();
+ } );
+ } );
+
+ test.describe( 'Sidebar', () => {
+ test( 'Should open plugins sidebar using More Menu item and render content', async ( {
+ page,
+ } ) => {
+ await page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'button', { name: 'Options' } )
+ .click();
+ await page
+ .getByRole( 'menuitemcheckbox', {
+ name: 'Plugin more menu title',
+ } )
+ .click();
+
+ const settingsSidebar = page.getByRole( 'region', {
+ name: 'Editor settings',
+ } );
+
+ await expect(
+ settingsSidebar.getByRole( 'textbox', {
+ name: 'Title',
+ } )
+ ).toBeVisible();
+ await expect(
+ settingsSidebar.getByRole( 'button', {
+ name: 'Reset',
+ } )
+ ).toBeVisible();
+ } );
+
+ test( 'Should be pinned by default and can be opened and closed using pinned items', async ( {
+ page,
+ } ) => {
+ const pinnedButton = page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'button', { name: 'Plugin title' } );
+ const pluginField = page
+ .getByRole( 'region', {
+ name: 'Editor settings',
+ } )
+ .getByRole( 'textbox', {
+ name: 'Title',
+ } );
+
+ await pinnedButton.click();
+ await expect( pluginField ).toBeVisible();
+
+ await pinnedButton.click();
+ await expect( pluginField ).toBeHidden();
+ } );
+
+ test( 'Can be pinned and unpinned', async ( { page } ) => {
+ const pinnedButton = page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'button', { name: 'Plugin title' } );
+
+ await pinnedButton.click();
+ await page
+ .getByRole( 'button', { name: 'Unpin from toolbar' } )
+ .click();
+
+ await expect( pinnedButton ).toBeHidden();
+
+ await page.getByRole( 'button', { name: 'Close plugin' } ).click();
+ await page.reload();
+
+ await expect( pinnedButton ).toBeHidden();
+
+ await page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'button', { name: 'Options' } )
+ .click();
+ await page
+ .getByRole( 'menuitemcheckbox', {
+ name: 'Plugin more menu title',
+ } )
+ .click();
+ await page
+ .getByRole( 'button', { name: 'Pin to toolbar' } )
+ .click();
+
+ await expect( pinnedButton ).toBeVisible();
+ await page.reload();
+ await expect( pinnedButton ).toBeVisible();
+ } );
+
+ test( 'Should close plugins sidebar using More Menu item', async ( {
+ page,
+ } ) => {
+ const options = page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'button', { name: 'Options' } );
+ const moreMenuItem = page.getByRole( 'menuitemcheckbox', {
+ name: 'Plugin more menu title',
+ } );
+ const pluginField = page
+ .getByRole( 'region', {
+ name: 'Editor settings',
+ } )
+ .getByRole( 'textbox', {
+ name: 'Title',
+ } );
+
+ await options.click();
+ await moreMenuItem.click();
+ await expect( pluginField ).toBeVisible();
+
+ await options.click();
+ await moreMenuItem.click();
+ await expect( pluginField ).toBeHidden();
+ } );
+
+ test( 'Should open plugins sidebar using More Menu item on smaller screens', async ( {
+ page,
+ pageUtils,
+ } ) => {
+ await pageUtils.setBrowserViewport( 'medium' );
+
+ await page
+ .getByRole( 'region', { name: 'Editor top bar' } )
+ .getByRole( 'button', { name: 'Options' } )
+ .click();
+ await page
+ .getByRole( 'menuitemcheckbox', {
+ name: 'Plugin more menu title',
+ } )
+ .click();
+
+ await expect(
+ page
+ .getByRole( 'region', {
+ name: 'Editor settings',
+ } )
+ .getByRole( 'textbox', {
+ name: 'Title',
+ } )
+ ).toBeVisible();
+
+ await pageUtils.setBrowserViewport( 'large' );
+ } );
+ } );
+
+ test.describe( 'Document Setting Custom Panel', () => {
+ test( 'Should render a custom panel inside Document Setting sidebar', async ( {
+ editor,
+ page,
+ } ) => {
+ await editor.openDocumentSettingsSidebar();
+
+ await expect(
+ page
+ .getByRole( 'region', { name: 'Editor settings' } )
+ .getByRole( 'button', { name: 'My Custom Panel' } )
+ ).toBeVisible();
+ } );
+ } );
+} );