Add CLI integration test for site create (custom name, domain, HTTPS)#3947
Conversation
📊 Performance Test ResultsComparing ed958ee vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
…3961) ## Related issues - Fixes STU-1871 - Stacked on #3947 ## How AI was used in this PR I used Claude to review the existing Playwright blueprint tests and the new CLI e2e harness from #3947, plan the migration, and to write the test. I reviewd and verified all changes. ## Proposed Changes Blueprint coverage currently lives only in `apps/studio/e2e/blueprints.test.ts`, which boots the entire desktop app through Playwright to create a site from a custom Blueprint and then inspects wp-admin — slow, flaky, and coupled to the UI. This PR continues the "Migrate Studio E2E tests to CLI" effort by exercising the same capability directly through the CLI. - Adds integration tests that run `studio site create --blueprint <file>` against an isolated config directory and asserts on the file system. - Closes a gap in the #3947 harness: the helper isolated the config directory but not the legacy Electron appdata directory, so the Studio-compatibility startup migration could find a real pre-split `appdata-v1.json` and abort the CLI on a developer's machine. The harness now also isolates that path, which fixes the sibling `create.e2e.test.ts` locally. ## Testing Instructions 1. Build the CLI: `npm run cli:build`. 2. Run the new suite (needs a network connection for the download install step): `npm test -- apps/cli/commands/site/tests/create-blueprint.e2e.test.ts --tagsFilter='e2e'` Confirm all four tests pass. 3. Confirm the fast suite is unaffected: `npm test -- apps/cli/commands/site/tests/create-blueprint.e2e.test.ts --tagsFilter='!e2e'` The four tests are skipped. 4. Regression check for the harness fix — confirm the sibling test also passes: `npm test -- apps/cli/commands/site/tests/create.e2e.test.ts --tagsFilter='e2e'` ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors? --------- Co-authored-by: Rahul Gavande <rahul.gavande@automattic.com>
fredrikekelund
left a comment
There was a problem hiding this comment.
I left some comments about doing HTTP requests to the site's homepage after running the site create commands. The fundamentals here look really good, though 👍
| expect( result.code, result.stderr ).toBe( 0 ); | ||
|
|
||
| // The site is persisted to the real cli.json with the custom name. | ||
| const config = readCliConfig( env ); | ||
| expect( config.sites ).toHaveLength( 1 ); | ||
| const [ site ] = config.sites; | ||
| expect( site.name ).toBe( siteName ); | ||
| expect( site.path ).toBe( sitePath ); | ||
| expect( site.phpVersion ).toBeTruthy(); | ||
| expect( site.running ).toBe( false ); | ||
|
|
||
| // Real WordPress core files were copied into the site directory. | ||
| // (wp-config.php is generated at server start, which --no-start skips.) | ||
| expect( fs.existsSync( path.join( sitePath, 'wp-load.php' ) ) ).toBe( true ); | ||
| expect( fs.existsSync( path.join( sitePath, 'wp-includes', 'version.php' ) ) ).toBe( true ); |
There was a problem hiding this comment.
I'd add an HTTP request that verifies that we get a 200 OK HTTP response from the site. Either we need to parse the regular stdout output from the site create command, or we add a --format=json parameter (that's the kind of change I was talking about in our huddle where working on the test suite might uncover flaws in the CLI implementation)
There was a problem hiding this comment.
Done in #4000. The create test now starts the site and asserts a 200 with HTML from the homepage.
| type CliEnv, | ||
| } from './helpers/cli-e2e'; | ||
|
|
||
| describe.skipIf( ! cliE2ePrerequisitesMet() )( 'CLI e2e: studio site create', () => { |
There was a problem hiding this comment.
It seems more helpful if the test would break rather than gracefully skip if the CLI artifacts don't exist.
There was a problem hiding this comment.
We already have open issue to handle CLI tests.
| expect( result.code, result.stderr ).toBe( 0 ); | ||
|
|
||
| // The custom domain and HTTPS preference are persisted to cli.json. | ||
| // (--no-start skips the hosts-file / certificate setup that running would do.) | ||
| const config = readCliConfig( env ); | ||
| expect( config.sites ).toHaveLength( 1 ); | ||
| const [ site ] = config.sites; | ||
| expect( site.name ).toBe( siteName ); | ||
| expect( site.customDomain ).toBe( customDomain ); | ||
| expect( site.enableHttps ).toBe( true ); | ||
| expect( site.running ).toBe( false ); | ||
|
|
||
| expect( fs.existsSync( path.join( sitePath, 'wp-load.php' ) ) ).toBe( true ); |
There was a problem hiding this comment.
Same thing here about adding an HTTP request for verification
There was a problem hiding this comment.
I kept the custom-domain and HTTPS case as persistence-only. Serving it needs the full stack: the proxy on ports 80 and 443, a trusted root CA, and a write to the shared /etc/hosts behind an elevated-privileges prompt, so it cannot run in an isolated, headless test. The live check stays on the plain localhost site in #4000.
| version: 1, | ||
| sites: [], | ||
| snapshots: [], | ||
| lastDependencyCheckTime: Date.now(), |
|
Thank you for the review @fredrikekelund. I have addressed your comments in #4000. |
## Related issues - Fixes STU-1868 - Builds on #3947 (the `site create` integration test + e2e harness) and complements the UI suite in #3950 ## How AI was used in this PR I used Claude to write the test and the harness changes, and traced the daemon connection failures to a Unix socket path length limit. I reviewed the diff, ran the suite on nodes 22 and 24, and confirmed that runs are isolated, with no orphan daemons/servers and no temp-dir leaks. ## Proposed Changes We're migrating the legacy blueprint-based start/stop test cases to the CLI integration approach. The existing `start.test.ts` / `stop.test.ts` unit tests mock the daemon and server manager. This PR instead boots a real WordPress server through the process-manager daemon and verifies the live running state via `site list --format json`, so it actually exercises the daemon -> server -> port lifecycle. - Adds an `e2e`-tagged suite that creates a site with `--no-start`. It runs in the slower (release/manual) suite, not on every PR. - Updates the harness to prevent the tests affecting local sites. The lifecycle commands talk to the process-manager daemon, and the cleanup step `stop --all` would kill the developer's real running sites. The harness now gives each run its own daemon home via `STUDIO_PROCESS_MANAGER_HOME`, so runs are fully isolated and parallel-safe. That home is deliberately kept short and under the temp dir: the daemon's control socket is a Unix domain socket, and nesting it under the `studio-cli-e2e-<uuid>` root path overflows macOS's 104-char socket path limit. This surfaces as `EINVAL` on node 24 and as an indefinite connect-retry (hang) on node 22. Windows uses a fixed named pipe, so this isolation is macOS/Linux only. - The harness also seeds a minimal `app.json` so the `00-check-studio-compatibility` migration returns early. Without it, that migration falls through to the developer's real legacy app data and aborts the CLI, so the suite would pass on CI yet fail on a dev machine with Studio installed. This also retroactively hardens the `site create` test from #3947, which carries the same gap. - Uses `--runtime sandbox` to stay hermetic. The native PHP runtime drives the same lifecycle but downloads its ~25 MB binary into the isolated config dir on the first run. Covering it hermetically needs CI to provision that binary, so native-PHP coverage is a follow-up. ## Testing Instructions 1. `npm run cli:build` 2. `npm test -- --tagsFilter='e2e' apps/cli/commands/site/tests/start-stop.e2e.test.ts` 3. Expect 2 tests green (`starts a site`, `stops a site`). 4. While it runs, confirm it does not disturb sites you have running in Studio, and leaves no orphan processes or temp dirs afterward. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors?
…te suite (covered by CLI #3947)
Related issues
How AI was used in this PR
Proposed Changes
The end-to-end suite drives every site action through the Studio UI, which is slow, flaky, and ties coverage to the UI. This adds the first real CLI integration test for
studio site create: it runs the actual command against an isolated config directory and asserts on the persisted result, covering a site with a custom name and a site with a custom domain plus HTTPS. The tests are taggede2eso they run in the slower release or manual suite rather than on every pull request.Testing Instructions
npm run cli:build.npm test -- --tagsFilter='e2e'and confirm both tests pass.npm test -- --tagsFilter='!e2e'and confirm these tests are skipped, so the fast suite is unaffected.Pre-merge Checklist