Commit 3b385853330 for woocommerce
commit 3b38585333098025113f42d2e1ca46a54d78954e
Author: Brandon Kraft <public@brandonkraft.com>
Date: Tue Aug 4 09:29:52 2026 -0600
e2e-utils-playwright: harden getCanvas beyond trunk's iframe wait (#65326)
diff --git a/packages/js/e2e-utils-playwright/changelog/fix-get-canvas-iframe-wait b/packages/js/e2e-utils-playwright/changelog/fix-get-canvas-iframe-wait
new file mode 100644
index 00000000000..c6a76deb823
--- /dev/null
+++ b/packages/js/e2e-utils-playwright/changelog/fix-get-canvas-iframe-wait
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Harden `getCanvas` so the non-iframed editor path also waits for the canvas, hidden leftover iframes are ignored, and a missing canvas fails loudly instead of silently resolving to the wrong document.
diff --git a/packages/js/e2e-utils-playwright/src/editor.ts b/packages/js/e2e-utils-playwright/src/editor.ts
index d0593de65f9..13099b0760f 100644
--- a/packages/js/e2e-utils-playwright/src/editor.ts
+++ b/packages/js/e2e-utils-playwright/src/editor.ts
@@ -92,26 +92,35 @@ export const openEditorSettings = async ( {
/**
* Returns the editor canvas frame for Gutenberg interactions.
*
- * The Gutenberg editor content can be contained within an iframe in some contexts.
- * This helper function returns the content frame of the editor canvas iframe if it exists,
- * or falls back to the main page if the iframe isn't present.
+ * The Gutenberg editor mounts either inside an `iframe[name="editor-canvas"]`
+ * (modern site/post editor) or directly on the outer page (non-iframed
+ * contexts, e.g. accessibility mode). Recent Gutenberg
+ * builds mount the iframe slightly after initial paint, so callers that resolve
+ * the canvas before the iframe attaches end up running locators against the
+ * outer page and timing out inside the editor.
+ *
+ * Resolves as soon as either surface becomes visible, using a union selector
+ * so neither path incurs a hardcoded probe timeout. If neither surface appears
+ * within Playwright's default timeout, the underlying `waitFor` throws and the
+ * test fails loudly rather than silently degrading to the wrong document.
*
* @param page - The Playwright page object
* @return The editor canvas frame or the original page
*/
export const getCanvas = async ( page: Page ): Promise< EditorCanvas > => {
- const iframeLocator = page.locator( 'iframe[name="editor-canvas"]' );
- await iframeLocator.waitFor( { state: 'attached' } ).catch( ( error ) => {
- console.warn(
- 'The editor canvas iframe was not found. Falling back to the page context.',
- error
- );
- } );
+ const canvasLocator = page
+ .locator(
+ 'iframe[name="editor-canvas"]:visible, .wp-block-post-content:visible'
+ )
+ .first();
- if ( ( await iframeLocator.count() ) > 0 ) {
- return iframeLocator.contentFrame();
- }
- return page;
+ await canvasLocator.waitFor();
+
+ const isFramed = await canvasLocator.evaluate(
+ ( node ) => node.tagName === 'IFRAME'
+ );
+
+ return isFramed ? canvasLocator.contentFrame() : page;
};
/**