160 lines
7.7 KiB
TypeScript
160 lines
7.7 KiB
TypeScript
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);
|
|
});
|