Skip to content

Commit 40b4959

Browse files
Merge pull request #427 from LambdaTest/dev
DevToMaster
2 parents 336a945 + 2a60112 commit 40b4959

File tree

4 files changed

+128
-6
lines changed

4 files changed

+128
-6
lines changed

accessibility/plugin/index.js

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
const fs = require("fs");
22
const path = require('path');
3+
4+
function getImageResolution(buffer) {
5+
try {
6+
if (buffer.length < 24) {
7+
return { width: 0, height: 0 };
8+
}
9+
10+
const pngSignature = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
11+
for (let i = 0; i < 8; i++) {
12+
if (buffer[i] !== pngSignature[i]) {
13+
return { width: 0, height: 0 };
14+
}
15+
}
16+
17+
const width = buffer.readUInt32BE(16);
18+
const height = buffer.readUInt32BE(20);
19+
20+
return { width, height };
21+
} catch (error) {
22+
console.error(`Error extracting image resolution: ${error.message}`);
23+
return { width: 0, height: 0 };
24+
}
25+
}
26+
327
const Accessibility = (on, config) => {
428

529
on('task', {
@@ -25,6 +49,43 @@ const Accessibility = (on, config) => {
2549
} else {
2650
return { exists: false, content: null }; // Return null if the file doesn't exist
2751
}
52+
},
53+
convertScreenshotToBase64(filePath) {
54+
try {
55+
const fullPath = path.resolve(filePath);
56+
57+
if (fs.existsSync(fullPath)) {
58+
const imageBuffer = fs.readFileSync(fullPath);
59+
const base64String = imageBuffer.toString('base64');
60+
61+
const imageResolution = getImageResolution(imageBuffer);
62+
return {
63+
base64: base64String,
64+
resolution: imageResolution
65+
};
66+
} else {
67+
console.log(`Screenshot file not found at: ${fullPath}`);
68+
return null;
69+
}
70+
} catch (error) {
71+
console.error(`Error converting screenshot to base64: ${error.message}`);
72+
return null;
73+
}
74+
},
75+
deleteFile(filePath) {
76+
try {
77+
const fullPath = path.resolve(filePath);
78+
if (fs.existsSync(fullPath)) {
79+
fs.unlinkSync(fullPath);
80+
return true;
81+
} else {
82+
console.log(`File not found for deletion: ${filePath}`);
83+
return false;
84+
}
85+
} catch (error) {
86+
console.error(`Error deleting file: ${error.message}`);
87+
return false;
88+
}
2889
}
2990
})
3091

@@ -70,6 +131,7 @@ const Accessibility = (on, config) => {
70131
config.env.ACCESSIBILITY = process.env.ACCESSIBILITY;
71132
config.env.TEST_ID = process.env.TEST_ID;
72133
config.env.ACCESSIBILITY_OVERIDE_COMMANDS = process.env.ACCESSIBILITY_OVERIDE_COMMANDS;
134+
config.env.CAPTURE_SCREENSHOT_ENABLED = process.env.CAPTURE_SCREENSHOT_ENABLED;
73135
config.env.GENERATE_REPORT_API = process.env.GENERATE_REPORT_API || "NA";
74136
console.log(`parameter for accessibility report ACCESSIBILITY - ` + config.env.ACCESSIBILITY)
75137
console.log(`parameter for accessibility report WCAG_CRITERIA - ` + config.env.WCAG_CRITERIA)
@@ -80,7 +142,7 @@ const Accessibility = (on, config) => {
80142
console.log(`parameter for accessibility report ACCESSIBILITY_EXTENSION_PATH -` + process.env.ACCESSIBILITY_EXTENSION_PATH)
81143
console.log(`parameter for accessibility report ACCESSIBILITY_OVERIDE_COMMANDS -` + config.env.ACCESSIBILITY_OVERIDE_COMMANDS)
82144
console.log(`parameter for accessibility report GENERATE_REPORT_API -` + config.env.GENERATE_REPORT_API)
83-
145+
console.log(`parameter for accessibility report CAPTURE_SCREENSHOT_ENABLED -` + config.env.CAPTURE_SCREENSHOT_ENABLED)
84146

85147
return config;
86148
}

accessibility/scanner/index.js

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ const LambdatestLog = (message) => {
44
cy.task('lambdatest_log', message);
55
}
66

7+
let globalScreenshots = null;
8+
const captureScreenshotEnabled = Cypress.env("CAPTURE_SCREENSHOT_ENABLED") === "true";
9+
710
const commandsToOverride = [
811
'visit', 'click', 'type', 'request', 'dblclick', 'rightclick', 'clear', 'check',
912
'uncheck', 'select', 'trigger', 'selectFile', 'scrollIntoView', 'scrollTo',
@@ -40,7 +43,43 @@ const performNewLambdaScan = (originalFn, Subject, stateType, ...args) => {
4043
if (subjectChainFn !== null && subjectChainFn !== void 0) {
4144
cypressCommandChain = subjectChainFn.call(cy);
4245
}
43-
cycustomChaining.performScanSubjectQuery(cypressCommandChain, setTimeout).then({timeout: 30000}, (newSubject) => originalFn(...updateSubj(args, stateType, newSubject)));
46+
47+
if (captureScreenshotEnabled) {
48+
cy.log('Starting performScanSubjectQuery');
49+
cycustomChaining
50+
.performScanSubjectQuery(cypressCommandChain, setTimeout)
51+
.then({ timeout: 30000 }, (newSubject) => {
52+
const updatedArgs = updateSubj(args, stateType, newSubject);
53+
const screenshotId= crypto.randomUUID();
54+
const screenshotName = 'accessibility-screenshot-'+ screenshotId;
55+
cy.screenshot(screenshotName, { capture: 'fullPage' });
56+
cy.task('convertScreenshotToBase64', `cypress/screenshots/${Cypress.spec.name}/${screenshotName}.png`).then((result) => {
57+
if (result && result.base64) {
58+
const imageUrl = `data:image/png;base64,${result.base64}`;
59+
const imageResolution = result.resolution;
60+
// Create screenshots array
61+
const screenshots = [
62+
{
63+
image_url: imageUrl,
64+
image_resolution: `${imageResolution.width}x${imageResolution.height}`,
65+
screenshotId: screenshotId
66+
}
67+
];
68+
// Store globally for use in processAccessibilityReport
69+
globalScreenshots = screenshots;
70+
71+
cy.task('deleteFile', `cypress/screenshots/${Cypress.spec.name}/${screenshotName}.png`).then((_) => {
72+
});
73+
} else {
74+
cy.log('Failed to process screenshot');
75+
}
76+
});
77+
const result = originalFn(...updatedArgs);
78+
return result;
79+
});
80+
} else {
81+
cycustomChaining.performScanSubjectQuery(cypressCommandChain, setTimeout).then({timeout: 30000}, (newSubject) => originalFn(...updateSubj(args, stateType, newSubject)));
82+
}
4483
}
4584
}
4685
runCustomizedChainingCommand();
@@ -124,12 +163,14 @@ const processAccessibilityReport = async (windowNew) => {
124163
let wcagCriteriaValue = Cypress.env("WCAG_CRITERIA") || "wcag21a";
125164
let bestPracticeValue = Cypress.env("BEST_PRACTICE") === "true";
126165
let needsReviewValue = Cypress.env("NEEDS_REVIEW") !== "false"; // Default to true
166+
let captureScreenshotEnabled = Cypress.env("CAPTURE_SCREENSHOT_ENABLED") === "true";
127167

128168
const payloadToSend = {
129169
message: 'SET_CONFIG',
130170
wcagCriteria: wcagCriteriaValue,
131171
bestPractice: bestPracticeValue,
132-
needsReview: needsReviewValue
172+
needsReview: needsReviewValue,
173+
captureScreenshotEnabled: captureScreenshotEnabled
133174
};
134175

135176
console.log('log', "SET SCAN: Payload to send: ", payloadToSend);
@@ -146,6 +187,25 @@ const processAccessibilityReport = async (windowNew) => {
146187
const payload = {message: 'GET_LATEST_SCAN_DATA'};
147188
scanData = await getScanData(windowNew, payload);
148189
LambdatestLog("GET SCAN:LambdaTest Accessibility: Scanning URL");
190+
if(captureScreenshotEnabled){
191+
if (scanData && scanData.data && scanData.data.length > 0 && globalScreenshots) {
192+
const firstDataItem = scanData.data[0];
193+
if (firstDataItem.events && firstDataItem.events.length > 0) {
194+
const firstEvent = firstDataItem.events[0];
195+
if (firstEvent.issues && firstEvent.issues.length > 0) {
196+
// Update screenshotId with the actual screenshotId
197+
globalScreenshots[0].screenshotId=firstEvent.issues[0].screenshotId;
198+
}
199+
}
200+
for (let i = 0; i < scanData.data.length; i++) {
201+
if (scanData.data[i].screenshots && Array.isArray(scanData.data[i].screenshots)) {
202+
scanData.data[i].screenshots = globalScreenshots;
203+
break;
204+
}
205+
}
206+
}
207+
globalScreenshots = null;
208+
}
149209
} catch (err) {
150210
console.error("GET SCAN:Error while setting scan", err);
151211
return ;

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lambdatest-cypress-cli",
3-
"version": "3.0.38",
3+
"version": "3.0.39",
44
"description": "The lambdatest-cypress-cli is LambdaTest's command-line interface (CLI) aimed to help you run your Cypress tests on LambdaTest platform.",
55
"homepage": "https://github.com/LambdaTest/lambdatest-cypress-cli",
66
"author": "LambdaTest <keys@lambdatest.com>",

0 commit comments

Comments
 (0)