Skip to content

Commit

Permalink
Feat/tabby extract function (#400)
Browse files Browse the repository at this point in the history
* feat: extracted custom functions for axe.config

* feat: apply customAxeConfig

* chore: remove devnotes:

---------

Co-authored-by: younglim <[email protected]>
  • Loading branch information
CKodes and younglim authored Sep 11, 2024
1 parent c5d189d commit d162965
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 69 deletions.
125 changes: 56 additions & 69 deletions src/crawlers/commonCrawlerFunc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { axeScript, guiInfoStatusTypes, saflyIconSelector } from '../constants/c
import { guiInfoLog } from '../logs.js';
import { takeScreenshotForHTMLElements } from '../screenshotFunc/htmlScreenshotFunc.js';
import { isFilePath } from '../constants/common.js';
import { customAxeConfig } from './customAxeFunctions.js';

// types
type RuleDetails = {
Expand Down Expand Up @@ -42,8 +43,6 @@ export const filterAxeResults = (
pageTitle: string,
customFlowDetails?: CustomFlowDetails,
): FilteredResults => {


const { violations, passes, incomplete, url } = results;

let totalItems = 0;
Expand Down Expand Up @@ -76,7 +75,14 @@ export const filterAxeResults = (
const { html, failureSummary, screenshotPath, target } = node;
const axeImpact = node.impact;
if (!(rule in category.rules)) {
category.rules[rule] = {description,axeImpact, helpUrl, conformance, totalItems: 0, items: [] };
category.rules[rule] = {
description,
axeImpact,
helpUrl,
conformance,
totalItems: 0,
items: [],
};
}
const message = displayNeedsReview
? failureSummary.slice(failureSummary.indexOf('\n') + 1).trim()
Expand Down Expand Up @@ -117,7 +123,6 @@ export const filterAxeResults = (
violations.forEach(item => process(item, false));
incomplete.forEach(item => process(item, true));


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

Expand All @@ -128,7 +133,14 @@ export const filterAxeResults = (
nodes.forEach(node => {
const { html } = node;
if (!(rule in passed.rules)) {
passed.rules[rule] = { description,axeImpact, helpUrl, conformance, totalItems: 0, items: [] };
passed.rules[rule] = {
description,
axeImpact,
helpUrl,
conformance,
totalItems: 0,
items: [],
};
}
passed.rules[rule].items.push({ html });
passed.totalItems += 1;
Expand All @@ -141,7 +153,9 @@ export const filterAxeResults = (
url,
pageTitle: customFlowDetails ? `${customFlowDetails.pageIndex}: ${pageTitle}` : pageTitle,
pageIndex: customFlowDetails ? customFlowDetails.pageIndex : undefined,
metadata: customFlowDetails?.metadata ? `${customFlowDetails.pageIndex}: ${customFlowDetails.metadata}` : undefined,
metadata: customFlowDetails?.metadata
? `${customFlowDetails.pageIndex}: ${customFlowDetails.metadata}`
: undefined,
pageImagePath: customFlowDetails ? customFlowDetails.pageImagePath : undefined,
totalItems,
mustFix,
Expand Down Expand Up @@ -184,69 +198,42 @@ export const runAxeScript = async (
await crawlee.playwrightUtils.injectFile(page, axeScript);

const results = await page.evaluate(
async ({ selectors, saflyIconSelector}) => {
async ({ selectors, saflyIconSelector, customAxeConfig }) => {
const evaluateAltText = node => {
const altText = node.getAttribute('alt');
const confusingTexts = ['img', 'image', 'picture', 'photo', 'graphic'];

if (altText) {
const trimmedAltText = altText.trim().toLowerCase();
if (confusingTexts.includes(trimmedAltText)) {
return false;
}
}
return true;
};

// remove so that axe does not scan
document.querySelector(saflyIconSelector)?.remove();

axe.configure({
branding: {
application: 'purple-a11y',
},
// Add custom img alt text check
branding: customAxeConfig.branding,
checks: [
{
id: 'oobee-confusing-alt-text',
evaluate: function(node: HTMLElement) {
const altText = node.getAttribute('alt');
const confusingTexts = ['img', 'image', 'picture', 'photo', 'graphic'];

if (altText) {
const trimmedAltText = altText.trim().toLowerCase();
// Check if the alt text exactly matches one of the confusingTexts
if (confusingTexts.some(text => text === trimmedAltText)) {
return false; // Fail the check if the alt text is confusing or not useful
}
}

return true; // Pass the check if the alt text seems appropriate
},
metadata: {
impact: 'serious', // Set the severity to serious
messages: {
pass: 'The image alt text is probably useful',
fail: 'The image alt text set as \'img\', \'image\', \'picture\', \'photo\', or \'graphic\' is confusing or not useful',
}
}
}
...customAxeConfig.checks[0],
evaluate: evaluateAltText,
},
],
rules: [
{ id: 'target-size', enabled: true },
{
id: 'oobee-confusing-alt-text',
selector: 'img[alt]',
enabled: true,
any: ['oobee-confusing-alt-text'],
all: [],
none: [],
tags: ['wcag2a', 'wcag111'],
metadata: {
description: 'Ensures image alt text is clear and useful',
help: 'Image alt text must not be vague or unhelpful',
helpUrl: 'https://www.deque.com/blog/great-alt-text-introduction/'
}
}
]
rules: customAxeConfig.rules,
});

//removed needsReview condition
let defaultResultTypes:resultGroups[]= ['violations', 'passes', 'incomplete']

let defaultResultTypes: resultGroups[] = ['violations', 'passes', 'incomplete'];

return axe.run(selectors, {
resultTypes: defaultResultTypes,
});
},
{ selectors, saflyIconSelector},
{ selectors, saflyIconSelector, customAxeConfig },
);

if (includeScreenshots) {
Expand All @@ -258,25 +245,28 @@ export const runAxeScript = async (
return filterAxeResults(results, pageTitle, customFlowDetails);
};

export const createCrawleeSubFolders = async (randomToken:string): Promise<{dataset:crawlee.Dataset, requestQueue:crawlee.RequestQueue}> => {
const dataset= await crawlee.Dataset.open(randomToken);
export const createCrawleeSubFolders = async (
randomToken: string,
): Promise<{ dataset: crawlee.Dataset; requestQueue: crawlee.RequestQueue }> => {
const dataset = await crawlee.Dataset.open(randomToken);
const requestQueue = await crawlee.RequestQueue.open(randomToken);
return { dataset, requestQueue };
};

export const preNavigationHooks = (extraHTTPHeaders) => {
export const preNavigationHooks = extraHTTPHeaders => {
return [
async (crawlingContext, gotoOptions) => {
if (extraHTTPHeaders) {
crawlingContext.request.headers = extraHTTPHeaders;
}
gotoOptions = { waitUntil: 'networkidle', timeout: 30000 };
},
]};
async (crawlingContext, gotoOptions) => {
if (extraHTTPHeaders) {
crawlingContext.request.headers = extraHTTPHeaders;
}
gotoOptions = { waitUntil: 'networkidle', timeout: 30000 };
},
];
};

export const postNavigationHooks = [
async _crawlingContext => {
guiInfoLog(guiInfoStatusTypes.COMPLETED,{});
guiInfoLog(guiInfoStatusTypes.COMPLETED, {});
},
];

Expand All @@ -286,13 +276,10 @@ export const failedRequestHandler = async ({ request }) => {
};

export const isUrlPdf = url => {
if(isFilePath(url)) {
if (isFilePath(url)) {
return /\.pdf$/i.test(url);
} else {
const parsedUrl = new URL(url);
return /\.pdf($|\?|#)/i.test(parsedUrl.pathname) || /\.pdf($|\?|#)/i.test(parsedUrl.href);
}
};



33 changes: 33 additions & 0 deletions src/crawlers/customAxeFunctions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Custom Axe Functions for axe.config
export const customAxeConfig = {
branding: {
application: 'purple-a11y',
},
checks: [
{
id: 'oobee-confusing-alt-text',
metadata: {
impact: 'serious',
messages: {
pass: 'The image alt text is probably useful.',
fail: "The image alt text set as 'img', 'image', 'picture', 'photo', or 'graphic' is confusing or not useful.",
},
},
},
],
rules: [
{ id: 'target-size', enabled: true },
{
id: 'oobee-confusing-alt-text',
selector: 'img[alt]',
enabled: true,
any: ['oobee-confusing-alt-text'],
tags: ['wcag2a', 'wcag111'],
metadata: {
description: 'Ensures image alt text is clear and useful.',
help: 'Image alt text must not be vague or unhelpful.',
helpUrl: 'https://www.deque.com/blog/great-alt-text-introduction/',
},
},
],
};

0 comments on commit d162965

Please sign in to comment.