test(ui): disambiguate session filter controls

The online-people toolbar added by c1b973aec1 shares the Filter & sort
name prefix and sidebar-session-sort class with the session toolbar.
Playwright substring lookups therefore matched both controls, breaking six
Control UI e2e suites in scheduled main CI run 37054655798.

Match the complete session button name at all 16 ambiguous lookups,
including the shared ownership helper. Also target that exact button in
the owner-header filtered-state assertion, which reproduced the same
collision through the shared class after the first selectors were fixed.
Product code and existing assertions remain unchanged.

Before: six suites failed, nine tests failed, 24 passed (235.19s wall).
After: all 12 relevant suites and 74 tests passed with one worker.
Independent autoreview found no actionable findings.

Test cost: 408.17s wall for node scripts/run-vitest.mjs run --config test/vitest/vitest.ui-e2e.config.ts --configLoader runner <12 e2e files> --maxWorkers=1.
This commit is contained in:
Peter Steinberger 2026-10-02 13:49:23 -07:00
parent 2d8a022362
commit 12e5f8dac6
12 changed files with 17 additions and 17 deletions

View file

@ -784,7 +784,7 @@ suite.define(() => {
.evaluate((label) => getComputedStyle(label).fontWeight);
expect(activeWeight).toBe(inactiveWeight);
const filterAndSort = page.getByRole("button", { name: "Filter & sort" });
const filterAndSort = page.getByRole("button", { name: "Filter & sort", exact: true });
await filterAndSort.click();
await chooseSidebarMenuOption(page, "Sort by", "Last updated");
await closeSidebarMenu(page);

View file

@ -150,7 +150,7 @@ suite.define(() => {
if (restartable) {
await page.getByRole("button", { name: "Unarchive", exact: true }).waitFor();
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await chooseSidebarMenuOption(page, "Status", "All");
await closeSidebarMenu(page);
}

View file

@ -395,7 +395,7 @@ suite.define(() => {
},
],
});
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await chooseSidebarMenuOption(page, "Status", "Archived");
await closeSidebarMenu(page);
await gateway.waitForRequest("sessions.list", {

View file

@ -76,11 +76,11 @@ suite.define(() => {
expect(await gateway.getRequests("sessions.patch")).toEqual([]);
await captureUiProof(suite, page, "agent-archive-after.png");
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await chooseSidebarMenuOption(page, "Status", "Archived");
await closeSidebarMenu(page);
await row.waitFor({ state: "visible" });
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await chooseSidebarMenuOption(page, "Status", "Active");
await closeSidebarMenu(page);
await row.waitFor({ state: "detached" });
@ -121,7 +121,7 @@ suite.define(() => {
try {
await page.goto(`${suite.server.baseUrl}chat`);
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await chooseSidebarMenuOption(page, "Status", "Archived");
await closeSidebarMenu(page);

View file

@ -136,7 +136,7 @@ suite.define(() => {
await page.screenshot({ path: path.join(artifactDir, `${stage}.png`) });
};
const filter = async (label: "Archived" | "All") => {
await sidebar.getByRole("button", { name: "Filter & sort" }).click();
await sidebar.getByRole("button", { name: "Filter & sort", exact: true }).click();
await chooseSidebarMenuOption(sidebar.page(), "Status", label);
await closeSidebarMenu(page);
};

View file

@ -134,7 +134,7 @@ suite.define(() => {
try {
await page.goto(`${suite.server.baseUrl}chat`);
const selectFilter = async (label: "Archived" | "All" | "Active") => {
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await chooseSidebarMenuOption(page, "Status", label);
await closeSidebarMenu(page);
};

View file

@ -694,7 +694,7 @@ suite.define(() => {
// Group by "None" flattens the category sections into the plain list. The
// confirm left the pointer over the dialog rather than the sidebar; the
// global toolbar remains available without revealing a section action.
const filterAndSortButton = page.getByRole("button", { name: "Filter & sort" });
const filterAndSortButton = page.getByRole("button", { name: "Filter & sort", exact: true });
await filterAndSortButton.click();
await openSidebarMenu(page);
const showAutomationSessions = page.getByRole("switch", {
@ -937,7 +937,7 @@ suite.define(() => {
await expect.poll(() => page.locator(".sidebar-recent-session").count()).toBe(11);
const patchCountBeforeFlatDrag = (await gateway.getRequests("sessions.patch")).length;
const filterAndSortButton = page.getByRole("button", { name: "Filter & sort" });
const filterAndSortButton = page.getByRole("button", { name: "Filter & sort", exact: true });
await filterAndSortButton.click();
await chooseSidebarMenuOption(page, "Group by", "None");
await closeSidebarMenu(page);

View file

@ -52,7 +52,7 @@ suite.define(() => {
try {
await page.goto(controlUiSessionUrl(suite.server.baseUrl, "agent:main:owner-0"));
const filter = page.getByRole("button", { name: "Filter & sort" });
const filter = page.getByRole("button", { name: "Filter & sort", exact: true });
const menu = page.locator(".sidebar-session-sort-menu");
await filter.click();
await chooseSidebarMenuOption(menu.page(), "Group by", "Person");

View file

@ -109,7 +109,7 @@ suite.define(() => {
await expectBrowser(bobSection).toHaveCount(0);
await expectBrowser(adaSection.getByText("Ada research", { exact: true })).toBeVisible();
const summary = page.locator(".sidebar-session-filter-summary");
const funnel = page.locator(".sidebar-session-sort");
const funnel = page.getByRole("button", { name: "Filter & sort", exact: true });
await expectBrowser(summary).toBeVisible();
await expectBrowser(summary).toContainText("Ada");
await expectBrowser(summary).toHaveAccessibleName("Ada · Show all sessions");

View file

@ -51,7 +51,7 @@ suite.define(() => {
try {
await page.goto(controlUiSessionUrl(suite.server.baseUrl, "agent:main:ada"));
await waitForSessionRosterHydration(page);
const trigger = page.getByRole("button", { name: "Filter & sort" });
const trigger = page.getByRole("button", { name: "Filter & sort", exact: true });
await trigger.focus();
await page.keyboard.press("Enter");
const menu = page.locator(".sidebar-session-sort-menu");
@ -125,7 +125,7 @@ suite.define(() => {
if (name === "compact") {
await page.getByRole("button", { name: "Expand sidebar" }).click();
}
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await openSidebarMenu(page);
const menu = page.locator(".sidebar-session-sort-menu");
const menuBounds = await menu.locator(".sidebar-session-filter-panel").boundingBox();
@ -180,7 +180,7 @@ suite.define(() => {
await page.goto(controlUiSessionUrl(suite.server.baseUrl, "agent:main:rtl-owners"));
await page.locator("html").evaluate((element) => element.setAttribute("dir", "rtl"));
await page.getByRole("button", { name: "Expand sidebar" }).click();
await page.getByRole("button", { name: "Filter & sort" }).click();
await page.getByRole("button", { name: "Filter & sort", exact: true }).click();
await openSidebarMenu(page);
const menu = page.locator(".sidebar-session-sort-menu");
const owners = menu.locator("#sidebar-sessions-owner");

View file

@ -95,7 +95,7 @@ export async function captureSessionOwnerPageProof(
}
export async function openSidebarSortMenu(page: Page) {
const filterAndSort = page.getByRole("button", { name: "Filter & sort" });
const filterAndSort = page.getByRole("button", { name: "Filter & sort", exact: true });
await expect.poll(() => filterAndSort.count(), { timeout: 2_000 }).toBe(1);
const menu = await openSidebarMenu(page);
await waitForControlUiProofSurface(menu.locator(".sidebar-session-filter-panel"), [

View file

@ -490,7 +490,7 @@ suite.define(() => {
await currentPage.getByText("Ada research", { exact: true }).first().waitFor();
await currentPage.getByText("Bob operations", { exact: true }).first().waitFor();
const filterAndSort = currentPage.getByRole("button", { name: "Filter & sort" });
const filterAndSort = currentPage.getByRole("button", { name: "Filter & sort", exact: true });
await filterAndSort.focus();
await currentPage.keyboard.press("Enter");