@govtechsg/oobee 0.10.20 → 0.10.28

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.
Files changed (42) hide show
  1. package/.github/workflows/docker-test.yml +1 -1
  2. package/DETAILS.md +40 -25
  3. package/Dockerfile +41 -47
  4. package/LICENSE-3RD-PARTY-REPORT.txt +448 -0
  5. package/LICENSE-3RD-PARTY.txt +19913 -0
  6. package/README.md +26 -0
  7. package/__mocks__/mock-report.html +1503 -1360
  8. package/package.json +9 -5
  9. package/scripts/decodeUnzipParse.js +29 -0
  10. package/scripts/install_oobee_dependencies.command +2 -2
  11. package/scripts/install_oobee_dependencies.ps1 +3 -3
  12. package/src/cli.ts +9 -7
  13. package/src/combine.ts +13 -5
  14. package/src/constants/cliFunctions.ts +38 -1
  15. package/src/constants/common.ts +31 -5
  16. package/src/constants/constants.ts +28 -26
  17. package/src/constants/questions.ts +4 -1
  18. package/src/crawlers/commonCrawlerFunc.ts +114 -152
  19. package/src/crawlers/crawlDomain.ts +25 -32
  20. package/src/crawlers/crawlIntelligentSitemap.ts +7 -1
  21. package/src/crawlers/crawlLocalFile.ts +1 -1
  22. package/src/crawlers/crawlSitemap.ts +1 -1
  23. package/src/crawlers/custom/flagUnlabelledClickableElements.ts +546 -472
  24. package/src/crawlers/customAxeFunctions.ts +1 -1
  25. package/src/index.ts +2 -2
  26. package/src/mergeAxeResults.ts +590 -214
  27. package/src/screenshotFunc/pdfScreenshotFunc.ts +3 -3
  28. package/src/static/ejs/partials/components/scanAbout.ejs +65 -0
  29. package/src/static/ejs/partials/components/wcagCompliance.ejs +10 -29
  30. package/src/static/ejs/partials/footer.ejs +10 -13
  31. package/src/static/ejs/partials/scripts/categorySummary.ejs +2 -2
  32. package/src/static/ejs/partials/scripts/decodeUnzipParse.ejs +3 -0
  33. package/src/static/ejs/partials/scripts/reportSearch.ejs +1 -0
  34. package/src/static/ejs/partials/scripts/ruleOffcanvas.ejs +54 -52
  35. package/src/static/ejs/partials/scripts/scanAboutScript.ejs +38 -0
  36. package/src/static/ejs/partials/styles/styles.ejs +26 -1
  37. package/src/static/ejs/partials/summaryMain.ejs +15 -42
  38. package/src/static/ejs/report.ejs +22 -12
  39. package/src/utils.ts +10 -2
  40. package/src/xPathToCss.ts +186 -0
  41. package/a11y-scan-results.zip +0 -0
  42. package/src/types/xpath-to-css.d.ts +0 -3
@@ -1,5 +1,5 @@
1
1
  import _ from 'lodash';
2
- import pdfjs, { PDFPageProxy } from 'pdfjs-dist';
2
+ import { getDocument, PDFPageProxy } from 'pdfjs-dist';
3
3
  import fs from 'fs';
4
4
  import { Canvas, createCanvas, SKRSContext2D } from '@napi-rs/canvas';
5
5
  import assert from 'assert';
@@ -67,7 +67,7 @@ export async function getPdfScreenshots(
67
67
  screenshotPath: string,
68
68
  ) {
69
69
  const newItems = _.cloneDeep(items);
70
- const loadingTask = pdfjs.getDocument({
70
+ const loadingTask = getDocument({
71
71
  url: pdfFilePath,
72
72
  standardFontDataUrl: path.join(dirname, '../node_modules/pdfjs-dist/standard_fonts/'),
73
73
  disableFontFace: true,
@@ -739,7 +739,7 @@ export const getBboxPage = (bbox, structure) => {
739
739
 
740
740
  export const getPageFromContext = async (context: string, pdfFilePath: string): Promise<number> => {
741
741
  try {
742
- const loadingTask = pdfjs.getDocument({
742
+ const loadingTask = getDocument({
743
743
  url: pdfFilePath,
744
744
  standardFontDataUrl: path.join(dirname, '../../node_modules/pdfjs-dist/standard_fonts/'),
745
745
  disableFontFace: true,
@@ -225,6 +225,71 @@
225
225
  </svg>
226
226
  </span>
227
227
  </li>
228
+
229
+ <li>
230
+ <svg aria-label="Advanced options scan summary" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
231
+ <rect x="0.87" y="0.87" width="16.26" height="16.26" rx="3.13" stroke="#93928D" stroke-width="1.74"/>
232
+ <path d="M5 9L7.5 11.5L13 6" stroke="#93928D" stroke-width="1.74" stroke-linecap="square"/>
233
+ </svg>
234
+ <div>
235
+ <div class="d-flex flex-row justify-content-center align-items-center gap-3">
236
+ <button id="advancedScanOptionsSummaryTitle" onclick="toggleAdvanceScanSummary()">Advanced scan summary
237
+ </button>
238
+ </div>
239
+
240
+ </div>
241
+ </li>
242
+ <ul id="advancedScanOptionsSummary" class="d-none mb-3">
243
+ <li id="showIncludeScreenshots"class="d-flex flex-row">
244
+ <svg aria-label="Include screenshots was checked" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
245
+ <rect x="0.87" y="0.87" width="16.26" height="16.26" rx="3.13" fill="#93928D" stroke="#93928D" stroke-width="1.74"/>
246
+ <path d="M5 9L7.5 11.5L13 6" fill="none" stroke="#ffffff" stroke-width="1.74" stroke-linecap="square"/>
247
+ </svg>
248
+ <div>Include screenshots
249
+ </div>
250
+ </li>
251
+ <li id="showAllowSubdomains"class="d-flex flex-row">
252
+ <svg aria-label="Allow subdomains was checked" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
253
+ <rect x="0.87" y="0.87" width="16.26" height="16.26" rx="3.13" fill="#93928D" stroke="#93928D" stroke-width="1.74"/>
254
+ <path d="M5 9L7.5 11.5L13 6" fill="none" stroke="#ffffff" stroke-width="1.74" stroke-linecap="square"/>
255
+ </svg>
256
+ <div>Allow subdomains for scans
257
+ </div>
258
+ </li>
259
+ <li id="showEnableCustomChecks"class="d-flex flex-row">
260
+ <svg aria-label="Enable custom checks was checked" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
261
+ <rect x="0.87" y="0.87" width="16.26" height="16.26" rx="3.13" fill="#93928D" stroke="#93928D" stroke-width="1.74"/>
262
+ <path d="M5 9L7.5 11.5L13 6" fill="none" stroke="#ffffff" stroke-width="1.74" stroke-linecap="square"/>
263
+ </svg>
264
+ <div>Enable custom checks
265
+ </div>
266
+ </li>
267
+ <li id="showEnableWcagAaa"class="d-flex flex-row">
268
+ <svg aria-label="Enable WCAG AAA checks was checked" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
269
+ <rect x="0.87" y="0.87" width="16.26" height="16.26" rx="3.13" fill="#93928D" stroke="#93928D" stroke-width="1.74"/>
270
+ <path d="M5 9L7.5 11.5L13 6" fill="none" stroke="#ffffff" stroke-width="1.74" stroke-linecap="square"/>
271
+ </svg>
272
+ <div>Enable WCAG AAA checks
273
+ </div>
274
+ </li>
275
+ <li id="showSlowScanMode"class="d-flex flex-row">
276
+ <svg aria-label="Slow scan mode was checked" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
277
+ <rect x="0.87" y="0.87" width="16.26" height="16.26" rx="3.13" fill="#93928D" stroke="#93928D" stroke-width="1.74"/>
278
+ <path d="M5 9L7.5 11.5L13 6" fill="none" stroke="#ffffff" stroke-width="1.74" stroke-linecap="square"/>
279
+ </svg>
280
+ <div>Slow scan mode
281
+ </div>
282
+ </li>
283
+
284
+ <li id="showAdhereRobots"class="d-flex flex-row">
285
+ <svg aria-label="Adhere to robots.txt was checked" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none">
286
+ <rect x="0.87" y="0.87" width="16.26" height="16.26" rx="3.13" fill="#93928D" stroke="#93928D" stroke-width="1.74"/>
287
+ <path d="M5 9L7.5 11.5L13 6" fill="none" stroke="#ffffff" stroke-width="1.74" stroke-linecap="square"/>
288
+ </svg>
289
+ <div>Adhere to robots.txt
290
+ </div>
291
+ </li>
292
+ </ul>
228
293
  <li>
229
294
  <svg
230
295
  aria-label="Scan engine"
@@ -5,24 +5,14 @@
5
5
  <span aria-label="Pass percentage" class="ms-2" id="passPercentage"></span>
6
6
  </div>
7
7
  <div class="wcag-compliance-passes-bar">
8
- <div
9
- class="wcag-compliance-passes-bar-progress"
10
- id="wcag-compliance-passes-bar-progress"
11
- style="width: 0%"
12
- ></div>
8
+ <div class="wcag-compliance-passes-bar-progress" id="wcag-compliance-passes-bar-progress" style="width: 0%"></div>
13
9
  </div>
14
10
  <button id="wcagModalToggle" type="button" data-bs-toggle="modal" data-bs-target="#wcagModal">
15
11
  More details
16
12
  </button>
17
13
  </div>
18
14
  <!-- START Modal Pop up -->
19
- <div
20
- id="wcagModal"
21
- class="modal fade"
22
- tabindex="-1"
23
- aria-labelledby="wcagModalLabel"
24
- aria-hidden="true"
25
- >
15
+ <div id="wcagModal" class="modal fade" tabindex="-1" aria-labelledby="wcagModalLabel" aria-hidden="true">
26
16
  <div class="modal-dialog">
27
17
  <div class="modal-content">
28
18
  <div class="modal-header">
@@ -31,28 +21,19 @@
31
21
  </div>
32
22
  <div class="modal-body">
33
23
  <div>
34
- Only 20 WCAG 2.2 Success Criteria can be checked reasonably through automated testing:
24
+ Only 20 WCAG 2.2 Success Criteria (A & AA) can be checked reasonably through automated testing:
35
25
  </div>
36
26
  <div class="accordion my-3" id="wcagLinksAccordion">
37
27
  <div class="accordion-item">
38
28
  <div class="accordion-header" id="wcagLinksAccordionTitle">
39
- <button
40
- class="accordion-button collapsed"
41
- type="button"
42
- data-bs-toggle="collapse"
43
- data-bs-target="#wcagLinksAccordionContent"
44
- aria-expanded="false"
45
- aria-controls="wcagLinksAccordionContent"
46
- >
47
- 20 WCAG Success Criteria (A & AA)
29
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
30
+ data-bs-target="#wcagLinksAccordionContent" aria-expanded="false"
31
+ aria-controls="wcagLinksAccordionContent">
32
+ 20 (A & AA) and 5 (AAA) WCAG Success Criteria
48
33
  </button>
49
34
  </div>
50
- <div
51
- id="wcagLinksAccordionContent"
52
- class="accordion-collapse collapse"
53
- aria-labelledby="wcagLinksAccordionTitle"
54
- data-bs-parent="#accordionExample"
55
- >
35
+ <div id="wcagLinksAccordionContent" class="accordion-collapse collapse"
36
+ aria-labelledby="wcagLinksAccordionTitle" data-bs-parent="#accordionExample">
56
37
  <div class="accordion-body">
57
38
  <ul id="wcagLinksList"></ul>
58
39
  </div>
@@ -67,4 +48,4 @@
67
48
  </div>
68
49
  </div>
69
50
  </div>
70
- <!-- END Modal Pop up -->
51
+ <!-- END Modal Pop up -->
@@ -1,21 +1,18 @@
1
1
  <footer aria-label="Report footer" id="footer" class="card">
2
2
  <div class="row mx-0">
3
3
  <div class="col-sm-6 text-sm-start">
4
- <%
5
- const urlScannedField = '64d49b567c3c460011feb8b5';
6
- const encodedUrlScanned = encodeURIComponent(urlScanned);
7
- const versionNumberField = '64db1f79141a46001243b77a';
8
- const encodedVersionNumber = encodeURIComponent(phAppVersion);
9
- const feedbackForm = `https://form.gov.sg/64d1fcde4d0bb70012010995/?${urlScannedField}=${encodedUrlScanned}&${versionNumberField}=${encodedVersionNumber}`;
10
- %>
11
- <a href="<%=feedbackForm%>" target="_blank">Help us improve</a>
12
- <hr class="d-sm-none" />
4
+ <% const urlScannedField='64d49b567c3c460011feb8b5' ; const encodedUrlScanned=encodeURIComponent(urlScanned);
5
+ const versionNumberField='64db1f79141a46001243b77a' ; const
6
+ encodedVersionNumber=encodeURIComponent(phAppVersion); const
7
+ feedbackForm=`https://form.gov.sg/64d1fcde4d0bb70012010995/?${urlScannedField}=${encodedUrlScanned}&${versionNumberField}=${encodedVersionNumber}`;
8
+ %>
9
+ <a href="<%=feedbackForm%>" target="_blank">Help us improve</a>
10
+ <hr class="d-sm-none" />
13
11
  </div>
14
12
  <div class="col-sm-6 text-sm-end">
15
13
  Created by
16
- <a href="https://form.gov.sg/64d1fcde4d0bb70012010995" target="_blank"
17
- >GovTech Accessibility Enabling Team</a
18
- >
14
+ <a href="https://form.gov.sg/64d1fcde4d0bb70012010995" target="_blank">GovTech Accessibility Enabling Team</a> |
15
+ <a href="https://go.gov.sg/oobee-report-third-party-licenses" target="_blank">Third-Party Licenses</a>
19
16
  </div>
20
17
  </div>
21
- </footer>
18
+ </footer>
@@ -17,7 +17,7 @@
17
17
  .getElementById('categorySummary')
18
18
  .setAttribute('aria-label', `${getFormattedCategoryTitle(category)} summary`);
19
19
  selected = event.currentTarget;
20
- window.currentCategory = JSON.parse(JSON.stringify(category));
20
+ window.currentCategory = structuredClone(category);
21
21
 
22
22
  // Ensures <category>DropdownSelector on mobile view matches
23
23
  const matchingDropdownId = category + 'DropdownSelector';
@@ -28,7 +28,7 @@
28
28
 
29
29
  function loadRulesSummary(category, searchVal) {
30
30
  const newItems = [];
31
- window.filteredItems = JSON.parse(JSON.stringify(scanItems));
31
+ window.filteredItems = structuredClone(scanItems);
32
32
  if (document.getElementById('searchBarInput').value.trim() !== '') {
33
33
  for (let category in filteredItems) {
34
34
  handleSearch(category, searchVal, filteredItems);