Skip to content

Commit 6c931d8

Browse files
committed
Add screenshot variants
We may not want to screenshot default examples by, er, default. Move component screenshot config entirely to its fixtures YAML. With the screenshot option overloaded, we can either take a standard snapshot, or set the page up in different ways with screenshot variants
1 parent 1cda598 commit 6c931d8

1 file changed

Lines changed: 50 additions & 33 deletions

File tree

shared/tasks/browser.mjs

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import { download } from '@govuk-frontend/helpers/jest/browser/download.mjs'
22
import { goToComponent, goToExample } from '@govuk-frontend/helpers/puppeteer'
3-
import {
4-
getComponentFiles,
5-
getComponentNames,
6-
getExamples
7-
} from '@govuk-frontend/lib/components'
8-
import { filterPath } from '@govuk-frontend/lib/files'
3+
import { getComponentNames, getExamples } from '@govuk-frontend/lib/components'
94
import percySnapshot from '@percy/puppeteer'
105
import puppeteer from 'puppeteer'
116

@@ -33,18 +28,14 @@ export async function screenshots() {
3328

3429
// Screenshot components
3530
for (const componentName of componentNames) {
36-
const componentExamples = await getExamples(componentName)
37-
38-
// Screenshot "default" example
39-
await screenshotComponent(browser, componentName)
40-
41-
// Screenshot any other examples with 'screenshot: true'
42-
const otherExamples = Object.keys(componentExamples).filter(
43-
(key) => componentExamples[key].fixture.screenshot
31+
const allExamples = await getExamples(componentName)
32+
const componentExampleNames = Object.keys(allExamples).filter(
33+
(key) => allExamples[key].fixture.screenshot
4434
)
4535

46-
for (const exampleName of otherExamples) {
36+
for (const exampleName of componentExampleNames) {
4737
await screenshotComponent(browser, componentName, {
38+
screenshot: allExamples[exampleName].fixture.screenshot,
4839
exampleName
4940
})
5041
}
@@ -59,21 +50,39 @@ export async function screenshots() {
5950
await browser.close()
6051
}
6152

53+
/**
54+
* @overload
55+
* @param {Browser} browser - Puppeteer browser object
56+
* @param {string} componentName - Component name
57+
* @param {object} options - Component options
58+
* @param {string} options.exampleName - Example name
59+
* @param {object} options.screenshot - Screenshot options
60+
* @param {Array} [options.screenshot.variants] - Screenshot variants
61+
*/
62+
63+
/**
64+
* @overload
65+
* @param {Browser} browser - Puppeteer browser object
66+
* @param {string} componentName - Component name
67+
* @param {object} options - Component options
68+
* @param {string} options.exampleName - Example name
69+
* @param {boolean} options.screenshot - Whether to take a screenshot
70+
*/
71+
6272
/**
6373
* Send single component screenshots to Percy
6474
* for visual regression testing
6575
*
6676
* @param {Browser} browser - Puppeteer browser object
6777
* @param {string} componentName - Component name
68-
* @param {object} [options] - Component options
78+
* @param {object} options - Component options
6979
* @param {string} options.exampleName - Example name
80+
* @param {object | boolean} options.screenshot - Screenshot options
7081
* @returns {Promise<void>}
7182
*/
7283
export async function screenshotComponent(browser, componentName, options) {
73-
const componentFiles = await getComponentFiles(componentName)
74-
7584
// Percy snapshot options
76-
// Scope is .app-wihtespace-highlight rather than .govuk-main-wrapper like with
85+
// Scope is .app-whitespace-highlight rather than .govuk-main-wrapper like with
7786
// the examples so that margin that isn't part of the component doesn't get
7887
// included in the screenshot
7988
/** @type {SnapshotOptions} */
@@ -82,27 +91,35 @@ export async function screenshotComponent(browser, componentName, options) {
8291
// Navigate to component
8392
const page = await goToComponent(browser, componentName, options)
8493

85-
// Add optional example to screenshot name
86-
const screenshotName = options?.exampleName
87-
? `${componentName} (${options.exampleName})`
88-
: componentName
89-
90-
// Screenshot preview page (with JavaScript)
91-
await percySnapshot(page, `js: ${screenshotName}`, snapshotOptions)
94+
const screenshotName = `${componentName} (${options.exampleName})`
9295

93-
// Check for "JavaScript enabled" components
94-
if (componentFiles.some(filterPath([`**/${componentName}.mjs`]))) {
95-
await page.setJavaScriptEnabled(false)
96+
if (options.screenshot.variants?.noJs) {
97+
await percySnapshotNoJs(page, screenshotName, snapshotOptions)
98+
}
9699

97-
// Screenshot preview page (without JavaScript)
98-
await page.reload({ waitUntil: 'load' })
99-
await percySnapshot(page, `no-js: ${screenshotName}`, snapshotOptions)
100+
if (options.screenshot === true || options.screenshot.variants?.default) {
101+
await percySnapshot(page, screenshotName, snapshotOptions)
100102
}
101103

102104
// Close page
103105
return page.close()
104106
}
105107

108+
/**
109+
*
110+
* @param {Page} page - Puppeteer page object
111+
* @param {string} screenshotName - The name of the screenshot
112+
* @param {SnapshotOptions} snapShotOptions - Percy snapshot options
113+
*/
114+
export async function percySnapshotNoJs(page, screenshotName, snapShotOptions) {
115+
await page.setJavaScriptEnabled(false)
116+
await page.reload({ waitUntil: 'load' })
117+
screenshotName = `no-js: ${screenshotName}`
118+
await percySnapshot(page, screenshotName, snapShotOptions)
119+
await page.setJavaScriptEnabled(true)
120+
await page.reload({ waitUntil: 'load' })
121+
}
122+
106123
/**
107124
* Send single example screenshot to Percy
108125
* for visual regression testing
@@ -124,6 +141,6 @@ export async function screenshotExample(browser, exampleName) {
124141
}
125142

126143
/**
127-
* @import { Browser } from 'puppeteer'
144+
* @import { Browser, Page } from 'puppeteer'
128145
* @import { SnapshotOptions } from '@percy/core'
129146
*/

0 commit comments

Comments
 (0)