70 lines
3.3 KiB
TypeScript
70 lines
3.3 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
import { defaultState } from '../src/lib/defaults';
|
|
import { planFlooringOptions } from '../src/lib/flooring';
|
|
import { mm } from '../src/lib/format';
|
|
import { decodeState, encodeState } from '../src/lib/url-state';
|
|
|
|
test('random optimisation choices show actual totals, select the plan and survive reload', async ({
|
|
page,
|
|
isMobile,
|
|
}) => {
|
|
if (isMobile) await page.setViewportSize({ width: 320, height: 844 });
|
|
const state = defaultState();
|
|
state.project.flooring.pattern = 'random';
|
|
const p = state.project;
|
|
const options = planFlooringOptions(p.rooms, p.flooring, p.tolerance);
|
|
await page.goto(`/${encodeState(state)}`);
|
|
const choices = page.getByRole('group', { name: 'Flooring optimisation', exact: true });
|
|
const cuts = choices.getByRole('button', { name: /^Minimise cuts/ });
|
|
const random = choices.getByRole('button', { name: /^Maximise randomness/ });
|
|
await expect(cuts).toHaveAttribute('aria-pressed', 'true');
|
|
await expect(cuts).toContainText(
|
|
`${options.cuts.cuts} cuts · ${mm(options.cuts.wastePercent)}% waste`,
|
|
);
|
|
await expect(random).toContainText(
|
|
`${options.random.cuts} cuts · ${mm(options.random.wastePercent)}% waste`,
|
|
);
|
|
expect(options.cuts.cuts).toBeLessThan(options.random.cuts);
|
|
const checkbox = page.locator('.stock-cut-group input[type="checkbox"]').first();
|
|
await checkbox.check();
|
|
expect(decodeState(new URL(page.url()).search).state.project.completedBoards).not.toEqual([]);
|
|
await random.click();
|
|
await expect(random).toHaveAttribute('aria-pressed', 'true');
|
|
await expect(cuts).toHaveAttribute('aria-pressed', 'false');
|
|
expect(decodeState(new URL(page.url()).search).state.project.flooring.optimisation).toBe(
|
|
'random',
|
|
);
|
|
expect(decodeState(new URL(page.url()).search).state.project.completedBoards).toEqual([]);
|
|
const drawn = page.getByRole('region', { name: 'Floor plan preview' }).locator('.floor-piece');
|
|
await expect(drawn).toHaveCount(options.random.pieces.length);
|
|
const ids = await drawn.evaluateAll((pieces) =>
|
|
pieces.map((piece) => piece.getAttribute('data-piece-id')),
|
|
);
|
|
expect(ids.sort()).toEqual(options.random.pieces.map((piece) => piece.id).sort());
|
|
await page.reload();
|
|
await expect(random).toHaveAttribute('aria-pressed', 'true');
|
|
expect(decodeState(new URL(page.url()).search).state.project.flooring.optimisation).toBe(
|
|
'random',
|
|
);
|
|
await cuts.click();
|
|
await expect(cuts).toHaveAttribute('aria-pressed', 'true');
|
|
await expect(drawn).toHaveCount(options.cuts.pieces.length);
|
|
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(
|
|
page.viewportSize()!.width,
|
|
);
|
|
await page.getByRole('button', { name: 'Brick', exact: true }).click();
|
|
await expect(choices).toHaveCount(0);
|
|
});
|
|
|
|
test('infeasible measurements do not advertise zero-cut or zero-waste options', async ({
|
|
page,
|
|
}) => {
|
|
const state = defaultState();
|
|
state.project.flooring.pattern = 'random';
|
|
state.project.flooring.minOffset = 700;
|
|
await page.goto(`/${encodeState(state)}`);
|
|
const choices = page.getByRole('group', { name: 'Flooring optimisation', exact: true });
|
|
await expect(choices.getByText('Check measurements', { exact: true })).toHaveCount(2);
|
|
await expect(choices).not.toContainText('0 cuts');
|
|
await expect(choices).not.toContainText('0% waste');
|
|
});
|