mirror of
https://github.com/rookiestar28/ComfyUI-OpenClaw.git
synced 2026-08-14 00:48:07 +00:00
fix(e2e): recover harness after exhausted import retries
This commit is contained in:
@@ -118,4 +118,31 @@ test.describe('OpenClaw Sidebar', () => {
|
||||
.poll(() => page.evaluate(() => window.__openclawTestLoadAttempts))
|
||||
.toBe(4);
|
||||
});
|
||||
|
||||
test('recovers when the first harness boot exhausts transient entry fetch retries', async ({ page }) => {
|
||||
let remainingFailures = 4;
|
||||
let totalEntryRequests = 0;
|
||||
|
||||
await page.route('**/web/openclaw.js?openclaw_harness_attempt=*', async (route) => {
|
||||
const url = new URL(route.request().url());
|
||||
if (url.pathname !== '/web/openclaw.js') {
|
||||
await route.fallback();
|
||||
return;
|
||||
}
|
||||
|
||||
totalEntryRequests += 1;
|
||||
if (remainingFailures > 0) {
|
||||
remainingFailures -= 1;
|
||||
await route.abort('failed');
|
||||
return;
|
||||
}
|
||||
|
||||
await route.fallback();
|
||||
});
|
||||
|
||||
await page.reload();
|
||||
await waitForOpenClawReady(page);
|
||||
await expect(page.locator('.openclaw-title')).toHaveText('OpenClaw');
|
||||
await expect.poll(() => totalEntryRequests).toBe(5);
|
||||
});
|
||||
});
|
||||
|
||||
+49
-11
@@ -24,6 +24,23 @@ function resolveUiTimeoutMs() {
|
||||
return 30_000;
|
||||
}
|
||||
|
||||
function resolveHarnessReloadBudget() {
|
||||
const raw = process.env.OPENCLAW_E2E_HARNESS_RELOADS;
|
||||
if (raw) {
|
||||
const parsed = Number.parseInt(raw, 10);
|
||||
if (Number.isInteger(parsed) && parsed >= 0) {
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
function isTransientModuleFetchFailure(error) {
|
||||
const message = String(error?.message || error || '');
|
||||
return message.includes('Failed to fetch dynamically imported module');
|
||||
}
|
||||
|
||||
function normalizeApiPath(pathname) {
|
||||
if (typeof pathname !== 'string') return '';
|
||||
const stripped = pathname.startsWith('/api/') ? pathname.slice(4) : pathname;
|
||||
@@ -573,20 +590,41 @@ export async function mockRemoteAdminBaseline(
|
||||
|
||||
export async function waitForOpenClawReady(page) {
|
||||
const timeoutMs = resolveUiTimeoutMs();
|
||||
await page.waitForFunction(
|
||||
() => window.__openclawTestReady === true || window.__openclawTestError,
|
||||
null,
|
||||
{ timeout: timeoutMs }
|
||||
);
|
||||
const maxHarnessReloads = resolveHarnessReloadBudget();
|
||||
|
||||
for (let reloadAttempt = 0; reloadAttempt <= maxHarnessReloads; reloadAttempt += 1) {
|
||||
await page.waitForFunction(
|
||||
() => window.__openclawTestReady === true || window.__openclawTestError,
|
||||
null,
|
||||
{ timeout: timeoutMs }
|
||||
);
|
||||
|
||||
const [error, loadAttempts] = await Promise.all([
|
||||
page.evaluate(() => window.__openclawTestError),
|
||||
page.evaluate(() => window.__openclawTestLoadAttempts || 0),
|
||||
]);
|
||||
|
||||
if (!error) {
|
||||
// Basic sanity: header + tab bar exists
|
||||
await expect(page.locator('.openclaw-header')).toBeVisible();
|
||||
await expect(page.locator('.openclaw-tabs')).toBeVisible();
|
||||
return;
|
||||
}
|
||||
|
||||
// IMPORTANT: only recover via full-page reload after the in-page harness
|
||||
// has already exhausted its own transient-fetch retry budget. This keeps
|
||||
// CI-only fetch flakes recoverable without masking real module/runtime bugs.
|
||||
if (
|
||||
isTransientModuleFetchFailure(error) &&
|
||||
loadAttempts >= 4 &&
|
||||
reloadAttempt < maxHarnessReloads
|
||||
) {
|
||||
await page.reload({ waitUntil: 'load' });
|
||||
continue;
|
||||
}
|
||||
|
||||
const error = await page.evaluate(() => window.__openclawTestError);
|
||||
if (error) {
|
||||
throw new Error(`OpenClaw test harness failed to load: ${error?.message || error}`);
|
||||
}
|
||||
|
||||
// Basic sanity: header + tab bar exists
|
||||
await expect(page.locator('.openclaw-header')).toBeVisible();
|
||||
await expect(page.locator('.openclaw-tabs')).toBeVisible();
|
||||
}
|
||||
|
||||
export async function clickTab(page, title) {
|
||||
|
||||
Reference in New Issue
Block a user