From c1c8bf2696ed8f4898759da38818592724bc90dc Mon Sep 17 00:00:00 2001 From: CieanYau Date: Fri, 6 Nov 2026 01:42:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=EF=BC=9A=E9=9A=94=E7=A6=BB?= =?UTF-8?q?=E6=97=A0=E6=95=88=E8=A7=84=E5=88=99=E5=9C=BA=E6=99=AF=E5=B9=B6?= =?UTF-8?q?=E5=8F=AA=E7=AD=89=E5=BE=85=E6=9C=AC=E8=BD=AE=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/review-routes.e2e.test.mjs | 47 ++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/tests/review-routes.e2e.test.mjs b/tests/review-routes.e2e.test.mjs index 27a284a..011bde7 100644 --- a/tests/review-routes.e2e.test.mjs +++ b/tests/review-routes.e2e.test.mjs @@ -129,26 +129,31 @@ test( }), ); -test( - "security group batches reject unknown enums without submitting partial rules", - { timeout: 25000 }, - (t) => - scenario(t, { loginMode: "password-only" }, async (page) => { - const writes = await securityGroupBoundary(page); - await login(page, "/security/groups/group?id=1"); - const dialog = await openBatchEditor(page); - const invalidInputs = [ - "ot tcp 22 0.0.0.0/0 misspelled-direction", - "in tcq 22 0.0.0.0/0 misspelled-protocol", - "out tcp 443 0.0.0.0/0 valid-first\not tcp 22 0.0.0.0/0 invalid-second", - ]; - for (const input of invalidInputs) { +// 每种拒绝输入使用全新的浏览器上下文;上一轮的错误提示不能冒充本轮已处理完成。 +for (const [name, input] of [ + ["unknown direction", "ot tcp 22 0.0.0.0/0 misspelled-direction"], + ["unknown protocol", "in tcq 22 0.0.0.0/0 misspelled-protocol"], + [ + "a valid rule followed by an unknown direction", + "out tcp 443 0.0.0.0/0 valid-first\not tcp 22 0.0.0.0/0 invalid-second", + ], +]) { + test( + `security group batches reject ${name} without partial writes`, + { timeout: 25000 }, + (t) => + scenario(t, { loginMode: "password-only" }, async (page) => { + const writes = await securityGroupBoundary(page); + await login(page, "/security/groups/group?id=1"); + const dialog = await openBatchEditor(page); + // 弹窗本来就有 info 级使用说明;只有错误级别的可见提示才表示本次校验失败。 + const errorAlert = dialog.locator('[role="alert"].p-message-error'); + assert.equal(await errorAlert.count(), 0); await dialog.locator("textarea").fill(input); await dialog.getByRole("button", { name: "添加", exact: true }).click(); // 等到可观察的拒绝或错误下发,不用休眠长度推断“没有发请求”。 await eventually( - async () => - writes.length > 0 || (await dialog.getByRole("alert").count()) > 0, + async () => writes.length > 0 || (await errorAlert.isVisible()), Boolean, "Invalid rules must produce a form error or expose an unexpected write", ); @@ -158,11 +163,11 @@ test( "Unknown enums must never reach the API", ); assert.equal(await dialog.isVisible(), true); - assert.ok((await dialog.getByRole("alert").count()) > 0); - } - return { rejectedInputs: invalidInputs.length, submittedBatches: 0 }; - }), -); + assert.equal(await errorAlert.isVisible(), true); + return { rejectedInput: name, submittedBatches: 0 }; + }), + ); +} test( "legacy ticket menu query navigation resets drafts and writes only the selected ticket",