Skip to content
Merged
82 changes: 76 additions & 6 deletions packages/gitbook/e2e/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,21 +191,20 @@ export function runTestCases(testCases: TestsCase[]) {
.intercom-lightweight-app {
display: none !important;
}

/* Switch image rendering to pixelated */
img {
image-rendering: pixelated;
}
`,
threshold: screenshotOptions?.threshold ?? undefined,
fullPage: testEntry.fullPage ?? false,
beforeScreenshot: async ({ runStabilization }) => {
await runStabilization();
await waitForIcons(page);
await roundImageSizes(page);
if (screenshotOptions?.waitForTOCScrolling !== false) {
await waitForTOCScrolling(page);
}
},
afterScreenshot: async () => {
await restoreImageSizes(page);
},
});
}
});
Expand Down Expand Up @@ -326,7 +325,14 @@ async function waitForIcons(page: Page) {
function loadImage(src: string) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onload = () => {
// Wait two frames to ensure the image has been rendered
requestAnimationFrame(() => {
requestAnimationFrame(() => {
resolve(true);
});
});
};
img.onerror = (_error) => reject(new Error(`Failed to load image: ${src}`));
img.src = src;
});
Expand All @@ -348,6 +354,70 @@ async function waitForIcons(page: Page) {
});
}

/**
* Take all images, measure them and set their width and height to rounded values.
*/
async function roundImageSizes(page: Page) {
await page.waitForFunction(async () => {
const images = Array.from(document.querySelectorAll('img'));
await Promise.all(
images.map(async (img) => {
return new Promise<void>((resolve) => {
const setDimensions = () => {
// Mark it as stabilized
img.dataset.stabilized = 'true';
// Preserve the original width and height
img.dataset.originalWidth = img.style.width ?? '';
img.dataset.originalHeight = img.style.height ?? '';
const rect = img.getBoundingClientRect();
img.style.width = `${Math.round(rect.width)}px`;
img.style.height = `${Math.round(rect.height)}px`;
resolve();
};

if (img.complete) {
setDimensions();
} else {
const cleanup = () => {
img.removeEventListener('load', handleLoad);
img.removeEventListener('error', handleError);
};
const handleError = () => {
cleanup();
resolve();
};
const handleLoad = () => {
cleanup();
setDimensions();
};
img.addEventListener('load', handleLoad);
img.addEventListener('error', handleError);
}
});
})
);
return true;
});
}

/**
* Restore images to their original size.
*/
async function restoreImageSizes(page: Page) {
await page.evaluate(() => {
const images = Array.from(document.querySelectorAll('img[data-stabilized]'));
images.forEach((img) => {
if (img instanceof HTMLImageElement) {
img.style.width = img.dataset.originalWidth ?? '';
img.style.height = img.dataset.originalHeight ?? '';
delete img.dataset.originalWidth;
delete img.dataset.originalHeight;
delete img.dataset.stabilized;
}
});
});
}

/**
* Wait for TOC to be correctly scrolled into view.
*/
Expand Down
3 changes: 3 additions & 0 deletions packages/gitbook/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ export default defineConfig({
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
contextOptions: {
reducedMotion: 'reduce',
},
},
});
12 changes: 8 additions & 4 deletions packages/gitbook/src/components/Search/SearchButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,15 @@ function Shortcut() {
setOperatingSystem(getOperatingSystem());
}, []);

return operatingSystem ? (
return (
<div
className={`shortcut -mr-1 hidden animate-fadeIn justify-end gap-0.5 whitespace-nowrap text-tint text-xs [font-feature-settings:"calt",_"case"] contrast-more:text-tint-strong md:flex`}
aria-busy={operatingSystem === null ? 'true' : undefined}
className={tcls(
`shortcut -mr-1 hidden justify-end gap-0.5 whitespace-nowrap text-tint text-xs [font-feature-settings:"calt",_"case"] contrast-more:text-tint-strong md:flex`,
operatingSystem
? 'motion-safe:animate-fadeIn motion-reduce:opacity-100'
: 'opacity-0'
)}
>
<kbd
className={`flex h-5 min-w-5 items-center justify-center rounded border border-tint-subtle theme-bold:border-header-link/5 bg-tint-base theme-bold:bg-header-background px-1 ${operatingSystem === 'mac' ? 'text-sm' : ''}`}
Expand All @@ -128,7 +134,5 @@ function Shortcut() {
K
</kbd>
</div>
) : (
<span aria-busy />
);
}
4 changes: 2 additions & 2 deletions packages/gitbook/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ const config: Config = {
present: 'present .5s ease-out both',
scaleIn: 'scaleIn 200ms ease',
scaleOut: 'scaleOut 200ms ease',
fadeIn: 'fadeIn 200ms ease',
fadeOut: 'fadeOut 200ms ease',
fadeIn: 'fadeIn 200ms ease forwards',
fadeOut: 'fadeOut 200ms ease forwards',
enterFromLeft: 'enterFromLeft 250ms ease',
enterFromRight: 'enterFromRight 250ms ease',
exitToLeft: 'exitToLeft 250ms ease',
Expand Down