Skip to content

Commit c8d2b2d

Browse files
used separate file for snapshotQueue
1 parent 279f35d commit c8d2b2d

File tree

8 files changed

+341
-339
lines changed

8 files changed

+341
-339
lines changed

src/commander/exec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import createBuild from '../tasks/createBuild.js'
1010
import exec from '../tasks/exec.js'
1111
import processSnapshots from '../tasks/processSnapshot.js'
1212
import finalizeBuild from '../tasks/finalizeBuild.js'
13-
import snapshotQueue from '../lib/processSnapshot.js'
13+
import snapshotQueue from '../lib/snapshotQueue.js'
1414

1515
const command = new Command();
1616

src/lib/ctx.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export default (options: Record<string, string>): Context => {
7676
allowedHostnames: config.allowedHostnames || [],
7777
basicAuthorization: basicAuthObj,
7878
smartIgnore: config.smartIgnore ?? false,
79-
deferUploads: config.deferUploads ?? false
79+
delayedUploads: config.delayedUploads ?? false
8080
},
8181
uploadFilePath: '',
8282
webStaticConfig: [],

src/lib/processSnapshot.ts

Lines changed: 1 addition & 329 deletions
Original file line numberDiff line numberDiff line change
@@ -10,335 +10,7 @@ const ALLOWED_STATUSES = [200, 201];
1010
const REQUEST_TIMEOUT = 10000;
1111
const MIN_VIEWPORT_HEIGHT = 1080;
1212

13-
export default class Queue {
14-
private snapshots: Array<Snapshot> = [];
15-
private processedSnapshots: Array<Record<string, any>> = [];
16-
private processing: boolean = false;
17-
private processingSnapshot: string = '';
18-
private ctx: Context;
19-
private snapshotNames: Array<string> = [];
20-
private variants: Array<string> = [];
21-
22-
constructor(ctx: Context) {
23-
this.ctx = ctx;
24-
}
25-
26-
enqueue(item: Snapshot, start: boolean): void {
27-
this.snapshots.push(item);
28-
if(start){
29-
if (!this.processing) {
30-
this.processing = true;
31-
this.processNext();
32-
}
33-
}
34-
}
35-
36-
startProcessingfunc(): void {
37-
if (!this.processing) {
38-
this.processing = true;
39-
this.processNext();
40-
}
41-
}
42-
43-
private processGenerateVariants(snapshot: Snapshot): void {
44-
if (snapshot.options) {
45-
if (snapshot.options.web) {
46-
this.generateWebVariants(snapshot, snapshot.options.web);
47-
}
48-
if (snapshot.options.mobile) {
49-
this.generateMobileVariants(snapshot, snapshot.options.mobile);
50-
}
51-
}
52-
53-
if (!snapshot.options || (snapshot.options && !snapshot.options.web && !snapshot.options.mobile)) {
54-
this.generateVariants(snapshot, this.ctx.config);
55-
}
56-
}
57-
58-
59-
private generateVariants(snapshot: Snapshot, config: any): void {
60-
// Process web configurations if they exist
61-
62-
if (config.web) {
63-
const browsers = config.web.browsers || [];
64-
const viewports = config.web.viewports || [];
65-
66-
for (const browser of browsers) {
67-
for (const viewport of viewports) {
68-
const width = viewport.width;
69-
const height = viewport.height || 0; // Use 0 if height is not provided
70-
const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
71-
this.variants.push(variant);
72-
}
73-
}
74-
}
75-
76-
// Process mobile configurations if they exist
77-
if (config.mobile) {
78-
const devices = config.mobile.devices || [];
79-
const orientation = config.mobile.orientation || constants.MOBILE_ORIENTATION_PORTRAIT;
80-
81-
for (const device of devices) {
82-
const variant = `${snapshot.name}_${device}_${orientation}`;
83-
this.variants.push(variant);
84-
}
85-
}
86-
}
87-
88-
89-
private generateWebVariants(snapshot: Snapshot, webConfig: any): void {
90-
const browsers = webConfig.browsers ?? this.ctx.config.web?.browsers ?? [constants.CHROME, constants.EDGE, constants.FIREFOX, constants.SAFARI];
91-
const viewports = webConfig.viewports || [];
92-
93-
for (const browser of browsers) {
94-
for (const viewport of viewports) {
95-
const width = viewport[0];
96-
const height = viewport[1] || 0; // Use 0 if height is not provided
97-
const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
98-
this.variants.push(variant);
99-
}
100-
}
101-
}
102-
103-
private generateMobileVariants(snapshot: Snapshot, mobileConfig: any): void {
104-
const devices = mobileConfig.devices || [];
105-
const orientation = mobileConfig.orientation ?? this.ctx.config.mobile?.orientation ?? constants.MOBILE_ORIENTATION_PORTRAIT;
106-
107-
for (const device of devices) {
108-
const variant = `${snapshot.name}_${device}_${orientation}`;
109-
this.variants.push(variant);
110-
}
111-
}
112-
113-
114-
private filterExistingVariants(snapshot: Snapshot, config: any): boolean {
115-
116-
let drop = true;
117-
118-
if (snapshot.options && snapshot.options.web) {
119-
const webDrop = this.filterWebVariants(snapshot, snapshot.options.web);
120-
if (!webDrop) drop = false;
121-
}
122-
123-
if (snapshot.options && snapshot.options.mobile) {
124-
const mobileDrop = this.filterMobileVariants(snapshot, snapshot.options.mobile);
125-
if (!mobileDrop) drop = false;
126-
}
127-
128-
// Fallback to the global config if neither web nor mobile options are present in snapshot.options
129-
if (!snapshot.options || (snapshot.options && !snapshot.options.web && !snapshot.options.mobile)) {
130-
const configDrop = this.filterVariants(snapshot, config);
131-
if (!configDrop) drop = false;
132-
}
133-
return drop;
134-
}
135-
136-
private filterVariants(snapshot: Snapshot, config: any): boolean {
137-
let allVariantsDropped = true;
138-
139-
// Process web configurations if they exist in config
140-
if (config.web) {
141-
const browsers = config.web.browsers || [];
142-
const viewports = config.web.viewports || [];
143-
144-
for (const browser of browsers) {
145-
for (const viewport of viewports) {
146-
const width = viewport.width;
147-
const height = viewport.height || 0;
148-
const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
149-
150-
if (!this.variants.includes(variant)) {
151-
allVariantsDropped = false; // Found a variant that needs processing
152-
if (!snapshot.options) snapshot.options = {};
153-
if (!snapshot.options.web) snapshot.options.web = { browsers: [], viewports: [] };
154-
155-
if (!snapshot.options.web.browsers.includes(browser)) {
156-
snapshot.options.web.browsers.push(browser);
157-
}
158-
159-
// Check for unique viewports to avoid duplicates
160-
const viewportExists = snapshot.options.web.viewports.some(existingViewport =>
161-
existingViewport[0] === width &&
162-
(existingViewport.length < 2 || existingViewport[1] === height)
163-
);
164-
165-
if (!viewportExists) {
166-
if (height > 0) {
167-
snapshot.options.web.viewports.push([width, height]);
168-
} else {
169-
snapshot.options.web.viewports.push([width]);
170-
}
171-
}
172-
}
173-
}
174-
}
175-
}
176-
177-
// Process mobile configurations if they exist in config
178-
if (config.mobile) {
179-
const devices = config.mobile.devices || [];
180-
const orientation = config.mobile.orientation || constants.MOBILE_ORIENTATION_PORTRAIT;
181-
const fullPage = config.mobile.fullPage || true;
182-
183-
for (const device of devices) {
184-
const variant = `${snapshot.name}_${device}_${orientation}`;
185-
186-
if (!this.variants.includes(variant)) {
187-
allVariantsDropped = false; // Found a variant that needs processing
188-
if (!snapshot.options) snapshot.options = {};
189-
if (!snapshot.options.mobile) snapshot.options.mobile = { devices: [], orientation: constants.MOBILE_ORIENTATION_PORTRAIT };
190-
191-
if (!snapshot.options.mobile.devices.includes(device)) {
192-
snapshot.options.mobile.devices.push(device);
193-
}
194-
snapshot.options.mobile.orientation = orientation;
195-
}
196-
}
197-
}
198-
199-
200-
return allVariantsDropped;
201-
}
202-
203-
private filterWebVariants(snapshot: Snapshot, webConfig: any): boolean {
204-
const browsers = webConfig.browsers ?? this.ctx.config.web?.browsers ?? [constants.CHROME, constants.EDGE, constants.FIREFOX, constants.SAFARI];
205-
const viewports = webConfig.viewports || [];
206-
let allVariantsDropped = true;
207-
208-
if (!snapshot.options) {
209-
snapshot.options = {};
210-
}
211-
212-
snapshot.options.web = { browsers: [], viewports: [] };
213-
214-
for (const browser of browsers) {
215-
for (const viewport of viewports) {
216-
const width = viewport[0];
217-
const height = viewport[1] || 0;
218-
const variant = `${snapshot.name}_${browser}_viewport[${width}]_viewport[${height}]`;
219-
220-
if (!this.variants.includes(variant)) {
221-
allVariantsDropped = false; // Found a variant that needs processing
222-
if (!snapshot.options.web.browsers.includes(browser)) {
223-
snapshot.options.web.browsers.push(browser);
224-
}
225-
// Only add unique viewports to avoid duplicates
226-
const viewportExists = snapshot.options.web.viewports.some(existingViewport =>
227-
existingViewport[0] === width &&
228-
(existingViewport.length < 2 || existingViewport[1] === height)
229-
);
230-
if (!viewportExists) {
231-
if (height > 0) {
232-
snapshot.options.web.viewports.push([width, height]);
233-
} else {
234-
snapshot.options.web.viewports.push([width]);
235-
}
236-
}
237-
}
238-
}
239-
}
240-
return allVariantsDropped;
241-
}
242-
243-
244-
private filterMobileVariants(snapshot: Snapshot, mobileConfig: any): boolean {
245-
if (!snapshot.options) {
246-
snapshot.options = {};
247-
}
248-
249-
snapshot.options.mobile = { devices: [], orientation: constants.MOBILE_ORIENTATION_PORTRAIT };
250-
251-
const devices = mobileConfig.devices || [];
252-
const orientation = mobileConfig.orientation ?? this.ctx.config.mobile?.orientation ?? constants.MOBILE_ORIENTATION_PORTRAIT;
253-
const fullPage = mobileConfig.fullPage ?? this.ctx.config.mobile?.fullPage ?? true;
254-
let allVariantsDropped = true;
255-
256-
for (const device of devices) {
257-
const variant = `${snapshot.name}_${device}_${orientation}`;
258-
259-
if (!this.variants.includes(variant)) {
260-
allVariantsDropped = false; // Found a variant that needs processing
261-
snapshot.options.mobile.devices.push(device);
262-
snapshot.options.mobile.orientation = orientation;
263-
}
264-
}
265-
return allVariantsDropped;
266-
}
267-
268-
private async processNext(): Promise<void> {
269-
if (!this.isEmpty()) {
270-
let snapshot;
271-
if (this.ctx.config.deferUploads){
272-
snapshot = this.snapshots.pop();
273-
} else {
274-
snapshot = this.snapshots.shift();
275-
}
276-
try {
277-
this.processingSnapshot = snapshot?.name;
278-
let drop = false;
279-
280-
if (snapshot && snapshot.name && this.snapshotNames.includes(snapshot.name)) {
281-
if (!this.ctx.config.deferUploads){
282-
drop = true;
283-
this.ctx.log.debug(`snapshot failed; Same snapshot has been encountered with defer Uploads being false`);
284-
} else {
285-
drop = this.filterExistingVariants(snapshot, this.ctx.config);
286-
}
287-
}
288-
289-
if (snapshot && snapshot.name && !this.snapshotNames.includes(snapshot.name) && !drop) {
290-
this.snapshotNames.push(snapshot.name);
291-
}
292-
293-
if (snapshot && !drop) {
294-
this.processGenerateVariants(snapshot);
295-
}
296-
297-
if (!drop) {
298-
let { processedSnapshot, warnings } = await processSnapshot(snapshot, this.ctx);
299-
await this.ctx.client.uploadSnapshot(this.ctx, processedSnapshot);
300-
this.ctx.totalSnapshots++;
301-
this.processedSnapshots.push({ name: snapshot.name, warnings });
302-
}
303-
} catch (error: any) {
304-
this.ctx.log.debug(`snapshot failed; ${error}`);
305-
this.processedSnapshots.push({ name: snapshot.name, error: error.message });
306-
}
307-
// Close open browser contexts and pages
308-
if (this.ctx.browser) {
309-
for (let context of this.ctx.browser.contexts()) {
310-
for (let page of context.pages()) {
311-
await page.close();
312-
this.ctx.log.debug(`Closed browser page for snapshot ${snapshot.name}`);
313-
}
314-
await context.close();
315-
this.ctx.log.debug(`Closed browser context for snapshot ${snapshot.name}`);
316-
}
317-
}
318-
this.processNext();
319-
} else {
320-
this.processing = false;
321-
}
322-
}
323-
324-
isProcessing(): boolean {
325-
return this.processing;
326-
}
327-
328-
getProcessingSnapshot(): string {
329-
return this.processingSnapshot;
330-
}
331-
332-
getProcessedSnapshots(): Array<Record<string, any>> {
333-
return this.processedSnapshots;
334-
}
335-
336-
isEmpty(): boolean {
337-
return this.snapshots && this.snapshots.length ? false : true;
338-
}
339-
}
340-
341-
async function processSnapshot(snapshot: Snapshot, ctx: Context): Promise<Record<string, any>> {
13+
export default async function processSnapshot(snapshot: Snapshot, ctx: Context): Promise<Record<string, any>> {
34214
updateLogContext({ task: 'discovery' });
34315
ctx.log.debug(`Processing snapshot ${snapshot.name} ${snapshot.url}`);
34416

src/lib/schemaValidation.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,9 @@ const ConfigSchema = {
151151
},
152152
}
153153
},
154-
deferUploads: {
154+
delayedUploads: {
155155
type: "boolean",
156-
errorMessage: "Invalid config; deferUploads must be true/false"
156+
errorMessage: "Invalid config; delayedUploads must be true/false"
157157
},
158158
},
159159
anyOf: [

src/lib/server.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ export default async (ctx: Context): Promise<FastifyInstance<Server, IncomingMes
3636
let { snapshot, testType } = request.body;
3737
if (!validateSnapshot(snapshot)) throw new Error(validateSnapshot.errors[0].message);
3838
ctx.testType = testType;
39-
const start = ctx.config.deferUploads ? false : true;
40-
ctx.snapshotQueue?.enqueue(snapshot, start);
39+
ctx.snapshotQueue?.enqueue(snapshot);
4140
replyCode = 200;
4241
replyBody = { data: { message: "success", warnings: [] }};
4342
} catch (error: any) {

0 commit comments

Comments
 (0)