Skip to content

Commit

Permalink
Clickable elements check to error and Playwright dependency browser c…
Browse files Browse the repository at this point in the history
…rash issue (#421)

* Resolves clickable checks for iframe

* Cleanup console messages

* Resolve playwright dependency > 1.46.1 causing browser to crash.
  • Loading branch information
younglim authored Dec 10, 2024
1 parent 81c3210 commit 097d2c4
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 33 deletions.
16 changes: 8 additions & 8 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
Expand Up @@ -21,7 +21,7 @@
"mime-types": "^2.1.35",
"minimatch": "^9.0.3",
"pdfjs-dist": "github:veraPDF/pdfjs-dist#v2.14.305-taggedPdf-0.1.11",
"playwright": "^1.49.0",
"playwright": "1.46.1",
"prettier": "^3.1.0",
"print-message": "^3.0.1",
"safe-regex": "^2.1.1",
Expand Down
163 changes: 142 additions & 21 deletions src/crawlers/commonCrawlerFunc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,8 @@ export const runAxeScript = async ({
check => check.id === 'oobee-grading-text-contents',
);
if (gradingCheck) {
gradingCheck.metadata.messages.incomplete = `The text content is potentially difficult to read, with a Flesch-Kincaid Reading Ease score of ${
gradingReadabilityFlag
}.\nThe target passing score is above 50, indicating content readable by university students and lower grade levels.\nA higher score reflects better readability.`;
gradingCheck.metadata.messages.incomplete = `The text content is potentially difficult to read, with a Flesch-Kincaid Reading Ease score of ${gradingReadabilityFlag
}.\nThe target passing score is above 50, indicating content readable by university students and lower grade levels.\nA higher score reflects better readability.`;
}

// Fail if readability issues are detected
Expand All @@ -375,22 +374,22 @@ export const runAxeScript = async ({
.concat(
enableWcagAaa
? [
{
id: 'color-contrast-enhanced',
enabled: true,
tags: ['wcag2aaa', 'wcag146'],
},
{
id: 'identical-links-same-purpose',
enabled: true,
tags: ['wcag2aaa', 'wcag249'],
},
{
id: 'meta-refresh-no-exceptions',
enabled: true,
tags: ['wcag2aaa', 'wcag224', 'wcag325'],
},
]
{
id: 'color-contrast-enhanced',
enabled: true,
tags: ['wcag2aaa', 'wcag146'],
},
{
id: 'identical-links-same-purpose',
enabled: true,
tags: ['wcag2aaa', 'wcag249'],
},
{
id: 'meta-refresh-no-exceptions',
enabled: true,
tags: ['wcag2aaa', 'wcag224', 'wcag325'],
},
]
: [],
),
});
Expand All @@ -410,8 +409,129 @@ export const runAxeScript = async ({
const escapedCssSelectors =
oobeeAccessibleLabelFlaggedCssSelectors.map(escapeCSSSelector);

function frameCheck(cssSelector: string): { doc: Document; remainingSelector: string } {
let doc = document; // Start with the main document
let frameSelector = ""; // To store the frame part of the selector

// Extract the 'frame' part of the selector
let frameMatch = cssSelector.match(/(frame[^>]*>)/i);
if (frameMatch) {
frameSelector = frameMatch[1].replace(">", "").trim(); // Clean up the frame part
cssSelector = cssSelector.split(frameMatch[1])[1].trim(); // Remove the frame portion
}

let targetFrame = null; // Target frame element

// Locate the frame based on the extracted frameSelector
if (frameSelector.includes("first-of-type")) {
// Select the first frame
targetFrame = document.querySelector("frame:first-of-type");
} else if (frameSelector.includes("nth-of-type")) {
// Select the nth frame
let nthIndex = frameSelector.match(/nth-of-type\((\d+)\)/);
if (nthIndex) {
let index = parseInt(nthIndex[1]) - 1; // Zero-based index
targetFrame = document.querySelectorAll("frame")[index];
}
} else if (frameSelector.includes("#")) {
// Frame with a specific ID
let idMatch = frameSelector.match(/#([\w-]+)/);
if (idMatch) {
targetFrame = document.getElementById(idMatch[1]);
}
} else if (frameSelector.includes('[name="')) {
// Frame with a specific name attribute
let nameMatch = frameSelector.match(/name="([\w-]+)"/);
if (nameMatch) {
targetFrame = document.querySelector(`frame[name="${nameMatch[1]}"]`);
}
} else {
// Default to the first frame
targetFrame = document.querySelector("frame");
}

// Update the document if the frame was found
if (targetFrame && targetFrame.contentDocument) {
doc = targetFrame.contentDocument;
} else {
console.warn("Frame not found or contentDocument inaccessible.");
}

return { doc, remainingSelector: cssSelector };
}

function iframeCheck(cssSelector: string): { doc: Document; remainingSelector: string } {
let doc = document; // Start with the main document
let iframeSelector = ""; // To store the iframe part of the selector

// Extract the 'iframe' part of the selector
let iframeMatch = cssSelector.match(/(iframe[^>]*>)/i);
if (iframeMatch) {
iframeSelector = iframeMatch[1].replace(">", "").trim(); // Clean up the iframe part
cssSelector = cssSelector.split(iframeMatch[1])[1].trim(); // Remove the iframe portion
}

let targetIframe = null; // Target iframe element

// Locate the iframe based on the extracted iframeSelector
if (iframeSelector.includes("first-of-type")) {
// Select the first iframe
targetIframe = document.querySelector("iframe:first-of-type");
} else if (iframeSelector.includes("nth-of-type")) {
// Select the nth iframe
let nthIndex = iframeSelector.match(/nth-of-type\((\d+)\)/);
if (nthIndex) {
let index = parseInt(nthIndex[1]) - 1; // Zero-based index
targetIframe = document.querySelectorAll("iframe")[index];
}
} else if (iframeSelector.includes("#")) {
// Iframe with a specific ID
let idMatch = iframeSelector.match(/#([\w-]+)/);
if (idMatch) {
targetIframe = document.getElementById(idMatch[1]);
}
} else if (iframeSelector.includes('[name="')) {
// Iframe with a specific name attribute
let nameMatch = iframeSelector.match(/name="([\w-]+)"/);
if (nameMatch) {
targetIframe = document.querySelector(`iframe[name="${nameMatch[1]}"]`);
}
} else {
// Default to the first iframe
targetIframe = document.querySelector("iframe");
}

// Update the document if the iframe was found
if (targetIframe && targetIframe.contentDocument) {
doc = targetIframe.contentDocument;
} else {
console.warn("Iframe not found or contentDocument inaccessible.");
}

return { doc, remainingSelector: cssSelector };
}

function findElementByCssSelector(cssSelector: string): string | null {
let element = document.querySelector(cssSelector);
let doc = document;

// Check if the selector includes 'frame' and update doc and selector
if (cssSelector.includes("frame")) {
const result = frameCheck(cssSelector);
doc = result.doc;
cssSelector = result.remainingSelector;
}

// Check for iframe
if (cssSelector.includes("iframe")) {
const result = iframeCheck(cssSelector);
doc = result.doc;
cssSelector = result.remainingSelector;
}

// Query the element in the document (including inside frames)
let element = doc.querySelector(cssSelector);

// Handle Shadow DOM if the element is not found
if (!element) {
const shadowRoots = [];
const allElements = document.querySelectorAll('*');
Expand All @@ -432,6 +552,7 @@ export const runAxeScript = async ({
}
}
}

return element ? element.outerHTML : null;
}

Expand Down Expand Up @@ -532,4 +653,4 @@ export const isUrlPdf = (url: string) => {
}
const parsedUrl = new URL(url);
return /\.pdf($|\?|#)/i.test(parsedUrl.pathname) || /\.pdf($|\?|#)/i.test(parsedUrl.href);
};
};
4 changes: 2 additions & 2 deletions src/mergeAxeResults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,12 +443,12 @@ function writeLargeJsonToFile(obj, filePath) {
const writeStream = fs.createWriteStream(filePath, { encoding: 'utf8' });

writeStream.on('error', error => {
console.error('Stream error:', error);
consoleLogger.error('Stream error:', error);
reject(error);
});

writeStream.on('finish', () => {
console.log('File written successfully:', filePath);
consoleLogger.info('Temporary file written successfully:', filePath);
resolve(true);
});

Expand Down
2 changes: 1 addition & 1 deletion src/screenshotFunc/htmlScreenshotFunc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const takeScreenshotForHTMLElements = async (

// Check if rule ID is 'oobee-grading-text-contents' and skip screenshot logic
if (rule === 'oobee-grading-text-contents') {
console.log('Skipping screenshot for rule oobee-grading-text-contents');
consoleLogger.info('Skipping screenshot for rule oobee-grading-text-contents');
newViolations.push(violation); // Make sure it gets added
continue;
}
Expand Down

0 comments on commit 097d2c4

Please sign in to comment.