Skip to content

Fix E2E tests on macOS when STUDIO_RUNTIME=native-php#3301

Merged
fredrikekelund merged 7 commits intotrunkfrom
rsm-1725-fix-e2e-tests-native-php-runtime
May 5, 2026
Merged

Fix E2E tests on macOS when STUDIO_RUNTIME=native-php#3301
fredrikekelund merged 7 commits intotrunkfrom
rsm-1725-fix-e2e-tests-native-php-runtime

Conversation

@fredrikekelund
Copy link
Copy Markdown
Contributor

Related issues

  • Fixes RSM-1725

How AI was used in this PR

Primarily to help me debug the problem. I alternated between Claude and Codex.

Proposed Changes

While working on #3271, @bcotrim discovered that the E2E tests were failing when run with STUDIO_RUNTIME=native-php. This PR fixes that by implementing the following fixes:

  • When Studio clones a site, explicitly update the site URL. Playground can handle this internally, but the native PHP runtime obviously cannot.
  • On Posix platforms, spawn process daemon children with detached: true to assign them to a new process group. This is so we can pass a negative PID to process.kill to terminate the entire process group (the Node.js process and the associated PHP process). This approach isn't bulletproof, but it's alright, and it works for the purpose of the E2E tests.
  • Favor SIGTERM over SIGKILL when killing child processes to give them a chance to clean up.

Testing Instructions

Run the E2E tests locally on macOS by following these steps:

  1. npm run package
  2. STUDIO_RUNTIME=native-php npm run e2e
  3. Ensure that they pass successfully

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

- When Studio clones a site, explicitly update the site URL. Playground can handle this internally, but the native PHP runtime obviously cannot.
- On Posix platforms, spawn process daemon children with `detached: true` to assign them to a new process group. This is so we can pass a negative PID to `process.kill` to terminate the entire process group (the Node.js process and the associated PHP process). This approach isn't bulletproof, but it's alright, and it works for the purpose of the E2E tests.
- Favor SIGTERM over SIGKILL when killing child processes to give them a chance to clean up.
@fredrikekelund fredrikekelund requested a review from bcotrim April 30, 2026 14:22
@fredrikekelund fredrikekelund self-assigned this Apr 30, 2026
@fredrikekelund fredrikekelund changed the title Fix E2E tests on macOS Fix E2E tests on macOS when STUDIO_RUNTIME=native-php Apr 30, 2026
@wpmobilebot
Copy link
Copy Markdown
Collaborator

wpmobilebot commented Apr 30, 2026

📊 Performance Test Results

Comparing e82c8a0 vs trunk

app-size

Metric trunk e82c8a0 Diff Change
App Size (Mac) 1667.60 MB 1652.64 MB 14.95 MB 🟢 -0.9%

site-editor

Metric trunk e82c8a0 Diff Change
load 1499 ms 1494 ms 5 ms ⚪ 0.0%

site-startup

Metric trunk e82c8a0 Diff Change
siteCreation 8079 ms 8109 ms +30 ms ⚪ 0.0%
siteStartup 4935 ms 4953 ms +18 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

Copy link
Copy Markdown
Contributor

@bcotrim bcotrim left a comment

Choose a reason for hiding this comment

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

I had trouble running the e2e tests locally.
First issue was checksum mismatches — looks like upstream static-php-cli re-publishes archives, so the pinned hashes go stale. Should be moot once #3297 lands and we build binaries ourselves.

Second issue: even with hashes fixed, e2e teardown hung for 3 minutes with one PHP child orphaned per session. Root cause is that php-server-child.ts only handles exit/disconnect, not SIGTERM. When the daemon SIGTERMs the Node fork, it dies without firing exit, so killPhpProcess() never runs and the PHP grandchild leaks. Adding these unblocks teardown for me:

process.on( 'SIGTERM', () => {
	killPhpProcess();
	process.exit( 0 );
} );
process.on( 'SIGINT', () => {
	killPhpProcess();
	process.exit( 0 );
} );

Could you reproduce + confirm the fix on your end?


// Playground sets the correct siteurl internally, but for the native-php runtime, we need to
// explicitly update that option
await updateSiteUrl( server, `http://localhost:${ details.port }` );
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.

Should we run this only for native-php?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's obviously not required for Playground, but that's only because Playground enforces the siteurl internally. I think it makes sense to follow the more standard approach of explicitly updating the siteurl rather than relying on some runtimes to do it for us.

@fredrikekelund
Copy link
Copy Markdown
Contributor Author

fredrikekelund commented May 5, 2026

Sorry about that, @bcotrim. I did confirm this working previously… It seems you're correct that process.on( 'exit' ) isn't called in response to SIGINT or SIGTERM signals, so I'm not sure what made the cleanup work before. I may have broken it by messing up a git merge.

In any case, I've updated php-server-child to explicitly handle SIGINT or SIGTERM signals. I've also made it so process-manager-daemon sends SIGTERM signals to the entire process group (previously we SIGTERM only to the Node.js child process and followed up with SIGKILL signals to the group if needed).

I've also updated the PHP binary checksums for macOS with ARM chips to make the tests pass.

@fredrikekelund
Copy link
Copy Markdown
Contributor Author

I'm playing around with Windows changes here, too. I could move those commits to a new PR, though.

@bcotrim, if you review this again, feel free to ignore the changes explicitly targeting Windows. I'll let you know when those are ready for review.

Copy link
Copy Markdown
Contributor

@bcotrim bcotrim left a comment

Choose a reason for hiding this comment

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

Thanks for following up on the changes @fredrikekelund
e2e now run successfully on macOS.

I would suggest moving the Windows to another PR so we can land this one.

Nit: A nice workflow would be to control the STUDIO_RUNTIME via a PR label (for example) so the CI runs native PHP e2e. But we can do it in a follow-up PR, and maybe only after we have the binaries in our own CDN.

@fredrikekelund fredrikekelund force-pushed the rsm-1725-fix-e2e-tests-native-php-runtime branch from 0f9ece1 to e82c8a0 Compare May 5, 2026 11:09
@fredrikekelund fredrikekelund enabled auto-merge (squash) May 5, 2026 11:11
@fredrikekelund fredrikekelund merged commit b4d0a3c into trunk May 5, 2026
14 checks passed
@fredrikekelund fredrikekelund deleted the rsm-1725-fix-e2e-tests-native-php-runtime branch May 5, 2026 12:09
@fredrikekelund
Copy link
Copy Markdown
Contributor Author

A nice workflow would be to control the STUDIO_RUNTIME via a PR label (for example) so the CI runs native PHP e2e

Good idea 👍 I added this in #3343

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants