Skip to content

Commit ad01f47

Browse files
committed
Add tests for pages that rely on Headless UI
1 parent 6daab1d commit ad01f47

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { test, expect } from "@playwright/test"
2+
3+
test("opens and dismisses calendar menu, all links match expectation", async ({
4+
page,
5+
}) => {
6+
await page.goto("/conf/2025/schedule")
7+
await page.waitForLoadState("networkidle")
8+
9+
const calendarButton = page
10+
.locator('button:has-text("Add to calendar")')
11+
.first()
12+
13+
if ((await calendarButton.count()) === 0) {
14+
test.skip()
15+
}
16+
17+
await calendarButton.scrollIntoViewIfNeeded()
18+
await expect(calendarButton).toBeVisible()
19+
20+
// Test aria-expanded attribute
21+
await expect(calendarButton).toHaveAttribute("aria-expanded", "false")
22+
23+
// Test opening menu
24+
const menuItems = page.locator('[role="menu"]')
25+
await expect(menuItems).not.toBeVisible()
26+
27+
await calendarButton.click()
28+
await expect(menuItems).toBeVisible()
29+
await expect(calendarButton).toHaveAttribute("aria-expanded", "true")
30+
31+
// Test menu contains correct links
32+
const icsLink = menuItems.locator('a:has-text("ICS")')
33+
const googleLink = menuItems.locator('a:has-text("Google")')
34+
const outlookLink = menuItems.locator('a:has-text("Outlook")')
35+
36+
await expect(icsLink).toBeVisible()
37+
await expect(googleLink).toBeVisible()
38+
await expect(outlookLink).toBeVisible()
39+
40+
await expect(icsLink).toHaveAttribute("href", /data:text\/calendar/)
41+
await expect(googleLink).toHaveAttribute("href", /google\.com/)
42+
await expect(outlookLink).toHaveAttribute("href", /outlook\./)
43+
44+
// Test closing menu by clicking outside
45+
await page.mouse.click(10, 10)
46+
await expect(menuItems).not.toBeVisible()
47+
await expect(calendarButton).toHaveAttribute("aria-expanded", "false")
48+
})

test/e2e/conf-filters.spec.ts

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { test, expect } from "@playwright/test"
2+
3+
test("conference schedule filter combinations and results", async ({
4+
page,
5+
}) => {
6+
await page.goto("/conf/2025/schedule")
7+
await page.waitForLoadState("networkidle")
8+
9+
const comboboxOptions = page.locator('[role="listbox"]')
10+
11+
const sessionFormatCombobox = page.getByRole("combobox", {
12+
name: "Session Format",
13+
})
14+
await expect(sessionFormatCombobox).toBeVisible()
15+
16+
await sessionFormatCombobox.click()
17+
await expect(comboboxOptions).toBeVisible()
18+
19+
const graphqlProductionOption = comboboxOptions.locator(
20+
'[role="option"]:has-text("GraphQL in Production")',
21+
)
22+
await expect(graphqlProductionOption).toBeVisible()
23+
await graphqlProductionOption.click()
24+
25+
await page.keyboard.press("Escape")
26+
await expect(comboboxOptions).not.toBeVisible()
27+
28+
const talkCategoryCombobox = page.getByRole("combobox", {
29+
name: "Talk Category",
30+
})
31+
await expect(talkCategoryCombobox).toBeVisible()
32+
33+
await talkCategoryCombobox.click()
34+
await expect(comboboxOptions).toBeVisible()
35+
36+
const securityOption = comboboxOptions.locator(
37+
'[role="option"]:has-text("Security")',
38+
)
39+
await expect(securityOption).toBeVisible()
40+
await securityOption.click()
41+
42+
await page.keyboard.press("Escape")
43+
await expect(comboboxOptions).not.toBeVisible()
44+
45+
const audienceCombobox = page.getByRole("combobox", { name: "Audience" })
46+
await expect(audienceCombobox).toBeVisible()
47+
48+
await audienceCombobox.click()
49+
await expect(comboboxOptions).toBeVisible()
50+
51+
const allAudienceOptions = comboboxOptions.locator('[role="option"]')
52+
const audienceOptionCount = await allAudienceOptions.count()
53+
54+
expect(audienceOptionCount).toBeGreaterThan(0)
55+
56+
const intermediateOption = comboboxOptions.locator(
57+
'[role="option"]:has-text("Intermediate")',
58+
)
59+
await expect(intermediateOption).toBeVisible()
60+
await expect(intermediateOption).not.toHaveAttribute("aria-disabled", "true")
61+
62+
const beginnerOption = comboboxOptions.locator(
63+
'[role="option"]:has-text("Beginner")',
64+
)
65+
await expect(beginnerOption).toBeVisible()
66+
await expect(beginnerOption).toHaveAttribute("aria-disabled", "true")
67+
68+
await page.keyboard.press("Escape")
69+
await expect(comboboxOptions).not.toBeVisible()
70+
71+
await page.keyboard.press("Escape")
72+
73+
const sessionLink = page.locator(
74+
'a[aria-label*="Unlocking Federation Security at Scale in Booking"]',
75+
)
76+
await expect(sessionLink).toBeVisible()
77+
})
78+
79+
test("talk category multi-selection and escape key functionality", async ({
80+
page,
81+
}) => {
82+
await page.goto("/conf/2025/schedule")
83+
await page.waitForLoadState("networkidle")
84+
85+
const comboboxOptions = page.locator('[role="listbox"]')
86+
87+
const talkCategoryCombobox = page.getByRole("combobox", {
88+
name: "Talk Category",
89+
})
90+
await expect(talkCategoryCombobox).toBeVisible()
91+
92+
await talkCategoryCombobox.click()
93+
await expect(comboboxOptions).toBeVisible()
94+
95+
const backendOption = comboboxOptions.locator(
96+
'[role="option"]:has-text("Backend")',
97+
)
98+
const scalingOption = comboboxOptions.locator(
99+
'[role="option"]:has-text("Scaling")',
100+
)
101+
102+
await expect(backendOption).toBeVisible()
103+
await expect(scalingOption).toBeVisible()
104+
105+
await backendOption.click()
106+
107+
await talkCategoryCombobox.click()
108+
await expect(comboboxOptions).toBeVisible()
109+
await scalingOption.click()
110+
111+
await talkCategoryCombobox.click()
112+
await expect(comboboxOptions).toBeVisible()
113+
114+
await page.keyboard.press("Escape")
115+
await expect(comboboxOptions).not.toBeVisible()
116+
})

0 commit comments

Comments
 (0)