Skip to content

Commit f353994

Browse files
authored
CLI test: add HTTP response check for created site (#4000)
## Related issues - Related to STU-1867 ## How AI was used in this PR Claude was used to write the code and explore the solution. The author reviewed it manually. ## Proposed Changes Follow-up to the CLI e2e tests in #3947. The `site create` test only asserted persisted state on disk. This adds a real check: after creating and starting a site, the test requests its homepage and confirms a 200 with HTML, so it now fails if a created site cannot be served. This does not cover the custom-domain and HTTPS case, which cannot run in an isolated, headless test. See the discussion in #3947. ## Testing Instructions 1. Build the CLI with `npm run cli:build`. 2. Run `npm test -- apps/cli/commands/site/tests/create.e2e.test.ts --tagsFilter='e2e'` and confirm both tests pass. 3. Run the same with `--tagsFilter='!e2e'` and confirm the tests are skipped, so the fast suite is unaffected. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors?
1 parent 70b8078 commit f353994

1 file changed

Lines changed: 53 additions & 38 deletions

File tree

‎apps/cli/commands/site/tests/create.e2e.test.ts‎

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -18,57 +18,72 @@ import {
1818
readCliConfig,
1919
runCli,
2020
setupCliEnv,
21+
waitForSiteResponse,
2122
type CliEnv,
2223
} from './helpers/cli-e2e';
2324

2425
describe.skipIf( ! cliE2ePrerequisitesMet() )( 'CLI e2e: studio site create', () => {
2526
let env: CliEnv | undefined;
2627

27-
afterEach( () => {
28+
afterEach( async () => {
2829
if ( env ) {
30+
// The homepage test starts a site; stop it before tearing down the env.
31+
await runCli( [ 'site', 'stop', '--all' ], env );
2932
cleanupCliEnv( env );
3033
env = undefined;
3134
}
32-
} );
35+
}, 60_000 );
3336

34-
it( 'creates a site with a custom name', { tags: [ 'e2e' ], timeout: 120_000 }, async () => {
35-
env = setupCliEnv();
36-
const siteName = 'Custom E2E Site';
37-
const sitePath = path.join( env.sitesDir, 'custom-e2e-site' );
37+
it(
38+
'creates a site that serves its homepage',
39+
{ tags: [ 'e2e' ], timeout: 180_000 },
40+
async () => {
41+
env = setupCliEnv();
42+
const siteName = 'Custom E2E Site';
43+
const sitePath = path.join( env.sitesDir, 'custom-e2e-site' );
3844

39-
const result = await runCli(
40-
[
41-
'site',
42-
'create',
43-
'--name',
44-
siteName,
45-
'--path',
46-
sitePath,
47-
'--wp',
48-
'latest',
49-
'--no-start',
50-
'--skip-browser',
51-
'--skip-log-details',
52-
],
53-
env
54-
);
45+
const result = await runCli(
46+
[
47+
'site',
48+
'create',
49+
'--name',
50+
siteName,
51+
'--path',
52+
sitePath,
53+
'--wp',
54+
'latest',
55+
// Sandbox is bundled; the default native runtime downloads PHP on start.
56+
'--runtime',
57+
'sandbox',
58+
'--skip-browser',
59+
'--skip-log-details',
60+
],
61+
env
62+
);
5563

56-
expect( result.code, result.stderr ).toBe( 0 );
64+
expect( result.code, result.stderr ).toBe( 0 );
5765

58-
// The site is persisted to the real cli.json with the custom name.
59-
const config = readCliConfig( env );
60-
expect( config.sites ).toHaveLength( 1 );
61-
const [ site ] = config.sites;
62-
expect( site.name ).toBe( siteName );
63-
expect( site.path ).toBe( sitePath );
64-
expect( site.phpVersion ).toBeTruthy();
65-
expect( site.running ).toBe( false );
66+
const config = readCliConfig( env );
67+
expect( config.sites ).toHaveLength( 1 );
68+
const [ site ] = config.sites;
69+
expect( site.name ).toBe( siteName );
70+
expect( site.path ).toBe( sitePath );
71+
expect( site.phpVersion ).toBeTruthy();
72+
expect( site.port ).toBeTruthy();
73+
74+
// wp-config.php only exists if the server started (create alone doesn't generate it).
75+
expect( fs.existsSync( path.join( sitePath, 'wp-load.php' ) ) ).toBe( true );
76+
expect( fs.existsSync( path.join( sitePath, 'wp-includes', 'version.php' ) ) ).toBe( true );
77+
expect( fs.existsSync( path.join( sitePath, 'wp-config.php' ) ) ).toBe( true );
6678

67-
// Real WordPress core files were copied into the site directory.
68-
// (wp-config.php is generated at server start, which --no-start skips.)
69-
expect( fs.existsSync( path.join( sitePath, 'wp-load.php' ) ) ).toBe( true );
70-
expect( fs.existsSync( path.join( sitePath, 'wp-includes', 'version.php' ) ) ).toBe( true );
71-
} );
79+
// A freshly started site can return a warm-up 302 before serving, so poll for the 200.
80+
const response = await waitForSiteResponse( `http://localhost:${ String( site.port ) }`, {
81+
expectedStatus: 200,
82+
} );
83+
expect( response.status ).toBe( 200 );
84+
expect( response.headers.get( 'content-type' ) ).toMatch( /text\/html/ );
85+
}
86+
);
7287

7388
it(
7489
'creates a site with a custom domain and HTTPS',
@@ -101,8 +116,8 @@ describe.skipIf( ! cliE2ePrerequisitesMet() )( 'CLI e2e: studio site create', ()
101116

102117
expect( result.code, result.stderr ).toBe( 0 );
103118

104-
// The custom domain and HTTPS preference are persisted to cli.json.
105-
// (--no-start skips the hosts-file / certificate setup that running would do.)
119+
// --no-start skips the hosts-file / certificate setup that running would do,
120+
// so this only checks the custom domain and HTTPS preference are persisted.
106121
const config = readCliConfig( env );
107122
expect( config.sites ).toHaveLength( 1 );
108123
const [ site ] = config.sites;

0 commit comments

Comments
 (0)