@govtechsg/oobee 0.10.33 → 0.10.34

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/Dockerfile CHANGED
@@ -1,6 +1,6 @@
1
1
  # Use Microsoft Playwright image as base image
2
2
  # Node version is v22
3
- FROM mcr.microsoft.com/playwright:v1.50.0-noble
3
+ FROM mcr.microsoft.com/playwright:v1.50.1-noble
4
4
 
5
5
  # Installation of packages for oobee and runner
6
6
  RUN apt-get update && apt-get install -y zip git
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@govtechsg/oobee",
3
3
  "main": "dist/npmIndex.js",
4
- "version": "0.10.33",
4
+ "version": "0.10.34",
5
5
  "type": "module",
6
6
  "author": "Government Technology Agency <info@tech.gov.sg>",
7
7
  "dependencies": {
@@ -178,14 +178,14 @@ export const axeScript = path.join(dirname, '../../node_modules/axe-core/axe.min
178
178
  export class UrlsCrawled {
179
179
  toScan: string[] = [];
180
180
  scanned: { url: string; actualUrl: string; pageTitle: string }[] = [];
181
- invalid: string[] = [];
181
+ invalid: { url: string; actualUrl: string; pageTitle: string }[] = [];
182
182
  scannedRedirects: { fromUrl: string; toUrl: string }[] = [];
183
183
  notScannedRedirects: { fromUrl: string; toUrl: string }[] = [];
184
184
  outOfDomain: string[] = [];
185
- blacklisted: string[] = [];
185
+ blacklisted: { url: string; actualUrl: string; pageTitle: string }[] = [];
186
186
  error: { url: string }[] = [];
187
187
  exceededRequests: string[] = [];
188
- forbidden: string[] = [];
188
+ forbidden: { url: string; actualUrl: string; pageTitle: string }[] = [];
189
189
  userExcluded: { url: string; actualUrl: string; pageTitle: string }[] = [];
190
190
  everything: string[] = [];
191
191
 
@@ -638,7 +638,12 @@ const crawlDomain = async ({
638
638
  numScanned: urlsCrawled.scanned.length,
639
639
  urlScanned: request.url,
640
640
  });
641
- urlsCrawled.blacklisted.push(request.url);
641
+ urlsCrawled.blacklisted.push({
642
+ url: request.url,
643
+ pageTitle: request.url,
644
+ actualUrl: actualUrl, // i.e. actualUrl
645
+ });
646
+
642
647
  return;
643
648
  }
644
649
  const { pdfFileName, url } = handlePdfDownload(
@@ -662,7 +667,12 @@ const crawlDomain = async ({
662
667
  numScanned: urlsCrawled.scanned.length,
663
668
  urlScanned: request.url,
664
669
  });
665
- urlsCrawled.blacklisted.push(request.url);
670
+ urlsCrawled.blacklisted.push({
671
+ url: request.url,
672
+ pageTitle: request.url,
673
+ actualUrl: actualUrl, // i.e. actualUrl
674
+ });
675
+
666
676
  return;
667
677
  }
668
678
 
@@ -671,7 +681,12 @@ const crawlDomain = async ({
671
681
  numScanned: urlsCrawled.scanned.length,
672
682
  urlScanned: request.url,
673
683
  });
674
- urlsCrawled.blacklisted.push(request.url);
684
+ urlsCrawled.blacklisted.push({
685
+ url: request.url,
686
+ pageTitle: request.url,
687
+ actualUrl: actualUrl, // i.e. actualUrl
688
+ });
689
+
675
690
  return;
676
691
  }
677
692
 
@@ -691,7 +706,12 @@ const crawlDomain = async ({
691
706
  numScanned: urlsCrawled.scanned.length,
692
707
  urlScanned: request.url,
693
708
  });
694
- urlsCrawled.forbidden.push(request.url);
709
+ urlsCrawled.forbidden.push({
710
+ url: request.url,
711
+ pageTitle: request.url,
712
+ actualUrl: actualUrl, // i.e. actualUrl
713
+ });
714
+
695
715
  return;
696
716
  }
697
717
 
@@ -700,7 +720,12 @@ const crawlDomain = async ({
700
720
  numScanned: urlsCrawled.scanned.length,
701
721
  urlScanned: request.url,
702
722
  });
703
- urlsCrawled.invalid.push(request.url);
723
+ urlsCrawled.invalid.push({
724
+ url: request.url,
725
+ pageTitle: request.url,
726
+ actualUrl: actualUrl, // i.e. actualUrl
727
+ });
728
+
704
729
  return;
705
730
  }
706
731
 
@@ -779,7 +804,12 @@ const crawlDomain = async ({
779
804
  numScanned: urlsCrawled.scanned.length,
780
805
  urlScanned: request.url,
781
806
  });
782
- urlsCrawled.blacklisted.push(request.url);
807
+ urlsCrawled.blacklisted.push({
808
+ url: request.url,
809
+ pageTitle: request.url,
810
+ actualUrl: actualUrl, // i.e. actualUrl
811
+ });
812
+
783
813
  }
784
814
 
785
815
  if (followRobots) await getUrlsFromRobotsTxt(request.url, browser);
@@ -250,7 +250,12 @@ const crawlSitemap = async (
250
250
  numScanned: urlsCrawled.scanned.length,
251
251
  urlScanned: request.url,
252
252
  });
253
- urlsCrawled.blacklisted.push(request.url);
253
+ urlsCrawled.blacklisted.push({
254
+ url: request.url,
255
+ pageTitle: request.url,
256
+ actualUrl: actualUrl, // i.e. actualUrl
257
+ });
258
+
254
259
  return;
255
260
  }
256
261
  // pushes download promise into pdfDownloads
@@ -297,7 +302,12 @@ const crawlSitemap = async (
297
302
  numScanned: urlsCrawled.scanned.length,
298
303
  urlScanned: request.url,
299
304
  });
300
- urlsCrawled.invalid.push(request.url);
305
+ urlsCrawled.invalid.push({
306
+ url: request.url,
307
+ pageTitle: request.url,
308
+ actualUrl: actualUrl, // i.e. actualUrl
309
+ });
310
+
301
311
  return;
302
312
  }
303
313
 
@@ -874,7 +874,6 @@ export const flagUnlabelledClickableElements = async (page: Page) => {
874
874
  }
875
875
 
876
876
  function flagElements() {
877
- console.time('Accessibility Check Time');
878
877
 
879
878
  const currentFlaggedElementsByDocument: Record<string, HTMLElement[]> = {}; // Temporary object to hold current flagged elements
880
879
 
@@ -1014,7 +1013,6 @@ export const flagUnlabelledClickableElements = async (page: Page) => {
1014
1013
  previousFlaggedXPathsByDocument = { ...flaggedXPathsByDocument };
1015
1014
 
1016
1015
  cleanupFlaggedElements();
1017
- console.timeEnd('Accessibility Check Time');
1018
1016
  return previousAllFlaggedElementsXPaths;
1019
1017
  }
1020
1018
 
@@ -295,7 +295,11 @@ export const handlePdfDownload = (
295
295
  numScanned: urlsCrawled.scanned.length,
296
296
  urlScanned: request.url,
297
297
  });
298
- urlsCrawled.invalid.push(url);
298
+ urlsCrawled.invalid.push({
299
+ url: request.url,
300
+ pageTitle: url,
301
+ actualUrl: url, // i.e. actualUrl
302
+ });
299
303
  }
300
304
  resolve();
301
305
  });
@@ -13,14 +13,15 @@
13
13
  <div class="d-flex justify-content-between align-items-center">
14
14
  <span class="fw-bold"> WCAG (A & AA) Passes </span>
15
15
  <span aria-label="Pass percentage" class="ms-2">
16
- <%= wcagPassPercentage %>% of automated checks
16
+ <%= wcagPassPercentage.passPercentageAA %>% of automated checks
17
17
  </span>
18
18
  </div>
19
19
  <div class="wcag-compliance-passes-bar mb-5 d-flex">
20
20
  <svg width="500" role="none" height="6" fill="none" xmlns="http://www.w3.org/2000/svg"
21
21
  style="display: flex; width: 100%; position: absolute">
22
22
  <rect width="100%" height="10" rx="3" fill="#E7ECEE" style="justify-content: left"></rect>
23
- <rect width="<%= wcagPassPercentage %>%" height="6" rx="3" fill="#9021a6" style=""></rect>
23
+ <rect width="<%= wcagPassPercentage.passPercentageAA %>%" height="6" rx="3" fill="#9021a6" style="">
24
+ </rect>
24
25
  </svg>
25
26
  </div>
26
27
  <ul class="unbulleted-list">
@@ -47,9 +47,9 @@
47
47
  // Scan DATA FUNCTION TO REPLACE NA
48
48
  const scanDataWCAGCompliance = () => {
49
49
  const passPecentage = document.getElementById('passPercentage');
50
- passPecentage.innerHTML = scanData.wcagPassPercentage + '% of automated checks';
50
+ passPecentage.innerHTML = scanData.wcagPassPercentage.passPercentageAA + '% of automated checks';
51
51
  const wcagBarProgess = document.getElementById('wcag-compliance-passes-bar-progress');
52
- wcagBarProgess.style.width = `${scanData.wcagPassPercentage}%`; // Set this to your desired width
52
+ wcagBarProgess.style.width = `${scanData.wcagPassPercentage.passPercentageAA}%`; // Set this to your desired width
53
53
 
54
54
  const wcagLinksList = document.getElementById('wcagLinksList');
55
55
 
package/src/utils.ts CHANGED
@@ -190,19 +190,23 @@ export const cleanUp = async pathToDelete => {
190
190
  // timeZoneName: "longGeneric",
191
191
  // });
192
192
 
193
- export const getWcagPassPercentage = (wcagViolations: string[]): string => {
193
+ export const getWcagPassPercentage = (wcagViolations: string[]): { passPercentageAA: string; totalWcagChecksAA: number; totalWcagViolationsAA: number } => {
194
194
 
195
195
  // These AAA rules should not be counted as WCAG Pass Percentage only contains A and AA
196
196
  const wcagAAA = ['WCAG 1.4.6', 'WCAG 2.2.4', 'WCAG 2.4.9', 'WCAG 3.1.5', 'WCAG 3.2.5'];
197
197
 
198
198
  const filteredWcagLinks = Object.keys(constants.wcagLinks).filter(key => !wcagAAA.includes(key));
199
199
  const filteredWcagViolations = wcagViolations.filter(violation => !wcagAAA.includes(violation));
200
- const totalChecks = filteredWcagLinks.length;
200
+ const totalChecksAA = filteredWcagLinks.length;
201
201
 
202
- const passedChecks = totalChecks - filteredWcagViolations.length;
203
- const passPercentage = (passedChecks / totalChecks) * 100;
202
+ const passedChecks = totalChecksAA - filteredWcagViolations.length;
203
+ const passPercentageAA = (passedChecks / totalChecksAA) * 100;
204
204
 
205
- return passPercentage.toFixed(2); // toFixed returns a string, which is correct here
205
+ return {
206
+ passPercentageAA: passPercentageAA.toFixed(2), // toFixed returns a string, which is correct here
207
+ totalWcagChecksAA: totalChecksAA,
208
+ totalWcagViolationsAA: filteredWcagViolations.length,
209
+ };
206
210
  };
207
211
 
208
212
  export const getFormattedTime = inputDate => {