Skip to content

Commit 8e89743

Browse files
committed
fix failing e2e tests
1 parent 2ef0688 commit 8e89743

5 files changed

Lines changed: 26 additions & 15 deletions

File tree

test/e2e/breadcrumbs.e2e.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
import { expect, test, type Page } from '@playwright/test'
1010

1111
async function getCrumbs(page: Page) {
12-
const links = await page
13-
.getByRole('navigation', { name: 'Breadcrumbs' })
14-
.getByRole('link')
15-
.all()
12+
// CSS locator instead of getByRole so we can still read breadcrumbs while a
13+
// dialog is open — base-ui sets aria-hidden on outside content, which hides
14+
// the nav from the accessibility tree.
15+
const links = await page.locator('nav[aria-label="Breadcrumbs"] a').all()
1616
return Promise.all(
1717
links.map(async (link) => [await link.textContent(), await link.getAttribute('href')])
1818
)

test/e2e/instance.e2e.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
closeToast,
1212
expect,
1313
expectRowVisible,
14+
fillNumberInput,
1415
test,
1516
type Page,
1617
} from './utils'
@@ -168,8 +169,8 @@ test('can resize a failed or stopped instance', async ({ page }) => {
168169
await clickRowAction(page, 'you-fail', 'Resize')
169170
const resizeModal = page.getByRole('dialog', { name: 'Resize instance' })
170171
await expect(resizeModal).toBeVisible()
171-
await resizeModal.getByRole('textbox', { name: 'vCPUs' }).fill('10')
172-
await resizeModal.getByRole('textbox', { name: 'Memory' }).fill('20')
172+
await fillNumberInput(resizeModal.getByRole('textbox', { name: 'vCPUs' }), '10')
173+
await fillNumberInput(resizeModal.getByRole('textbox', { name: 'Memory' }), '20')
173174
await resizeModal.getByRole('button', { name: 'Resize' }).click()
174175
await expectRowVisible(table, {
175176
name: 'you-fail',
@@ -195,8 +196,8 @@ test('can resize a failed or stopped instance', async ({ page }) => {
195196
await expect(resizeModal).toBeVisible()
196197
await expect(resizeModal.getByText('Current (db1): 2 vCPUs / 4 GiB')).toBeVisible()
197198

198-
await resizeModal.getByRole('textbox', { name: 'vCPUs' }).fill('8')
199-
await resizeModal.getByRole('textbox', { name: 'Memory' }).fill('16')
199+
await fillNumberInput(resizeModal.getByRole('textbox', { name: 'vCPUs' }), '8')
200+
await fillNumberInput(resizeModal.getByRole('textbox', { name: 'Memory' }), '16')
200201
await resizeModal.getByRole('button', { name: 'Resize' }).click()
201202
await expectRowVisible(table, {
202203
name: 'db1',
@@ -214,8 +215,8 @@ test('resize modal stays open on server error', async ({ page }) => {
214215
const resizeModal = page.getByRole('dialog', { name: 'Resize instance' })
215216
await expect(resizeModal).toBeVisible()
216217

217-
await resizeModal.getByRole('textbox', { name: 'vCPUs' }).fill('10')
218-
await resizeModal.getByRole('textbox', { name: 'Memory' }).fill('20')
218+
await fillNumberInput(resizeModal.getByRole('textbox', { name: 'vCPUs' }), '10')
219+
await fillNumberInput(resizeModal.getByRole('textbox', { name: 'Memory' }), '20')
219220
await resizeModal.getByRole('button', { name: 'Resize' }).click()
220221

221222
// Error renders inline inside the modal; modal stays open so the user can

test/e2e/nav-guard-modal.e2e.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@ import { expect, expectObscured, test } from './utils'
1010

1111
test('navigating away from SideModal form triggers nav guard', async ({ page }) => {
1212
const floatingIpsPage = '/projects/mock-project/floating-ips'
13-
const formModal = page.getByRole('dialog', { name: 'Create floating IP' })
13+
// CSS locator for the form modal: when the confirmModal opens on top of
14+
// it, base-ui aria-hides the form modal (it's outside the inner dialog's
15+
// portal tree), so role-based locators can't find it.
16+
const formModal = page.locator('[role=dialog]:has(h2:text-is("Create floating IP"))')
1417
const confirmModal = page.getByRole('dialog', { name: 'Confirm navigation' })
1518

1619
await page.goto(floatingIpsPage)
1720

1821
// we don't have to force click here because it's not covered by the modal overlay yet
1922
await expect(formModal).toBeHidden()
20-
const somethingOnPage = page.getByRole('heading', { name: 'Floating IPs' })
23+
// CSS locator so we can still find the heading while the dialog is open —
24+
// base-ui sets aria-hidden on outside content, which hides it from the
25+
// accessibility tree that getByRole walks.
26+
const somethingOnPage = page.locator('h1:has-text("Floating IPs")')
2127
await somethingOnPage.click({ trial: true }) // test that it's not obscured
2228

2329
// now open the modal

test/e2e/vpcs.e2e.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@ test('can create and delete subnet', async ({ page }) => {
126126

127127
test('can create and update subnets with a custom router', async ({ page }) => {
128128
await page.goto('/projects/mock-project/vpcs/mock-vpc/subnets')
129-
await page.getByRole('link', { name: 'New VPC subnet' }).click()
130129

130+
// Check initial table state before opening the dialog — once it's open the
131+
// table is aria-hidden and role-based locators won't find it.
131132
const table = page.getByRole('table')
132133
const rows = table.getByRole('row')
133134
await expect(rows).toHaveCount(3)
@@ -137,6 +138,7 @@ test('can create and update subnets with a custom router', async ({ page }) => {
137138
'IP Block': expect.stringContaining('10.1.1.1/24'),
138139
})
139140

141+
await page.getByRole('link', { name: 'New VPC subnet' }).click()
140142
const dialog = page.getByRole('dialog', { name: 'Create VPC subnet' })
141143
await expect(dialog).toBeVisible()
142144

test/e2e/z-index.e2e.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ test('Dropdown content in SidebarModal shows on screen', async ({ page }) => {
3030

3131
const sidebar = page.getByRole('dialog', { name: 'Add network interface' })
3232

33-
// verify that the SideModal header is positioned above the TopBar
34-
await expectObscured(page.getByRole('button', { name: 'User menu' }))
33+
// verify that the SideModal header is positioned above the TopBar. CSS
34+
// locator instead of getByRole because base-ui sets aria-hidden on outside
35+
// content while the dialog is open.
36+
await expectObscured(page.locator('button[aria-label="User menu"]'))
3537

3638
// test that the form can be submitted and a new network interface is created
3739
await sidebar.getByRole('button', { name: 'Add network interface' }).click()

0 commit comments

Comments
 (0)