@se-studio/site-check 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +3 -1
- package/dist/smoke-test/index.d.ts +2 -2
- package/dist/smoke-test/index.d.ts.map +1 -1
- package/dist/smoke-test/index.js +1 -1
- package/dist/smoke-test/index.js.map +1 -1
- package/dist/smoke-test/runner.d.ts +6 -3
- package/dist/smoke-test/runner.d.ts.map +1 -1
- package/dist/smoke-test/runner.js +155 -16
- package/dist/smoke-test/runner.js.map +1 -1
- package/dist/smoke-test/static.d.ts +2 -2
- package/dist/smoke-test/static.d.ts.map +1 -1
- package/dist/smoke-test/static.js +13 -3
- package/dist/smoke-test/static.js.map +1 -1
- package/dist/smoke-test/types.d.ts +12 -0
- package/dist/smoke-test/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/smoke-test-one.mjs +153 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix `smoke-test-one` appearing to hang: add fetch timeouts, startup/progress logging, fail fast when port is busy but not responding, reuse an already-healthy dev server (`SMOKE_TEST_USE_RUNNING_SERVER`, default true), and inherit stdio so dev server output is visible.
|
|
8
|
+
|
|
9
|
+
## 2.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- `smoke-test-one` starts `pnpm dev:dev` by default (configurable via `SMOKE_TEST_SERVER_SCRIPT`; `start` still runs `pnpm build` first).
|
|
14
|
+
- Add cache verification: `SMOKE_TEST_VERIFY_CACHE=true` runs smoke twice and checks `x-nextjs-cache` on HTML responses.
|
|
15
|
+
- Smoke runner records per-case cache headers and timing; exports `runSmokeTestWithCacheVerify` and `parseNextJsCacheHeader`.
|
|
16
|
+
|
|
3
17
|
## 2.0.0
|
|
4
18
|
|
|
5
19
|
### Major Changes
|
package/README.md
CHANGED
|
@@ -107,11 +107,13 @@ Import from `@se-studio/site-check/smoke-test`:
|
|
|
107
107
|
pnpm build --filter @se-studio/site-check # once, or after package changes
|
|
108
108
|
cd apps/example-empty
|
|
109
109
|
pnpm smoke-test:run # dev server must be running on app port
|
|
110
|
-
pnpm smoke-test #
|
|
110
|
+
pnpm smoke-test # dev server + smoke (default dev:dev) + stop
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
Add `smoke.cases.json` and `scripts/smoke-test-run.ts`. No Contentful or `cms-server` imports required. Set `SMOKE_TEST_IGNORE=true` in `.env.local` to skip the full `smoke-test` CI script.
|
|
114
114
|
|
|
115
|
+
**`smoke-test-one` env:** `SMOKE_TEST_SERVER_SCRIPT=dev:dev` (default) or `start` (runs `pnpm build` first). `SMOKE_TEST_VERIFY_CACHE=true` runs smoke twice and checks `x-nextjs-cache` headers (sets `LOG_CMS_FETCH=1` on the dev server). `SMOKE_TEST_READY_PATH=/` polls until the server responds.
|
|
116
|
+
|
|
115
117
|
## Exit codes
|
|
116
118
|
|
|
117
119
|
- `0` — Validation passed (sitemap.xml required; llms.txt and sitemap-unindexed.xml optional). If `--check-rewrites` was set, no unexpected rewrites. Every sitemap page returned 200 for its `.md` URL and files were saved (or in compare mode: all production sitemap pages exist on development and, if `--check-rewrites`, no unexpected rewrites).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { formatSmokeTestReport, getSmokeTestExitCode, runSmokeTest, } from './runner.js';
|
|
1
|
+
export { formatSmokeTestReport, getSmokeTestExitCode, isSmokeTestCacheVerifyResult, parseNextJsCacheHeader, runSmokeTest, runSmokeTestWithCacheVerify, } from './runner.js';
|
|
2
2
|
export { joinSmokeBaseUrl, loadStaticSmokeConfig, runStaticSmokeTest } from './static.js';
|
|
3
|
-
export type { LoadStaticSmokeConfigOptions, RunStaticSmokeTestOptions, SmokeFailureReason, SmokeTestCase, SmokeTestCaseResult, SmokeTestCategory, SmokeTestResult, SmokeTestRunnerConfig, StaticSmokeCaseDefinition, StaticSmokeConfigFile, } from './types.js';
|
|
3
|
+
export type { LoadStaticSmokeConfigOptions, NextJsCacheStatus, RunStaticSmokeTestOptions, SmokeFailureReason, SmokeTestCacheVerifyResult, SmokeTestCase, SmokeTestCaseResult, SmokeTestCategory, SmokeTestResult, SmokeTestRunnerConfig, StaticSmokeCaseDefinition, StaticSmokeConfigFile, } from './types.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC1F,YAAY,EACV,4BAA4B,EAC5B,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
|
package/dist/smoke-test/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { formatSmokeTestReport, getSmokeTestExitCode, runSmokeTest, } from './runner.js';
|
|
1
|
+
export { formatSmokeTestReport, getSmokeTestExitCode, isSmokeTestCacheVerifyResult, parseNextJsCacheHeader, runSmokeTest, runSmokeTestWithCacheVerify, } from './runner.js';
|
|
2
2
|
export { joinSmokeBaseUrl, loadStaticSmokeConfig, runStaticSmokeTest } from './static.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,YAAY,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/smoke-test/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,4BAA4B,EAC5B,sBAAsB,EACtB,YAAY,EACZ,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/** biome-ignore-all lint/suspicious/noConsole: CLI output is intentional */
|
|
2
|
-
import type { SmokeTestResult, SmokeTestRunnerConfig } from './types.js';
|
|
2
|
+
import type { NextJsCacheStatus, SmokeTestCacheVerifyResult, SmokeTestResult, SmokeTestRunnerConfig } from './types.js';
|
|
3
|
+
export declare function parseNextJsCacheHeader(value: string | null): NextJsCacheStatus | null;
|
|
3
4
|
export declare function runSmokeTest(config: SmokeTestRunnerConfig): Promise<SmokeTestResult>;
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function runSmokeTestWithCacheVerify(config: SmokeTestRunnerConfig): Promise<SmokeTestCacheVerifyResult>;
|
|
6
|
+
export declare function isSmokeTestCacheVerifyResult(result: SmokeTestResult | SmokeTestCacheVerifyResult): result is SmokeTestCacheVerifyResult;
|
|
7
|
+
export declare function getSmokeTestExitCode(result: SmokeTestResult | SmokeTestCacheVerifyResult): number;
|
|
8
|
+
export declare function formatSmokeTestReport(result: SmokeTestResult | SmokeTestCacheVerifyResult): string;
|
|
6
9
|
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/smoke-test/runner.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAG5E,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/smoke-test/runner.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAG5E,OAAO,KAAK,EACV,iBAAiB,EAEjB,0BAA0B,EAG1B,eAAe,EACf,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAapB,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAOrF;AAuFD,wBAAsB,YAAY,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAqC1F;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,0BAA0B,CAAC,CA2DrC;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,eAAe,GAAG,0BAA0B,GACnD,MAAM,IAAI,0BAA0B,CAEtC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,0BAA0B,GAAG,MAAM,CAQjG;AAuFD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,eAAe,GAAG,0BAA0B,GACnD,MAAM,CAiBR"}
|
|
@@ -9,16 +9,47 @@ function isMarkdownContentType(contentType) {
|
|
|
9
9
|
return false;
|
|
10
10
|
return contentType.toLowerCase().includes('text/markdown');
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
export function parseNextJsCacheHeader(value) {
|
|
13
|
+
if (!value)
|
|
14
|
+
return null;
|
|
15
|
+
const normalized = value.toUpperCase();
|
|
16
|
+
if (normalized === 'HIT' || normalized === 'MISS' || normalized === 'STALE') {
|
|
17
|
+
return normalized;
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function countCacheStatuses(cases) {
|
|
22
|
+
let hit = 0;
|
|
23
|
+
let stale = 0;
|
|
24
|
+
let miss = 0;
|
|
25
|
+
let absent = 0;
|
|
26
|
+
for (const row of cases) {
|
|
27
|
+
const status = row.htmlNextCache;
|
|
28
|
+
if (status === 'HIT')
|
|
29
|
+
hit++;
|
|
30
|
+
else if (status === 'STALE')
|
|
31
|
+
stale++;
|
|
32
|
+
else if (status === 'MISS')
|
|
33
|
+
miss++;
|
|
34
|
+
else
|
|
35
|
+
absent++;
|
|
36
|
+
}
|
|
37
|
+
return { hit, stale, miss, absent };
|
|
38
|
+
}
|
|
39
|
+
async function checkCase(testCase, minMarkdownLength, fetchFn) {
|
|
40
|
+
const started = Date.now();
|
|
13
41
|
const failures = [];
|
|
14
42
|
let htmlStatus = 0;
|
|
15
43
|
let markdownStatus = 0;
|
|
16
44
|
let markdownLength = 0;
|
|
17
45
|
let markdownContentType = null;
|
|
18
46
|
let markdownBodySnippet = null;
|
|
47
|
+
let htmlNextCache = null;
|
|
48
|
+
let markdownNextCache = null;
|
|
19
49
|
try {
|
|
20
50
|
const htmlRes = await fetchFn(testCase.pageUrl, { method: 'GET', redirect: 'follow' });
|
|
21
51
|
htmlStatus = htmlRes.status;
|
|
52
|
+
htmlNextCache = parseNextJsCacheHeader(htmlRes.headers.get('x-nextjs-cache'));
|
|
22
53
|
if (htmlStatus < 200 || htmlStatus >= 300) {
|
|
23
54
|
failures.push('html_non_2xx');
|
|
24
55
|
}
|
|
@@ -33,6 +64,7 @@ async function checkCase(testCase, baseUrl, minMarkdownLength, fetchFn) {
|
|
|
33
64
|
const mdRes = await fetchFn(mdUrl, { method: 'GET', redirect: 'follow' });
|
|
34
65
|
markdownStatus = mdRes.status;
|
|
35
66
|
markdownContentType = mdRes.headers.get('content-type');
|
|
67
|
+
markdownNextCache = parseNextJsCacheHeader(mdRes.headers.get('x-nextjs-cache'));
|
|
36
68
|
const body = await mdRes.text();
|
|
37
69
|
markdownLength = body.length;
|
|
38
70
|
markdownBodySnippet = body.slice(0, 120).replace(/\s+/g, ' ').trim();
|
|
@@ -59,6 +91,9 @@ async function checkCase(testCase, baseUrl, minMarkdownLength, fetchFn) {
|
|
|
59
91
|
markdownContentType,
|
|
60
92
|
failures,
|
|
61
93
|
markdownBodySnippet,
|
|
94
|
+
htmlNextCache,
|
|
95
|
+
markdownNextCache,
|
|
96
|
+
durationMs: Date.now() - started,
|
|
62
97
|
};
|
|
63
98
|
}
|
|
64
99
|
export async function runSmokeTest(config) {
|
|
@@ -69,7 +104,7 @@ export async function runSmokeTest(config) {
|
|
|
69
104
|
if (requestDelayMs > 0 && results.length > 0) {
|
|
70
105
|
await sleep(requestDelayMs);
|
|
71
106
|
}
|
|
72
|
-
results.push(await checkCase(testCase,
|
|
107
|
+
results.push(await checkCase(testCase, minMarkdownLength, fetchFn));
|
|
73
108
|
}
|
|
74
109
|
let errorCount = 0;
|
|
75
110
|
const warnCount = 0;
|
|
@@ -87,14 +122,93 @@ export async function runSmokeTest(config) {
|
|
|
87
122
|
warnCount,
|
|
88
123
|
};
|
|
89
124
|
}
|
|
125
|
+
export async function runSmokeTestWithCacheVerify(config) {
|
|
126
|
+
const pass1Started = Date.now();
|
|
127
|
+
const pass1 = await runSmokeTest(config);
|
|
128
|
+
const pass1DurationMs = Date.now() - pass1Started;
|
|
129
|
+
const pass2Started = Date.now();
|
|
130
|
+
const pass2 = await runSmokeTest(config);
|
|
131
|
+
const pass2DurationMs = Date.now() - pass2Started;
|
|
132
|
+
const cacheVerifyFailures = [];
|
|
133
|
+
if (pass1.errorCount > 0) {
|
|
134
|
+
cacheVerifyFailures.push(`pass 1 had ${pass1.errorCount} functional failure(s)`);
|
|
135
|
+
}
|
|
136
|
+
if (pass2.errorCount > 0) {
|
|
137
|
+
cacheVerifyFailures.push(`pass 2 had ${pass2.errorCount} functional failure(s)`);
|
|
138
|
+
}
|
|
139
|
+
const pass2Cache = countCacheStatuses(pass2.cases);
|
|
140
|
+
const pass1Cache = countCacheStatuses(pass1.cases);
|
|
141
|
+
const pass2WithHeader = pass2.cases.length - pass2Cache.absent;
|
|
142
|
+
if (pass2WithHeader > 0) {
|
|
143
|
+
const pass2Cached = pass2Cache.hit + pass2Cache.stale;
|
|
144
|
+
if (pass2Cached < pass2.cases.length) {
|
|
145
|
+
cacheVerifyFailures.push(`pass 2 HTML cache: expected all HIT/STALE, got HIT=${pass2Cache.hit} STALE=${pass2Cache.stale} MISS=${pass2Cache.miss} absent=${pass2Cache.absent}`);
|
|
146
|
+
}
|
|
147
|
+
const pass1Uncached = pass1Cache.miss + pass1Cache.absent;
|
|
148
|
+
if (pass1Uncached > 0 && pass2Cached < pass1Uncached) {
|
|
149
|
+
cacheVerifyFailures.push(`pass 2 did not improve on pass 1 (pass1 MISS/absent=${pass1Uncached}, pass2 HIT/STALE=${pass2Cached})`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
pass2.warnings.push('x-nextjs-cache header absent on all pass 2 HTML responses — cache verify used timing only');
|
|
154
|
+
if (pass2DurationMs >= pass1DurationMs) {
|
|
155
|
+
cacheVerifyFailures.push(`pass 2 (${pass2DurationMs}ms) not faster than pass 1 (${pass1DurationMs}ms) with no cache headers`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (pass2WithHeader > 0 && pass2DurationMs >= pass1DurationMs) {
|
|
159
|
+
pass2.warnings.push(`pass 2 (${pass2DurationMs}ms) not faster than pass 1 (${pass1DurationMs}ms) despite cache hits`);
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
pass1,
|
|
163
|
+
pass2,
|
|
164
|
+
pass1DurationMs,
|
|
165
|
+
pass2DurationMs,
|
|
166
|
+
cacheVerifyFailures,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
export function isSmokeTestCacheVerifyResult(result) {
|
|
170
|
+
return 'pass1' in result;
|
|
171
|
+
}
|
|
90
172
|
export function getSmokeTestExitCode(result) {
|
|
173
|
+
if (isSmokeTestCacheVerifyResult(result)) {
|
|
174
|
+
if (result.pass2.errorCount > 0 || result.pass1.errorCount > 0)
|
|
175
|
+
return 1;
|
|
176
|
+
if (result.cacheVerifyFailures.length > 0)
|
|
177
|
+
return 1;
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
91
180
|
if (result.errorCount > 0)
|
|
92
181
|
return 1;
|
|
93
182
|
return 0;
|
|
94
183
|
}
|
|
95
|
-
|
|
184
|
+
function formatCacheLabel(status) {
|
|
185
|
+
return status ?? 'absent';
|
|
186
|
+
}
|
|
187
|
+
function formatCaseRows(rows, includeCache) {
|
|
96
188
|
const lines = [];
|
|
97
|
-
|
|
189
|
+
for (const row of rows) {
|
|
190
|
+
const status = row.failures.length === 0 ? 'ok' : `FAIL (${row.failures.join(', ')})`;
|
|
191
|
+
const cacheSuffix = includeCache
|
|
192
|
+
? `, x-nextjs-cache=${formatCacheLabel(row.htmlNextCache)}, ${row.durationMs}ms`
|
|
193
|
+
: '';
|
|
194
|
+
lines.push(` ${row.case.label}`);
|
|
195
|
+
lines.push(` page: ${row.case.pageUrl} → HTML ${row.htmlStatus} [${status}]${cacheSuffix}`);
|
|
196
|
+
if (row.case.expectMarkdown) {
|
|
197
|
+
const mdUrl = htmlUrlToMarkdownUrl(row.case.pageUrl);
|
|
198
|
+
const mdCacheSuffix = includeCache
|
|
199
|
+
? `, x-nextjs-cache=${formatCacheLabel(row.markdownNextCache)}`
|
|
200
|
+
: '';
|
|
201
|
+
lines.push(` md: ${mdUrl} → ${row.markdownStatus} (${row.markdownLength} chars) [${status}]${mdCacheSuffix}`);
|
|
202
|
+
if (row.failures.includes('markdown_missing') && row.markdownBodySnippet) {
|
|
203
|
+
lines.push(` md body: ${row.markdownBodySnippet}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return lines;
|
|
208
|
+
}
|
|
209
|
+
function formatSinglePass(result, label, includeCache) {
|
|
210
|
+
const lines = [];
|
|
211
|
+
lines.push(`### ${label}`);
|
|
98
212
|
lines.push('');
|
|
99
213
|
const byCategory = new Map();
|
|
100
214
|
for (const row of result.cases) {
|
|
@@ -105,18 +219,7 @@ export function formatSmokeTestReport(result) {
|
|
|
105
219
|
}
|
|
106
220
|
for (const [category, rows] of byCategory) {
|
|
107
221
|
lines.push(`## ${category}`);
|
|
108
|
-
|
|
109
|
-
const status = row.failures.length === 0 ? 'ok' : `FAIL (${row.failures.join(', ')})`;
|
|
110
|
-
lines.push(` ${row.case.label}`);
|
|
111
|
-
lines.push(` page: ${row.case.pageUrl} → HTML ${row.htmlStatus} [${status}]`);
|
|
112
|
-
if (row.case.expectMarkdown) {
|
|
113
|
-
const mdUrl = htmlUrlToMarkdownUrl(row.case.pageUrl);
|
|
114
|
-
lines.push(` md: ${mdUrl} → ${row.markdownStatus} (${row.markdownLength} chars) [${status}]`);
|
|
115
|
-
if (row.failures.includes('markdown_missing') && row.markdownBodySnippet) {
|
|
116
|
-
lines.push(` md body: ${row.markdownBodySnippet}`);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
222
|
+
lines.push(...formatCaseRows(rows, includeCache));
|
|
120
223
|
lines.push('');
|
|
121
224
|
}
|
|
122
225
|
if (result.warnings.length > 0) {
|
|
@@ -127,6 +230,42 @@ export function formatSmokeTestReport(result) {
|
|
|
127
230
|
lines.push('');
|
|
128
231
|
}
|
|
129
232
|
lines.push(`Summary: ${result.cases.length} cases, ${result.errorCount} failed, ${result.warnings.length} warnings`);
|
|
233
|
+
return lines;
|
|
234
|
+
}
|
|
235
|
+
function formatCacheVerifySummary(result) {
|
|
236
|
+
const pass1Cache = countCacheStatuses(result.pass1.cases);
|
|
237
|
+
const pass2Cache = countCacheStatuses(result.pass2.cases);
|
|
238
|
+
const lines = [];
|
|
239
|
+
lines.push('## cache-verify');
|
|
240
|
+
lines.push(` pass 1: ${result.pass1.cases.length} cases, ${result.pass1DurationMs}ms, x-nextjs-cache HIT=${pass1Cache.hit} STALE=${pass1Cache.stale} MISS=${pass1Cache.miss} absent=${pass1Cache.absent}`);
|
|
241
|
+
lines.push(` pass 2: ${result.pass2.cases.length} cases, ${result.pass2DurationMs}ms, x-nextjs-cache HIT=${pass2Cache.hit} STALE=${pass2Cache.stale} MISS=${pass2Cache.miss} absent=${pass2Cache.absent}`);
|
|
242
|
+
if (result.cacheVerifyFailures.length > 0) {
|
|
243
|
+
lines.push(' failures:');
|
|
244
|
+
for (const failure of result.cacheVerifyFailures) {
|
|
245
|
+
lines.push(` - ${failure}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
lines.push(' cache verify: ok');
|
|
250
|
+
}
|
|
251
|
+
lines.push('');
|
|
252
|
+
return lines;
|
|
253
|
+
}
|
|
254
|
+
export function formatSmokeTestReport(result) {
|
|
255
|
+
if (isSmokeTestCacheVerifyResult(result)) {
|
|
256
|
+
const lines = [];
|
|
257
|
+
lines.push(`Smoke test (cache verify): ${result.pass1.siteName} (${result.pass1.baseUrl})`);
|
|
258
|
+
lines.push('');
|
|
259
|
+
lines.push(...formatCacheVerifySummary(result));
|
|
260
|
+
lines.push(...formatSinglePass(result.pass1, 'Pass 1 (warm cache)', true));
|
|
261
|
+
lines.push('');
|
|
262
|
+
lines.push(...formatSinglePass(result.pass2, 'Pass 2 (expect cached)', true));
|
|
263
|
+
return lines.join('\n');
|
|
264
|
+
}
|
|
265
|
+
const lines = [];
|
|
266
|
+
lines.push(`Smoke test: ${result.siteName} (${result.baseUrl})`);
|
|
267
|
+
lines.push('');
|
|
268
|
+
lines.push(...formatSinglePass(result, 'Results', false));
|
|
130
269
|
return lines.join('\n');
|
|
131
270
|
}
|
|
132
271
|
//# sourceMappingURL=runner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/smoke-test/runner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/smoke-test/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { LoadStaticSmokeConfigOptions, RunStaticSmokeTestOptions, SmokeTestResult, SmokeTestRunnerConfig } from './types.js';
|
|
1
|
+
import type { LoadStaticSmokeConfigOptions, RunStaticSmokeTestOptions, SmokeTestCacheVerifyResult, SmokeTestResult, SmokeTestRunnerConfig } from './types.js';
|
|
2
2
|
export declare function joinSmokeBaseUrl(baseUrl: string, path: string): string;
|
|
3
3
|
export declare function loadStaticSmokeConfig(filePath: string, options?: LoadStaticSmokeConfigOptions): SmokeTestRunnerConfig;
|
|
4
|
-
export declare function runStaticSmokeTest(filePath: string, options?: RunStaticSmokeTestOptions): Promise<SmokeTestResult>;
|
|
4
|
+
export declare function runStaticSmokeTest(filePath: string, options?: RunStaticSmokeTestOptions): Promise<SmokeTestResult | SmokeTestCacheVerifyResult>;
|
|
5
5
|
//# sourceMappingURL=static.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,4BAA4B,EAC5B,yBAAyB,
|
|
1
|
+
{"version":3,"file":"static.d.ts","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,4BAA4B,EAC5B,yBAAyB,EACzB,0BAA0B,EAE1B,eAAe,EACf,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAItE;AAaD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,4BAA4B,GACrC,qBAAqB,CA0BvB;AASD,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,yBAAyB,GAClC,OAAO,CAAC,eAAe,GAAG,0BAA0B,CAAC,CAUvD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
|
-
import { runSmokeTest } from './runner.js';
|
|
3
|
+
import { runSmokeTest, runSmokeTestWithCacheVerify } from './runner.js';
|
|
4
4
|
export function joinSmokeBaseUrl(baseUrl, path) {
|
|
5
5
|
const normalizedBase = baseUrl.replace(/\/$/, '');
|
|
6
6
|
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
@@ -39,11 +39,21 @@ export function loadStaticSmokeConfig(filePath, options) {
|
|
|
39
39
|
requestDelayMs: raw.requestDelayMs,
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
+
function resolveVerifyCache(options) {
|
|
43
|
+
if (options?.verifyCache !== undefined) {
|
|
44
|
+
return options.verifyCache;
|
|
45
|
+
}
|
|
46
|
+
return (process.env.SMOKE_TEST_VERIFY_CACHE ?? '').toLowerCase() === 'true';
|
|
47
|
+
}
|
|
42
48
|
export async function runStaticSmokeTest(filePath, options) {
|
|
43
49
|
const config = loadStaticSmokeConfig(filePath, options);
|
|
44
|
-
|
|
50
|
+
const runnerConfig = {
|
|
45
51
|
...config,
|
|
46
52
|
fetch: options?.fetch,
|
|
47
|
-
}
|
|
53
|
+
};
|
|
54
|
+
if (resolveVerifyCache(options)) {
|
|
55
|
+
return runSmokeTestWithCacheVerify(runnerConfig);
|
|
56
|
+
}
|
|
57
|
+
return runSmokeTest(runnerConfig);
|
|
48
58
|
}
|
|
49
59
|
//# sourceMappingURL=static.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"static.js","sourceRoot":"","sources":["../../src/smoke-test/static.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,7 @@ export interface StaticSmokeConfigFile {
|
|
|
21
21
|
requestDelayMs?: number;
|
|
22
22
|
}
|
|
23
23
|
export type SmokeFailureReason = 'html_non_2xx' | 'markdown_missing' | 'markdown_wrong_content_type' | 'markdown_too_short';
|
|
24
|
+
export type NextJsCacheStatus = 'HIT' | 'MISS' | 'STALE';
|
|
24
25
|
export interface SmokeTestCaseResult {
|
|
25
26
|
case: SmokeTestCase;
|
|
26
27
|
htmlStatus: number;
|
|
@@ -29,6 +30,9 @@ export interface SmokeTestCaseResult {
|
|
|
29
30
|
markdownContentType: string | null;
|
|
30
31
|
failures: SmokeFailureReason[];
|
|
31
32
|
markdownBodySnippet: string | null;
|
|
33
|
+
htmlNextCache: NextJsCacheStatus | null;
|
|
34
|
+
markdownNextCache: NextJsCacheStatus | null;
|
|
35
|
+
durationMs: number;
|
|
32
36
|
}
|
|
33
37
|
export interface SmokeTestResult {
|
|
34
38
|
siteName: string;
|
|
@@ -52,5 +56,13 @@ export interface LoadStaticSmokeConfigOptions {
|
|
|
52
56
|
}
|
|
53
57
|
export interface RunStaticSmokeTestOptions extends LoadStaticSmokeConfigOptions {
|
|
54
58
|
fetch?: typeof fetch;
|
|
59
|
+
verifyCache?: boolean;
|
|
60
|
+
}
|
|
61
|
+
export interface SmokeTestCacheVerifyResult {
|
|
62
|
+
pass1: SmokeTestResult;
|
|
63
|
+
pass2: SmokeTestResult;
|
|
64
|
+
pass1DurationMs: number;
|
|
65
|
+
pass2DurationMs: number;
|
|
66
|
+
cacheVerifyFailures: string[];
|
|
55
67
|
}
|
|
56
68
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/smoke-test/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,MAAM,GACN,oBAAoB,GACpB,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,KAAK,GACL,0BAA0B,GAC1B,YAAY,GACZ,gBAAgB,GAChB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,qEAAqE;AACrE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,mFAAmF;AACnF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,yBAAyB,EAAE,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,kBAAkB,GAClB,6BAA6B,GAC7B,oBAAoB,CAAC;AAEzB,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/smoke-test/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,MAAM,GACN,oBAAoB,GACpB,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,KAAK,GACL,0BAA0B,GAC1B,YAAY,GACZ,gBAAgB,GAChB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,qEAAqE;AACrE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,mFAAmF;AACnF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,yBAAyB,EAAE,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,kBAAkB,GAC1B,cAAc,GACd,kBAAkB,GAClB,6BAA6B,GAC7B,oBAAoB,CAAC;AAEzB,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,4BAA4B;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,yBAA0B,SAAQ,4BAA4B;IAC7E,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,eAAe,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B"}
|
package/package.json
CHANGED
package/smoke-test-one.mjs
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Start a dev (or production) server and smoke-test one marketing app.
|
|
5
5
|
* Usage: smoke-test-one <port> (from app directory)
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
|
+
* Env:
|
|
8
|
+
* SMOKE_TEST_IGNORE=true — skip entirely
|
|
9
|
+
* SMOKE_TEST_SERVER_SCRIPT=dev:dev — pnpm script to start server (default dev:dev; use "start" for prod)
|
|
10
|
+
* SMOKE_TEST_VERIFY_CACHE=true — run smoke twice and assert cache headers / timing
|
|
11
|
+
* SMOKE_TEST_READY_PATH=/ — path polled until server responds
|
|
12
|
+
* SMOKE_TEST_USE_RUNNING_SERVER=true — reuse server already on port (default true)
|
|
13
|
+
* LOG_CMS_FETCH=1 — set automatically when SMOKE_TEST_VERIFY_CACHE=true
|
|
7
14
|
*/
|
|
8
15
|
|
|
16
|
+
import net from 'node:net';
|
|
9
17
|
import fs from 'node:fs';
|
|
10
18
|
import path from 'node:path';
|
|
11
19
|
import { spawn, spawnSync } from 'node:child_process';
|
|
@@ -18,8 +26,16 @@ if (!port || !/^\d+$/.test(port)) {
|
|
|
18
26
|
|
|
19
27
|
const appDir = process.cwd();
|
|
20
28
|
const baseUrl = `http://localhost:${port}`;
|
|
21
|
-
const startTimeoutMs = 120_000;
|
|
22
29
|
const pollIntervalMs = 1_000;
|
|
30
|
+
const progressIntervalMs = 10_000;
|
|
31
|
+
const fetchTimeoutMs = 10_000;
|
|
32
|
+
|
|
33
|
+
function fetchWithTimeout(url, options = {}) {
|
|
34
|
+
return fetch(url, {
|
|
35
|
+
...options,
|
|
36
|
+
signal: AbortSignal.timeout(fetchTimeoutMs),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
23
39
|
|
|
24
40
|
function parseEnvFile(filePath) {
|
|
25
41
|
const env = {};
|
|
@@ -44,20 +60,70 @@ function loadEnv() {
|
|
|
44
60
|
return { ...process.env, ...envLocal, PORT: port };
|
|
45
61
|
}
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
63
|
+
function sleep(ms) {
|
|
64
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function isServerUp(url) {
|
|
68
|
+
try {
|
|
69
|
+
const res = await fetchWithTimeout(url, { method: 'GET', redirect: 'follow' });
|
|
70
|
+
return res.status >= 200 && res.status < 500;
|
|
71
|
+
} catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function isPortListening(listenPort) {
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
const socket = net.connect(Number(listenPort), '127.0.0.1');
|
|
79
|
+
socket.setTimeout(2_000);
|
|
80
|
+
socket.once('connect', () => {
|
|
81
|
+
socket.destroy();
|
|
82
|
+
resolve(true);
|
|
83
|
+
});
|
|
84
|
+
socket.once('timeout', () => {
|
|
85
|
+
socket.destroy();
|
|
86
|
+
resolve(false);
|
|
87
|
+
});
|
|
88
|
+
socket.once('error', () => resolve(false));
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function waitForServer(url, timeoutMs, options = {}) {
|
|
93
|
+
const { child, label = 'Server' } = options;
|
|
94
|
+
const started = Date.now();
|
|
95
|
+
let lastProgressAt = 0;
|
|
96
|
+
let childExited = false;
|
|
97
|
+
let childExitCode = null;
|
|
98
|
+
|
|
99
|
+
if (child) {
|
|
100
|
+
child.on('exit', (code) => {
|
|
101
|
+
childExited = true;
|
|
102
|
+
childExitCode = code;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
while (Date.now() - started < timeoutMs) {
|
|
107
|
+
if (childExited) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`${label} process exited with code ${childExitCode ?? 'unknown'} before ${url} was ready`,
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (await isServerUp(url)) {
|
|
114
|
+
return Date.now() - started;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const elapsed = Date.now() - started;
|
|
118
|
+
if (elapsed - lastProgressAt >= progressIntervalMs) {
|
|
119
|
+
console.log(`Still waiting for ${url} (${Math.round(elapsed / 1000)}s)...`);
|
|
120
|
+
lastProgressAt = elapsed;
|
|
57
121
|
}
|
|
58
|
-
|
|
122
|
+
|
|
123
|
+
await sleep(pollIntervalMs);
|
|
59
124
|
}
|
|
60
|
-
|
|
125
|
+
|
|
126
|
+
throw new Error(`${label} did not respond at ${url} within ${timeoutMs}ms`);
|
|
61
127
|
}
|
|
62
128
|
|
|
63
129
|
function killProcessTree(child) {
|
|
@@ -80,41 +146,94 @@ if ((env.SMOKE_TEST_IGNORE ?? '').toLowerCase() === 'true') {
|
|
|
80
146
|
process.exit(0);
|
|
81
147
|
}
|
|
82
148
|
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
149
|
+
const serverScript = env.SMOKE_TEST_SERVER_SCRIPT ?? 'dev:dev';
|
|
150
|
+
const verifyCache = (env.SMOKE_TEST_VERIFY_CACHE ?? '').toLowerCase() === 'true';
|
|
151
|
+
const useRunningServer = (env.SMOKE_TEST_USE_RUNNING_SERVER ?? 'true').toLowerCase() !== 'false';
|
|
152
|
+
const readyPath = env.SMOKE_TEST_READY_PATH ?? '/';
|
|
153
|
+
const readyUrl = `${baseUrl}${readyPath.startsWith('/') ? readyPath : `/${readyPath}`}`;
|
|
154
|
+
const isProductionStart = serverScript === 'start';
|
|
155
|
+
const startTimeoutMs = isProductionStart ? 120_000 : 300_000;
|
|
156
|
+
|
|
157
|
+
if (isProductionStart) {
|
|
158
|
+
console.log('Building app...');
|
|
159
|
+
const buildResult = spawnSync('pnpm', ['build'], {
|
|
160
|
+
cwd: appDir,
|
|
161
|
+
stdio: 'inherit',
|
|
162
|
+
env,
|
|
163
|
+
});
|
|
164
|
+
if (buildResult.status !== 0) {
|
|
165
|
+
process.exit(buildResult.status ?? 1);
|
|
166
|
+
}
|
|
91
167
|
}
|
|
92
168
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
});
|
|
169
|
+
const smokeEnv = {
|
|
170
|
+
...env,
|
|
171
|
+
SMOKE_TEST_PORT: port,
|
|
172
|
+
...(verifyCache ? { SMOKE_TEST_VERIFY_CACHE: 'true', LOG_CMS_FETCH: '1' } : {}),
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
console.log(`Smoke test: checking ${readyUrl} (port ${port})...`);
|
|
100
176
|
|
|
177
|
+
let server = null;
|
|
178
|
+
let spawnedServer = false;
|
|
101
179
|
let exitCode = 1;
|
|
102
180
|
|
|
103
181
|
try {
|
|
104
|
-
await
|
|
105
|
-
|
|
182
|
+
const serverUp = await isServerUp(readyUrl);
|
|
183
|
+
const portBusy = await isPortListening(port);
|
|
184
|
+
|
|
185
|
+
if (serverUp && useRunningServer) {
|
|
186
|
+
console.log(`Using existing server at ${readyUrl}.`);
|
|
187
|
+
} else if (serverUp && !useRunningServer) {
|
|
188
|
+
console.error(
|
|
189
|
+
`Server already running at ${readyUrl}. Stop it first, or set SMOKE_TEST_USE_RUNNING_SERVER=true.`,
|
|
190
|
+
);
|
|
191
|
+
process.exit(1);
|
|
192
|
+
} else if (portBusy) {
|
|
193
|
+
console.error(
|
|
194
|
+
`Port ${port} is in use but ${readyUrl} is not responding. Stop the process on :${port} and retry.`,
|
|
195
|
+
);
|
|
196
|
+
process.exit(1);
|
|
197
|
+
} else {
|
|
198
|
+
console.log(`Starting server (${serverScript}) on ${baseUrl}...`);
|
|
199
|
+
server = spawn('pnpm', [serverScript], {
|
|
200
|
+
cwd: appDir,
|
|
201
|
+
env: smokeEnv,
|
|
202
|
+
stdio: 'inherit',
|
|
203
|
+
detached: true,
|
|
204
|
+
});
|
|
205
|
+
spawnedServer = true;
|
|
206
|
+
|
|
207
|
+
const readyMs = await waitForServer(readyUrl, startTimeoutMs, {
|
|
208
|
+
child: server,
|
|
209
|
+
label: 'Dev server',
|
|
210
|
+
});
|
|
211
|
+
console.log(`Server ready at ${readyUrl} (${Math.round(readyMs / 1000)}s).`);
|
|
212
|
+
}
|
|
106
213
|
|
|
214
|
+
console.log('Running smoke tests...');
|
|
107
215
|
const runResult = spawnSync('pnpm', ['smoke-test:run'], {
|
|
108
216
|
cwd: appDir,
|
|
109
217
|
stdio: 'inherit',
|
|
110
|
-
env:
|
|
218
|
+
env: smokeEnv,
|
|
111
219
|
});
|
|
112
220
|
exitCode = runResult.status ?? 1;
|
|
221
|
+
|
|
222
|
+
if (verifyCache) {
|
|
223
|
+
console.log('');
|
|
224
|
+
console.log('## CMS fetch logging');
|
|
225
|
+
console.log(
|
|
226
|
+
' LOG_CMS_FETCH=1 is set on the dev server — check its terminal for [CMS fetch] lines.',
|
|
227
|
+
);
|
|
228
|
+
console.log(' Pass-level cache stats are in the smoke report (x-nextjs-cache).');
|
|
229
|
+
}
|
|
113
230
|
} catch (error) {
|
|
114
231
|
console.error(error instanceof Error ? error.message : error);
|
|
115
232
|
exitCode = 1;
|
|
116
233
|
} finally {
|
|
117
|
-
|
|
234
|
+
if (spawnedServer) {
|
|
235
|
+
killProcessTree(server);
|
|
236
|
+
}
|
|
118
237
|
}
|
|
119
238
|
|
|
120
239
|
process.exit(exitCode);
|