-
Notifications
You must be signed in to change notification settings - Fork 204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add dark snapshots to 2xl breakpoint visual regression tests #4915
Conversation
034eace
to
2ccbc68
Compare
cdc0ee3
to
5d5bd27
Compare
2567791
to
bfa076e
Compare
5d5bd27
to
406ed4a
Compare
1b312d1
to
07284b8
Compare
So one issue with this specific version of the approach, is that putting two snapshots in the same I've gone through a bunch of variations I can think of locally, some of them worked, others didn't, but most involved big refactors to existing tests. That was especially true when I tried to separate the setup from the expectation. However, I think there's maybe a simpler way, that results in very minimal diffs across the board, including no change at all to the behaviour for existing e2e tests. diff --git a/frontend/test/playwright/utils/breakpoints.ts b/frontend/test/playwright/utils/breakpoints.ts
index 4bfcbe8a0..0487164dc 100644
--- a/frontend/test/playwright/utils/breakpoints.ts
+++ b/frontend/test/playwright/utils/breakpoints.ts
@@ -15,9 +15,12 @@ type ExpectSnapshot = <T extends ScreenshotAble>(
snapshotOptions?: Parameters<ReturnType<Expect>["toMatchSnapshot"]>[0]
) => Promise<Buffer | void>
+type BaseName = `${string}-${Breakpoint}`
+type NameWithColorScheme = `${BaseName}-${"light" | "dark"}`
+
type BreakpointBlock = (options: {
getConfigValues: (name: string) => {
- name: `${typeof name}-${Breakpoint}.png`
+ name: `${BaseName | NameWithColorScheme}.png`
}
breakpoint: Breakpoint
expectSnapshot: ExpectSnapshot
@@ -54,14 +57,16 @@ interface Options {
/**
* Disable animations to remove flakiness.
*/
- animations: "disabled"
+ animations?: "disabled"
/**
* To make sure caret blinking doesn't cause diffs.
*/
- caret: "hide"
+ caret?: "hide"
+
+ colorScheme?: "all" | "light" | "dark"
}
-const defaultOptions = Object.freeze({
+const defaultOptions = Object.freeze<Options>({
uaMocking: true,
animations: "disabled",
caret: "hide",
@@ -73,41 +78,50 @@ const makeBreakpointDescribe =
blockOrOptions: T,
block?: T extends Record<string, unknown> ? BreakpointBlock : undefined
) => {
- test.describe(`screen at breakpoint ${breakpoint} with width ${screenWidth}`, () => {
- const _block = (
- typeof blockOrOptions === "function" ? blockOrOptions : block
- ) as BreakpointBlock
- const options =
- typeof blockOrOptions !== "function"
- ? { ...defaultOptions, ...blockOrOptions }
- : defaultOptions
-
- test.use({
- viewport: { width: screenWidth, height: 700 },
- userAgent: options.uaMocking ? mockUaStrings[breakpoint] : undefined,
- })
-
- const getConfigValues = (name: string) => ({
- name: `${name}-${breakpoint}.png` as const,
- })
-
- const expectSnapshot = async <T extends ScreenshotAble>(
- name: string,
- screenshotAble: T,
- options?: Parameters<T["screenshot"]>[0],
- snapshotOptions?: Parameters<ReturnType<Expect>["toMatchSnapshot"]>[0]
- ) => {
- const { name: snapshotName } = getConfigValues(name)
- return expect(await screenshotAble.screenshot(options)).toMatchSnapshot(
- {
- name: snapshotName,
- ...snapshotOptions,
- }
- )
- }
-
- _block({ breakpoint, getConfigValues, expectSnapshot })
- })
+ const _block = (
+ typeof blockOrOptions === "function" ? blockOrOptions : block
+ ) as BreakpointBlock
+ const options =
+ typeof blockOrOptions !== "function"
+ ? { ...defaultOptions, ...blockOrOptions }
+ : defaultOptions
+
+ const colorSchemes = options.colorScheme === "all" ? ["light", "dark"] as const : [options.colorScheme ?? "light"]
+ for (const colorScheme of colorSchemes) {
+ test.describe(`screen at breakpoint ${breakpoint} with width ${screenWidth} in color scheme ${colorScheme}`, () => {
+ test.beforeEach(`set color scheme ${colorScheme}`, async ({ page }) => {
+ // do whatever to set the color scheme...
+ // maybe only do this beforeEach if `options.colorScheme` != "light" so existing tests don't change?
+ // only if light is truly the "default" and safely so
+ })
+
+ test.use({
+ viewport: { width: screenWidth, height: 700 },
+ userAgent: options.uaMocking ? mockUaStrings[breakpoint] : undefined,
+ })
+
+ const getConfigValues = (name: string) => ({
+ name: options.colorScheme === "light" ? `${name}-${breakpoint}.png` as const : `${name}-${breakpoint}-${colorScheme}.png` as const,
+ })
+
+ const expectSnapshot = async <T extends ScreenshotAble>(
+ name: string,
+ screenshotAble: T,
+ options?: Parameters<T["screenshot"]>[0],
+ snapshotOptions?: Parameters<ReturnType<Expect>["toMatchSnapshot"]>[0]
+ ) => {
+ const { name: snapshotName } = getConfigValues(name)
+ return expect(await screenshotAble.screenshot(options)).toMatchSnapshot(
+ {
+ name: snapshotName,
+ ...snapshotOptions,
+ }
+ )
+ }
+
+ _block({ breakpoint, getConfigValues, expectSnapshot })
+ })
+ }
}
const capitalize = (s: string): Capitalize<typeof s> => With those changes, the only change required to make a test run in multiple colour schemes, is just to pass the diff --git a/frontend/test/playwright/visual-regression/components/global-audio-player.spec.ts b/frontend/test/playwright/visual-regression/components/global-audio-player.spec.ts
index 0360192e6..c2e6d0682 100644
--- a/frontend/test/playwright/visual-regression/components/global-audio-player.spec.ts
+++ b/frontend/test/playwright/visual-regression/components/global-audio-player.spec.ts
@@ -11,7 +11,7 @@ import { languageDirections, t } from "~~/test/playwright/utils/i18n"
test.describe.configure({ mode: "parallel" })
for (const dir of languageDirections) {
- breakpoints.describeXs(async ({ expectSnapshot }) => {
+ breakpoints.describeXs({ colorScheme: "all" }, async ({ expectSnapshot }) => {
test(`global audio player on the search page - ${dir}`, async ({
page,
}) => { There might be some problems with taking this approach that I haven't considered, that the approach in this PR of using multiple expect calls in the same However, I think it's probably more important to optimise for test isolation, even at the expense of than speed, at least to begin with. Then we can explore other approaches for speeding up tests (like parallelising fully isolated test cases, for example). To be clear though, it is good to acknowledge this approach would double the total execution time of our visual regression tests. One other option though... it's kind of wacky... and I do not like it, but I can't resist suggesting it. What if it were possible to create screenshots that included both color schemes of the page, stacked vertically? It isn't possible to just arbitrarily concatenate pngs as far as I can tell, but if it were... 😛. Then we would just use a single snapshot assertion on the stacked screenshots. Voilá. Horrifying, but it solves the speed problem and implicitly parallelises the two colour schemes 😬. |
d0525f4
to
610061b
Compare
d11fbb0
to
1db05ad
Compare
440bd40
to
9037d69
Compare
59a0eed
to
207d1d3
Compare
d52fc7d
to
82e3c7a
Compare
207d1d3
to
409a00d
Compare
82e3c7a
to
6bcc141
Compare
8e5c7b2
to
fd20e0e
Compare
bf04a21
to
27dc277
Compare
c9680e9
to
bd137fb
Compare
bd11e2e
to
effb9d2
Compare
bd137fb
to
e87f7ae
Compare
07def70
to
14069a0
Compare
8c1210a
to
adc4b70
Compare
adc4b70
to
1cfd10a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀
1cfd10a
to
7f6cd1d
Compare
Fixes
Fixes #4305 by @zackkrida
Description
This PR adds the dark snapshots for 2xl tests by setting the
useColorMode
totrue
when the snapshot name contains-2xl
string. It also adds asleep
of 200ms after turning on the dark mode to make sure that it's been fully rendered before taking the snapshot.Testing Instructions
It is expected that only the dark snapshots are added in this PR. If the added snapshots are incorrect, it should be addressed in a different PR.
Checklist
Update index.md
).main
) or a parent feature branch.ov just catalog/generate-docs
for catalogPRs) or the media properties generator (
ov just catalog/generate-docs media-props
for the catalog or
ov just api/generate-docs
for the API) where applicable.Developer Certificate of Origin
Developer Certificate of Origin