Skip to content

Commit

Permalink
Implement new scan report (#116)
Browse files Browse the repository at this point in the history
* Implement new scan report

* Bump version number
  • Loading branch information
khoodehui authored May 2, 2023
1 parent a2d015e commit 668ccbf
Show file tree
Hide file tree
Showing 38 changed files with 14,866 additions and 274 deletions.
2 changes: 1 addition & 1 deletion combine.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const combineRun = async (details, deviceToScan) => {

if (scanDetails.urlsCrawled.scanned.length > 0) {
await createAndUpdateResultsFolders(randomToken);
await generateArtifacts(randomToken, deviceToScan);
await generateArtifacts(randomToken, url, deviceToScan);
} else {
printMessage([`No pages were scanned.`], constants.alertMessageOoptions);
}
Expand Down
9 changes: 9 additions & 0 deletions constants/itemTypeDescription.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const itemTypeDescription = {
mustFix:
'Issues that need to be addressed promptly, as they create significant barriers for persons with disabilities and can prevent them from accessing essential content or features.',
goodToFix:
'Issues that could pose certain challenges for persons with disabilities (PWDs), but are unlikely to completely hinder their access to essential content or features.',
passed: 'Occurrences that passed the automated checks.',
};

export default itemTypeDescription;
135 changes: 113 additions & 22 deletions crawlers/commonCrawlerFunc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,135 @@ import crawlee from 'crawlee';
import axe from 'axe-core';
import { axeScript } from '../constants/constants.js';

const filterAxeResults = (results, host) => {
const { violations, url } = results;
const page = host === '' || url.split(host).length !== 2 ? url : url.split(host)[1];

const errors = violations.map(violation => {
const { id, nodes, help, impact, helpUrl } = violation;
const fixes = nodes.map(node => ({
htmlElement: node.html,
}));
return {
id,
description: help,
impact,
helpUrl,
fixes,
// const filterAxeResults = (results, host) => {
// const { violations, url } = results;
// const page = host === '' || url.split(host).length !== 2 ? url : url.split(host)[1];

// const errors = violations.map(violation => {
// const { id, nodes, help, impact, helpUrl } = violation;
// const fixes = nodes.map(node => ({
// htmlElement: node.html,
// }));
// return {
// id,
// description: help,
// impact,
// helpUrl,
// fixes,
// };
// });
// return {
// url,
// page,
// errors,
// };
// };

const filterAxeResults = (results, pageTitle) => {
const { violations, incomplete, passes, url } = results;

let totalItems = 0;
const mustFix = { totalItems: 0, rules: {} };
const goodToFix = { totalItems: 0, rules: {} };
const passed = { totalItems: 0, rules: {} };

const process = (item, needsReview = false) => {
const { id: rule, help: description, helpUrl, tags, nodes } = item;

if (rule === 'frame-tested') return;

const conformance = tags.filter(tag => tag.startsWith('wcag') || tag === 'best-practice');

const addTo = (category, node) => {
const { html, failureSummary } = node;
if (!(rule in category.rules)) {
category.rules[rule] = { description, helpUrl, conformance, totalItems: 0, items: [] };
}
const message = needsReview
? failureSummary.slice(failureSummary.indexOf('\n') + 1).trim()
: failureSummary;
category.rules[rule].items.push(
needsReview ? { html, message, needsReview } : { html, message },
);
category.rules[rule].totalItems += 1;
category.totalItems += 1;
totalItems += 1;
};

nodes.forEach(node => {
const { impact } = node;
if (impact === 'critical' || impact === 'serious') {
addTo(mustFix, node);
} else {
addTo(goodToFix, node);
}
});
};

violations.forEach(item => process(item));
incomplete.forEach(item => process(item, true));

passes.forEach(item => {
const { id: rule, help: description, helpUrl, tags, nodes } = item;

if (rule === 'frame-tested') return;

const conformance = tags.filter(tag => tag.startsWith('wcag') || tag === 'best-practice');

nodes.forEach(node => {
const { html } = node;
if (!(rule in passed.rules)) {
passed.rules[rule] = { description, helpUrl, conformance, totalItems: 0, items: [] };
}
passed.rules[rule].items.push({ html });
passed.totalItems += 1;
passed.rules[rule].totalItems += 1;
totalItems += 1;
});
});

return {
url,
page,
errors,
pageTitle,
totalItems,
mustFix,
goodToFix,
passed,
};
};

export const runAxeScript = async (page, host) => {
// export const runAxeScript = async (page, host) => {
// await crawlee.puppeteerUtils.injectFile(page, axeScript);
// const results = await page.evaluate(() => {
// axe.configure({
// branding: {
// application: 'purple-hats',
// },
// reporter: 'no-passes',
// });
// return axe.run({
// resultTypes: ['violations'],
// });
// });
// return filterAxeResults(results, host);
// };

export const runAxeScript = async (page) => {
await crawlee.puppeteerUtils.injectFile(page, axeScript);
const results = await page.evaluate(() => {
axe.configure({
branding: {
application: 'purple-hats',
},
reporter: 'no-passes',
});
return axe.run({
resultTypes: ['violations'],
resultTypes: ['violations', 'passes', 'incomplete'],
});
});
return filterAxeResults(results, host);
const pageTitle = await page.evaluate(() => {
return document.title;
});
return filterAxeResults(results, pageTitle);
};

export const createCrawleeSubFolders = async randomToken => {
Expand All @@ -52,7 +143,7 @@ export const createCrawleeSubFolders = async randomToken => {

export const preNavigationHooks = [
async (_crawlingContext, gotoOptions) => {
gotoOptions = { waitUntil: "domcontentloaded", timeout: 30000 };
gotoOptions = { waitUntil: 'domcontentloaded', timeout: 30000 };
},
];

Expand Down
31 changes: 14 additions & 17 deletions crawlers/crawlDomain.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
} from './commonCrawlerFunc.js';
import constants from '../constants/constants.js';


const crawlDomain = async (url, randomToken, host, viewportSettings, maxRequestsPerCrawl) => {
const urlsCrawled = { ...constants.urlsCrawledObj };
const { maxConcurrency } = constants;
Expand All @@ -26,7 +25,7 @@ const crawlDomain = async (url, randomToken, host, viewportSettings, maxRequests
} else if (customDevice === 'Samsung Galaxy S9+') {
device = devices['Galaxy S9+'];
} else if (viewportWidth) {
device = { viewport: { width: Number(viewportWidth), height: 720 }};
device = { viewport: { width: Number(viewportWidth), height: 720 } };
} else if (customDevice) {
device = devices[customDevice.replace('_', / /g)];
} else {
Expand All @@ -41,21 +40,20 @@ const crawlDomain = async (url, randomToken, host, viewportSettings, maxRequests
},
browserPoolOptions: {
useFingerprints: false,
preLaunchHooks: [async (pageId, launchContext) => {

launchContext.launchOptions = {
...launchContext.launchOptions,
bypassCSP: true,
ignoreHTTPSErrors: true,
...device,
};

}],
preLaunchHooks: [
async (pageId, launchContext) => {
launchContext.launchOptions = {
...launchContext.launchOptions,
bypassCSP: true,
ignoreHTTPSErrors: true,
...device,
};
},
],
},
requestQueue,
preNavigationHooks,
requestHandler: async ({ page, request, enqueueLinks, enqueueLinksByClickingElements }) => {

const currentUrl = request.url;
const location = await page.evaluate('location');

Expand All @@ -66,12 +64,12 @@ const crawlDomain = async (url, randomToken, host, viewportSettings, maxRequests

await enqueueLinks({
// set selector matches anchor elements with href but not contains # or starting with mailto:
selector:'a:not(a[href*="#"],a[href^="mailto:"])',
selector: 'a:not(a[href*="#"],a[href^="mailto:"])',
strategy: 'same-domain',
requestQueue,
transformRequestFunction(req) {
// ignore all links ending with `.pdf`
req.url = req.url.replace(/(?<=&|\?)utm_.*?(&|$)/igm, "");
req.url = req.url.replace(/(?<=&|\?)utm_.*?(&|$)/gim, '');
return req;
},
});
Expand All @@ -84,11 +82,10 @@ const crawlDomain = async (url, randomToken, host, viewportSettings, maxRequests
selector: ':not(a):is(*[role="link"], button[onclick])',
transformRequestFunction(req) {
// ignore all links ending with `.pdf`
req.url = req.url.replace(/(?<=&|\?)utm_.*?(&|$)/igm, "");
req.url = req.url.replace(/(?<=&|\?)utm_.*?(&|$)/gim, '');
return req;
},
});

} else {
urlsCrawled.outOfDomain.push(currentUrl);
}
Expand Down
Loading

0 comments on commit 668ccbf

Please sign in to comment.