Files
TX/artifacts/tx-os/tests/executive-meetings-row-actions-menu.spec.mjs
T
riyadhafraa 5c21bf9737 Improve test to accurately verify meeting row actions menu
Refactor e2e test assertion for executive meeting row actions menu to use a more robust check for kebab visibility and count.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 4624aae4-b60d-45dd-aeaa-32ff564cc1b9
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/wd2kz0e
Replit-Helium-Checkpoint-Created: true
2026-04-30 06:27:40 +00:00

120 lines
4.8 KiB
JavaScript

// Verifies the consolidated row-actions kebab menu introduced as part
// of task #191 — the three previously-separate row overlays (delete,
// row color, merge cells) are now collapsed into a single menu so they
// no longer collide visually inside narrow cells. Each sub-action
// keeps its original testid, so the rest of the suite + any external
// tooling that targeted them keeps working without changes.
import { test, expect } from "@playwright/test";
async function loginViaUi(page, username, password) {
await page.goto("/login");
await page.locator("#username").fill(username);
await page.locator("#password").fill(password);
await Promise.all([
page.waitForURL((url) => !url.pathname.endsWith("/login"), {
timeout: 15_000,
}),
page.locator('form button[type="submit"]').click(),
]);
}
async function ensureEditModeOn(page) {
const toggle = page.getByTestId("em-edit-mode-toggle");
await expect(toggle).toBeVisible();
if ((await toggle.getAttribute("aria-pressed")) === "false") {
await toggle.click();
}
await expect(toggle).toHaveAttribute("aria-pressed", "true");
}
test("Schedule: row actions menu exposes delete + color + merge in a single popover and supports back navigation", async ({
page,
}) => {
await page.addInitScript(() => {
try {
window.localStorage.setItem("tx-lang", "en");
} catch {
/* localStorage may not be ready before navigation */
}
});
await loginViaUi(page, "admin", "admin123");
await page.goto("/executive-meetings");
await ensureEditModeOn(page);
// Exactly one consolidated kebab trigger per row, replacing what used
// to be three separate overlay icons (Trash, Palette, Combine).
// We require at least one row to be present — `>= 1` keeps the assertion
// resilient to the dev DB seed varying across runs while still confirming
// the kebab is mounted at all.
const kebabs = page.locator('[data-testid^="em-row-actions-"]');
const kebabCount = await kebabs.count();
expect(kebabCount).toBeGreaterThanOrEqual(1);
// Should be exactly one kebab per visible meeting row — rule out
// duplicate triggers leaking across multiple cells of the same row.
const visibleRows = await page
.locator('tr[data-testid^="em-row-"]')
.count();
if (visibleRows > 0) {
expect(kebabCount).toBe(visibleRows);
}
const kebab = kebabs.first();
// Closed state: none of the legacy testids are mounted yet.
await expect(page.locator('[data-testid^="em-delete-row-"]')).toHaveCount(0);
await expect(page.getByTestId("em-row-color-trigger")).toHaveCount(0);
await expect(page.locator('[data-testid^="em-merge-trigger-"]')).toHaveCount(
0,
);
// The kebab is opacity-0 until row hover, so force the click.
await kebab.click({ force: true });
// Main menu shows all three legacy testids — preserves selectors used
// elsewhere in the suite.
await expect(page.locator('[data-testid^="em-delete-row-"]')).toHaveCount(1);
await expect(page.getByTestId("em-row-color-trigger")).toHaveCount(1);
await expect(page.locator('[data-testid^="em-merge-trigger-"]')).toHaveCount(
1,
);
// Drill into the Row color sub-view: Delete + Merge get hidden,
// a Back affordance + the swatch row appear.
await page.getByTestId("em-row-color-trigger").click();
await expect(page.locator('[data-testid^="em-delete-row-"]')).toHaveCount(0);
await expect(page.locator('[data-testid^="em-merge-trigger-"]')).toHaveCount(
0,
);
await expect(page.getByTestId("em-row-actions-back")).toBeVisible();
// Back returns to the main 3-item view.
await page.getByTestId("em-row-actions-back").click();
await expect(page.locator('[data-testid^="em-delete-row-"]')).toHaveCount(1);
await expect(page.getByTestId("em-row-color-trigger")).toHaveCount(1);
await expect(page.locator('[data-testid^="em-merge-trigger-"]')).toHaveCount(
1,
);
// Drill into the Merge sub-view — three merge options appear and the
// other items disappear.
await page.locator('[data-testid^="em-merge-trigger-"]').click();
await expect(
page.locator('[data-testid^="em-merge-opt-meeting-attendees-"]'),
).toHaveCount(1);
await expect(
page.locator('[data-testid^="em-merge-opt-meeting-time-"]'),
).toHaveCount(1);
await expect(page.locator('[data-testid^="em-merge-opt-all-"]')).toHaveCount(
1,
);
await expect(page.locator('[data-testid^="em-delete-row-"]')).toHaveCount(0);
await expect(page.getByTestId("em-row-color-trigger")).toHaveCount(0);
// Escape closes the popover entirely.
await page.keyboard.press("Escape");
await expect(page.locator('[data-testid^="em-delete-row-"]')).toHaveCount(0);
await expect(page.getByTestId("em-row-color-trigger")).toHaveCount(0);
await expect(page.locator('[data-testid^="em-merge-trigger-"]')).toHaveCount(
0,
);
});