Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding check for correct SDK for percy product #1522

Merged
merged 4 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/client/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ export class PercyClient {
Object.assign(this, { token, config: config || {}, apiUrl });
this.addClientInfo(clientInfo);
this.addEnvironmentInfo(environmentInfo);
this.buildType = null;
this.screenshotFlow = null;
}

// Adds additional unique client info.
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ export function createPercyServer(percy, port) {
.route('post', '/percy/comparison', async (req, res) => {
let data;
if (percy.syncMode(req.body)) {
const snapshotPromise = new Promise((resolve, reject) => percy.upload(req.body, { resolve, reject }));
const snapshotPromise = new Promise((resolve, reject) => percy.upload(req.body, { resolve, reject }, 'app'));
data = await handleSyncJob(snapshotPromise, percy, 'comparison');
} else {
let upload = percy.upload(req.body);
let upload = percy.upload(req.body, null, 'app');
if (req.url.searchParams.has('await')) await upload;
}

Expand Down Expand Up @@ -139,10 +139,10 @@ export function createPercyServer(percy, port) {
percyAutomateRequestHandler(req, percy);
let comparisonData = await WebdriverUtils.automateScreenshot(req.body);
if (percy.syncMode(comparisonData)) {
const snapshotPromise = new Promise((resolve, reject) => percy.upload(comparisonData, { resolve, reject }));
const snapshotPromise = new Promise((resolve, reject) => percy.upload(comparisonData, { resolve, reject }, 'automate'));
data = await handleSyncJob(snapshotPromise, percy, 'comparison');
} else {
percy.upload(comparisonData);
percy.upload(comparisonData, null, 'automate');
}

res.json(200, { success: true, data: data });
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/percy.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ export class Percy {
}

// Uploads one or more snapshots directly to the current Percy build
upload(options, callback = null) {
upload(options, callback = null, screenshotFlow = null) {
if (this.readyState !== 1) {
throw new Error('Not running');
} else if (Array.isArray(options)) {
Expand All @@ -359,6 +359,7 @@ export class Percy {
// add client & environment info
this.client.addClientInfo(options.clientInfo);
this.client.addEnvironmentInfo(options.environmentInfo);
this.client.screenshotFlow = screenshotFlow;

// Sync CLI support, attached resolve, reject promise
if (this.syncMode(options)) {
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/snapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ export function createSnapshotsQueue(percy) {
let { data } = await percy.client.createBuild({ projectType: percy.projectType });
let url = data.attributes['web-url'];
let number = data.attributes['build-number'];
percy.client.buildType = data.attributes?.type;
Object.assign(build, { id: data.id, url, number });
// immediately run the queue if not delayed or deferred
if (!percy.delayUploads && !percy.deferUploads) queue.run();
Expand Down Expand Up @@ -361,6 +362,11 @@ export function createSnapshotsQueue(percy) {
.handle('task', async function*({ resources, ...snapshot }) {
let { name, meta } = snapshot;

if (percy.client.screenshotFlow === 'automate' && percy.client.buildType !== 'automate') {
throw new Error(`Cannot run automate screenshots in ${percy.client.buildType} project. Please use automate project token`);
} else if (percy.client.screenshotFlow === 'app' && percy.client.buildType !== 'app') {
throw new Error(`Cannot run App Percy screenshots in ${percy.client.buildType} project. Please use App Percy project token`);
rishigupta1599 marked this conversation as resolved.
Show resolved Hide resolved
}
// yield to evaluated snapshot resources
snapshot.resources = typeof resources === 'function'
? yield* yieldTo(resources())
Expand Down
8 changes: 5 additions & 3 deletions packages/core/test/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ describe('API Server', () => {
}));

expect(percy.upload).toHaveBeenCalledOnceWith(
{ 'test-me': true, me_too: true }
{ 'test-me': true, me_too: true },
null,
'app'
);

await expectAsync(test).toBePending();
Expand Down Expand Up @@ -376,7 +378,7 @@ describe('API Server', () => {
}
}));

expect(percy.upload).toHaveBeenCalledOnceWith(mockWebdriverUtilResponse);
expect(percy.upload).toHaveBeenCalledOnceWith(mockWebdriverUtilResponse, null, 'automate');
await expectAsync(test).toBePending();
resolve(); // no hanging promises
});
Expand Down Expand Up @@ -433,7 +435,7 @@ describe('API Server', () => {
}));

expect(percy.client.getComparisonDetails).toHaveBeenCalled();
expect(percy.upload).toHaveBeenCalledOnceWith({ sync: true }, jasmine.objectContaining({}));
expect(percy.upload).toHaveBeenCalledOnceWith({ sync: true }, jasmine.objectContaining({}), 'automate');
});

it('has a /events endpoint that calls #sendBuildEvents() async with provided options with clientInfo present', async () => {
Expand Down
44 changes: 44 additions & 0 deletions packages/core/test/snapshot.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1365,6 +1365,50 @@ describe('Snapshot', () => {
});
});

describe('invalid screenshot flow', () => {
it('should throw error if app percy build is ran using automate SDK', async () => {
await percy.stop(true);
await api.mock();

percy = await Percy.start({
token: 'PERCY_TOKEN',
projectType: 'app'
});

percy.client.buildType = 'app';
await percy.upload({
name: 'Snapshot',
external_debug_url: 'localhost',
some_other_rand_prop: 'random value',
tag: { name: 'device', foobar: 'baz' },
tiles: [{ content: 'foo' }, { content: 'vbv' }]
}, null, 'automate');

expect(logger.stderr).toEqual(jasmine.arrayContaining([jasmine.stringContaining('[percy] Error: Cannot run automate screenshots in app project. Please use automate project token')]));
});

it('should throw error if automate build is ran using app percy SDK', async () => {
await percy.stop(true);
await api.mock();

percy = await Percy.start({
token: 'PERCY_TOKEN',
projectType: 'automate'
});

percy.client.buildType = 'automate';
await percy.upload({
name: 'Snapshot',
external_debug_url: 'localhost',
some_other_rand_prop: 'random value',
tag: { name: 'device', foobar: 'baz' },
tiles: [{ content: 'foo' }, { content: 'vbv' }]
}, null, 'app');

expect(logger.stderr).toEqual(jasmine.arrayContaining([jasmine.stringContaining('[percy] Error: Cannot run App Percy screenshots in automate project. Please use App Percy project token')]));
});
});

describe('with percy-css', () => {
let getResourceData = () => (
api.requests['/builds/123/snapshots'][0].body.data.relationships.resources.data
Expand Down
Loading