import { expect, test, type Locator } from "@playwright/test"; const tableOnlyCards = ["direct-table", "collapsible-table", "loading-table", "admin-table", "loading-admin-table", "connection-table", "loading-connection-table", "explicit-table"]; async function expectFlush(card: Locator) { const geometry = await card.evaluate((element) => { const body = element.querySelector(".card-body")!; const surface = element.querySelector(".data-grid-shell, .connection-tree")!; const cardRect = element.getBoundingClientRect(); const bodyRect = body.getBoundingClientRect(); const rect = surface.getBoundingClientRect(); const grid = surface.querySelector(".data-grid"); const scrollRegion = surface.querySelector(".data-grid-scroll-region"); return { left: rect.left - cardRect.left, right: cardRect.right - rect.right, top: rect.top - bodyRect.top, bottom: cardRect.bottom - rect.bottom, padding: getComputedStyle(body).padding, border: getComputedStyle(surface).borderWidth, unfilledWidth: grid && scrollRegion ? scrollRegion.clientWidth - grid.getBoundingClientRect().width : 0 }; }); expect(geometry.padding).toBe("0px"); expect(geometry.border).toBe("0px"); expect(geometry.unfilledWidth).toBeLessThanOrEqual(1); for (const edge of [geometry.left, geometry.right, geometry.top, geometry.bottom]) expect(Math.abs(edge)).toBeLessThanOrEqual(1); } for (const width of [1280, 390, 320]) { test(`table-only cards use their full interior without negative margins at ${width}px`, async ({ page }) => { const errors: string[] = []; page.on("pageerror", (error) => errors.push(error.message)); await page.setViewportSize({ width, height: 900 }); await page.goto("/?data-grid-layout&table-cards&language=en&theme=light"); for (const id of tableOnlyCards) await expectFlush(page.getByTestId(id)); for (const id of ["mixed-content", "loading-mixed-content"]) { const body = page.getByTestId(id).locator(".card-body"); await expect(body).toHaveCSS("padding", "22px 24px"); await expect(body.locator(".data-grid-shell")).toHaveCSS("border-width", "1px"); } const context = page.getByTestId("table-with-context"); await expect(context.locator(".card-body")).toHaveCSS("padding", "0px"); await expect(context.locator(".content-section")).toHaveCSS("padding", "18px"); const contextBounds = await context.boundingBox(); const contextGrid = await context.locator(".data-grid-shell").boundingBox(); expect(contextGrid!.x - contextBounds!.x).toBeCloseTo(1, 0); expect(contextBounds!.width - contextGrid!.width).toBeCloseTo(2, 0); await expect(page.getByTestId("standalone-table").locator(".data-grid-shell")).toHaveCSS("border-width", "1px"); expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth + 1)).toBe(true); expect(errors).toEqual([]); }); } test("loading overlays and collapse do not change table insets or lose row actions", async ({ page }) => { await page.setViewportSize({ width: 390, height: 900 }); await page.goto("/?data-grid-layout&table-cards&language=en&theme=light"); const before = await page.getByTestId("loading-table").boundingBox(); await page.getByRole("button", { name: "Toggle loading", exact: true }).click(); for (const id of ["loading-table", "loading-admin-table", "loading-connection-table", "explicit-table"]) { const card = page.getByTestId(id); await expectFlush(card); const frame = await card.locator(".loading-frame").boundingBox(); const overlay = await card.locator(".loading-frame-overlay").boundingBox(); expect(overlay).toEqual(frame); await expect(card.locator(".loading-frame")).toHaveAttribute("aria-busy", "true"); } expect(await page.getByTestId("loading-table").boundingBox()).toEqual(before); await page.getByRole("button", { name: "Toggle loading", exact: true }).click(); const collapsible = page.getByTestId("collapsible-table"); await collapsible.locator(".card-collapse-toggle").click(); await expect(collapsible.locator(".data-grid-shell")).toHaveCount(0); await collapsible.locator(".card-collapse-toggle").click(); await expectFlush(collapsible); const direct = page.getByTestId("direct-table"); const scroller = direct.locator(".data-grid-scroll-region"); expect(await scroller.evaluate((element) => element.scrollWidth > element.clientWidth)).toBe(true); await scroller.evaluate((element) => { element.scrollLeft = element.scrollWidth; }); const action = direct.getByRole("button", { name: "Inspect Alpha", exact: true }); await action.click(); await expect(page.getByTestId("card-table-inspected")).toHaveText("Alpha"); });