From 5cce2eb580b4dc9d410262c13bf8452b4ba92b74 Mon Sep 17 00:00:00 2001 From: Robb Hamilton Date: Tue, 28 Jul 2026 10:45:12 -0400 Subject: [PATCH 1/3] Replace page.locator('[data-test-id=...]') with getByTestId() Add data-test attributes alongside existing data-test-id attributes in React source components so Playwright's getByTestId() can target them (testIdAttribute is configured to match data-test). Then replace all page.locator('[data-test-id="..."]') calls with idiomatic getByTestId() in e2e tests and page objects. Co-Authored-By: Claude Opus 4.6 --- frontend/e2e/pages/base-page.ts | 4 ++-- .../console/app/poll-console-updates.spec.ts | 2 +- .../alertmanager/alertmanager.spec.ts | 15 +++++++-------- .../crd-extensions/console-cli-download.spec.ts | 2 +- .../e2e/tests/smoke/developer/smoke-test.spec.ts | 2 +- .../nodes/node-dashboard/DetailsCard.tsx | 2 +- .../src/components/dashboard/Dashboard.tsx | 2 +- frontend/public/components/command-line-tools.tsx | 4 +++- .../components/modals/alert-routing-modal.tsx | 4 ++++ 9 files changed, 21 insertions(+), 16 deletions(-) diff --git a/frontend/e2e/pages/base-page.ts b/frontend/e2e/pages/base-page.ts index 21c86aa2098..d5c5e478583 100644 --- a/frontend/e2e/pages/base-page.ts +++ b/frontend/e2e/pages/base-page.ts @@ -166,14 +166,14 @@ export default abstract class BasePage { Administrator: ['Administrator', 'Core platform'], Developer: ['Developer'], }; - const toggle = this.page.locator('[data-test-id="perspective-switcher-toggle"]'); + const toggle = this.page.getByTestId('perspective-switcher-toggle'); const labels = labelMap[target] || [target]; const currentText = (await toggle.textContent()) || ''; if (labels.some((label) => currentText.includes(label))) { return; } await this.robustClick(toggle); - const menuOption = this.page.locator('[data-test-id="perspective-switcher-menu-option"]'); + const menuOption = this.page.getByTestId('perspective-switcher-menu-option'); for (const label of labels) { const option = menuOption.filter({ hasText: label }); if ((await option.count()) > 0) { diff --git a/frontend/e2e/tests/console/app/poll-console-updates.spec.ts b/frontend/e2e/tests/console/app/poll-console-updates.spec.ts index 69859f9678a..b71fa120959 100644 --- a/frontend/e2e/tests/console/app/poll-console-updates.spec.ts +++ b/frontend/e2e/tests/console/app/poll-console-updates.spec.ts @@ -65,7 +65,7 @@ async function navigateAndWaitForInit(page: Page) { try { await page.goto('/'); - await expect(page.locator('[data-test-id="dashboard"]').first()).toBeVisible({ + await expect(page.getByTestId('dashboard').first()).toBeVisible({ timeout: 60_000, }); await initPromise; diff --git a/frontend/e2e/tests/console/cluster-settings/alertmanager/alertmanager.spec.ts b/frontend/e2e/tests/console/cluster-settings/alertmanager/alertmanager.spec.ts index 4977a28a7c5..c38441f023d 100644 --- a/frontend/e2e/tests/console/cluster-settings/alertmanager/alertmanager.spec.ts +++ b/frontend/e2e/tests/console/cluster-settings/alertmanager/alertmanager.spec.ts @@ -53,14 +53,13 @@ test.describe('Alertmanager', { tag: ['@admin'] }, () => { await page.getByTestId('edit-alert-routing-btn').click(); - // Edit routing values (using legacy test IDs) - await page.locator('[data-test-id="input-group-by"]').fill(', cluster'); - await page.locator('[data-test-id="input-group-wait"]').clear(); - await page.locator('[data-test-id="input-group-wait"]').fill('60s'); - await page.locator('[data-test-id="input-group-interval"]').clear(); - await page.locator('[data-test-id="input-group-interval"]').fill('10m'); - await page.locator('[data-test-id="input-repeat-interval"]').clear(); - await page.locator('[data-test-id="input-repeat-interval"]').fill('24h'); + await page.getByTestId('input-group-by').fill(', cluster'); + await page.getByTestId('input-group-wait').clear(); + await page.getByTestId('input-group-wait').fill('60s'); + await page.getByTestId('input-group-interval').clear(); + await page.getByTestId('input-group-interval').fill('10m'); + await page.getByTestId('input-repeat-interval').clear(); + await page.getByTestId('input-repeat-interval').fill('24h'); await page.getByTestId('confirm-action').click(); diff --git a/frontend/e2e/tests/console/crd-extensions/console-cli-download.spec.ts b/frontend/e2e/tests/console/crd-extensions/console-cli-download.spec.ts index 44f1dafbc3f..5baadbda3ea 100644 --- a/frontend/e2e/tests/console/crd-extensions/console-cli-download.spec.ts +++ b/frontend/e2e/tests/console/crd-extensions/console-cli-download.spec.ts @@ -67,7 +67,7 @@ test.describe(`${crd} CRD`, { tag: ['@admin'] }, () => { await test.step('Verify instance appears on Command Line Tools page', async () => { await page.goto('/command-line-tools'); - await expect(page.locator(`[data-test-id="${name}"]`)).toContainText(name); + await expect(page.getByTestId(name)).toContainText(name); }); await test.step('Delete the ConsoleCLIDownload instance', async () => { diff --git a/frontend/e2e/tests/smoke/developer/smoke-test.spec.ts b/frontend/e2e/tests/smoke/developer/smoke-test.spec.ts index 14783ff3d0c..f6392e4182e 100644 --- a/frontend/e2e/tests/smoke/developer/smoke-test.spec.ts +++ b/frontend/e2e/tests/smoke/developer/smoke-test.spec.ts @@ -3,6 +3,6 @@ import { test, expect } from '../../../fixtures'; test('console loads in developer perspective', async ({ page }) => { await page.goto('/'); await expect( - page.locator('[data-test-id="perspective-switcher-toggle"]'), + page.getByTestId('perspective-switcher-toggle'), ).toContainText('Developer', { timeout: 60_000 }); }); diff --git a/frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx b/frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx index dd3b54379d3..9ec611e33c0 100644 --- a/frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx +++ b/frontend/packages/console-app/src/components/nodes/node-dashboard/DetailsCard.tsx @@ -38,7 +38,7 @@ const DetailsCard: FC = () => { const nodeGroups = useMemo(() => getNodeGroups(obj).sort().join(', ') || DASH, [obj]); return ( - + = ({ className, children }) => ( - + {children} ); diff --git a/frontend/public/components/command-line-tools.tsx b/frontend/public/components/command-line-tools.tsx index 62d015b53ca..b8e0783b63f 100644 --- a/frontend/public/components/command-line-tools.tsx +++ b/frontend/public/components/command-line-tools.tsx @@ -37,7 +37,9 @@ export const CommandLineTools: FC = ({ obj }) => { return ( {index > 0 && } - {displayName} + + {displayName} + {sortedLinks.length === 1 && (

diff --git a/frontend/public/components/modals/alert-routing-modal.tsx b/frontend/public/components/modals/alert-routing-modal.tsx index 84b97b5051c..a0b1c2e948c 100644 --- a/frontend/public/components/modals/alert-routing-modal.tsx +++ b/frontend/public/components/modals/alert-routing-modal.tsx @@ -79,6 +79,7 @@ const AlertRoutingModal: FC = ({ config, secret, cancel, defaultValue={_.get(config, ['route', 'group_by'], []).join(', ')} placeholder="cluster, alertname" aria-describedby="input-group-by-help" + data-test="input-group-by" data-test-id="input-group-by" /> @@ -90,6 +91,7 @@ const AlertRoutingModal: FC = ({ config, secret, cancel, defaultValue={_.get(config, ['route', 'group_wait'], '')} placeholder="30s" aria-describedby="input-group-wait-help" + data-test="input-group-wait" data-test-id="input-group-wait" /> @@ -101,6 +103,7 @@ const AlertRoutingModal: FC = ({ config, secret, cancel, defaultValue={_.get(config, ['route', 'group_interval'], '')} placeholder="5m" aria-describedby="input-group-interval-help" + data-test="input-group-interval" data-test-id="input-group-interval" /> @@ -112,6 +115,7 @@ const AlertRoutingModal: FC = ({ config, secret, cancel, defaultValue={_.get(config, ['route', 'repeat_interval'], '')} placeholder="3h" aria-describedby="input-repeat-interval-help" + data-test="input-repeat-interval" data-test-id="input-repeat-interval" /> From 85d29720232daf7e30b7b6dc0b1d5cb206ebd255 Mon Sep 17 00:00:00 2001 From: Robb Hamilton Date: Tue, 28 Jul 2026 11:07:15 -0400 Subject: [PATCH 2/3] Replace page.locator('[data-test-selector=...]') with getByTestId() Add data-test attribute alongside existing data-test-selector on the DetailsItem label element in details-item.tsx (the value element already had one). Then replace all page.locator('[data-test-selector="..."]') calls with getByTestId() in console-notification.spec.ts. Co-Authored-By: Claude Opus 4.6 --- .../console-notification.spec.ts | 22 +++++-------------- .../public/components/utils/details-item.tsx | 1 + 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts b/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts index b14968b63e1..2ae8f5c51e5 100644 --- a/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts +++ b/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts @@ -75,22 +75,12 @@ test.describe(`${crd} CRD`, { tag: ['@admin'] }, () => { await expect(page.getByRole('heading', { name })).toBeVisible(); await expect(page.getByTestId('additional-printer-columns')).toBeVisible(); - await expect(page.locator('[data-test-selector="details-item-label__Text"]')).toHaveText( - 'Text', - ); - await expect(page.locator('[data-test-selector="details-item-value__Text"]')).toHaveText( - text, - ); - await expect( - page.locator('[data-test-selector="details-item-label__Location"]'), - ).toHaveText('Location'); - await expect( - page.locator('[data-test-selector="details-item-value__Location"]'), - ).toHaveText(location); - await expect(page.locator('[data-test-selector="details-item-label__Age"]')).toHaveText( - 'Age', - ); - await expect(page.locator('[data-test-selector="details-item-value__Age"]')).toBeVisible(); + await expect(page.getByTestId('details-item-label__Text')).toHaveText('Text'); + await expect(page.getByTestId('details-item-value__Text')).toHaveText(text); + await expect(page.getByTestId('details-item-label__Location')).toHaveText('Location'); + await expect(page.getByTestId('details-item-value__Location')).toHaveText(location); + await expect(page.getByTestId('details-item-label__Age')).toHaveText('Age'); + await expect(page.getByTestId('details-item-value__Age')).toBeVisible(); }); await test.step('Verify notification banner appears', async () => { diff --git a/frontend/public/components/utils/details-item.tsx b/frontend/public/components/utils/details-item.tsx index 7305e2fce80..e731aa853a1 100644 --- a/frontend/public/components/utils/details-item.tsx +++ b/frontend/public/components/utils/details-item.tsx @@ -82,6 +82,7 @@ export const DetailsItem: FC = ({ return hide ? null : ( From c344267d14fb87ce0c074041d9affb1e3966876b Mon Sep 17 00:00:00 2001 From: Robb Hamilton Date: Tue, 28 Jul 2026 11:32:35 -0400 Subject: [PATCH 3/3] Replace locator('[data-test=...]') with getByTestId() Co-Authored-By: Claude Opus 4.6 --- frontend/e2e/pages/cluster-settings-page.ts | 2 +- .../e2e/tests/console/cluster-settings/channel-modal.spec.ts | 2 +- .../tests/console/crd-extensions/console-notification.spec.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/e2e/pages/cluster-settings-page.ts b/frontend/e2e/pages/cluster-settings-page.ts index b6cb53754e2..59afb0521bc 100644 --- a/frontend/e2e/pages/cluster-settings-page.ts +++ b/frontend/e2e/pages/cluster-settings-page.ts @@ -67,7 +67,7 @@ export class ClusterSettingsPage extends BasePage { * Open the channel dropdown and select a channel (for "Select channel" modal) */ async selectChannelFromDropdown(channelName: string): Promise { - const dropdownToggle = this.channelModal.locator('[data-test="console-select-menu-toggle"]'); + const dropdownToggle = this.channelModal.getByTestId('console-select-menu-toggle'); await this.robustClick(dropdownToggle); const channelOption = this.page.locator(`[data-test-dropdown-menu="${channelName}"]`); diff --git a/frontend/e2e/tests/console/cluster-settings/channel-modal.spec.ts b/frontend/e2e/tests/console/cluster-settings/channel-modal.spec.ts index f3e36281420..cda597ef54f 100644 --- a/frontend/e2e/tests/console/cluster-settings/channel-modal.spec.ts +++ b/frontend/e2e/tests/console/cluster-settings/channel-modal.spec.ts @@ -49,7 +49,7 @@ test.describe('Cluster Settings channel modal', { tag: ['@admin', '@smoke'] }, ( const dropdown = clusterSettings .getChannelModal() - .locator('[data-test="console-select-menu-toggle"]'); + .getByTestId('console-select-menu-toggle'); await expect(dropdown).toBeVisible(); await clusterSettings.page.keyboard.press('Escape'); diff --git a/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts b/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts index 2ae8f5c51e5..a64bb628ec9 100644 --- a/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts +++ b/frontend/e2e/tests/console/crd-extensions/console-notification.spec.ts @@ -84,7 +84,7 @@ test.describe(`${crd} CRD`, { tag: ['@admin'] }, () => { }); await test.step('Verify notification banner appears', async () => { - const notification = page.locator(`[data-test="${name}-${location}"]`); + const notification = page.getByTestId(`${name}-${location}`); await expect(notification).toBeVisible(); await expect(notification).toContainText(text); }); @@ -100,7 +100,7 @@ test.describe(`${crd} CRD`, { tag: ['@admin'] }, () => { }); await test.step('Verify modified notification banner appears', async () => { - const altNotification = page.locator(`[data-test="${name}-${altLocation}"]`); + const altNotification = page.getByTestId(`${name}-${altLocation}`); await expect(altNotification).toBeVisible(); await expect(altNotification).toContainText(altText); });