Skip to content

Commit

Permalink
Merge pull request #101 from LambdaTest/stage
Browse files Browse the repository at this point in the history
Release v3.0.12
  • Loading branch information
arushsaxena1998 authored Jun 19, 2024
2 parents 290447f + 427eecf commit 3df71ac
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 26 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lambdatest/smartui-cli",
"version": "3.0.11",
"version": "3.0.12",
"description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
"files": [
"dist/**/*"
Expand Down
10 changes: 8 additions & 2 deletions src/commander/exec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { color, Listr, ListrDefaultRendererLogLevels } from 'listr2'
import startServer from '../tasks/startServer.js'
import auth from '../tasks/auth.js'
import ctxInit from '../lib/ctx.js'
import getGitInfo from '../tasks/getGitInfo.js';
import getGitInfo from '../tasks/getGitInfo.js'
import createBuild from '../tasks/createBuild.js'
import exec from '../tasks/exec.js'
import processSnapshots from '../tasks/processSnapshot.js'
import finalizeBuild from '../tasks/finalizeBuild.js'
import snapshotQueue from '../lib/processSnapshot.js'

const command = new Command();

Expand All @@ -25,6 +27,7 @@ command
return
}
ctx.args.execCommand = execCommand
ctx.snapshotQueue = new snapshotQueue(ctx)
ctx.totalSnapshots = 0

let tasks = new Listr<Context>(
Expand All @@ -34,6 +37,7 @@ command
getGitInfo(ctx),
createBuild(ctx),
exec(ctx),
processSnapshots(ctx),
finalizeBuild(ctx)
],
{
Expand All @@ -53,8 +57,10 @@ command
} catch (error) {
ctx.log.info('\nRefer docs: https://www.lambdatest.com/support/docs/smart-visual-regression-testing/');
} finally {
await ctx.server?.close();
await ctx.browser?.close();
ctx.log.debug(`Closed browser`);
await ctx.server?.close();
ctx.log.debug(`Closed server`);
}
})

Expand Down
8 changes: 4 additions & 4 deletions src/lib/httpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,19 @@ export default class httpClient {
}, log)
}

uploadSnapshot(buildId: string, snapshot: ProcessedSnapshot, testType: string, log: Logger) {
uploadSnapshot(ctx: Context, snapshot: ProcessedSnapshot) {
return this.request({
url: `/builds/${buildId}/snapshot`,
url: `/builds/${ctx.build.id}/snapshot`,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
data: {
snapshot,
test: {
type: testType,
type: ctx.testType,
source: 'cli'
}
}
}, log)
}, ctx.log)
}

uploadScreenshot(
Expand Down
68 changes: 67 additions & 1 deletion src/lib/processSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,73 @@ const ALLOWED_STATUSES = [200, 201];
const REQUEST_TIMEOUT = 10000;
const MIN_VIEWPORT_HEIGHT = 1080;

export default async (snapshot: Snapshot, ctx: Context): Promise<Record<string, any>> => {
export default class Queue {
private snapshots: Array<Snapshot> = [];
private processedSnapshots: Array<Record<string, any>> = [];
private processing: boolean = false;
private processingSnapshot: string = '';
private ctx: Context;

constructor(ctx: Context) {
this.ctx = ctx;
}

enqueue(item: Snapshot): void {
this.snapshots.push(item);
if (!this.processing) {
this.processing = true;
this.processNext();
}
}

private async processNext(): Promise<void> {
if (!this.isEmpty()) {
const snapshot = this.snapshots.shift();
try {
this.processingSnapshot = snapshot?.name;
let { processedSnapshot, warnings } = await processSnapshot(snapshot, this.ctx);
await this.ctx.client.uploadSnapshot(this.ctx, processedSnapshot);
this.ctx.totalSnapshots++;
this.processedSnapshots.push({name: snapshot.name, warnings});
} catch (error: any) {
this.ctx.log.debug(`snapshot failed; ${error}`);
this.processedSnapshots.push({name: snapshot.name, error: error.message});
}
// Close open browser contexts and pages
if (this.ctx.browser) {
for (let context of this.ctx.browser.contexts()) {
for (let page of context.pages()) {
await page.close();
this.ctx.log.debug(`Closed browser page for snapshot ${snapshot.name}`);
}
await context.close();
this.ctx.log.debug(`Closed browser context for snapshot ${snapshot.name}`);
}
}
this.processNext();
} else {
this.processing = false;
}
}

isProcessing(): boolean {
return this.processing;
}

getProcessingSnapshot(): string {
return this.processingSnapshot;
}

getProcessedSnapshots(): Array<Record<string, any>> {
return this.processedSnapshots;
}

isEmpty(): boolean {
return this.snapshots.length ? false : true;
}
}

async function processSnapshot(snapshot: Snapshot, ctx: Context): Promise<Record<string, any>> {
ctx.log.debug(`Processing snapshot ${snapshot.name}`);

let launchOptions: Record<string, any> = { headless: true }
Expand Down
21 changes: 4 additions & 17 deletions src/lib/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,23 @@ export default async (ctx: Context): Promise<FastifyInstance<Server, IncomingMes
reply.code(200).send({ data: { dom: SMARTUI_DOM }});
});

// upload snpashot
// process and upload snpashot
server.post('/snapshot', opts, async (request, reply) => {
let replyCode: number;
let replyBody: Record<string, any>;

try {
let { snapshot, testType } = request.body;
if (!validateSnapshot(snapshot)) throw new Error(validateSnapshot.errors[0].message);
let { processedSnapshot, warnings } = await processSnapshot(snapshot, ctx);
await ctx.client.uploadSnapshot(ctx.build.id, processedSnapshot, testType, ctx.log);
ctx.totalSnapshots++;
ctx.testType = testType;
ctx.snapshotQueue?.enqueue(snapshot);
replyCode = 200;
replyBody = { data: { message: "success", warnings }};
replyBody = { data: { message: "success", warnings: [] }};
} catch (error: any) {
ctx.log.debug(`snapshot failed; ${error}`)
replyCode = 500;
replyBody = { error: { message: error.message }}
}

// Close open browser contexts and pages
if (ctx.browser) {
for (let context of ctx.browser.contexts()) {
for (let page of context.pages()) {
await page.close();
ctx.log.debug(`Closed browser page`);
}
await context.close();
ctx.log.debug(`Closed browser context`);
}
}

return reply.code(replyCode).send(replyBody);
});
Expand Down
40 changes: 40 additions & 0 deletions src/tasks/processSnapshot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { ListrTask, ListrRendererFactory } from 'listr2';
import { Context } from '../types.js'
import chalk from 'chalk';
import { updateLogContext } from '../lib/logger.js';

export default (ctx: Context): ListrTask<Context, ListrRendererFactory, ListrRendererFactory> => {
return {
title: `Processing snapshots`,
task: async (ctx, task): Promise<void> => {

try {
// wait for snapshot queue to be empty
await new Promise((resolve) => {
let output: string = '';
const intervalId = setInterval(() => {
if (ctx.snapshotQueue?.isEmpty() && !ctx.snapshotQueue?.isProcessing()) {
clearInterval(intervalId);
resolve();
} else {
task.title = `Processing snapshot ${ctx.snapshotQueue?.getProcessingSnapshot()}`
}
}, 500);
})

let output = '';
for (let snapshot of ctx.snapshotQueue?.getProcessedSnapshots()) {
if (snapshot.error) output += `${chalk.red('\u{2717}')} ${chalk.gray(`${snapshot.name}\n[error] ${snapshot.error}`)}\n`;
else output += `${chalk.green('\u{2713}')} ${chalk.gray(snapshot.name)}\n${snapshot.warnings.length ? chalk.gray(`[warning] ${snapshot.warnings.join('\n[warning] ')}\n`) : ''}`;
}
task.output = output;
task.title = 'Processed snapshots'
} catch (error: any) {
ctx.log.debug(error);
task.output = chalk.gray(error.message);
throw new Error('Processing of snapshots failed');
}
},
rendererOptions: { persistentOutput: true }
}
}
5 changes: 4 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import httpClient from './lib/httpClient.js'
import type { Logger } from 'winston'
import { ListrTaskWrapper, ListrRenderer } from "listr2";
import { Browser } from '@playwright/test';
import snapshotQueue from './lib/processSnapshot.js';

export interface Context {
env: Env;
Expand All @@ -12,6 +13,7 @@ export interface Context {
server?: FastifyInstance<Server, IncomingMessage, ServerResponse>;
client: httpClient;
browser?: Browser;
snapshotQueue?: snapshotQueue;
config: {
web?: WebConfig;
mobile?: MobileConfig,
Expand All @@ -34,7 +36,8 @@ export interface Context {
}
cliVersion: string;
totalSnapshots: number;
figmaDesignConfig: FigmaDesignConfig;
figmaDesignConfig?: FigmaDesignConfig;
testType?: string;
}

export interface Env {
Expand Down

0 comments on commit 3df71ac

Please sign in to comment.