Taking 72 Screenshots in 5 Minutes

In WordPress, there are nine available color schemes for use in the admin. They’re generated from a base _admin.scss file, and if I make a change, I need to go and test it out nine different times. I also have a plugin that adds another ten schemes… so you can see where this is going.

I needed something to take a bunch of screenshots, over and over again. Luckily (since the last time I wanted something like this, 5+ years ago…), I knew that puppeteer could handle most of the heavy lifting here. Also, there are some helpers from Gutenberg published to @wordpress/e2e-test-utils for navigating around wp-admin.

Honestly, it all came together so quickly. You can see my end result on GitHub, grab-screenshots.

How does it work?

Puppeteer is a tool that runs a “headless browser” (Chrome, in this case), which means it runs all the rendering that Chrome would do, but without human interaction. It has an API for navigating pages and performing actions on pages like hovering, clicking, typing, etc. The @wordpress/e2e-test-utils package is a set of helper functions that build on the puppeteer API. To be honest, I only needed visitAdminPage, but it’s worth it because it handles logging in if necessary.

Below I’m walking through grab-screenshots/index.js, if you want to read along.

First, I set up a list of the core color schemes, and loop​*​ over them so every action is repeated for all schemes. The first step in each loop is to set the color scheme. Next, set up the viewport to the size of the screenshot I want – these will be “desktop” sized, at 1024px × 600px. Now we can start taking screenshots.

await visitAdminPage( 'index.php' );
await page.screenshot( {
	path: `${ IMAGE_PATH }/dashboard-${ slug }.png`,
} );

Yep, that’s it. Visit /wp-admin/index.php (Dashboard), take a screenshot and save it to the filename I specified. Since this is in the loop, I save it with the scheme name in the file name: dashboard-fresh.png, dashboard-coffee.png, etc.

A lot of the color schemes’ accents only appear on focus or hover, so I want to get some of those as well.

await page.focus( '#welcome-panel .button-hero' );
await screenshotDOMElement( {
	path: `${ IMAGE_PATH }/dashboard-button-focus-${ slug }.png`,
	selector: '#welcome-panel',
	padding: 16,
} );

The browser instance is still on the Dashboard from above. Trigger focus on the big button in the Welcome panel. Take a screenshot of just the welcome panel, since I already have the full dashboard (using a helper function from this gist).

Continuing like this, I grab a few more pages – themes, post list, and the customizer. For the customizer screenshots, I used the helper function again to only capture the customizer itself – I don’t want to waste processing time on capturing the frontend of the site.

I’ve noticed some inconsistencies with the color schemes on small screens, so now I want to take some screenshots with a smaller viewport.

await page.setViewport( {
	width: 425,
	height: 600,
	deviceScaleFactor: 2,
} );
await visitAdminPage( 'edit.php' );
await page.hover( '#wp-admin-bar-site-name a' );
await page.screenshot( {
	path: `${ IMAGE_PATH }/mobile-edit-${ slug }.png`,
} );

This resizes the screen to 425px × 600px and fakes a retina screen. Then we go back to the Posts page, hover over the “home” icon in the toolbar, and take a screenshot. Sure enough, the home icon should be the highlight color like in the default scheme, but it’s white.

At this point, we’re done with the content of the loop, and it circles back to the top to switch to the next color scheme and do it all again. When it’s finished, there are 72 screenshots, and it only took a few minutes to run.

I’m not sure how much I’ll use this particular script, but now that I have the framework it’ll make color scheme fixes a lot less tedious.

I also have two other scripts in this project, but I think I’ll save those for another post.


  1. ​*​
    I’m using a for loop here (instead of schemes.forEach) since I need this to be synchronous.

One thought on “Taking 72 Screenshots in 5 Minutes

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: