From cf8fb1db328b5cf1618d598dc3c9489996bd4029 Mon Sep 17 00:00:00 2001 From: Rogee Date: Mon, 31 Aug 2026 09:45:27 +0800 Subject: [PATCH] HH-859: cover readiness and credential limits in browser E2E (#26) --- web/tests/responsive.e2e.js | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/web/tests/responsive.e2e.js b/web/tests/responsive.e2e.js index 269ac76..225cc7f 100644 --- a/web/tests/responsive.e2e.js +++ b/web/tests/responsive.e2e.js @@ -48,6 +48,58 @@ test('shows the CDP endpoint only in the active branch at 900px and 599px', asyn await expect(endpoint.filter({ visible: true })).toHaveCount(1) }) +test('enforces browser readiness before starting at 900px', async ({ page }) => { + const stopped = { ...runtime, state: 'exited', status: 'Exited', endpoint: '' } + const environments = [ + { ...stopped, id: 'ready', alias: 'ready', name: '就绪环境', schedule_status: 'ready' }, + { ...stopped, id: 'missing', alias: 'missing', name: '实例缺失环境', schedule_status: 'blocked', schedule_block_reason: 'runtime_missing' }, + { ...stopped, id: 'revoked', alias: 'revoked', name: '已撤权环境', schedule_status: 'blocked', schedule_block_reason: 'account_revoked' }, + ] + await page.route('**/api/browsers', route => route.fulfill({ json: environments })) + await page.route('**/api/gateways', route => route.fulfill({ json: [] })) + await page.route('**/api/browser-images', route => route.fulfill({ json: [] })) + await page.route('**/api/phase-a/accounts', route => route.fulfill({ json: [] })) + await page.route('**/api/network-exits', route => route.fulfill({ json: [] })) + await page.route('**/api/browsers/*/start', route => route.fulfill({ status: 204 })) + await page.setViewportSize({ width: 900, height: 900 }) + await page.goto('/#/browsers') + + const ready = page.getByRole('button', { name: '启动 就绪环境' }) + const missing = page.getByRole('button', { name: '启动 实例缺失环境' }) + await expect(ready).toBeEnabled() + await expect(missing).toBeEnabled() + await expect(page.getByRole('button', { name: '启动 已撤权环境(授权已撤销)' })).toBeDisabled() + + for (const [button, alias] of [[ready, 'ready'], [missing, 'missing']]) { + const request = page.waitForRequest(`**/api/browsers/${alias}/start`) + await button.click() + expect((await request).method()).toBe('POST') + } +}) + +test('submits a complete 192-character credential reference at 900px', async ({ page }) => { + const credentialKey = `${'a'.repeat(64)}/${'b'.repeat(127)}` + await page.route('**/api/phase-a/accounts', async route => { + if (route.request().method() === 'POST') return route.fulfill({ json: { id: 'account-new' } }) + return route.fulfill({ json: [] }) + }) + await page.route('**/api/browsers', route => route.fulfill({ json: [] })) + await page.setViewportSize({ width: 900, height: 900 }) + await page.goto('/#/accounts') + + await page.getByRole('textbox', { name: '平台', exact: true }).fill('mock') + await page.getByRole('textbox', { name: '平台账号标识', exact: true }).fill('shop-new') + await page.getByRole('textbox', { name: '凭据引用 ID', exact: true }).fill('credential-new') + const input = page.getByRole('textbox', { name: '凭据引用键', exact: true }) + await input.fill(credentialKey) + await expect(input).toHaveAttribute('maxlength', '192') + await expect(input).toHaveValue(credentialKey) + + const request = page.waitForRequest(request => request.url().endsWith('/api/phase-a/accounts') && request.method() === 'POST') + await page.getByRole('button', { name: '创建账号' }).click() + await expect((await request).postDataJSON()).toMatchObject({ credential_reference: { key: credentialKey } }) +}) + test('keeps account and network-exit pages inside 599px, 900px and 1280px', async ({ page }) => { const accountKey = 'a'.repeat(128) const credentialID = 'c'.repeat(128)