import { expect, test } from '@playwright/test'; import { defaultState } from '../src/lib/defaults'; import { decodeState, encodeState } from '../src/lib/url-state'; test.beforeEach(async ({ page }) => { await page.goto('/?planner'); await expect(page.getByRole('heading', { name: 'Room measurements', exact: true })).toBeVisible(); }); test('new plans start random and guide custom measurements through to the cut plan', async ({ page, }) => { await expect(page.getByRole('button', { name: 'Random', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); await expect(page.locator('#custom-shape-help')).toContainText('Click Custom'); await page.getByRole('button', { name: 'Custom', exact: true }).click(); await expect(page.getByRole('button', { name: 'Custom', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); await expect(page.getByLabel('Wall 1 length', { exact: true })).toBeVisible(); await page.getByRole('button', { name: 'Add a wall', exact: true }).click(); await page.getByLabel('Wall 2 length', { exact: true }).fill('3000'); await page.getByRole('button', { name: 'Add a wall', exact: true }).click(); await page.getByLabel('Wall 3 length', { exact: true }).fill('4000'); await page.getByRole('button', { name: 'Add closing wall', exact: true }).click(); await expect(page.getByText('Outline closed', { exact: true })).toBeVisible(); await expect(page.getByLabel('Wall 4 length', { exact: true })).toBeVisible(); await expect(page.getByRole('button', { name: 'Custom', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); await page.getByRole('button', { name: 'Materials', exact: true }).click(); await expect(page.getByLabel('Board length', { exact: true })).toBeHidden(); await page.getByRole('button', { name: 'Materials', exact: true }).click(); await expect(page.getByRole('button', { name: 'Materials', exact: true })).toBeFocused(); await expect(page.getByLabel('Board length', { exact: true })).toBeVisible(); await expect(page.getByLabel('Saw kerf', { exact: true })).toBeHidden(); await page.getByText('Advanced flooring settings', { exact: true }).click(); await page.getByLabel('Saw kerf', { exact: true }).fill('4'); expect(decodeState(new URL(page.url()).search).state.project.flooring.kerf).toBe(4); await page.getByRole('button', { name: 'Cut plan', exact: true }).click(); await page.getByRole('button', { name: 'Cut plan', exact: true }).click(); await expect(page.getByRole('button', { name: 'Cut plan', exact: true })).toBeFocused(); await expect(page.getByLabel('Find a cut or room', { exact: true })).toBeVisible(); }); test('the top switch shows one material and preserves inputs and progress across reloads', async ({ page, }) => { const preview = page.getByRole('region', { name: 'Floor plan preview' }); const toggle = page.getByRole('group', { name: 'Plan view', exact: true }); await expect(toggle.getByRole('button', { name: 'Floorboards', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); expect(await preview.locator('.floor-piece').count()).toBeGreaterThan(0); await expect(preview.locator('.skirt-piece')).toHaveCount(0); await page.locator('.stock-cut-group input[type="checkbox"]').first().check(); const project = decodeState(new URL(page.url()).search).state.project; await toggle.getByRole('button', { name: 'Skirting', exact: true }).click(); await expect(preview.locator('.floor-piece')).toHaveCount(0); expect(await preview.locator('.skirt-piece').count()).toBeGreaterThan(0); await expect(preview.getByText('Flooring cuts', { exact: true })).toHaveCount(0); expect(decodeState(new URL(page.url()).search).state.project).toEqual(project); await page.reload(); await expect(toggle.getByRole('button', { name: 'Skirting', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); await expect(preview.locator('.floor-piece')).toHaveCount(0); await page.goto('/?planner'); await expect(toggle.getByRole('button', { name: 'Skirting', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); expect(decodeState(new URL(page.url()).search).state.project).toEqual(project); await toggle.getByRole('button', { name: 'Floorboards', exact: true }).click(); expect(await preview.locator('.floor-piece').count()).toBeGreaterThan(0); await expect(preview.locator('.skirt-piece')).toHaveCount(0); }); test('saved brick plans keep their pattern and explicit links restore the selected material', async ({ page, }) => { const state = defaultState(); state.project.flooring.pattern = 'brick'; state.view.material = 'skirting'; await page.goto(`/${encodeState(state)}`); await expect(page.getByRole('button', { name: 'Brick', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); await expect( page .getByRole('group', { name: 'Plan view' }) .getByRole('button', { name: 'Skirting', exact: true }), ).toHaveAttribute('aria-pressed', 'true'); await page.goto('/?planner'); await expect(page.getByRole('button', { name: 'Brick', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); }); test('locating cuts changes material automatically and printing includes both materials', async ({ page, }) => { const preview = page.getByRole('region', { name: 'Floor plan preview' }); const toggle = page.getByRole('group', { name: 'Plan view', exact: true }); await page.locator('.skirting-cuts .board-group-actions .board-locate').first().click(); await expect(toggle.getByRole('button', { name: 'Skirting', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); expect(await preview.locator('.skirt-piece[data-highlighted="true"]').count()).toBeGreaterThan(0); await page.getByRole('button', { name: 'Show all pieces', exact: true }).click(); await page.getByLabel('Find a cut or room', { exact: true }).fill('F1'); await expect(toggle.getByRole('button', { name: 'Floorboards', exact: true })).toHaveAttribute( 'aria-pressed', 'true', ); await expect(preview.locator('.floor-piece[data-piece-id="F1"]')).toHaveAttribute( 'data-highlighted', 'true', ); await toggle.getByRole('button', { name: 'Skirting', exact: true }).click(); await expect(page.getByRole('button', { name: 'Show all pieces', exact: true })).toHaveCount(0); await preview .getByRole('button', { name: /^Select skirting cut / }) .first() .click(); await expect(page.getByRole('dialog')).toBeVisible(); await page.keyboard.press('Escape'); await page.emulateMedia({ media: 'print' }); expect(await page.locator('.print-plan .floor-piece').count()).toBeGreaterThan(0); expect(await page.locator('.print-plan .skirt-piece').count()).toBeGreaterThan(0); }); test('setup and the pinned view switch fit a narrow phone', async ({ page }) => { await page.setViewportSize({ width: 320, height: 844 }); await page.getByRole('button', { name: 'Materials', exact: true }).scrollIntoViewIfNeeded(); const heading = await page.getByRole('button', { name: 'Materials', exact: true }).boundingBox(); const drawing = await page.getByRole('complementary', { name: 'Room drawing' }).boundingBox(); expect(heading!.y).toBeGreaterThanOrEqual(drawing!.y + drawing!.height); await page .getByRole('group', { name: 'Plan view' }) .getByRole('button', { name: 'Skirting', exact: true }) .click(); await page.getByText('Advanced flooring settings', { exact: true }).click(); await page.getByText('Advanced skirting settings', { exact: true }).click(); expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(320); const toggle = await page.getByRole('group', { name: 'Plan view' }).boundingBox(); expect(toggle!.y).toBeGreaterThanOrEqual(0); expect(toggle!.y + toggle!.height).toBeLessThan(844); });