Merge remote-tracking branch 'origin/main' into fix/inspect-webkit-video-replace

This commit is contained in:
Vito Sansevero
2026-10-23 00:09:15 -07:00
2 changed files with 27 additions and 21 deletions
+21 -20
View File
@@ -178,27 +178,28 @@ async function captureFooter(page,testInfo,name) {
test.beforeEach(async({request})=>{await seedConcept(request);});
for(const [width,height] of SIZES)for(const theme of THEMES)test(`shell geometry, tokens and controls match the concept ${width}x${height} ${theme}`,async({page},testInfo)=>{
// One test per route, size, theme and motion. All of them in one test per size and theme (12 page loads, 12 captures,
// 36 hovers) steadily took 22 s median and up to 33 s on CI WebKit, past the 30 s budget with no step stalled; one
// route in one motion is a sixth of that work under the same budget.
for(const [route,breadcrumb] of ROUTES)for(const [width,height] of SIZES)for(const theme of THEMES)for(const motion of MOTIONS)test(`shell geometry, tokens and controls match the concept on ${route} ${width}x${height} ${theme} ${motion}`,async({page},testInfo)=>{
await page.setViewportSize({width,height});const result={};
for(const motion of MOTIONS)for(const [route,breadcrumb] of ROUTES) {
await openConcept(page,route,theme,motion);await page.mouse.move(0,0);
const reference=await inventoryOf(page,'#main');
if(motion==='no-preference')await captureCanonicalState(page,testInfo,`concept-shell-${route}-${width}-${theme}`);
const referenceRings=FULL_HEADING.has(route)?await ringsOf(page,'#main'):null;
const referenceHovers=await hoversOf(page);
if(motion==='no-preference')await captureFooter(page,testInfo,`concept-footer-${route}-${width}-${theme}`);
await openProduction(page,route,theme,motion);await page.mouse.move(0,0);
const actual=await inventoryOf(page,'#workspace-main');
if(motion==='no-preference')await captureCanonicalState(page,testInfo,`production-shell-${route}-${width}-${theme}`);
const actualRings=FULL_HEADING.has(route)?await ringsOf(page,'#workspace-main'):null;
const actualHovers=await hoversOf(page);
if(motion==='no-preference')await captureFooter(page,testInfo,`production-footer-${route}-${width}-${theme}`);
result[`${motion} ${route}`]={route,breadcrumb,reference,actual,diff:compare(route,reference,actual),referenceRings,actualRings,
referenceHovers,actualHovers};
}
const path=testInfo.outputPath('shell-geometry.json');await writeFile(path,JSON.stringify(result,null,2));
await testInfo.attach('shell-geometry',{path,contentType:'application/json'});
for(const [key,{route,breadcrumb,reference,actual,diff,referenceRings,actualRings,referenceHovers,actualHovers}] of Object.entries(result)) {
await openConcept(page,route,theme,motion);await page.mouse.move(0,0);
const reference=await inventoryOf(page,'#main');
if(motion==='no-preference')await captureCanonicalState(page,testInfo,`concept-shell-${route}-${width}-${theme}`);
const referenceRings=FULL_HEADING.has(route)?await ringsOf(page,'#main'):null;
const referenceHovers=await hoversOf(page);
if(motion==='no-preference')await captureFooter(page,testInfo,`concept-footer-${route}-${width}-${theme}`);
await openProduction(page,route,theme,motion);await page.mouse.move(0,0);
const actual=await inventoryOf(page,'#workspace-main');
if(motion==='no-preference')await captureCanonicalState(page,testInfo,`production-shell-${route}-${width}-${theme}`);
const actualRings=FULL_HEADING.has(route)?await ringsOf(page,'#workspace-main'):null;
const actualHovers=await hoversOf(page);
if(motion==='no-preference')await captureFooter(page,testInfo,`production-footer-${route}-${width}-${theme}`);
result[`${motion} ${route}`]={reference,actual,diff:compare(route,reference,actual),referenceRings,actualRings,
referenceHovers,actualHovers};
const path=testInfo.outputPath(`shell-geometry-${route}-${motion}.json`);await writeFile(path,JSON.stringify(result,null,2));
await testInfo.attach(`shell-geometry-${route}-${motion}`,{path,contentType:'application/json'});
for(const [key,{reference,actual,diff,referenceRings,actualRings,referenceHovers,actualHovers}] of Object.entries(result)) {
// The concept itself is what this comparison assumes: its sample counts and its shell controls.
expect.soft(reference.chrome.navs[0].rows.map(row=>[row.text,row.count?.text??null]),`${key} concept WORKSPACE rows`)
.toEqual([['Images','24'],['Prompt library','6'],['Tags & categories','15'],['Inspect a file',null]]);
+6 -1
View File
@@ -787,7 +787,12 @@ test('density changes and resize preserve identity focus and selection', async (
await page.getByRole('button',{name:'Grid',exact:true}).click();
for (const [width,columns] of [[951,3],[950,3],[700,2],[390,2]]) {
await page.setViewportSize({width,height:844});
await expect.poll(()=>cards(page).nth(columns).evaluate(node=>node.offsetLeft)).toBe(0);
// 700px and 390px both lay out two columns, so a card at the row start alone is also true of the previous
// width's cards before WebKit runs the first frame after the resize; wait for the row to fit the new grid.
await expect.poll(()=>page.locator('.image-grid').evaluate((grid,columns)=>{
const row=[...grid.querySelectorAll(':scope > article[data-image-key]')];
return row[columns].offsetLeft===0&&row[columns-1].getBoundingClientRect().right<=grid.getBoundingClientRect().right+1;
},columns)).toBe(true);
await first.getByRole('button',{name:/^Open /}).focus();await page.keyboard.press('ArrowDown');
await expect(cards(page).nth(columns).getByRole('button',{name:/^Open /})).toBeFocused();
expect(await page.evaluate(()=>document.documentElement.scrollWidth-document.documentElement.clientWidth)).toBeLessThanOrEqual(1);