Преглед изворни кода

test: harden e2e helper error handling

Co-Authored-By: Codex <noreply@anthropic.com>
master
fengsilin пре 3 недеља
родитељ
комит
568a91dfcf
2 измењених фајлова са 32 додато и 4 уклоњено
  1. +17
    -2
      web/e2e/utils/process.js
  2. +15
    -2
      web/e2e/utils/wait.js

+ 17
- 2
web/e2e/utils/process.js Прегледај датотеку

@@ -12,6 +12,10 @@ export function startProcess(command, args, options = {}) {
child.stdout.on('data', (chunk) => output.push(chunk.toString()));
child.stderr.on('data', (chunk) => output.push(chunk.toString()));

child.once('error', (error) => {
output.push(`\nprocess failed to start: ${error.message}\n`);
});

child.once('exit', (code) => {
if (code !== null && code !== 0) {
output.push(`\nprocess exited with code ${code}\n`);
@@ -25,6 +29,17 @@ function hasExited(child) {
return child.exitCode !== null || child.signalCode !== null;
}

function sendSignal(child, signal) {
if (!child || hasExited(child)) return false;

try {
return child.kill(signal);
} catch (error) {
if (error?.code === 'ESRCH' || hasExited(child)) return false;
throw error;
}
}

function waitForExit(child, timeoutMs) {
if (!child || hasExited(child)) return Promise.resolve(true);

@@ -72,10 +87,10 @@ export async function stopProcess(child) {
return;
}

child.kill('SIGTERM');
sendSignal(child, 'SIGTERM');
const exited = await waitForExit(child, 5000);
if (exited) return;

child.kill('SIGKILL');
sendSignal(child, 'SIGKILL');
await waitForExit(child, 5000);
}

+ 15
- 2
web/e2e/utils/wait.js Прегледај датотеку

@@ -1,18 +1,31 @@
export async function waitForHttp(url, options = {}) {
const timeoutMs = options.timeoutMs || 60000;
const intervalMs = options.intervalMs || 500;
const attemptTimeoutMs = options.attemptTimeoutMs || 5000;
const start = Date.now();
let lastError;

while (Date.now() - start < timeoutMs) {
const remainingMs = timeoutMs - (Date.now() - start);
if (remainingMs <= 0) break;

const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), Math.min(attemptTimeoutMs, remainingMs));
timeout.unref?.();

try {
const response = await fetch(url, { cache: 'no-store' });
const response = await fetch(url, { cache: 'no-store', signal: controller.signal });
if (response.ok) return response;
lastError = new Error(`HTTP ${response.status}`);
} catch (error) {
lastError = error;
} finally {
clearTimeout(timeout);
}
await new Promise((resolve) => setTimeout(resolve, intervalMs));

const remainingAfterAttemptMs = timeoutMs - (Date.now() - start);
if (remainingAfterAttemptMs <= 0) break;
await new Promise((resolve) => setTimeout(resolve, Math.min(intervalMs, remainingAfterAttemptMs)));
}

throw new Error(`Timed out waiting for ${url}: ${lastError?.message || 'no response'}`);


Loading…
Откажи
Сачувај