Is it possible to change colorScheme in the middle of a Playwright test?
This was a question that was recently asked via the Playwright Discord server in the #help-playwright channel. If you aren't there you should join now!
Hi there, I wish to be able to change the system/browser's theme preference in the middle of my test, because my app can react to changes in user's preference without them having to reload the page. To assert this, I need to be able to change the system/browser's theme when the test runner is executing the test
It's worth noting that there are multiple ways to accomplish this, let's take a look at them!
Using test.use()
The first way is by using the codegen tool to build out your UI test. When you use the below command, this starts the codegen tool in with color-scheme
dark.
npx playwright codegen --color-scheme=dark
By default this is the codegen file that is generated.
import { test, expect } from '@playwright/test';
test.use({
colorScheme: 'dark'
});
test('test', async ({ page }) => {
});
This examples shows that you can use the test.use()
functionality outside of a test block. This will ensure that all tests that are run within this file will use the dark colorScheme
.
Using page.emulateMedia()
Another way to achieve this is to use the page.emulateMedia()
within the test block itself. This allows you to have multiple checks and assertions all within the same test. In the below example.
- I visit https://www.reddit.com
- Create a locator variable named postContainer
- Set the page to dark mode
colorScheme
- Validate the CSS background color is dark gray
- Set the page back to light mode
colorScheme
- Validate the CSS background color is white.
import { test, selectors, expect } from "@playwright/test";
test("Validate dark and light CSS", async ({ page }) => {
selectors.setTestIdAttribute("data-testid");
await page.goto("https://www.reddit.com/");
const postContainer = page.getByTestId("post-container").first();
await page.emulateMedia({ colorScheme: "dark" });
await expect(postContainer).toHaveCSS(
"background-color",
"rgba(26, 26, 27, 0.8)"
);
await page.screenshot({
path: `tests/ui/reddit.com/screenshot/reddit-home-dark.png`,
});
await page.emulateMedia({ colorScheme: "light" });
await expect(postContainer).toHaveCSS(
"background-color",
"rgba(255, 255, 255, 0.8)"
);
await page.screenshot({
path: `tests/ui/reddit.com/screenshot/reddit-home-light.png`,
});
});
Quick shoutout to @r_ydv on twitter who created the below article that walks you through how to make css assertions!
Specifying on newContext and newPage
The below example was pulled straight from the playwright docs that I listed above under the library
section. These examples can be used when using Playwright as a standalone library. In the example below, we will use them in the test
block as a 2nd context and page that we create and set the colorScheme
.
test("Exploring other options", async ({ page, browser }) => {
// Create context with dark mode
const context = await browser.newContext({
colorScheme: "dark", // or 'light'
});
// Create page with dark mode
const newPage = await browser.newPage({
colorScheme: "dark", // or 'light'
});
await newPage.goto("https://www.reddit.com/");
await newPage.screenshot({
path: `tests/ui/reddit.com/screenshot/reddit-home-dark-context.png`,
});
await context.close();
});
Wrap up
With all these examples you should have plenty of ways to update the colorScheme
of the browsers you are testing with. The code examples can all be found here. Have fun testing in dark mode!
Thanks for reading! If you found this helpful, reach out and let me know on LinkedIn or consider buying me a cup of coffee. If you want more content delivered to you in your inbox subscribe below, and be sure to leave a ❤️ to show some love.