@govtechsg/oobee 0.10.76 → 0.10.78-alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +8 -1
- package/INTEGRATION.md +50 -3
- package/dist/cli.js +252 -0
- package/dist/combine.js +221 -0
- package/dist/constants/cliFunctions.js +306 -0
- package/dist/constants/common.js +1669 -0
- package/dist/constants/constants.js +913 -0
- package/dist/constants/errorMeta.json +319 -0
- package/dist/constants/itemTypeDescription.js +7 -0
- package/dist/constants/oobeeAi.js +121 -0
- package/dist/constants/questions.js +151 -0
- package/dist/constants/sampleData.js +176 -0
- package/dist/crawlers/commonCrawlerFunc.js +428 -0
- package/dist/crawlers/crawlDomain.js +613 -0
- package/dist/crawlers/crawlIntelligentSitemap.js +135 -0
- package/dist/crawlers/crawlLocalFile.js +151 -0
- package/dist/crawlers/crawlSitemap.js +303 -0
- package/dist/crawlers/custom/escapeCssSelector.js +10 -0
- package/dist/crawlers/custom/evaluateAltText.js +11 -0
- package/dist/crawlers/custom/extractAndGradeText.js +44 -0
- package/dist/crawlers/custom/extractText.js +27 -0
- package/dist/crawlers/custom/findElementByCssSelector.js +36 -0
- package/dist/crawlers/custom/flagUnlabelledClickableElements.js +963 -0
- package/dist/crawlers/custom/framesCheck.js +37 -0
- package/dist/crawlers/custom/getAxeConfiguration.js +111 -0
- package/dist/crawlers/custom/gradeReadability.js +23 -0
- package/dist/crawlers/custom/utils.js +1024 -0
- package/dist/crawlers/custom/xPathToCss.js +147 -0
- package/dist/crawlers/guards/urlGuard.js +71 -0
- package/dist/crawlers/pdfScanFunc.js +276 -0
- package/dist/crawlers/runCustom.js +89 -0
- package/dist/exclusions.txt +7 -0
- package/dist/generateHtmlReport.js +144 -0
- package/dist/index.js +62 -0
- package/dist/logs.js +84 -0
- package/dist/mergeAxeResults.js +1588 -0
- package/dist/npmIndex.js +640 -0
- package/dist/proxyService.js +360 -0
- package/dist/runGenerateJustHtmlReport.js +16 -0
- package/dist/screenshotFunc/htmlScreenshotFunc.js +355 -0
- package/dist/screenshotFunc/pdfScreenshotFunc.js +645 -0
- package/dist/services/s3Uploader.js +127 -0
- package/dist/static/ejs/partials/components/allIssues/AllIssues.ejs +9 -0
- package/dist/static/ejs/partials/components/allIssues/CategoryBadges.ejs +82 -0
- package/dist/static/ejs/partials/components/allIssues/FilterBar.ejs +33 -0
- package/dist/static/ejs/partials/components/allIssues/IssuesTable.ejs +41 -0
- package/dist/static/ejs/partials/components/header/SiteInfo.ejs +119 -0
- package/dist/static/ejs/partials/components/header/aboutScanModal/AboutScanModal.ejs +15 -0
- package/dist/static/ejs/partials/components/header/aboutScanModal/ScanConfiguration.ejs +44 -0
- package/dist/static/ejs/partials/components/header/aboutScanModal/ScanDetails.ejs +142 -0
- package/dist/static/ejs/partials/components/prioritiseIssues/IssueDetailCard.ejs +36 -0
- package/dist/static/ejs/partials/components/prioritiseIssues/PrioritiseIssues.ejs +47 -0
- package/dist/static/ejs/partials/components/ruleModal/ruleOffcanvas.ejs +196 -0
- package/dist/static/ejs/partials/components/scannedPagesSegmentedTabs.ejs +48 -0
- package/dist/static/ejs/partials/components/screenshotLightbox.ejs +13 -0
- package/dist/static/ejs/partials/components/shared/InfoAlert.ejs +3 -0
- package/dist/static/ejs/partials/components/summaryScanAbout.ejs +141 -0
- package/dist/static/ejs/partials/components/summaryScanResults.ejs +16 -0
- package/dist/static/ejs/partials/components/summaryTable.ejs +20 -0
- package/dist/static/ejs/partials/components/summaryWcagCompliance.ejs +94 -0
- package/dist/static/ejs/partials/components/topTen.ejs +6 -0
- package/dist/static/ejs/partials/components/wcagCompliance/FailedCriteria.ejs +47 -0
- package/dist/static/ejs/partials/components/wcagCompliance/WcagCompliance.ejs +16 -0
- package/dist/static/ejs/partials/components/wcagCompliance/WcagGaugeBar.ejs +16 -0
- package/dist/static/ejs/partials/components/wcagCoverageDetails.ejs +18 -0
- package/dist/static/ejs/partials/footer.ejs +24 -0
- package/dist/static/ejs/partials/header.ejs +14 -0
- package/dist/static/ejs/partials/main.ejs +29 -0
- package/dist/static/ejs/partials/scripts/allIssues/AllIssues.ejs +376 -0
- package/dist/static/ejs/partials/scripts/bootstrap.ejs +8 -0
- package/dist/static/ejs/partials/scripts/categorySummary.ejs +141 -0
- package/dist/static/ejs/partials/scripts/decodeUnzipParse.ejs +3 -0
- package/dist/static/ejs/partials/scripts/header/SiteInfo.ejs +44 -0
- package/dist/static/ejs/partials/scripts/header/aboutScanModal/AboutScanModal.ejs +51 -0
- package/dist/static/ejs/partials/scripts/header/aboutScanModal/ScanConfiguration.ejs +127 -0
- package/dist/static/ejs/partials/scripts/header/aboutScanModal/ScanDetails.ejs +60 -0
- package/dist/static/ejs/partials/scripts/highlightjs.ejs +335 -0
- package/dist/static/ejs/partials/scripts/popper.ejs +7 -0
- package/dist/static/ejs/partials/scripts/prioritiseIssues/IssueDetailCard.ejs +137 -0
- package/dist/static/ejs/partials/scripts/prioritiseIssues/PrioritiseIssues.ejs +214 -0
- package/dist/static/ejs/partials/scripts/prioritiseIssues/wcagSvgMap.ejs +861 -0
- package/dist/static/ejs/partials/scripts/ruleModal/constants.ejs +957 -0
- package/dist/static/ejs/partials/scripts/ruleModal/itemCardRenderer.ejs +353 -0
- package/dist/static/ejs/partials/scripts/ruleModal/pageAccordionBuilder.ejs +468 -0
- package/dist/static/ejs/partials/scripts/ruleModal/ruleOffcanvas.ejs +306 -0
- package/dist/static/ejs/partials/scripts/ruleModal/utilities.ejs +483 -0
- package/dist/static/ejs/partials/scripts/scannedPagesSegmentedTabs.ejs +35 -0
- package/dist/static/ejs/partials/scripts/screenshotLightbox.ejs +75 -0
- package/dist/static/ejs/partials/scripts/summaryScanResults.ejs +14 -0
- package/dist/static/ejs/partials/scripts/summaryTable.ejs +78 -0
- package/dist/static/ejs/partials/scripts/topTen.ejs +61 -0
- package/dist/static/ejs/partials/scripts/utils.ejs +453 -0
- package/dist/static/ejs/partials/scripts/wcagCompliance/FailedCriteria.ejs +103 -0
- package/dist/static/ejs/partials/scripts/wcagCompliance/WcagGaugeBar.ejs +47 -0
- package/dist/static/ejs/partials/scripts/wcagCompliance.ejs +15 -0
- package/dist/static/ejs/partials/scripts/wcagCoverageDetails.ejs +75 -0
- package/dist/static/ejs/partials/styles/allIssues/AllIssues.ejs +384 -0
- package/dist/static/ejs/partials/styles/bootstrap.ejs +12391 -0
- package/dist/static/ejs/partials/styles/header/SiteInfo.ejs +121 -0
- package/dist/static/ejs/partials/styles/header/aboutScanModal/AboutScanModal.ejs +82 -0
- package/dist/static/ejs/partials/styles/header/aboutScanModal/ScanConfiguration.ejs +50 -0
- package/dist/static/ejs/partials/styles/header/aboutScanModal/ScanDetails.ejs +149 -0
- package/dist/static/ejs/partials/styles/header.ejs +7 -0
- package/dist/static/ejs/partials/styles/highlightjs.ejs +54 -0
- package/dist/static/ejs/partials/styles/prioritiseIssues/IssueDetailCard.ejs +141 -0
- package/dist/static/ejs/partials/styles/prioritiseIssues/PrioritiseIssues.ejs +204 -0
- package/dist/static/ejs/partials/styles/ruleModal/ruleOffcanvas.ejs +456 -0
- package/dist/static/ejs/partials/styles/scannedPagesSegmentedTabs.ejs +46 -0
- package/dist/static/ejs/partials/styles/shared/InfoAlert.ejs +12 -0
- package/dist/static/ejs/partials/styles/styles.ejs +1607 -0
- package/dist/static/ejs/partials/styles/summaryBootstrap.ejs +12458 -0
- package/dist/static/ejs/partials/styles/topTenCard.ejs +44 -0
- package/dist/static/ejs/partials/styles/wcagCompliance/FailedCriteria.ejs +59 -0
- package/dist/static/ejs/partials/styles/wcagCompliance/WcagGaugeBar.ejs +62 -0
- package/dist/static/ejs/partials/styles/wcagCompliance.ejs +36 -0
- package/dist/static/ejs/partials/styles/wcagCoverageDetails.ejs +33 -0
- package/dist/static/ejs/partials/summaryHeader.ejs +70 -0
- package/dist/static/ejs/partials/summaryMain.ejs +49 -0
- package/dist/static/ejs/report.ejs +226 -0
- package/dist/static/ejs/summary.ejs +47 -0
- package/dist/types/types.js +1 -0
- package/dist/utils.js +1070 -0
- package/examples/oobee-cypress-integration-js/cypress/support/e2e.js +36 -6
- package/examples/oobee-cypress-integration-js/cypress.config.js +45 -1
- package/examples/oobee-cypress-integration-ts/cypress.config.ts +47 -1
- package/examples/oobee-cypress-integration-ts/src/cypress/support/e2e.ts +36 -6
- package/examples/oobee-playwright-integration-js/oobee-playwright-demo.js +2 -1
- package/examples/oobee-playwright-integration-ts/src/oobee-playwright-demo.ts +2 -1
- package/examples/oobee-scan-html-demo.js +51 -0
- package/examples/oobee-scan-page-demo.js +40 -0
- package/package.json +9 -3
- package/src/constants/common.ts +2 -2
- package/src/constants/constants.ts +3 -1
- package/src/crawlers/crawlDomain.ts +1 -0
- package/src/crawlers/runCustom.ts +0 -1
- package/src/mergeAxeResults.ts +43 -22
- package/src/npmIndex.ts +500 -131
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function framesCheck(cssSelector) {
|
|
2
|
+
let doc = document; // Start with the main document
|
|
3
|
+
let remainingSelector = ''; // To store the last part of the selector
|
|
4
|
+
let targetIframe = null;
|
|
5
|
+
// Split the selector into parts at "> html"
|
|
6
|
+
const diffParts = cssSelector.split(/\s*>\s*html\s*/);
|
|
7
|
+
for (let i = 0; i < diffParts.length - 1; i++) {
|
|
8
|
+
let iframeSelector = `${diffParts[i].trim()}`;
|
|
9
|
+
// Add back '> html' to the current part
|
|
10
|
+
if (i > 0) {
|
|
11
|
+
iframeSelector = `html > ${iframeSelector}`;
|
|
12
|
+
}
|
|
13
|
+
let frameset = null;
|
|
14
|
+
// Find the iframe using the current document context
|
|
15
|
+
if (doc.querySelector('frameset')) {
|
|
16
|
+
frameset = doc.querySelector('frameset');
|
|
17
|
+
}
|
|
18
|
+
if (frameset) {
|
|
19
|
+
doc = frameset;
|
|
20
|
+
iframeSelector = iframeSelector.split('body >')[1].trim();
|
|
21
|
+
}
|
|
22
|
+
targetIframe = doc.querySelector(iframeSelector);
|
|
23
|
+
if (targetIframe && targetIframe.contentDocument) {
|
|
24
|
+
// Update the document to the iframe's contentDocument
|
|
25
|
+
doc = targetIframe.contentDocument;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.warn(`Iframe not found or contentDocument inaccessible for selector: ${iframeSelector}`);
|
|
29
|
+
return { doc, remainingSelector: cssSelector }; // Return original selector if iframe not found
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// The last part is the remaining CSS selector
|
|
33
|
+
remainingSelector = diffParts[diffParts.length - 1].trim();
|
|
34
|
+
// Remove any leading '>' combinators from remainingSelector
|
|
35
|
+
remainingSelector = `html${remainingSelector}`;
|
|
36
|
+
return { doc, remainingSelector };
|
|
37
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { evaluateAltText } from "./evaluateAltText.js";
|
|
2
|
+
export function getAxeConfiguration({ enableWcagAaa = false, gradingReadabilityFlag = '', disableOobee = false, }) {
|
|
3
|
+
return {
|
|
4
|
+
branding: {
|
|
5
|
+
application: 'oobee',
|
|
6
|
+
},
|
|
7
|
+
checks: [
|
|
8
|
+
{
|
|
9
|
+
id: 'oobee-confusing-alt-text',
|
|
10
|
+
metadata: {
|
|
11
|
+
impact: 'serious',
|
|
12
|
+
messages: {
|
|
13
|
+
pass: 'The image alt text is probably useful.',
|
|
14
|
+
fail: "The image alt text set as 'img', 'image', 'picture', 'photo', or 'graphic' is confusing or not useful.",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
evaluate: evaluateAltText,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: 'oobee-accessible-label',
|
|
21
|
+
metadata: {
|
|
22
|
+
impact: 'serious',
|
|
23
|
+
messages: {
|
|
24
|
+
pass: 'The clickable element has an accessible label.',
|
|
25
|
+
fail: 'The clickable element does not have an accessible label.',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
evaluate: (node) => {
|
|
29
|
+
return !node.dataset.flagged; // fail any element with a data-flagged attribute set to true
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
...(enableWcagAaa
|
|
33
|
+
? [
|
|
34
|
+
{
|
|
35
|
+
id: 'oobee-grading-text-contents',
|
|
36
|
+
metadata: {
|
|
37
|
+
impact: 'moderate',
|
|
38
|
+
messages: {
|
|
39
|
+
pass: 'The text content is easy to understand.',
|
|
40
|
+
fail: 'The text content is potentially difficult to understand.',
|
|
41
|
+
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.`,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
evaluate: (_node) => {
|
|
45
|
+
if (gradingReadabilityFlag === '') {
|
|
46
|
+
return true; // Pass if no readability issues
|
|
47
|
+
}
|
|
48
|
+
// Fail if readability issues are detected
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
]
|
|
52
|
+
: []),
|
|
53
|
+
],
|
|
54
|
+
rules: [
|
|
55
|
+
{ id: 'target-size', enabled: true },
|
|
56
|
+
{
|
|
57
|
+
id: 'oobee-confusing-alt-text',
|
|
58
|
+
selector: 'img[alt]',
|
|
59
|
+
enabled: true,
|
|
60
|
+
any: ['oobee-confusing-alt-text'],
|
|
61
|
+
tags: ['wcag2a', 'wcag111'],
|
|
62
|
+
metadata: {
|
|
63
|
+
description: 'Ensures image alt text is clear and useful.',
|
|
64
|
+
help: 'Image alt text must not be vague or unhelpful.',
|
|
65
|
+
helpUrl: 'https://www.deque.com/blog/great-alt-text-introduction/',
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'oobee-accessible-label',
|
|
70
|
+
// selector: '*', // to be set with the checker function output xpaths converted to css selectors
|
|
71
|
+
enabled: true,
|
|
72
|
+
any: ['oobee-accessible-label'],
|
|
73
|
+
tags: ['wcag2a', 'wcag211', 'wcag412'],
|
|
74
|
+
metadata: {
|
|
75
|
+
description: 'Ensures clickable elements have an accessible label.',
|
|
76
|
+
help: 'Clickable elements must have accessible labels.',
|
|
77
|
+
helpUrl: 'https://www.deque.com/blog/accessible-aria-buttons',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'oobee-grading-text-contents',
|
|
82
|
+
selector: 'html',
|
|
83
|
+
enabled: true,
|
|
84
|
+
any: ['oobee-grading-text-contents'],
|
|
85
|
+
tags: ['wcag2aaa', 'wcag315'],
|
|
86
|
+
metadata: {
|
|
87
|
+
description: 'Text content should be easy to understand for individuals with education levels up to university graduates. If the text content is difficult to understand, provide supplemental content or a version that is easy to understand.',
|
|
88
|
+
help: 'Text content should be clear and plain to ensure that it is easily understood.',
|
|
89
|
+
helpUrl: 'https://www.wcag.com/uncategorized/3-1-5-reading-level/',
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
]
|
|
93
|
+
.filter(rule => (disableOobee ? !rule.id.startsWith('oobee') : true))
|
|
94
|
+
.concat(enableWcagAaa
|
|
95
|
+
? [
|
|
96
|
+
{
|
|
97
|
+
id: 'color-contrast-enhanced',
|
|
98
|
+
enabled: true,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
id: 'identical-links-same-purpose',
|
|
102
|
+
enabled: true,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: 'meta-refresh-no-exceptions',
|
|
106
|
+
enabled: true,
|
|
107
|
+
},
|
|
108
|
+
]
|
|
109
|
+
: []),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import textReadability from 'text-readability';
|
|
2
|
+
export function gradeReadability(sentences) {
|
|
3
|
+
try {
|
|
4
|
+
// Check if any valid sentences were extracted
|
|
5
|
+
if (sentences.length === 0) {
|
|
6
|
+
return ''; // Return an empty string if no valid sentences are found
|
|
7
|
+
}
|
|
8
|
+
// Join the valid sentences into a single string
|
|
9
|
+
const filteredText = sentences.join(' ').trim();
|
|
10
|
+
// Count the total number of words in the filtered text
|
|
11
|
+
const wordCount = filteredText.split(/\s+/).length;
|
|
12
|
+
// Grade the text content only if there are 20 words or more
|
|
13
|
+
const readabilityScore = wordCount >= 20 ? textReadability.fleschReadingEase(filteredText) : 0;
|
|
14
|
+
// Log details for debugging
|
|
15
|
+
// Determine the return value
|
|
16
|
+
const result = readabilityScore === 0 || readabilityScore > 50 ? '' : readabilityScore.toString(); // Convert readabilityScore to string
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
console.error('Error extracting and grading text:', error);
|
|
21
|
+
return ''; // Return an empty string in case of an error
|
|
22
|
+
}
|
|
23
|
+
}
|