Skip to content

Commit 5b2bbf5

Browse files
committed
test(org): grow full-page shots only for panes that follow the viewport
A pane with its own ceiling, like the Home calendar, stays a scroller at any height, so counting its overflow left 1300px of blank page in the shot. Also holds Home's typed placeholder at its full text for the shot.
1 parent 1651dda commit 5b2bbf5

1 file changed

Lines changed: 37 additions & 14 deletions

File tree

  • apps/sim/scripts/org-redesign-e2e/checks

‎apps/sim/scripts/org-redesign-e2e/checks/walk.ts‎

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,29 +70,52 @@ function routesFor(persona: Persona): { name: string; path: string }[] {
7070
return shared
7171
}
7272

73-
/** The app scrolls inside its own panes, so the viewport grows to what they hold before the shot. */
73+
/** How far a probe grows the viewport to see which panes follow it. */
74+
const PANE_PROBE_PX = 200
75+
/** Home's composer types its suggestion out, then holds it this long before deleting it. */
76+
const TYPED_PLACEHOLDER = '[placeholder^="Ask Sim to "]:not([placeholder$="..."])'
77+
78+
/**
79+
* The app scrolls inside its own panes, so the viewport grows to what they hold before the shot. A
80+
* pane with a ceiling of its own, such as a Home widget's list, stays a scroller at any height and
81+
* shows no more for it: only the panes that follow the viewport count.
82+
*/
83+
async function viewportHolding(page: Page, viewport: Viewport) {
84+
const scrollers = await page.evaluateHandle(() =>
85+
Array.from(document.querySelectorAll('body *'))
86+
.filter((element) => element.scrollHeight - element.clientHeight > 1)
87+
.map((element) => ({
88+
element,
89+
clientHeight: element.clientHeight,
90+
overflow: element.scrollHeight - element.clientHeight,
91+
}))
92+
)
93+
await page.setViewportSize({ width: viewport.width, height: viewport.height + PANE_PROBE_PX })
94+
await sleep(150)
95+
const overflow = await scrollers.evaluate((measured) =>
96+
measured
97+
.filter(({ element, clientHeight }) => element.clientHeight > clientHeight)
98+
.reduce((tallest, { overflow }) => Math.max(tallest, overflow), 0)
99+
)
100+
await scrollers.dispose()
101+
return Math.min(viewport.height + overflow, 3600)
102+
}
103+
74104
export async function fullPageScreenshot(page: Page, path: string, viewport: Viewport) {
75-
const height = await page.evaluate(() => {
76-
let tallest = innerHeight
77-
for (const element of Array.from(document.querySelectorAll('body *'))) {
78-
const overflow = element.scrollHeight - element.clientHeight
79-
if (overflow > 1) tallest = Math.max(tallest, innerHeight + overflow)
80-
}
81-
return Math.min(tallest, 3600)
105+
const height = await viewportHolding(page, viewport)
106+
await page.setViewportSize({ width: viewport.width, height })
107+
await sleep(150)
108+
await page.waitForFunction((typing) => !document.querySelector(typing), TYPED_PLACEHOLDER, {
109+
timeout: 10_000,
82110
})
83-
const grows = height > viewport.height
84-
if (grows) {
85-
await page.setViewportSize({ width: viewport.width, height })
86-
await sleep(150)
87-
}
88111
await page.screenshot({
89112
path,
90113
fullPage: true,
91114
animations: 'disabled',
92115
style: 'nextjs-portal { display: none; }',
93116
timeout: 20_000,
94117
})
95-
if (grows) await page.setViewportSize({ width: viewport.width, height: viewport.height })
118+
await page.setViewportSize({ width: viewport.width, height: viewport.height })
96119
}
97120

98121
/** Long enough for a persona's walk to list every route that failed. */

0 commit comments

Comments
 (0)