Skip to content

Commit fdfc75a

Browse files
authored
Merge pull request #72 from LambdaTest/stage
Release 3.0.4
2 parents c0b272d + 7dc22f0 commit fdfc75a

File tree

3 files changed

+57
-27
lines changed

3 files changed

+57
-27
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lambdatest/smartui-cli",
3-
"version": "3.0.3",
3+
"version": "3.0.4",
44
"description": "A command line interface (CLI) to run SmartUI tests on LambdaTest",
55
"files": [
66
"dist/**/*"

src/dom/dom-serializer.js

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -332,32 +332,35 @@
332332
for (let video of dom.querySelectorAll('video')) {
333333
let videoId = video.getAttribute('data-smartui-element-id');
334334
let cloneEl = clone.querySelector(`[data-smartui-element-id="${videoId}"]`);
335-
// if the video already has a poster image, no work for us to do
336-
if (video.getAttribute('poster')) {
337-
cloneEl.removeAttribute('src');
338-
continue;
339-
}
340-
let canvas = document.createElement('canvas');
341-
let width = canvas.width = video.videoWidth;
342-
let height = canvas.height = video.videoHeight;
343-
let dataUrl;
344-
canvas.getContext('2d').drawImage(video, 0, 0, width, height);
345-
try {
346-
dataUrl = canvas.toDataURL();
347-
} catch (e) {
348-
warnings.add(`data-smartui-element-id="${videoId}" : ${e.toString()}`);
349-
}
350335

351-
// if the canvas produces a blank image, skip
352-
if (!dataUrl || dataUrl === 'data:,') continue;
336+
// remove video sources
337+
cloneEl.removeAttribute('src');
338+
const sourceEls = cloneEl.querySelectorAll('source');
339+
if (sourceEls.length) sourceEls.forEach((sourceEl) => sourceEl.remove());
340+
341+
// if the video doesn't have a poster image
342+
if (!video.getAttribute('poster')) {
343+
let canvas = document.createElement('canvas');
344+
let width = canvas.width = video.videoWidth;
345+
let height = canvas.height = video.videoHeight;
346+
let dataUrl;
347+
canvas.getContext('2d').drawImage(video, 0, 0, width, height);
348+
try {
349+
dataUrl = canvas.toDataURL();
350+
} catch (e) {
351+
warnings.add(`data-smartui-element-id="${videoId}" : ${e.toString()}`);
352+
}
353353

354-
// create a resource from the serialized data url
355-
// let resource = resourceFromDataURL(videoId, dataUrl);
356-
// resources.add(resource);
354+
// if the canvas produces a blank image, skip
355+
if (!dataUrl || dataUrl === 'data:,') continue;
357356

358-
// use a data attribute to avoid making a real request
359-
cloneEl.removeAttribute('src');
360-
cloneEl.setAttribute('poster', dataUrl);
357+
// create a resource from the serialized data url
358+
let resource = resourceFromDataURL(videoId, dataUrl);
359+
resources.add(resource);
360+
361+
// set poster attribute to resource url to avoid making a real request
362+
cloneEl.setAttribute('poster', resource.url);
363+
}
361364
}
362365
}
363366

src/lib/processSnapshot.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ export default async (snapshot: Snapshot, ctx: Context): Promise<Record<string,
2323
const requestHostname = new URL(requestUrl).hostname;
2424

2525
try {
26+
// abort audio/video media requests
27+
if (/\.(mp3|mp4|wav|ogg|webm)$/i.test(request.url())) {
28+
throw new Error('resource type mp3/mp4/wav/ogg/webm');
29+
}
30+
31+
// handle discovery config
2632
ctx.config.allowedHostnames.push(new URL(snapshot.url).hostname);
2733
if (ctx.config.enableJavaScript) ALLOWED_RESOURCES.push('script');
2834

@@ -118,15 +124,26 @@ export default async (snapshot: Snapshot, ctx: Context): Promise<Record<string,
118124
for (const { viewport, viewportString, fullPage } of renderViewports) {
119125
await page.setViewportSize({ width: viewport.width, height: viewport.height || MIN_VIEWPORT_HEIGHT });
120126
ctx.log.debug(`Page resized to ${viewport.width}x${viewport.height || MIN_VIEWPORT_HEIGHT}`);
127+
128+
// navigate to snapshot url once
121129
if (!navigated) {
122-
await page.goto(snapshot.url);
130+
// domcontentloaded event is more reliable than load event
131+
await page.goto(snapshot.url, { waitUntil: "domcontentloaded"});
132+
// adding extra timeout since domcontentloaded event is fired pretty quickly
133+
await new Promise(r => setTimeout(r, 1250));
134+
if (ctx.config.waitForTimeout) await page.waitForTimeout(ctx.config.waitForTimeout);
123135
navigated = true;
124136
ctx.log.debug(`Navigated to ${snapshot.url}`);
125137
}
126138
if (fullPage) await page.evaluate(scrollToBottomAndBackToTop);
127-
await page.waitForLoadState('networkidle');
128-
ctx.log.debug('Network idle 500ms');
129139

140+
try {
141+
await page.waitForLoadState('networkidle', { timeout: 5000 });
142+
ctx.log.debug('Network idle 500ms');
143+
} catch (error) {
144+
ctx.log.debug(`Network idle failed due to ${error}`);
145+
}
146+
130147
// snapshot options
131148
if (processedOptions.element) {
132149
let l = await page.locator(processedOptions.element).all()
@@ -162,6 +179,16 @@ export default async (snapshot: Snapshot, ctx: Context): Promise<Record<string,
162179
await page.close();
163180
await context.close();
164181

182+
// add dom resources to cache
183+
if (snapshot.dom.resources.length) {
184+
for (let resource of snapshot.dom.resources) {
185+
cache[resource.url] = {
186+
body: resource.content,
187+
type: resource.mimetype
188+
}
189+
}
190+
}
191+
165192
return {
166193
processedSnapshot: {
167194
name: snapshot.name,

0 commit comments

Comments
 (0)