From 9ddc96057800f7f9f199f7958b6e60a2adbaabed Mon Sep 17 00:00:00 2001 From: Hein Date: Tue, 17 Feb 2026 00:06:15 +0200 Subject: [PATCH] feat(tests): add comprehensive tree structure tests for various modes --- tests/e2e/tree-hierarchical.spec.ts | 381 ++++++++++++++++++++++++++++ 1 file changed, 381 insertions(+) create mode 100644 tests/e2e/tree-hierarchical.spec.ts diff --git a/tests/e2e/tree-hierarchical.spec.ts b/tests/e2e/tree-hierarchical.spec.ts new file mode 100644 index 0000000..c876750 --- /dev/null +++ b/tests/e2e/tree-hierarchical.spec.ts @@ -0,0 +1,381 @@ +import { expect, test } from '@playwright/test'; + +// Helper to navigate to a story inside the Storybook iframe +async function gotoStory(page: any, storyId: string) { + await page.goto(`/iframe.html?id=components-griddy--${storyId}&viewMode=story`); + await page.waitForSelector('[role="grid"]', { timeout: 10000 }); +} + +// Helper to get all visible row text content (from first gridcell in each row) +async function getVisibleRowNames(page: any): Promise { + const cells = page.locator('[role="row"] [role="gridcell"]:first-child'); + const count = await cells.count(); + const names: string[] = []; + for (let i = 0; i < count; i++) { + const text = await cells.nth(i).innerText(); + names.push(text.trim()); + } + return names; +} + +// Helper to click the expand button within a row that contains the given text +async function clickExpandButton(page: any, rowText: string) { + const row = page.locator('[role="row"]', { hasText: rowText }); + const expandBtn = row.locator('button').first(); + await expandBtn.click(); +} + +// ─── 1. Tree Nested Mode ────────────────────────────────────────────────────── + +test.describe('Tree Nested Mode', () => { + test.beforeEach(async ({ page }) => { + await gotoStory(page, 'tree-nested-mode'); + }); + + test('renders root-level rows collapsed by default', async ({ page }) => { + const rows = page.locator('[role="row"]'); + // Header row + 3 root rows (Engineering, Design, Sales) + await expect(rows).toHaveCount(4); + + await expect(page.locator('[role="row"]', { hasText: 'Engineering' })).toBeVisible(); + await expect(page.locator('[role="row"]', { hasText: 'Design' })).toBeVisible(); + await expect(page.locator('[role="row"]', { hasText: 'Sales' })).toBeVisible(); + }); + + test('expanding a root node reveals children', async ({ page }) => { + await clickExpandButton(page, 'Engineering'); + await expect(page.locator('[role="row"]', { hasText: 'Frontend Team' })).toBeVisible(); + await expect(page.locator('[role="row"]', { hasText: 'Backend Team' })).toBeVisible(); + }); + + test('expanding a child node reveals leaf nodes', async ({ page }) => { + await clickExpandButton(page, 'Engineering'); + await expect(page.locator('[role="row"]', { hasText: 'Frontend Team' })).toBeVisible(); + + await clickExpandButton(page, 'Frontend Team'); + await expect(page.locator('[role="row"]', { hasText: 'Alice Johnson' })).toBeVisible(); + await expect(page.locator('[role="row"]', { hasText: 'Bob Smith' })).toBeVisible(); + }); + + test('collapsing a parent hides all children', async ({ page }) => { + // Expand Engineering + await clickExpandButton(page, 'Engineering'); + await expect(page.locator('[role="row"]', { hasText: 'Frontend Team' })).toBeVisible(); + + // Collapse Engineering + await clickExpandButton(page, 'Engineering'); + await expect(page.locator('[role="row"]', { hasText: 'Frontend Team' })).not.toBeVisible(); + await expect(page.locator('[role="row"]', { hasText: 'Backend Team' })).not.toBeVisible(); + }); + + test('leaf nodes have no expand button', async ({ page }) => { + await clickExpandButton(page, 'Engineering'); + await clickExpandButton(page, 'Frontend Team'); + + const leafRow = page.locator('[role="row"]', { hasText: 'Alice Johnson' }); + await expect(leafRow).toBeVisible(); + // Leaf nodes render a instead of