Skip to content

Upgrade Playwright to v1.60#78632

Open
Mamaduka wants to merge 7 commits into
trunkfrom
upgrade/playwright-latest
Open

Upgrade Playwright to v1.60#78632
Mamaduka wants to merge 7 commits into
trunkfrom
upgrade/playwright-latest

Conversation

@Mamaduka

Copy link
Copy Markdown
Member

What?

Upgrade Playwright to v1.60.

What's new?

https://playwright.dev/docs/release-notes#version-160

I think new page.locator('#dropzone').drop could be useful for our tests. I'll start looking into migrations as a follow-up. The new description option could also be handy.

Testing Instructions

  • Run any e2e test locally; the command should download new browsers and run the test successfully.
  • CI checks are green.

@Mamaduka Mamaduka self-assigned this May 25, 2026
@Mamaduka Mamaduka added the [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. label May 25, 2026
@Mamaduka Mamaduka requested review from jsnajdr and manzoorwanijk May 25, 2026 11:14

@jsnajdr jsnajdr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good idea, should cause no trouble. The other day I did an upgrade from 1.58 to 1.59 locally, in an attempt to find a bug, but never committed it as a PR.

@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: adamsilverstein <adamsilverstein@git.wordpress.org>
Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
Co-authored-by: manzoorwanijk <manzoorwanijk@git.wordpress.org>
Co-authored-by: aduth <aduth@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

github-actions Bot commented May 25, 2026

Copy link
Copy Markdown

Size Change: +118 B (0%)

Total Size: 7.51 MB

📦 View Changed
Filename Size Change
build/scripts/editor/index.min.js 477 kB +118 B (+0.02%)

compressed-size-action

@Mamaduka Mamaduka enabled auto-merge (squash) May 25, 2026 11:27
@Mamaduka Mamaduka disabled auto-merge May 25, 2026 11:49
@Mamaduka Mamaduka force-pushed the upgrade/playwright-latest branch from c5ae24e to b1221cd Compare May 26, 2026 13:20
@Mamaduka Mamaduka force-pushed the upgrade/playwright-latest branch 2 times, most recently from d247f19 to 524f7a5 Compare June 10, 2026 07:40
@Mamaduka Mamaduka requested a review from spacedmonkey as a code owner June 10, 2026 07:40
@Mamaduka

Copy link
Copy Markdown
Member Author

It looks like previews end up with stale windows in the latest Chrome and DIP enabled. Pushed some test code for confirmations.

Here's the finding from Claude's debug sessions:

Summary

Playwright 1.60 ships Chrome for Testing 148 (1.58 used 145). The failing e2e tests aren't a test-infra issue — they're surfacing a Chromium 148 regression in Document-Isolation-Policy: isolate-and-credentialless (DIP), which Gutenberg sends on editor screens for Chromium ≥137 to get cross-origin isolation.

Proven by toggling the gutenberg_use_document_isolation_policy filter on the same Chrome 148:

Cluster DIP on (default) DIP off
Preview / block-context (window.open('', 'wp-preview-X') reuse) ❌ stale tab / waitForNavigation hangs ✅ pass
Client-side media processing ❌ silent server fallback ⏭️ skip (CSM needs isolation)
  • Preview: under DIP, Chrome 148 no longer re-navigates a reused named popup → preview shows stale content. DIP's spec says popups should keep working, so this is a genuine browser regression (closest public match: crbug 336222177). Likely affects real Chrome 148 users, not just CI.
  • CSM: same header is what enables crossOriginIsolated; a second 148 regression in the isolated/credentialless runtime makes the transcode silently fall back.
  • The Chrome 146/147/148 release notes document none of this.
**Playwright 1.60 ships Chrome for Testing 148** (1.58 used 145). The failing e2e tests aren't a test-infra issue — they're surfacing a **Chromium 148 regression in `Document-Isolation-Policy: isolate-and-credentialless`** (DIP), which Gutenberg sends on editor screens for Chromium ≥137 to get cross-origin isolation.

Proven by toggling the gutenberg_use_document_isolation_policy filter on the same Chrome 148:

Cluster DIP on (default) DIP off
Preview / block-context (window.open('', 'wp-preview-X') reuse) ❌ stale tab / waitForNavigation hangs ✅ pass
Client-side media processing ❌ silent server fallback ⏭️ skip (CSM needs isolation)
  • Preview: under DIP, Chrome 148 no longer re-navigates a reused named popup → preview shows stale content. DIP's spec says popups should keep working, so this is a genuine browser regression (closest public match: [crbug 336222177](https://issues.chromium.org/issues/336222177)). Likely affects real Chrome 148 users, not just CI.
  • CSM: same header is what enables crossOriginIsolated; a second 148 regression in the isolated/credentialless runtime makes the transcode silently fall back.
  • The Chrome 146/147/148 release notes document none of this.

@Mamaduka

Copy link
Copy Markdown
Member Author

I guess we can wait until the next release and see if the issue is fixed in the next Chrome upgrade

cc @adamsilverstein, just in case you've seen any similar reports.

@Mamaduka Mamaduka force-pushed the upgrade/playwright-latest branch from 524f7a5 to d102b08 Compare June 16, 2026 09:23
@Mamaduka Mamaduka force-pushed the upgrade/playwright-latest branch from d102b08 to 6433751 Compare June 16, 2026 09:40
},
"peerDependencies": {
"@playwright/test": "^1.58.2",
"@playwright/test": "^1.61.0",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Peer dependency should usually be the lowest supported version.

Also, IMHO, this peer dep here should be made optional, otherwise it breaks in strict peer deps mode for consumers.

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.

What's your recommendation?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Leave this unchanged and add the updated version as a dev dependency, as the package uses it but doesn't declare it and it receives the dependency from hoisting.

const { defineConfig, devices } = require( '@playwright/test' );

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Add this to peerDependenciesMeta below

"@playwright/test": {
	"optional": true
},

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.

Looking at the Git history, we've been bumping these versions alongside others. I don't remember exactly, but I think there were some version mismatches in the past on wordpress-develop.

P.S. I'm not against making those changes, mostly was double-checking previous updates.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yes, but it's better to go with best practices.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

CCing @jsnajdr and @aduth for their opinion.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

From my perspective, the peer dependency should be as wide as we can possibly allow based on what we actually need to use from this package or are fearful could break in how we use in future versions, even * or >=1. As best I can tell, that's whatever version provides a /cli export that accepts as 'test' argument and config flags and returns a 0 or non-0 status code, which is probably... all of them, forever? (i.e. *) We could add an upper bound like <= 2 or ^1 if we worry about those expectations breaking in a future major version.

The advantage being that this is a lot less annoying for downstream consumers. Why should someone have to bump their @playwright/test when upgrading @wordpress/scripts, if we're not actually doing anything in @wordpress/scripts that needs that newer version?

That's not to say we don't want to be using the same, consistent version across Gutenberg and/or wordpress-develop, but that's a project-level concern. We are our own consumer. So defining devDependencies with the higher version number makes sense so that we are using the one, newer version that has the new feature we want to use.

@manzoorwanijk

Copy link
Copy Markdown
Member

Heads up: Following #79221, we will need to update the dependency in root package.json as well.

@Mamaduka

Copy link
Copy Markdown
Member Author

It looks like Chrome and DIP issues still exist even after the recent Chromium version bump in Playwright - #78632 (comment).

That's a blocker for this update, until those issues are tested and resolved manually :(

@jsnajdr

jsnajdr commented Jun 17, 2026

Copy link
Copy Markdown
Member

I'm afraid that the Document-Isolation-Policy is a real Gutenberg bug that we'll need to address. The Playwright update merely surfaces it, by virtue of installing a newer Chrome.

When opening a preview (in openPreviewWindow) we do three steps:

  • window.open a new named tab, potentially reusing the already opened one.
  • writeInterstitialMessage( previewWindow.document ) uses the ancient document.write to render an animated WP logo while the preview is loading.
  • previewWindow.location = link forces a reload of the preview, with latest changes.

The code that crashes is the previewWindow.document access. If you comment out the writeInterstitialMessage call, the e2e test will be green again. Document-Isolation-Policy isolates the two windows (editor and preview) from each other, even if they are same-origin. And window.document is one of the things you can't touch any more. We'll have to write the interstitial in some less direct way, e.g., the preview window hosting the interstitial-writing script and receiving a message from the opener.

The https://issues.chromium.org/issues/336222177 bug is not really that related. It's about window.open not reusing the same tab, or window.location setter failing to navigate. None of that happens for us, our issue is the window.document access. Frankly this is fairly typical LLM debugging output, it's good at pointing you in the right direction, but there is often some subtle error, and a human judgment and review is needed to walk the last mile.

@gziolo gziolo removed their request for review June 17, 2026 10:11
@jsnajdr

jsnajdr commented Jun 17, 2026

Copy link
Copy Markdown
Member

Locally I'm able to fix the preview window error by adding these two lines before writeInterstitialMessage:

previewWindow.location = 'about:blank';
await new Promise( ( r ) => setTimeout( r, 100 ) );
writeInterstitialMessage( previewWindow.document );

The point is to reset the preview window location to about:blank because on this location the synchronous document access still works. That's why the first attempt to open the preview succeeds. Only the second one fails.

The 100ms wait is there to wait until the window really loads the new location. We can't add event listeners (load) to the window, so we need to wait. setTimeout( 0 ) is not long enough, but 100ms works.

If only we could tidy up this patch and make it production-ready, it would also fix the issue.

@adamsilverstein

Copy link
Copy Markdown
Member

I'm afraid that the Document-Isolation-Policy is a real Gutenberg bug that we'll need to address.

Catching up here... DIP shouldn't be active on previews, are you seeing it active there? If so, maybe we missed something or something changed? Are there steps to reproduce this manually? is this for previews in a new tab pr inline?

@jsnajdr

jsnajdr commented Jun 18, 2026

Copy link
Copy Markdown
Member

DIP shouldn't be active on previews, are you seeing it active there?

DIP is active only on the main editor tab, on the preview tabs it's not active. But that's enough to put both tabs into different "agent clusters", and they become isolated from each other. Like if they were cross-origin.

Are there steps to reproduce this manually?

Yes, it's very straighforward:

  1. Edit a post
  2. Open a preview by clicking "Preview in new tab" in the "View" menu
  3. Make edits to the post
  4. Click "Preview in new tab" again.

It's supposed to save the latest edits and update the existing preview tab with new content.

But the actual result is that the tab still shows the old content, and in console there is a security error that the preview tab's previewWindow.document can't be accessed.

@adamsilverstein

Copy link
Copy Markdown
Member

DIP shouldn't be active on previews, are you seeing it active there?

DIP is active only on the main editor tab, on the preview tabs it's not active. But that's enough to put both tabs into different "agent clusters", and they become isolated from each other. Like if they were cross-origin.

Are there steps to reproduce this manually?

Yes, it's very straighforward:

Thanks for clarifying, this helps me understand the issue more clearly.

But the actual result is that the tab still shows the old content, and in console there is a security error that the preview tab's previewWindow.document can't be accessed.

Ah - I didn't realize we were doing this kind of inter-tab communication for the preview window.

Locally I'm able to fix the preview window error by adding these two lines before writeInterstitialMessage:
The 100ms wait is there to wait until the window really loads the new location.

That fix makes sense, but feels a bit fragile. I wonder if we could catch the error if it occurs and retry, in case the tab takes longer to reset to about:blank?

I don't quite understand how upgrading Playwright exposed this bug; regardless it feels like something we legitimately need to fix! Thanks for the ping.

…atest-base

# Conflicts:
#	package-lock.json
#	test/storybook-playwright/package.json
@adamsilverstein

adamsilverstein commented Jun 19, 2026

Copy link
Copy Markdown
Member

@jsnajdr - I pushed a proposed fix in #79342. Rather than a fixed timeout, the PR sets the initial load directly, then uses the about:blank/reset approach, trying at 50ms intervals up to 1 second - using try/catch along the way to avoid the error.

The root package.json still pinned @playwright/test at ^1.58.2 while the
workspaces were bumped to ^1.61.0, failing 'lint:deps' (syncpack) which
requires a single version across the repo.
@adamsilverstein

Copy link
Copy Markdown
Member

don't quite understand how upgrading Playwright exposed this bug; regardless it feels like something we legitimately need to fix! Thanks for the ping.

oh, I see - its an issue with the new Chrome version.

adamsilverstein added a commit to adamsilverstein/gutenberg that referenced this pull request Jun 20, 2026
The Playwright 1.60 upgrade ships Chrome for Testing 148, which has a
regression in the cross-origin isolated `isolate-and-credentialless`
Document-Isolation-Policy runtime that Gutenberg sends on editor screens.

Under it three suites fail although the product behaves correctly on
shipping Chrome: client-side media processing silently falls back to the
server (so format/rotation/sub-size assertions break), and the preload
and Loading Patterns specs never reach a settled state so they time out.

Gate these specs on the major Chromium version so they skip on 148+ until
the browser regression is resolved, mirroring the existing 137+ gate used
for Document-Isolation-Policy. See
WordPress#78632.
@adamsilverstein

adamsilverstein commented Jun 21, 2026

Copy link
Copy Markdown
Member

I spent more time on this and discovered the underlying cause of the client side media failures issue wasn't quite what we expected. I opened a follow up issue just to fix this in #79377. The short version is:

  • Previous Playwright versions relied on a Chrome instance that lacked Document Isolation Policy, so the client side media tests were actually being skipped.
  • When they finally started running in the newer Playwright, a test environment only bug surfaced - the tests ran the client side media flows before wasm-vips was able to initialize which takes some small amount of time because the engine is lazy loaded and needs to be decoded as its embedded inline to avoid issues we our inability to set headers
  • Users never experience these issues because they aren't that fast, the problem only surfaced in the artificially fast test environment

The solution I came up with in #79378 should resolve the issue. I'm going to open a draft PR combining that with the Playwright update to verify CI goes green.

@adamsilverstein

Copy link
Copy Markdown
Member

The solution I came up with in #79378 should resolve the issue. I'm going to open a draft PR combining that with the Playwright update to verify CI goes green.

I opened a draft combined PR in #79381 that include the Playwright upgrade, the preview timing fix and the wasm loading fix. If CI goes green it will validate the fixes resolve the issues.

adamsilverstein added a commit to adamsilverstein/gutenberg that referenced this pull request Jun 21, 2026
Revert the CSM e2e rework (un-skipping the suite on Chromium 148, realigning
format/rotation expectations, and expanding EXIF-orientation coverage) that
accumulated on this branch during CI debugging. The base AVIF decode test
fails under the bundled Chrome for Testing 148/149 because of the
cross-origin-isolated wasm-vips decode race tracked in WordPress#78632, which is a CI
browser regression rather than anything this preview-fix PR changes.

Restore the `chromiumVersion >= 148` skip gate so the CSM suite skips on the
upgraded CI browser, keeping this PR scoped to the preview interstitial fix.
The EXIF sub-size rotation coverage lives in WordPress#79384, which targets trunk.
adamsilverstein added a commit to adamsilverstein/gutenberg that referenced this pull request Jun 23, 2026
The Playwright 1.60 upgrade ships Chrome for Testing 148, which has a
regression in the cross-origin isolated `isolate-and-credentialless`
Document-Isolation-Policy runtime that Gutenberg sends on editor screens.

Under it three suites fail although the product behaves correctly on
shipping Chrome: client-side media processing silently falls back to the
server (so format/rotation/sub-size assertions break), and the preload
and Loading Patterns specs never reach a settled state so they time out.

Gate these specs on the major Chromium version so they skip on 148+ until
the browser regression is resolved, mirroring the existing 137+ gate used
for Document-Isolation-Policy. See
WordPress#78632.
adamsilverstein added a commit to adamsilverstein/gutenberg that referenced this pull request Jun 23, 2026
Revert the CSM e2e rework (un-skipping the suite on Chromium 148, realigning
format/rotation expectations, and expanding EXIF-orientation coverage) that
accumulated on this branch during CI debugging. The base AVIF decode test
fails under the bundled Chrome for Testing 148/149 because of the
cross-origin-isolated wasm-vips decode race tracked in WordPress#78632, which is a CI
browser regression rather than anything this preview-fix PR changes.

Restore the `chromiumVersion >= 148` skip gate so the CSM suite skips on the
upgraded CI browser, keeping this PR scoped to the preview interstitial fix.
The EXIF sub-size rotation coverage lives in WordPress#79384, which targets trunk.
Bring the playwright-upgrade base current with trunk (was 63 commits
behind). Resolve test/e2e/package.json and package-lock.json conflicts:
keep the @playwright/test 1.61.0 bump and trunk's new @flakiness/playwright
dependency.
adamsilverstein added a commit to adamsilverstein/gutenberg that referenced this pull request Jun 24, 2026
The Playwright 1.60 upgrade ships Chrome for Testing 148, which has a
regression in the cross-origin isolated `isolate-and-credentialless`
Document-Isolation-Policy runtime that Gutenberg sends on editor screens.

Under it three suites fail although the product behaves correctly on
shipping Chrome: client-side media processing silently falls back to the
server (so format/rotation/sub-size assertions break), and the preload
and Loading Patterns specs never reach a settled state so they time out.

Gate these specs on the major Chromium version so they skip on 148+ until
the browser regression is resolved, mirroring the existing 137+ gate used
for Document-Isolation-Policy. See
WordPress#78632.
adamsilverstein added a commit to adamsilverstein/gutenberg that referenced this pull request Jun 24, 2026
Revert the CSM e2e rework (un-skipping the suite on Chromium 148, realigning
format/rotation expectations, and expanding EXIF-orientation coverage) that
accumulated on this branch during CI debugging. The base AVIF decode test
fails under the bundled Chrome for Testing 148/149 because of the
cross-origin-isolated wasm-vips decode race tracked in WordPress#78632, which is a CI
browser regression rather than anything this preview-fix PR changes.

Restore the `chromiumVersion >= 148` skip gate so the CSM suite skips on the
upgraded CI browser, keeping this PR scoped to the preview interstitial fix.
The EXIF sub-size rotation coverage lives in WordPress#79384, which targets trunk.
@adamsilverstein

Copy link
Copy Markdown
Member

@jsnajdr - Merging in #79495 into this PR will bring CI here green. It includes the preview fix as well as a bunch of follow up client-side media test fixes, see the ticket description for details.

…enable client-side media e2e on Chromium 148+ (#79495)

Co-authored-by: adamsilverstein <adamsilverstein@git.wordpress.org>
Co-authored-by: jsnajdr <jsnajdr@git.wordpress.org>
@github-actions github-actions Bot added the [Package] Editor /packages/editor label Jun 26, 2026
@adamsilverstein

Copy link
Copy Markdown
Member

Tests should go green after aade9a4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Package] Editor /packages/editor [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants