Skip to content

Commit

Permalink
addressing comments: making sending event more genric for future use
Browse files Browse the repository at this point in the history
  • Loading branch information
prklm10 committed Oct 25, 2023
1 parent c11c978 commit 469c4be
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 70 deletions.
8 changes: 6 additions & 2 deletions packages/cli-exec/src/exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import command from '@percy/cli-command';
import start from './start.js';
import stop from './stop.js';
import ping from './ping.js';
import { getPackageJSON } from '@percy/cli-command/utils';

const pkg = getPackageJSON(import.meta.url);

export const exec = command('exec', {
description: 'Start and stop Percy around a supplied command',
Expand Down Expand Up @@ -123,9 +126,10 @@ async function* spawn(cmd, args, percy) {
if (process.env.PERCY_TOKEN) {
const myObject = {
errorKind: 'cli',
errorMessage: '1'
cliVersion: pkg.version,
message: '1'
};
percy.client.sendFailedEvents(percy.build.id, myObject);
percy.client.sendBuildEvents(percy.build.id, myObject);
}
}
});
Expand Down
13 changes: 6 additions & 7 deletions packages/cli-exec/test/exec.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { logger, api, setupTest } from '@percy/cli-command/test/helpers';
import exec from '@percy/cli-exec';
import { getPackageJSON } from '@percy/cli-command/utils';

describe('percy exec', () => {
beforeEach(async () => {
Expand Down Expand Up @@ -144,6 +145,7 @@ describe('percy exec', () => {
});

it('tests process.stderr when token is present', async () => {
const pkg = getPackageJSON(import.meta.url);
let stderrSpy = spyOn(process.stderr, 'write').and.resolveTo('some response');
await expectAsync(
exec(['--', 'node', 'random.js']) // invalid command
Expand All @@ -157,14 +159,11 @@ describe('percy exec', () => {
'[percy] Finalized build #1: https://percy.io/test/test/123'
]);

expect(api.requests['/builds/123/failed-events']).toBeDefined();
expect(api.requests['/builds/123/failed-events'][0].body).toEqual({
expect(api.requests['/builds/123/send-events']).toBeDefined();
expect(api.requests['/builds/123/send-events'][0].body).toEqual({
data: {
buildId: '123',
errorKind: 'cli',
client: null,
clientVersion: null,
cliVersion: null,
cliVersion: pkg.version,
message: '1'
}
});
Expand All @@ -186,7 +185,7 @@ describe('percy exec', () => {
'[percy] Running "node random.js"'
]);

expect(api.requests['/builds/123/failed-events']).not.toBeDefined();
expect(api.requests['/builds/123/send-events']).not.toBeDefined();
});

it('does not run the command if canceled beforehand', async () => {
Expand Down
15 changes: 4 additions & 11 deletions packages/client/src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,18 +516,11 @@ export class PercyClient {
return comparison;
}

async sendFailedEvents(buildId, { errorKind = 'sdk', client = null, clientVersion = null, cliVersion = null, errorMessage = null } = {}) {
async sendBuildEvents(buildId, body) {
validateId('build', buildId);
this.log.debug('Sending FailedEvents');
return this.post(`builds/${buildId}/failed-events`, {
data: {
buildId: buildId,
errorKind: errorKind,
client: client,
clientVersion: clientVersion,
cliVersion: cliVersion,
message: errorMessage
}
this.log.debug('Sending Build Events');
return this.post(`builds/${buildId}/send-events`, {
data: body
});
}

Expand Down
31 changes: 7 additions & 24 deletions packages/client/test/client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1333,37 +1333,20 @@ describe('PercyClient', () => {
});
});

describe('sendFailedEvents', () => {
it('should send failed event with default values', async () => {
await expectAsync(client.sendFailedEvents(123)).toBeResolved();
expect(api.requests['/builds/123/failed-events']).toBeDefined();
expect(api.requests['/builds/123/failed-events'][0].method).toBe('POST');
expect(api.requests['/builds/123/failed-events'][0].body).toEqual({
data: {
buildId: 123,
errorKind: 'sdk',
client: null,
clientVersion: null,
cliVersion: null,
message: null
}
});
});

it('should send failed event with default values', async () => {
await expectAsync(client.sendFailedEvents(123, {
describe('sendBuildEvents', () => {
it('should send build event with default values', async () => {
await expectAsync(client.sendBuildEvents(123, {
errorKind: 'cli',
client: 'percy-appium-dotnet',
clientVersion: '3.0.1',
cliVersion: '1.27.3',
errorMessage: 'some error'
message: 'some error'
})).toBeResolved();

expect(api.requests['/builds/123/failed-events']).toBeDefined();
expect(api.requests['/builds/123/failed-events'][0].method).toBe('POST');
expect(api.requests['/builds/123/failed-events'][0].body).toEqual({
expect(api.requests['/builds/123/send-events']).toBeDefined();
expect(api.requests['/builds/123/send-events'][0].method).toBe('POST');
expect(api.requests['/builds/123/send-events'][0].body).toEqual({
data: {
buildId: 123,
errorKind: 'cli',
client: 'percy-appium-dotnet',
clientVersion: '3.0.1',
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import path from 'path';
import { createRequire } from 'module';
import logger from '@percy/logger';
import { normalize } from '@percy/config/utils';
import { getPackageJSON, Server, percyAutomateRequestHandler, percyFailedEventHandler } from './utils.js';
import { getPackageJSON, Server, percyAutomateRequestHandler, percyBuildEventHandler } from './utils.js';
import WebdriverUtils from '@percy/webdriver-utils';
// need require.resolve until import.meta.resolve can be transpiled
export const PERCY_DOM = createRequire(import.meta.url).resolve('@percy/dom');
Expand Down Expand Up @@ -123,8 +123,8 @@ export function createPercyServer(percy, port) {
})
// Recieves events from sdk's.
.route('post', '/percy/events', async (req, res) => {
percyFailedEventHandler(req, pkg.version);
await percy.client.sendFailedEvents(percy.build?.id, req.body);
percyBuildEventHandler(req, pkg.version);
await percy.client.sendBuildEvents(percy.build?.id, req.body);
res.json(200, { success: true });
})
// stops percy at the end of the current event loop
Expand Down
30 changes: 21 additions & 9 deletions packages/core/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,32 @@ export function percyAutomateRequestHandler(req, percy) {
req.body.buildInfo = percy.build;
}

// Returns the body for failedEvent structure
export function percyFailedEventHandler(req, cliVersion) {
if (req.body.clientInfo) {
const [client, clientVersion] = req.body.clientInfo.split('/');
// Returns the body for sendEvent structure
export function percyBuildEventHandler(req, cliVersion) {
if (Array.isArray(req.body)) {
req.body.forEach(element => {
processSendEventData(element, cliVersion);
});
} else {
// Treat the input as an object and perform instructions
processSendEventData(req.body, cliVersion);
}
}

// Process sendEvent object
function processSendEventData(input, cliVersion) {
if (input.clientInfo) {
const [client, clientVersion] = input.clientInfo.split('/');

// Add the client and clientVersion fields to the existing object
req.body.client = client;
req.body.clientVersion = clientVersion;
input.client = client;
input.clientVersion = clientVersion;

// Remove the original clientInfo field
delete req.body.clientInfo;
delete input.clientInfo;
}
if (!req.body.cliVersion) {
req.body.cliVersion = cliVersion;
if (!input.cliVersion) {
input.cliVersion = cliVersion;
}
}

Expand Down
56 changes: 50 additions & 6 deletions packages/core/test/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,11 +316,11 @@ describe('API Server', () => {
resolve(); // no hanging promises
});

it('has a /events endpoint that calls #sendFailedEvents() async with provided options with clientInfo present', async () => {
it('has a /events endpoint that calls #sendBuildEvents() async with provided options with clientInfo present', async () => {
let { getPackageJSON } = await import('@percy/client/utils');
let pkg = getPackageJSON(import.meta.url);
let resolve, test = new Promise(r => (resolve = r));
let sendFailedEventsSpy = spyOn(percy.client, 'sendFailedEvents').and.resolveTo('some response');
let sendBuildEventsSpy = spyOn(percy.client, 'sendBuildEvents').and.resolveTo('some response');

await percy.start();

Expand All @@ -332,7 +332,7 @@ describe('API Server', () => {
method: 'post'
})).toBeResolvedTo({ success: true });

expect(sendFailedEventsSpy).toHaveBeenCalledOnceWith(percy.build.id, jasmine.objectContaining({
expect(sendBuildEventsSpy).toHaveBeenCalledOnceWith(percy.build.id, jasmine.objectContaining({
errorMessage: 'some error',
client: 'percy-appium-dotnet',
clientVersion: '3.0.1',
Expand All @@ -343,9 +343,53 @@ describe('API Server', () => {
resolve(); // no hanging promises
});

it('has a /events endpoint that calls #sendFailedEvents() async with provided options with clientInfo absent', async () => {
it('has a /events endpoint called with body array that calls #sendBuildEvents() async with provided options with clientInfo present', async () => {
let { getPackageJSON } = await import('@percy/client/utils');
let pkg = getPackageJSON(import.meta.url);
let resolve, test = new Promise(r => (resolve = r));
let sendBuildEventsSpy = spyOn(percy.client, 'sendBuildEvents').and.resolveTo('some response');

await percy.start();

await expectAsync(request('/percy/events', {
body: [
{
errorMessage: 'some error 1',
clientInfo: 'percy-appium-dotnet/3.0.1'
},
{
errorMessage: 'some error 2',
clientInfo: 'percy-appium-dotnet/3.0.1'
}
],
method: 'post'
})).toBeResolvedTo({ success: true });

expect(sendBuildEventsSpy).toHaveBeenCalledOnceWith(percy.build.id, jasmine.objectContaining(
[
{
errorMessage: 'some error 1',
client: 'percy-appium-dotnet',
clientVersion: '3.0.1',
cliVersion: pkg.version
},
{
errorMessage: 'some error 2',
client: 'percy-appium-dotnet',
clientVersion: '3.0.1',
cliVersion: pkg.version

}
]
));

await expectAsync(test).toBePending();
resolve(); // no hanging promises
});

it('has a /events endpoint that calls #sendBuildEvents() async with provided options with clientInfo absent', async () => {
let resolve, test = new Promise(r => (resolve = r));
let sendFailedEventsSpy = spyOn(percy.client, 'sendFailedEvents').and.resolveTo('some response');
let sendBuildEventsSpy = spyOn(percy.client, 'sendBuildEvents').and.resolveTo('some response');

await percy.start();

Expand All @@ -357,7 +401,7 @@ describe('API Server', () => {
method: 'post'
})).toBeResolvedTo({ success: true });

expect(sendFailedEventsSpy).toHaveBeenCalledOnceWith(percy.build.id, jasmine.objectContaining({
expect(sendBuildEventsSpy).toHaveBeenCalledOnceWith(percy.build.id, jasmine.objectContaining({
errorMessage: 'some error',
cliVersion: '1.2.3'
}));
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk-utils/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import waitForPercyIdle from './percy-idle.js';
import fetchPercyDOM from './percy-dom.js';
import postSnapshot from './post-snapshot.js';
import postComparison from './post-comparison.js';
import postFailedEvent from './post-failed-event.js';
import postBuildEvents from './post-build-event.js';
import flushSnapshots from './flush-snapshots.js';
import captureAutomateScreenshot from './post-screenshot.js';

Expand All @@ -21,7 +21,7 @@ export {
postComparison,
flushSnapshots,
captureAutomateScreenshot,
postFailedEvent
postBuildEvents
};

// export the namespace by default
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import request from './request.js';

// Post failed event data to the CLI event endpoint.
export async function postFailedEvent(options) {
export async function postBuildEvents(options) {
return await request.post('/percy/events', options).catch(err => {
throw err;
});
}

export default postFailedEvent;
export default postBuildEvents;
8 changes: 4 additions & 4 deletions packages/sdk-utils/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ describe('SDK Utils', () => {
});
});

describe('postFailedEvent(options)', () => {
let { postFailedEvent } = utils;
describe('postBuildEvents(options)', () => {
let { postBuildEvents } = utils;
let options;

beforeEach(() => {
Expand All @@ -312,14 +312,14 @@ describe('SDK Utils', () => {

it('posts comparison options to the CLI API event endpoint', async () => {
spyOn(utils.request, 'post').and.callFake(() => Promise.resolve());
await expectAsync(postFailedEvent(options)).toBeResolved();
await expectAsync(postBuildEvents(options)).toBeResolved();
await expectAsync(helpers.get('requests')).toBeResolvedTo({});
});

it('throws when the event API fails', async () => {
await helpers.test('error', '/percy/events');

await expectAsync(postFailedEvent({}))
await expectAsync(postBuildEvents({}))
.toBeRejectedWithError('testing');
});
});
Expand Down

0 comments on commit 469c4be

Please sign in to comment.