test: stabilize closed-loop browser E2E

This commit is contained in:
z.zhang 2026-09-08 00:36:13 +08:00
parent f94350c7cb
commit 68a8b4c7e2
1 changed files with 13 additions and 9 deletions

View File

@ -42,9 +42,13 @@ async function loginThroughUi(page: Page, username = 'planner'): Promise<void> {
} }
async function openOrders(page: Page): Promise<void> { async function openOrders(page: Page): Promise<void> {
// A document reload briefly renders AuthGate, whose guest rail exposes the
// same data-tip. Wait for the authenticated shell and exclude that rail so
// the click cannot be consumed by the login dialog during bootstrap.
await expect(page.locator('.account-trigger:not(.guest-login-trigger)')).toBeVisible({ timeout: 60_000 });
const existing = page.getByTestId('closed-loop-aps-stages'); const existing = page.getByTestId('closed-loop-aps-stages');
if (await existing.isVisible().catch(() => false)) return; if (await existing.isVisible().catch(() => false)) return;
const trigger = page.locator('.right-rail button[data-tip="\u8ba2\u5355\u7ba1\u7406"]'); const trigger = page.locator('.right-rail:not(.guest-right-rail) button[data-tip="\u8ba2\u5355\u7ba1\u7406"]');
await expect(trigger).toBeVisible({ timeout: 30_000 }); await expect(trigger).toBeVisible({ timeout: 30_000 });
await trigger.click(); await trigger.click();
await expect(page.getByTestId('closed-loop-aps-stages')).toBeVisible({ timeout: 30_000 }); await expect(page.getByTestId('closed-loop-aps-stages')).toBeVisible({ timeout: 30_000 });
@ -137,8 +141,8 @@ test.describe('Round 65 real browser closed-loop APS E2E (isolated backend)', ()
await expect(tagClass(page, 'netting')).toContainText('230'); await expect(tagClass(page, 'netting')).toContainText('230');
await expect(tagClass(page, 'admission')).toContainText('0'); await expect(tagClass(page, 'admission')).toContainText('0');
await expect(page.getByTestId('closed-loop-stage-draft')).toContainText(/VL\s*0\s*\/\s*WO\s*0/); await expect(page.getByTestId('closed-loop-stage-draft')).toContainText(/VL\s*0\s*\/\s*WO\s*0/);
expect(await tagClass(page, 'publish').getAttribute('class')).not.toMatch(/ant-tag-(green|gold)/); await expect(tagClass(page, 'publish')).toHaveText('\u672a\u5f00\u653e');
expect(await tagClass(page, 'mes').getAttribute('class')).not.toMatch(/ant-tag-(green|gold)/); await expect(tagClass(page, 'mes')).toHaveText('\u672a\u5f00\u653e');
await openMakeTab(page); await openMakeTab(page);
await expect(page.getByTestId('closed-loop-manufacturing-demands')).toBeVisible(); await expect(page.getByTestId('closed-loop-manufacturing-demands')).toBeVisible();
@ -198,8 +202,8 @@ test.describe('Round 65 real browser closed-loop APS E2E (isolated backend)', ()
await refreshOrders(page); await refreshOrders(page);
await expect(page.getByTestId('closed-loop-stage-draft')).toContainText(versionNo); await expect(page.getByTestId('closed-loop-stage-draft')).toContainText(versionNo);
await expect(page.getByTestId('closed-loop-stage-draft')).toContainText(/VL\s*1\s*\/\s*WO\s*1/); await expect(page.getByTestId('closed-loop-stage-draft')).toContainText(/VL\s*1\s*\/\s*WO\s*1/);
expect(await tagClass(page, 'draft').getAttribute('class')).toMatch(/ant-tag-green/); await expect(tagClass(page, 'draft')).toHaveText('FEASIBLE');
expect(await tagClass(page, 'publish').getAttribute('class')).toMatch(/ant-tag-gold/); await expect(tagClass(page, 'publish')).toHaveText('\u5f85\u786e\u8ba4');
const stagedPublish = await browserApi<Json>(page, '/api/schedule/publish/stage', { const stagedPublish = await browserApi<Json>(page, '/api/schedule/publish/stage', {
method: 'POST', method: 'POST',
@ -224,8 +228,8 @@ test.describe('Round 65 real browser closed-loop APS E2E (isolated backend)', ()
expect(status.closedLoopStatus.gate.publishReady).toBe(false); expect(status.closedLoopStatus.gate.publishReady).toBe(false);
expect(status.closedLoopStatus.gate.dispatchReady).toBe(true); expect(status.closedLoopStatus.gate.dispatchReady).toBe(true);
await refreshOrders(page); await refreshOrders(page);
expect(await tagClass(page, 'publish').getAttribute('class')).toMatch(/ant-tag-green/); await expect(tagClass(page, 'publish')).toHaveText('\u5df2\u53d1\u5e03');
expect(await tagClass(page, 'mes').getAttribute('class')).toMatch(/ant-tag-gold/); await expect(tagClass(page, 'mes')).toHaveText('\u5f85\u53cc\u4eba\u786e\u8ba4');
const stagedMes = await browserApi<Json>(page, '/api/mes/dispatch/stage', { const stagedMes = await browserApi<Json>(page, '/api/mes/dispatch/stage', {
method: 'POST', method: 'POST',
@ -269,8 +273,8 @@ test.describe('Round 65 real browser closed-loop APS E2E (isolated backend)', ()
expect(execution.rows[0].mesExternalId).toBeTruthy(); expect(execution.rows[0].mesExternalId).toBeTruthy();
await refreshOrders(page); await refreshOrders(page);
expect(await tagClass(page, 'publish').getAttribute('class')).toMatch(/ant-tag-green/); await expect(tagClass(page, 'publish')).toHaveText('\u5df2\u53d1\u5e03');
expect(await tagClass(page, 'mes').getAttribute('class')).toMatch(/ant-tag-green/); await expect(tagClass(page, 'mes')).toHaveText('\u5df2\u4e0b\u53d1');
const isolatedState = await request.get(`${API_TARGET}/__e2e__/state`); const isolatedState = await request.get(`${API_TARGET}/__e2e__/state`);
const isolatedBody = await isolatedState.json() as Json; const isolatedBody = await isolatedState.json() as Json;