Skip to content

Commit

Permalink
Test Case implementation (#1527)
Browse files Browse the repository at this point in the history
* adding test case field to create snapshot endpoint

* adding support for test case in snapshot

* resolving conflict

* adding more test

* addressing comments, enhancing logs
  • Loading branch information
prklm10 committed Feb 27, 2024
1 parent 648f817 commit 1eaa54d
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 14 deletions.
1 change: 1 addition & 0 deletions packages/cli-upload/test/upload.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ describe('percy upload', () => {
widths: [10],
scope: null,
sync: false,
'test-case': null,
'scope-options': {},
'minimum-height': 10,
'enable-javascript': null,
Expand Down
2 changes: 2 additions & 0 deletions packages/client/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ export class PercyClient {
clientInfo,
environmentInfo,
sync,
testCase,
resources = []
} = {}) {
validateId('build', buildId);
Expand All @@ -371,6 +372,7 @@ export class PercyClient {
widths: widths || null,
scope: scope || null,
sync: !!sync,
'test-case': testCase || null,
'scope-options': scopeOptions || {},
'minimum-height': minHeight || null,
'enable-javascript': enableJavaScript || null,
Expand Down
5 changes: 5 additions & 0 deletions packages/client/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,7 @@ describe('PercyClient', () => {
widths: [1000],
scope: '#main',
sync: true,
testCase: 'foo test case',
scopeOptions: { scroll: true },
minHeight: 1000,
enableJavaScript: true,
Expand Down Expand Up @@ -675,6 +676,7 @@ describe('PercyClient', () => {
widths: [1000],
scope: '#main',
sync: true,
'test-case': 'foo test case',
'minimum-height': 1000,
'scope-options': { scroll: true },
'enable-javascript': true,
Expand Down Expand Up @@ -720,6 +722,7 @@ describe('PercyClient', () => {
widths: null,
scope: null,
sync: false,
'test-case': null,
'scope-options': {},
'minimum-height': null,
'enable-javascript': null,
Expand Down Expand Up @@ -787,6 +790,7 @@ describe('PercyClient', () => {
name: 'test snapshot name',
scope: null,
sync: true,
'test-case': null,
'scope-options': {},
'enable-javascript': null,
'minimum-height': null,
Expand Down Expand Up @@ -1294,6 +1298,7 @@ describe('PercyClient', () => {
attributes: {
name: 'test snapshot name',
scope: null,
'test-case': null,
'scope-options': {},
'enable-javascript': null,
'minimum-height': null,
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export const configSchema = {
sync: {
type: 'boolean'
},
testCase: {
type: 'string'
},
fullPage: {
type: 'boolean',
onlyAutomate: true
Expand Down Expand Up @@ -260,6 +263,7 @@ export const snapshotSchema = {
domTransformation: { $ref: '/config/snapshot#/properties/domTransformation' },
enableLayout: { $ref: '/config/snapshot#/properties/enableLayout' },
sync: { $ref: '/config/snapshot#/properties/sync' },
testCase: { $ref: '/config/snapshot#/properties/testCase' },
reshuffleInvalidTags: { $ref: '/config/snapshot#/properties/reshuffleInvalidTags' },
scopeOptions: { $ref: '/config/snapshot#/properties/scopeOptions' },
discovery: {
Expand Down
13 changes: 7 additions & 6 deletions packages/core/src/discovery.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
createRootResource,
createPercyCSSResource,
createLogResource,
yieldAll
yieldAll,
snapshotLogName
} from './utils.js';

// Logs verbose debug logs detailing various snapshot options.
Expand Down Expand Up @@ -130,7 +131,7 @@ function processSnapshotResources({ domSnapshot, resources, ...snapshot }) {

// include associated snapshot logs matched by meta information
resources.push(createLogResource(logger.query(log => (
log.meta.snapshot?.name === snapshot.meta.snapshot.name
log.meta.snapshot?.testCase === snapshot.meta.snapshot.testCase && log.meta.snapshot?.name === snapshot.meta.snapshot.name
))));

return { ...snapshot, resources };
Expand Down Expand Up @@ -264,9 +265,9 @@ export function createDiscoveryQueue(percy) {
.handle('end', async () => {
await percy.browser.close();
})
// snapshots are unique by name; when deferred also by widths
.handle('find', ({ name, widths }, snapshot) => (
snapshot.name === name && (!percy.deferUploads || (
// snapshots are unique by name and testCase; when deferred also by widths
.handle('find', ({ name, testCase, widths }, snapshot) => (
snapshot.testCase === testCase && snapshot.name === name && (!percy.deferUploads || (
!widths || widths.join() === snapshot.widths.join()))
))
// initialize the resources for DOM snapshots
Expand Down Expand Up @@ -318,7 +319,7 @@ export function createDiscoveryQueue(percy) {
if (error.name === 'AbortError' && queue.readyState < 3) {
// only error about aborted snapshots when not closed
percy.log.error('Received a duplicate snapshot, ' + (
`the previous snapshot was aborted: ${name}`), meta);
`the previous snapshot was aborted: ${snapshotLogName(name, meta)}`), meta);
} else {
// log all other encountered errors
percy.log.error(`Encountered an error taking snapshot: ${name}`, meta);
Expand Down
15 changes: 8 additions & 7 deletions packages/core/src/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import Queue from './queue.js';
import {
request,
hostnameMatches,
yieldTo
yieldTo,
snapshotLogName
} from './utils.js';
import { JobData } from './wait-for-job.js';

Expand Down Expand Up @@ -104,7 +105,7 @@ function getSnapshotOptions(options, { config, meta }) {
return PercyConfig.merge([{
widths: configSchema.snapshot.properties.widths.default,
discovery: { allowedHostnames: [validURL(options.url).hostname] },
meta: { ...meta, snapshot: { name: options.name } }
meta: { ...meta, snapshot: { name: options.name, testCase: options.testCase } }
}, config.snapshot, {
// only specific discovery options are used per-snapshot
discovery: {
Expand Down Expand Up @@ -339,17 +340,17 @@ export function createSnapshotsQueue(percy) {
percy.log.warn('Build not created', { build });
}
})
// snapshots are unique by name alone
.handle('find', ({ name }, snapshot) => (
snapshot.name === name
// snapshots are unique by name and testCase both
.handle('find', ({ name, testCase }, snapshot) => (
snapshot.testCase === testCase && snapshot.name === name
))
// when pushed, maybe flush old snapshots or possibly merge with existing snapshots
.handle('push', (snapshot, existing) => {
let { name, meta } = snapshot;

// log immediately when not deferred or dry-running
if (!percy.deferUploads) percy.log.info(`Snapshot taken: ${name}`, meta);
if (percy.dryRun) percy.log.info(`Snapshot found: ${name}`, meta);
if (!percy.deferUploads) percy.log.info(`Snapshot taken: ${snapshotLogName(name, meta)}`, meta);
if (percy.dryRun) percy.log.info(`Snapshot found: ${snapshotLogName(name, meta)}`, meta);

// immediately flush when uploads are delayed but not skipped
if (percy.delayUploads && !percy.deferUploads) queue.flush();
Expand Down
7 changes: 7 additions & 0 deletions packages/core/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,13 @@ export function serializeFunction(fn) {
return fnbody;
}

export function snapshotLogName(name, meta) {
if (meta?.snapshot?.testCase) {
return `testCase: ${meta.snapshot.testCase}, ${name}`;
}
return name;
}

// DefaultMap, which returns a default value for an uninitialized key
// Similar to defaultDict in python
export class DefaultMap extends Map {
Expand Down
50 changes: 49 additions & 1 deletion packages/core/test/snapshot.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ describe('Snapshot', () => {
expect(uploads[2]).toEqual(Buffer.from(textResource.content).toString('base64'));
});

it('handles duplicate snapshots', async () => {
it('handles duplicate snapshots when testCase is not passed', async () => {
await percy.snapshot([{
url: 'http://localhost:8000/foobar',
domSnapshot: '<p>Test 1</p>'
Expand All @@ -845,6 +845,54 @@ describe('Snapshot', () => {
]);
});

it('handles duplicate snapshots when same testCase is passed', async () => {
await percy.snapshot([{
url: 'http://localhost:8000/foobar',
testCase: 'test-case-1',
domSnapshot: '<p>Test 1</p>'
}, {
url: 'http://localhost:8000/foobar',
testCase: 'test-case-1',
domSnapshot: '<p>Test 2</p>'
}]);

expect(logger.stderr).toEqual([
'[percy] Received a duplicate snapshot, ' +
'the previous snapshot was aborted: testCase: test-case-1, /foobar'
]);
expect(logger.stdout).toEqual([
'[percy] Snapshot taken: testCase: test-case-1, /foobar'
]);
});

it('handles duplicate snapshots with different test cases', async () => {
await percy.snapshot([{
url: 'http://localhost:8000/one',
testCase: 'test-case-1',
domSnapshot: testDOM
}, {
url: 'http://localhost:8000/one',
testCase: 'test-case-2',
dom_snapshot: testDOM
}, {
url: 'http://localhost:8000/one',
testCase: 'test-case-3',
'dom-snapshot': testDOM
}, {
url: 'http://localhost:8000/one',
testCase: 'test-case-4',
domSnapshot: JSON.stringify({ html: testDOM })
}]);

expect(logger.stderr).toEqual([]);
expect(logger.stdout).toEqual([
'[percy] Snapshot taken: testCase: test-case-1, /one',
'[percy] Snapshot taken: testCase: test-case-2, /one',
'[percy] Snapshot taken: testCase: test-case-3, /one',
'[percy] Snapshot taken: testCase: test-case-4, /one'
]);
});

it('handles the browser closing early', async () => {
// close the browser after a page target is created
spyOn(percy.browser, 'send').and.callFake((...args) => {
Expand Down

0 comments on commit 1eaa54d

Please sign in to comment.