Skip to content

Commit 90d5779

Browse files
Merge pull request #226 from haim-io/feat/screenshot-name-format
feat: screenshot name format
2 parents d80322d + ff3f10c commit 90d5779

File tree

5 files changed

+86
-9
lines changed

5 files changed

+86
-9
lines changed

src/command.js

+23-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import merge from 'lodash/merge'
22
import { recurse } from 'cypress-recurse';
33
import DEFAULT_CONFIG from './config.default'
4+
import { getFileName } from './utils.browser'
45

56
const compareSnapshotCommand = () => {
67
const userConfig = Cypress.env('cypressImageDiff') || DEFAULT_CONFIG
@@ -16,19 +17,34 @@ const compareSnapshotCommand = () => {
1617
'compareSnapshot',
1718
{ prevSubject: 'optional' },
1819
(
19-
subject,
20-
orignalOptions,
20+
subject,
21+
orignalOptions,
2122
) => {
2223
const {
23-
name,
24+
name,
2425
testThreshold = userConfig.FAILURE_THRESHOLD,
2526
retryOptions = userConfig.RETRY_OPTIONS,
2627
exactName = false,
27-
cypressScreenshotOptions
28+
cypressScreenshotOptions,
29+
nameTemplate = userConfig.NAME_TEMPLATE
2830
} = typeof orignalOptions === 'string' ? { name: orignalOptions } : orignalOptions
2931

30-
const specName = Cypress.spec.name
31-
const testName = exactName ? name : `${specName.replace('.js', '')}${/^\//.test(name) ? '' : '-'}${name}`
32+
// IN-QUEUE-FOR-BREAKING-CHANGE: Ternary condition here is to avoid a breaking change with the new option nameTemplate, will be simplified once we remove the exactName option
33+
// eslint-disable-next-line no-nested-ternary
34+
const testName = nameTemplate
35+
? getFileName({
36+
nameTemplate,
37+
givenName: name,
38+
specName: Cypress.spec.name,
39+
browserName: Cypress.browser.name,
40+
width: Cypress.config('viewportWidth'),
41+
height: Cypress.config('viewportHeight'),
42+
})
43+
: exactName
44+
? name
45+
: `${Cypress.spec.name.replace('.js', '')}${
46+
/^\//.test(name) ? '' : '-'
47+
}${name}`
3248

3349
const defaultRetryOptions = {
3450
limit: 1,
@@ -65,7 +81,7 @@ const compareSnapshotCommand = () => {
6581
specPath: Cypress.spec.relative,
6682
inlineAssets: userConfig.INLINE_ASSETS
6783
}
68-
84+
6985
return cy.task('compareSnapshotsPlugin', options)
7086
},
7187
(percentage) => percentage <= testThreshold,

src/config.default.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ export default {
1111
OVERWRITE: true,
1212
},
1313
CYPRESS_SCREENSHOT_OPTIONS: {},
14-
INLINE_ASSETS: false
15-
}
14+
INLINE_ASSETS: false,
15+
// IN-QUEUE-FOR-BREAKING-CHANGE: default NAME_TEMPLATE can be set until the next breaking change
16+
// NAME_TEMPLATE: '[specName]-[givenName]'
17+
}

src/utils.browser.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* eslint-disable import/prefer-default-export */
2+
const getFileName = ({
3+
nameTemplate,
4+
givenName,
5+
specName,
6+
browserName,
7+
width,
8+
height,
9+
}) => {
10+
return (
11+
nameTemplate
12+
.replace(/\[givenName\]/, givenName)
13+
.replace(/\[specName\]/, specName.replace(/\.(js|jsx|ts|tsx)$/, ''))
14+
.replace(/\[browserName\]/, browserName)
15+
.replace(/\[width\]/, width)
16+
.replace(/\[height\]/, height)
17+
.replace(/[^a-z0-9_\-/.]/gi, '')
18+
) // remove anything that's not a letter, a number, a dash, an underscore or a dot.
19+
}
20+
21+
export { getFileName }
22+

src/utils.test.js

+29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { existsSync, mkdirSync, emptyDirSync, readdirSync, moveSync, copySync, writeFile } from 'fs-extra'
22
import { createDir, cleanDir, renameAndMoveFile, renameAndCopyFile, getRelativePathFromCwd, getCleanDate, writeFileIncrement } from './utils'
3+
import { getFileName } from './utils.browser'
34

45
jest.mock('fs-extra', () => ({
56
...jest.requireActual('fs-extra'),
@@ -131,4 +132,32 @@ describe('Utils', () => {
131132
expect(writeFile).toBeCalledWith(filenameIncremented, fakeData)
132133
})
133134
})
135+
136+
describe('getFileName', () => {
137+
it('should replace placeholders correctly', () => {
138+
const template = '[browserName]/[givenName]-[specName]-[width]x[height].js';
139+
const result = getFileName({
140+
nameTemplate: template,
141+
givenName: 'test',
142+
specName: 'example.spec.js',
143+
browserName: 'chrome',
144+
width: 1280,
145+
height: 720
146+
});
147+
expect(result).toBe('chrome/test-example.spec-1280x720.js');
148+
});
149+
150+
it('should remove special characters correctly', () => {
151+
const template = '[givenName]-[specName]-[browserName]-[width]x[height].js';
152+
const result = getFileName({
153+
nameTemplate: template,
154+
givenName: 'test$123',
155+
specName: 'spec file.js',
156+
browserName: 'safari',
157+
width: 800,
158+
height: 600
159+
});
160+
expect(result).toBe('test123-specfile-safari-800x600.js');
161+
});
162+
});
134163
})

types/options.d.ts

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ export interface CompareSnapshotOptions {
77
* The name of the snapshots that will be generated
88
*/
99
name: string
10+
/**
11+
* The snapshot naming pattern using replaceable labels. All possible labels are: specName, givenName, browserName, width and height.
12+
* All labels in square brackets are replaced with actual values during runtime.
13+
* giveName is the name property above.
14+
* @default undefined
15+
* @example '[browserName]/[specName]-[givenName].[width]x[height]'
16+
*/
17+
nameTemplate?: string
1018
/**
1119
* A number between 0 and 1 that represents the allowed percentage of pixels that can be different between the two snapshots
1220
* @default 0

0 commit comments

Comments
 (0)