Skip to content

Commit

Permalink
Merge pull request #327 from LambdaTest/dev
Browse files Browse the repository at this point in the history
Release 31 july
  • Loading branch information
HRanjan-11 authored Jul 31, 2024
2 parents 81e852d + 00172dc commit 94cf03e
Show file tree
Hide file tree
Showing 7 changed files with 242 additions and 4 deletions.
71 changes: 71 additions & 0 deletions accessibility/plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const fs = require("fs");
const path = require('path');
const Accessibility = (on, config) => {

on('task', {
lambdatest_log(message) {
console.log(message)
return null
},
initializeFile(filePath) {
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, '[]');
}
return filePath;
}
})

let browser_validation = true;

on('before:browser:launch', (browser = {}, launchOptions) => {
try {
if (process.env.ACCESSIBILITY_EXTENSION_PATH !== undefined) {
if (browser.name !== 'chrome') {
console.log(`Accessibility Automation will run only on Chrome browsers.`);
browser_validation = false;
}
if (browser.name === 'chrome' && browser.majorVersion <= 94) {
console.log(`Accessibility Automation will run only on Chrome browser version greater than 94.`);
browser_validation = false;
}
if (browser.isHeadless === true) {
console.log(`Accessibility Automation will not run on legacy headless mode. Switch to new headless mode or avoid using headless mode.`);
browser_validation = false;
}
if (!process.env.ACCESSIBILITY){
console.log(`Accessibility Automation is disabled.`);
browser_validation = false;
}
if (browser_validation) {

const accessibility_ext_path = process.env.ACCESSIBILITY_EXTENSION_PATH

launchOptions.args.push(`--load-extension=` + accessibility_ext_path)
return launchOptions
}
}
} catch(err) {
console.log(`Error in loading Accessibility Automation extension: ${err.message}`);
}

})
config.env.WCAG_CRITERIA= process.env.WCAG_CRITERIA;
config.env.BEST_PRACTICE= process.env.BEST_PRACTICE;
config.env.NEEDS_REVIEW= process.env.NEEDS_REVIEW;
config.env.ACCESSIBILITY_REPORT_PATH = process.env.ACCESSIBILITY_REPORT_PATH;
config.env.ACCESSIBILITY = process.env.ACCESSIBILITY;
console.log(`parameter for accessibility report ACCESSIBILITY - ` + config.env.ACCESSIBILITY)
console.log(`parameter for accessibility report WCAG_CRITERIA - ` + config.env.WCAG_CRITERIA)
console.log(`parameter for accessibility report BEST_PRACTICE -` + config.env.BEST_PRACTICE)
console.log(`parameter for accessibility report NEEDS_REVIEW -` + config.env.NEEDS_REVIEW)
console.log(`parameter for accessibility report ACCESSIBILITY_REPORT_PATH -` + config.env.ACCESSIBILITY_REPORT_PATH)


return config;
}

module.exports = Accessibility;
145 changes: 145 additions & 0 deletions accessibility/scanner/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
const fs = require("fs")

const LambdatestLog = (message) => {
if (!Cypress.env('LAMBDATEST_LOGS')) return;
cy.task('lambdatest_log', message);
}

const commandsToWrap = ['visit', 'click', 'type', 'request', 'dblclick', 'rightclick', 'clear', 'check', 'uncheck', 'select', 'trigger', 'selectFile', 'scrollIntoView', 'scroll', 'scrollTo', 'blur', 'focus', 'go', 'reload', 'submit', 'viewport', 'origin'];

const setScanConfig = (win, payload) =>
new Promise(async (resolve, reject) => {
const isHttpOrHttps = /^(http|https):$/.test(win.location.protocol);
if (!isHttpOrHttps) {
resolve();
}

function startScan() {
console.log('log', "Accessibility setting scan config")
function onScanComplete(event) {
win.document.removeEventListener("automation-custom-event", onScanComplete);
console.log('log', "Recieved scan config data " + event.detail)
resolve(event.detail);
}

win.document.addEventListener("automation-custom-event", onScanComplete);
const e = new CustomEvent("accessibility-extension-custom-event", { detail: payload });
win.document.dispatchEvent(e);


setTimeout(() => {
resolve(new Error('automation-custom-event not received within timeout'));
}, 45000);
}
startScan();

})

const getScanData = (win, payload) =>
new Promise( async (resolve,reject) => {
const isHttpOrHttps = /^(http|https):$/.test(window.location.protocol);
if (!isHttpOrHttps) {
resolve();
}


function getSummary() {
function onReceiveSummary(event) {

win.document.removeEventListener("automation-custom-event", onReceiveSummary);
resolve(event.detail);
}


win.document.addEventListener("automation-custom-event", onReceiveSummary);
const e = new CustomEvent("accessibility-extension-custom-event", { detail: payload });
win.document.dispatchEvent(e);

setTimeout(() => {
resolve(new Error('automation-custom-event not received within timeout'));
}, 45000);

}


getSummary();

})

Cypress.on('command:start', async (command) => {
if(!command || !command.attributes) return;
if(command.attributes.name == 'window' || command.attributes.name == 'then' || command.attributes.name == 'wrap' || command.attributes.name == 'wait') {
return;
}

if (!commandsToWrap.includes(command.attributes.name)) return;
let isAccessibilityLoaded = Cypress.env("ACCESSIBILITY") || false;
if (!isAccessibilityLoaded){
console.log('log', "accessibility not enabled " + isAccessibilityLoaded);
return;
}


console.log('log', "debugging scan form command " + command.attributes.name);
cy.window().then((win) => {
let wcagCriteriaValue = Cypress.env("WCAG_CRITERIA") || "wcag21a";
let bestPracticeValue = Cypress.env("BEST_PRACTICE") || false;
let needsReviewValue = Cypress.env("NEEDS_REVIEW") || true;

const payloadToSend = {
message: 'SET_CONFIG',
wcagCriteria: wcagCriteriaValue,
bestPractice: bestPracticeValue,
needsReview: needsReviewValue
}
let testId = Cypress.env("TEST_ID") || ""

const filePath = Cypress.env("ACCESSIBILITY_REPORT_PATH") || 'cypress/results/accessibilityReport_' + testId + '.json';

cy.wrap(setScanConfig(win, payloadToSend), {timeout: 30000}).then((res) => {
console.log('logging config reponse', res);

const payload = {
message: 'GET_LATEST_SCAN_DATA',
}

cy.wrap(getScanData(win, payload), {timeout: 45000}).then((res) => {
LambdatestLog('log', "scanning data ");


cy.task('initializeFile', filePath).then((filePath) => {
cy.readFile(filePath, { log: true, timeout: 45000 }).then((fileContent) => {
let resultsArray = [{}];
console.log('logging report', res);
// If the file is not empty, parse the existing content
if (fileContent) {
try {
resultsArray = JSON.parse(JSON.stringify(fileContent));
} catch (e) {
console.log("parsing error for content " , fileContent)
console.log('Error parsing JSON file:', e);
return;
}
}
console.log('scanned data recieved is', res.message);
if (res.message == "GET_LATEST_SCAN_DATA") {
// Append the new result
resultsArray.push(res);
console.log('resultsarray logging', resultsArray);
}

// Write the updated content back to the file
cy.writeFile(filePath, resultsArray, { log: true, timeout: 45000 });
});
});
});

});
})
})


Cypress.on('command:end', (command) => {

return;
})
10 changes: 10 additions & 0 deletions commands/utils/set_args.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,16 @@ function sync_args_from_cmd(args) {
lt_config["run_settings"]["useNode18"] = false;
}

if ("accessibility" in args) {
if (args["accessibility"] == "true") {
lt_config.run_settings.accessibility = true;
} else {
lt_config.run_settings.accessibility = false;
}
} else if (lt_config["run_settings"]["accessibility"] && !lt_config["run_settings"]["accessibility"]) {
lt_config["run_settings"]["accessibility"] = false;
}

if ("network_ws" in args) {
if (args["network_ws"] == "true") {
lt_config.run_settings.network_ws = true;
Expand Down
9 changes: 8 additions & 1 deletion commands/utils/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,14 @@ module.exports = validate_config = function (lt_config, validation_configs) {
}
}

//validate if network_http2 field contains expected value
//validate if accessibility field contains expected value
if ("accessibility" in lt_config["run_settings"]) {
if (![true, false].includes(lt_config["run_settings"]["accessibility"])) {
reject("Error!! boolean value is expected in accessibility key");
}
}

//validate if useNode18 field contains expected value
if ("useNode18" in lt_config["run_settings"]) {
if (![true, false].includes(lt_config["run_settings"]["useNode18"])) {
reject("Error!! boolean value is expected in useNode18 key");
Expand Down
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ const argv = require("yargs")
alias: "network_sse",
describe: "Bypass sse events calls for Network logs",
type: "bool",
})
.option("cypress_accessibility", {
alias: "accessibility",
describe: "enable accessibility testing for cypress.",
type: "bool",
});
},
function (argv) {
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "lambdatest-cypress-cli",
"version": "3.0.29",
"version": "3.0.30",
"description": "The lambdatest-cypress-cli is LambdaTest's command-line interface (CLI) aimed to help you run your Cypress tests on LambdaTest platform.",
"homepage": "https://github.com/LambdaTest/lambdatest-cypress-cli",
"author": "LambdaTest <[email protected]>",
Expand Down

0 comments on commit 94cf03e

Please sign in to comment.