Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/src/window-regression-fixtures.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function RegressionCase({ children, label, state, width }: RegressionCaseProps)
style={style}
>
<figcaption>
<strong>{width}px container</strong>
<strong>Up to {width}px</strong>
<span>{label}</span>
</figcaption>
{children}
Expand Down Expand Up @@ -202,15 +202,15 @@ export function WindowRegressionFixtures() {
</Menu.Popup>
</Menu.Root>
</Window.MenuBar>
<RegressionContent headerLayout="inline" actionLayout="stacked" />
<RegressionContent actionLayout="stacked" />
<Window.StatusBar data-regression-contained>
<Window.StatusBar.Item grow>2 items</Window.StatusBar.Item>
<Window.StatusBar.Light state="ready" label="Application ready" />
</Window.StatusBar>
</Window>
</RegressionCase>

<RegressionCase width={820} state="active" label="Automatic chrome above the breakpoint">
<RegressionCase width={820} state="active" label="Automatic chrome">
<Window title="Wide automatic window" data-regression-frame="window">
<RegressionContent />
<Window.StatusBar data-regression-contained>Wide layout</Window.StatusBar>
Expand Down
48 changes: 47 additions & 1 deletion tests/browser/docs-geometry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const viewports = [
] as const;

for (const viewport of viewports) {
test(`window fixtures stay contained at ${viewport.width}px`, async ({ page }) => {
test(`window fixtures stay contained at ${viewport.width}px`, async ({ page }, testInfo) => {
await page.setViewportSize(viewport);
await page.goto("/");

Expand Down Expand Up @@ -58,6 +58,10 @@ for (const viewport of viewports) {
return messages;
});

await suite.locator("[data-regression-width='760']").screenshot({
path: testInfo.outputPath("application-window.png"),
});
expect(await headerTextOverlaps(page)).toEqual([]);
expect(failures).toEqual([]);

const windowSurfaceFailures = await page.evaluate(() => {
Expand Down Expand Up @@ -306,3 +310,45 @@ async function expectViewportContainment(page: Page, popup: Locator) {
expect(box!.x + box!.width).toBeLessThanOrEqual(viewport!.width);
expect(box!.y + box!.height).toBeLessThanOrEqual(viewport!.height);
}

test("window headers adapt across responsive breakpoints", async ({ page }) => {
await page.goto("/");
for (const width of [
360, 375, 393, 414, 428, 519, 520, 521, 619, 620, 621, 767, 769, 820, 1024, 1440,
]) {
// Resize sequentially to exercise transitions in the same mounted components.
// eslint-disable-next-line no-await-in-loop
await page.setViewportSize({ width, height: 900 });
// eslint-disable-next-line no-await-in-loop
expect(await headerTextOverlaps(page), `Header overlap at ${width}px`).toEqual([]);
// eslint-disable-next-line no-await-in-loop
expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBeLessThanOrEqual(
width,
);
}
});

async function headerTextOverlaps(page: Page) {
return page.locator(".greyui-window-header-layout").evaluateAll((headers) =>
headers.flatMap((header) => {
const description = header.querySelector(".greyui-window-description");
const actions = header.querySelector(".greyui-window-actions");
if (!description || !actions || !description.getClientRects().length) return [];
const bounds = actions.getBoundingClientRect();
const range = document.createRange();
range.selectNodeContents(description);
const overlaps = [...range.getClientRects()].some(
(line) =>
line.left < bounds.right &&
line.right > bounds.left &&
line.top < bounds.bottom &&
line.bottom > bounds.top,
);
return overlaps
? [
`Description overlaps actions in ${header.closest(".greyui-window")?.querySelector(".greyui-window-title")?.textContent}`,
]
: [];
}),
);
}
Loading