Skip to content

Commit 488c77d

Browse files
committed
fix(e2e): resolve Phase 1 spec runtime issues (UX-1208, UX-1198)
Three runtime failures in enterprise CI run 24562051088: 1. AclPage.submitForm() waits for HTTP 2xx/3xx via page.waitForResponse, so acl-create-error.spec.ts tests that mock an HTTP 4xx/5xx response or abort the request hang until the 60s timeout. Added: AclPage.submitFormExpectingError(kind: 'http-error' | 'network-abort') — mirrors submitForm but matches status >= 400, or skips the response wait entirely for aborted requests. Zero change to existing callers. 2. acl-principal-special-chars.spec.ts + acl-delete-multi-match.spec.ts used getByTestId('search-field-input').getByRole('textbox').fill(...) for the ACLs page SearchField. Redpanda UI's SearchField does not expose an inner textbox role — existing acl.spec.ts calls .fill() directly on the testid'd wrapper. Removed the .getByRole sub-selector. No new RPC mocking logic; all fixes are in the test infrastructure (page-object + selector usage). No backend or frontend source changes. bun run type:check clean.
1 parent b07f4f4 commit 488c77d

4 files changed

Lines changed: 42 additions & 5 deletions

File tree

frontend/tests/test-variant-console/acls/acl-create-error.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ test.describe('ACL creation - Connect RPC error handling', () => {
4747
await aclPage.setPrincipal(`err-${Date.now()}`);
4848
await aclPage.setHost('*');
4949
await aclPage.configureRules([MINIMAL_RULE]);
50-
await aclPage.submitForm();
50+
await aclPage.submitFormExpectingError('http-error');
5151

5252
// Structural: mock fails the create, so page must stay on /create and NOT reach detail.
5353
await expect(page).toHaveURL(/\/security\/acls\/create/);
@@ -70,7 +70,7 @@ test.describe('ACL creation - Connect RPC error handling', () => {
7070
await aclPage.setPrincipal(`timeout-${Date.now()}`);
7171
await aclPage.setHost('*');
7272
await aclPage.configureRules([MINIMAL_RULE]);
73-
await aclPage.submitForm();
73+
await aclPage.submitFormExpectingError('network-abort');
7474

7575
// Structural: URL still /create.
7676
await expect(page).toHaveURL(/\/security\/acls\/create/);

frontend/tests/test-variant-console/acls/acl-delete-multi-match.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ test.describe
6565

6666
// Verify all ACLs for this principal are gone from the ACLs list.
6767
await page.goto('/security/acls', { waitUntil: 'domcontentloaded' });
68-
await page.getByTestId('search-field-input').getByRole('textbox').fill(principal);
68+
// Match acl.spec.ts pattern — `.fill()` on the testid'd wrapper, no role sub-selector.
69+
await page.getByTestId('search-field-input').fill(principal);
6970
await expect(page.getByTestId(`acl-list-item-${principal}-*`)).not.toBeVisible({ timeout: 5000 });
7071
await expect(page.getByTestId(`acl-list-item-${principal}-1.1.1.1`)).not.toBeVisible({ timeout: 5000 });
7172

frontend/tests/test-variant-console/acls/acl-principal-special-chars.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ test.describe('ACL principal URL encoding', () => {
4545
// Structural: URL correctly encodes the ":" as %3A.
4646
expect(page.url()).toContain(encoded);
4747

48-
// Return to list and search for the row.
48+
// Return to list and search for the row. Match existing acl.spec.ts pattern —
49+
// `.fill()` on the testid'd SearchField wrapper directly, not via .getByRole('textbox')
50+
// (the Redpanda UI SearchField does not expose an inner textbox role).
4951
await page.goto('/security/acls', { waitUntil: 'domcontentloaded' });
50-
await page.getByTestId('search-field-input').getByRole('textbox').fill(principal);
52+
await page.getByTestId('search-field-input').fill(principal);
5153
await expect(page.getByTestId(`acl-list-item-${principal}-*`)).toBeVisible({ timeout: 5000 });
5254

5355
// Click the row → detail URL again round-trips with encoded principal.

frontend/tests/test-variant-console/utils/acl-page.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,40 @@ export class AclPage {
336336
await responsePromise; // Wait for API response
337337
}
338338

339+
/**
340+
* Form submission for tests that mock an ACL RPC error.
341+
* - kind: 'http-error' → waits for a 4xx/5xx response (e.g., when using route.fulfill)
342+
* - kind: 'network-abort' → does NOT wait for a response (e.g., when using route.abort),
343+
* because an aborted request never produces a response frame
344+
*/
345+
async submitFormExpectingError(kind: 'http-error' | 'network-abort' = 'http-error') {
346+
const submitButton = this.page.getByTestId('submit-acl-button').first();
347+
await submitButton.waitFor({ state: 'visible' });
348+
await submitButton.scrollIntoViewIfNeeded();
349+
350+
if (kind === 'network-abort') {
351+
await submitButton.click();
352+
return;
353+
}
354+
355+
const responsePromise = this.page.waitForResponse(
356+
(response) => {
357+
const url = response.url();
358+
const method = response.request().method();
359+
const status = response.status();
360+
return (
361+
(url.includes('ACLService/CreateACL') || url.includes('ACLService/DeleteACLs')) &&
362+
method === 'POST' &&
363+
status >= 400
364+
);
365+
},
366+
{ timeout: 60_000 }
367+
);
368+
369+
await submitButton.click();
370+
await responsePromise;
371+
}
372+
339373
/**
340374
* Summary validation methods
341375
*/

0 commit comments

Comments
 (0)