@govtechsg/oobee 0.10.65 → 0.10.69

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 (36) hide show
  1. package/DETAILS.md +1 -1
  2. package/Dockerfile +1 -1
  3. package/INTEGRATION.md +36 -490
  4. package/README.md +44 -12
  5. package/examples/oobee-cypress-integration-js/cypress/e2e/spec.cy.js +19 -0
  6. package/examples/oobee-cypress-integration-js/cypress/support/e2e.js +73 -0
  7. package/examples/oobee-cypress-integration-js/cypress.config.js +62 -0
  8. package/examples/oobee-cypress-integration-js/package.json +13 -0
  9. package/examples/oobee-cypress-integration-ts/cypress.config.ts +94 -0
  10. package/examples/oobee-cypress-integration-ts/cypress.d.ts +22 -0
  11. package/examples/oobee-cypress-integration-ts/package.json +12 -0
  12. package/examples/oobee-cypress-integration-ts/src/cypress/e2e/spec.cy.ts +18 -0
  13. package/examples/oobee-cypress-integration-ts/src/cypress/support/e2e.ts +93 -0
  14. package/examples/oobee-cypress-integration-ts/tsconfig.json +19 -0
  15. package/examples/oobee-playwright-integration-js/oobee-playwright-demo.js +64 -0
  16. package/examples/oobee-playwright-integration-js/package.json +13 -0
  17. package/examples/oobee-playwright-integration-ts/package.json +15 -0
  18. package/examples/oobee-playwright-integration-ts/src/oobee-playwright-demo.ts +83 -0
  19. package/examples/oobee-playwright-integration-ts/tsconfig.json +11 -0
  20. package/package.json +4 -2
  21. package/scripts/install_oobee_dependencies.command +1 -1
  22. package/scripts/install_oobee_dependencies.ps1 +2 -2
  23. package/src/cli.ts +23 -78
  24. package/src/constants/common.ts +245 -126
  25. package/src/constants/constants.ts +23 -16
  26. package/src/constants/questions.ts +16 -33
  27. package/src/crawlers/commonCrawlerFunc.ts +8 -8
  28. package/src/crawlers/crawlDomain.ts +16 -4
  29. package/src/crawlers/crawlIntelligentSitemap.ts +2 -2
  30. package/src/crawlers/crawlLocalFile.ts +2 -1
  31. package/src/crawlers/crawlSitemap.ts +4 -3
  32. package/src/crawlers/pdfScanFunc.ts +29 -25
  33. package/src/index.ts +4 -5
  34. package/src/mergeAxeResults.ts +27 -27
  35. package/src/npmIndex.ts +248 -91
  36. package/src/utils.ts +1 -3
package/DETAILS.md CHANGED
@@ -102,7 +102,7 @@ Note: Level AAA are disabled by default. Please specify `enable-wcag-aaa` in ru
102
102
  | dlitem | Ensures `<dt>` and `<dd>` elements are contained by a `<dl>` | Must Fix | WCAG 1.3.1 |
103
103
  | document-title | Ensures each HTML document contains a non-empty `<title>` element | Must Fix | WCAG 2.4.2 |
104
104
  | duplicate-id-aria | Ensures every id attribute value used in ARIA and in labels is unique | Must Fix | WCAG 4.1.2 |
105
- | form-field-multiple-labels | Ensures form field does not have multiple label elements | Good to Fix | WCAG 3.3.2 |
105
+ | form-field-multiple-labels | Ensures form field does not have multiple label elements | Must Fix | WCAG 3.3.2 |
106
106
  | frame-focusable-content | Ensures `<frame>` and `<iframe>` elements with focusable content do not have tabindex=-1 | Must Fix | WCAG 2.1.1 |
107
107
  | frame-title-unique | Ensures `<iframe>` and `<frame>` elements contain a unique title attribute | Must Fix | WCAG 4.1.2 |
108
108
  | frame-title | Ensures `<iframe>` and `<frame>` elements have an accessible name | Must Fix | WCAG 4.1.2 |
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.1-noble
3
+ FROM mcr.microsoft.com/playwright:v1.55.0-noble
4
4
 
5
5
  # Installation of packages for oobee and runner (locked versions from build log)
6
6
  RUN apt-get update && apt-get install -y \
package/INTEGRATION.md CHANGED
@@ -86,9 +86,13 @@ Unique identifier for the scan instance
86
86
 
87
87
  ##### Methods
88
88
 
89
- `getScripts()`
89
+ `getAxeScript()`
90
90
 
91
- Get the axe-core script to be injected into the browser, along with other custom Oobee scripts
91
+ Get the axe-core engine to be injected into the browser.
92
+
93
+ `getOobeeFunctions()`
94
+
95
+ Get the Oobee custom functions to run accessibility scan. Call this after `getAxeScript()`.
92
96
 
93
97
  - `runA11yScan(elementsToScan, gradingReadabilityFlag)`
94
98
  Runs axe scan on the current page.
@@ -152,6 +156,7 @@ With reference to an instance of Oobee as `oobeeA11y`:
152
156
 
153
157
  We will be creating the following files in a demo Cypress project:
154
158
 
159
+ ```
155
160
  ├── cypress
156
161
  │   ├── e2e
157
162
  │   │   └── spec.cy.js
@@ -160,152 +165,33 @@ We will be creating the following files in a demo Cypress project:
160
165
  ├── cypress.config.js
161
166
  └── package.json
162
167
 
163
- Create a <code>package.json</code> by running <code>npm init</code> . Accept the default options or customise it as needed.
168
+ ```
164
169
 
165
- Change the type of npm package to module by running <code>npm pkg set type="module"</code>
170
+ Copy the examples provided in `./examples/oobee-cypress-integration-js` to a folder and set that as a working directory.
166
171
 
167
- Install the following node dependencies by running <code>npm install cypress @govtechsg/oobee --save-dev </code>
172
+ Install any dependencies with `npm install` .
168
173
 
169
174
  Navigate to <code>node_modules/@govtechsg/oobee</code> and run <code>npm install</code> and <code>npm run build</code> within the folder to install remaining Oobee dependencies:
170
175
 
176
+ ```
171
177
  cd node_modules/@govtechsg/oobee
172
178
  npm install
173
179
  npm run build
174
180
  cd ../../..
181
+ ```
175
182
 
176
- Create <code>cypress.config.js</code> with the following contents, and change your Name, E-mail address, and boolean value for whether rule items requiring manual review in the report should be displayed below:
177
-
178
- import { defineConfig } from "cypress";
179
- import oobeeA11yInit from "@govtechsg/oobee";
180
-
181
- // viewport used in tests to optimise screenshots
182
- const viewportSettings = { width: 1920, height: 1040 };
183
- // specifies the number of occurrences before error is thrown for test failure
184
- const thresholds = { mustFix: 20, goodToFix: 25 };
185
- // additional information to include in the "Scan About" section of the report
186
- const scanAboutMetadata = { browser: 'Chrome (Desktop)' };
187
- // name of the generated zip of the results at the end of scan
188
- const resultsZipName = "oobee-scan-results.zip";
189
-
190
- const oobeeA11y = await oobeeA11yInit({
191
- entryUrl: "https://govtechsg.github.io", // initial url to start scan
192
- testLabel: "Demo Cypress Scan", // label for test
193
- name: "Your Name",
194
- email: "email@domain.com",
195
- includeScreenshots: true, // include screenshots of affected elements in the report
196
- viewportSettings,
197
- thresholds: { mustFix: undefined, goodToFix: undefined },
198
- scanAboutMetadata: undefined,
199
- zip: resultsZipName,
200
- deviceChosen: "",
201
- strategy: undefined,
202
- ruleset: ["enable-wcag-aaa"], // add "disable-oobee" to disable Oobee custom checks
203
- specifiedMaxConcurrency: undefined,
204
- followRobots: undefined,
205
- });
206
-
207
- export default defineConfig({
208
- taskTimeout: 120000, // need to extend as screenshot function requires some time
209
- viewportHeight: viewportSettings.height,
210
- viewportWidth: viewportSettings.width,
211
- e2e: {
212
- setupNodeEvents(on, _config) {
213
- on("task", {
214
- getOobeeA11yScripts() {
215
- return oobeeA11y.getScripts();
216
- },
217
- gradeReadability(sentences) {
218
- return oobeeA11y.gradeReadability(sentences);
219
- },
220
- async pushOobeeA11yScanResults({res, metadata, elementsToClick}) {
221
- return await oobeeA11y.pushScanResults(res, metadata, elementsToClick);
222
- },
223
- returnResultsDir() {
224
- return `results/${oobeeA11y.randomToken}_${oobeeA11y.scanDetails.urlsCrawled.scanned.length}pages/report.html`;
225
- },
226
- finishOobeeA11yTestCase() {
227
- oobeeA11y.testThresholds();
228
- return null;
229
- },
230
- async terminateOobeeA11y() {
231
- return await oobeeA11y.terminate();
232
- },
233
- });
234
- },
235
- },
236
- });
237
-
238
- Create a sub-folder and file <code>cypress/support/e2e.js</code> with the following contents:
239
-
240
- Cypress.Commands.add("injectOobeeA11yScripts", () => {
241
- cy.task("getOobeeA11yScripts").then((s) => {
242
- cy.window().then((win) => {
243
- win.eval(s);
244
- });
245
- });
246
- });
247
-
248
- Cypress.Commands.add("runOobeeA11yScan", (items={}) => {
249
- cy.window().then(async (win) => {
250
- const { elementsToScan, elementsToClick, metadata } = items;
251
-
252
- // extract text from the page for readability grading
253
- const sentences = win.extractText();
254
- // run readability grading separately as it cannot be done within the browser context
255
- cy.task("gradeReadability", sentences).then(
256
- async (gradingReadabilityFlag) => {
257
- // passing the grading flag to runA11yScan to inject violation as needed
258
- const res = await win.runA11yScan(
259
- elementsToScan,
260
- gradingReadabilityFlag,
261
- );
262
- cy.task("pushOobeeA11yScanResults", {
263
- res,
264
- metadata,
265
- elementsToClick,
266
- }).then((count) => {
267
- return count;
268
- });
269
- },
270
- );
271
- cy.task("finishOobeeA11yTestCase"); // test the accumulated number of issue occurrences against specified thresholds. If exceed, terminate oobeeA11y instance.
272
- });
273
- });
274
-
275
- Cypress.Commands.add("terminateOobeeA11y", () => {
276
- cy.task("terminateOobeeA11y");
277
- });
278
-
279
- Create <code>cypress/e2e/spec.cy.js</code> with the following contents:
280
-
281
- describe("template spec", () => {
282
- it("should run oobee A11y", () => {
283
- cy.visit(
284
- "https://govtechsg.github.io/purple-banner-embeds/purple-integrated-scan-example.htm"
285
- );
286
- cy.injectOobeeA11yScripts();
287
- cy.runOobeeA11yScan();
288
- cy.get("button[onclick=\"toggleSecondSection()\"]").click();
289
- // Run a scan on <input> and <button> elements
290
- cy.runOobeeA11yScan({
291
- elementsToScan: ["input", "button"],
292
- elementsToClick: ["button[onclick=\"toggleSecondSection()\"]"],
293
- metadata: "Clicked button"
294
- });
295
-
296
- cy.terminateOobeeA11y();
297
- });
298
- });
183
+ Run your test with <code>npx cypress run</code>.
299
184
 
300
- Run your test with <code>npx cypress run</code>.
301
185
  You will see Oobee results generated in <code>results</code> folder.
302
186
 
303
187
  </details>
188
+
304
189
  <details>
305
- <summary>Click here to see an example usage in an E2E Cypress test (typescript)</summary>
190
+ <summary>Click here to see an example usage in an E2E Cypress test (typescript)</summary>
306
191
 
307
192
  We will be creating the following files in a demo Cypress project:
308
193
 
194
+ ```
309
195
  ├── cypress.config.ts
310
196
  ├── cypress.d.ts
311
197
  ├── package.json
@@ -317,197 +203,19 @@ We will be creating the following files in a demo Cypress project:
317
203
  │ └── e2e.ts
318
204
  └── tsconfig.json
319
205
 
320
- Create a <code>package.json</code> by running <code>npm init</code> . Accept the default options or customise it as needed.
321
-
322
- Change the type of npm package to module by running <code>npm pkg set type="module"</code>
323
-
324
- Install the following node dependencies by running <code>npm install cypress @types/cypress @govtechsg/oobee typescript --save-dev </code>
206
+ ```
325
207
 
326
- Create a <code>tsconfig.json</code> in the root directory and add the following:
208
+ Copy the examples provided in `./examples/oobee-cypress-integration-ts` to a folder and set that as a working directory.
327
209
 
328
- ```
329
- {
330
- "compilerOptions": {
331
- "outDir": "./dist",
332
- "allowJs": true,
333
- "target": "es2021",
334
- "module": "nodenext",
335
- "rootDir": "./src",
336
- "skipLibCheck": true,
337
- "types": ["cypress"]
338
- },
339
- "include": ["./src/**/*", "cypress.d.ts"]
340
- }
341
- ```
210
+ Install any dependencies with `npm install` .
342
211
 
343
212
  Navigate to <code>node_modules/@govtechsg/oobee</code> and run <code>npm install</code> and <code>npm run build</code> within the folder to install remaining Oobee dependencies:
344
213
 
214
+ ```
345
215
  cd node_modules/@govtechsg/oobee
346
216
  npm install
347
217
  npm run build
348
218
  cd ../../..
349
-
350
- Create <code>cypress.config.ts</code> with the following contents, and change your Name, E-mail address, and boolean value for whether rule items requiring manual review in the report should be displayed below:
351
-
352
- import { defineConfig } from "cypress";
353
- import oobeeA11yInit from "@govtechsg/oobee";
354
-
355
- interface ViewportSettings {
356
- width: number;
357
- height: number;
358
- }
359
-
360
- interface Thresholds {
361
- mustFix: number;
362
- goodToFix: number;
363
- }
364
-
365
- interface ScanAboutMetadata {
366
- browser: string;
367
- }
368
-
369
- // viewport used in tests to optimise screenshots
370
- const viewportSettings: ViewportSettings = { width: 1920, height: 1040 };
371
- // specifies the number of occurrences before error is thrown for test failure
372
- const thresholds: Thresholds = { mustFix: 20, goodToFix: 20 };
373
- // additional information to include in the "Scan About" section of the report
374
- const scanAboutMetadata: ScanAboutMetadata = { browser: 'Chrome (Desktop)' };
375
- // name of the generated zip of the results at the end of scan
376
- const resultsZipName: string = "oobee-scan-results.zip"
377
-
378
- const oobeeA11y = await oobeeA11yInit({
379
- "https://govtechsg.github.io", // initial url to start scan
380
- "Demo Cypress Scan", // label for test
381
- "Your Name",
382
- "email@domain.com",
383
- true, // include screenshots of affected elements in the report
384
- viewportSettings,
385
- thresholds: { mustFix: undefined, goodToFix: undefined },
386
- scanAboutMetadata: undefined,
387
- zip: resultsZipName,
388
- deviceChosen: "",
389
- strategy: undefined,
390
- ruleset: ["enable-wcag-aaa"], // add "disable-oobee" to disable Oobee custom checks
391
- specifiedMaxConcurrency: undefined,
392
- followRobots: undefined,
393
- });
394
-
395
- export default defineConfig({
396
- taskTimeout: 120000, // need to extend as screenshot function requires some time
397
- viewportHeight: viewportSettings.height,
398
- viewportWidth: viewportSettings.width,
399
- e2e: {
400
- setupNodeEvents(on, _config) {
401
- on("task", {
402
- getOobeeA11yScripts(): string {
403
- return oobeeA11y.getScripts();
404
- },
405
- gradeReadability(sentences: string[]): string {
406
- return oobeeA11y.gradeReadability(sentences);
407
- },
408
- async pushOobeeA11yScanResults({res, metadata, elementsToClick}: { res: any, metadata: any, elementsToClick: any[] }): Promise<{ mustFix: number, goodToFix: number }> {
409
- return await oobeeA11y.pushScanResults(res, metadata, elementsToClick);
410
- },
411
- returnResultsDir(): string {
412
- return `results/${oobeeA11y.randomToken}_${oobeeA11y.scanDetails.urlsCrawled.scanned.length}pages/reports/report.html`;
413
- },
414
- finishOobeeA11yTestCase(): null {
415
- oobeeA11y.testThresholds();
416
- return null;
417
- },
418
- async terminateOobeeA11y(): Promise<string> {
419
- return await oobeeA11y.terminate();
420
- },
421
- });
422
- },
423
- supportFile: 'dist/cypress/support/e2e.js',
424
- specPattern: 'dist/cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
425
- },
426
- });
427
-
428
- Create a sub-folder and file <code>src/cypress/support/e2e.ts</code> with the following contents:
429
-
430
- Cypress.Commands.add("injectOobeeA11yScripts", () => {
431
- cy.task("getOobeeA11yScripts").then((s: string) => {
432
- cy.window().then((win) => {
433
- win.eval(s);
434
- });
435
- });
436
- });
437
-
438
- Cypress.Commands.add("runOobeeA11yScan", (items={}) => {
439
- cy.window().then(async (win) => {
440
- const { elementsToScan, elementsToClick, metadata } = items;
441
-
442
- // extract text from the page for readability grading
443
- const sentences = win.extractText();
444
- // run readability grading separately as it cannot be done within the browser context
445
- cy.task("gradeReadability", sentences).then(
446
- async (gradingReadabilityFlag: string) => {
447
- // passing the grading flag to runA11yScan to inject violation as needed
448
- const res = await win.runA11yScan(
449
- elementsToScan,
450
- gradingReadabilityFlag,
451
- );
452
- cy.task("pushOobeeA11yScanResults", {
453
- res,
454
- metadata,
455
- elementsToClick,
456
- }).then((count) => {
457
- return count;
458
- });
459
- },
460
- );
461
- cy.task("finishOobeeA11yTestCase"); // test the accumulated number of issue occurrences against specified thresholds. If exceed, terminate oobeeA11y instance.
462
- });
463
- });
464
-
465
- Cypress.Commands.add("terminateOobeeA11y", () => {
466
- cy.task("terminateOobeeA11y");
467
- });
468
-
469
- Create <code>src/cypress/e2e/spec.cy.ts</code> with the following contents:
470
-
471
- describe("template spec", () => {
472
- it("should run oobee A11y", () => {
473
- cy.visit(
474
- "https://govtechsg.github.io/purple-banner-embeds/oobee-integrated-scan-example.htm"
475
- );
476
- cy.injectOobeeA11yScripts();
477
- cy.runOobeeA11yScan();
478
- cy.get("button[onclick=\"toggleSecondSection()\"]").click();
479
- // Run a scan on <input> and <button> elements
480
- cy.runOobeeA11yScan({
481
- elementsToScan: ["input", "button"],
482
- elementsToClick: ["button[onclick=\"toggleSecondSection()\"]"],
483
- metadata: "Clicked button"
484
- });
485
-
486
- cy.terminateOobeeA11y();
487
- });
488
- });
489
-
490
- Create <code>cypress.d.ts</code> in the root directory with the following contents:
491
-
492
- ```
493
- declare namespace Cypress {
494
- interface Chainable<Subject> {
495
- injectOobeeA11yScripts(): Chainable<void>;
496
- runOobeeA11yScan(options?: OobeeScanOptions): Chainable<void>;
497
- terminateOobeeA11y(): Chainable<any>;
498
- }
499
-
500
- interface OobeeScanOptions {
501
- elementsToScan?: string[];
502
- elementsToClick?: string[];
503
- metadata?: string;
504
- }
505
- }
506
-
507
- interface Window {
508
- runA11yScan: (elementsToScan?: string[]) => Promise<any>;
509
- extractText: () => string[];
510
- }
511
219
  ```
512
220
 
513
221
  Compile your typescript code with <code>npx tsc</code>.
@@ -522,211 +230,48 @@ You will see Oobee results generated in <code>results</code> folder.
522
230
  <details>
523
231
  <summary>Click here to see an example usage in Playwright (javascript)</summary>
524
232
 
525
- Create a <code>package.json</code> by running <code>npm init</code> . Accept the default options or customise it as needed.
233
+ Copy the examples provided in `./examples/oobee-playwright-integration-js` to a folder and set that as a working directory.
526
234
 
527
- Change the type of npm package to module by running <code>npm pkg set type="module"</code>
235
+ Install any dependencies with `npm install`.
528
236
 
529
- Install the following node dependencies by running <code>npm install playwright @govtechsg/oobee --save-dev</code> and <code>npx playwright install</code>
237
+ Install Playwright Chromium by running <code>npx playwright install chromium</code>
530
238
 
531
239
  Navigate to <code>node_modules/@govtechsg/oobee</code> and run <code>npm install</code> and <code>npm run build</code> within the folder to install remaining Oobee dependencies:
532
240
 
241
+ ```
533
242
  cd node_modules/@govtechsg/oobee
534
243
  npm install
535
244
  npm run build
536
245
  cd ../../..
246
+ ```
537
247
 
538
- On your project's root folder, create a Playwright test file <code>oobee-playwright-demo.js</code>:
539
-
540
- import { chromium } from "playwright";
541
- import oobeeA11yInit from "@govtechsg/oobee";
542
- import { extractText } from "@govtechsg/oobee/dist/crawlers/custom/extractText.js";
543
-
544
- // viewport used in tests to optimise screenshots
545
- const viewportSettings = { width: 1920, height: 1040 };
546
- // specifies the number of occurrences before error is thrown for test failure
547
- const thresholds = { mustFix: 20, goodToFix: 25 };
548
- // additional information to include in the "Scan About" section of the report
549
- const scanAboutMetadata = { browser: 'Chrome (Desktop)' };
550
- // name of the generated zip of the results at the end of scan
551
- const resultsZipName = "oobee-scan-results.zip";
552
-
553
- const oobeeA11y = await oobeeA11yInit({
554
- entryUrl: "https://govtechsg.github.io", // initial url to start scan
555
- testLabel: "Demo Cypress Scan", // label for test
556
- name: "Your Name",
557
- email: "email@domain.com",
558
- includeScreenshots: true, // include screenshots of affected elements in the report
559
- viewportSettings,
560
- thresholds: { mustFix: undefined, goodToFix: undefined },
561
- scanAboutMetadata: undefined,
562
- zip: resultsZipName,
563
- deviceChosen: "",
564
- strategy: undefined,
565
- ruleset: ["enable-wcag-aaa"],
566
- specifiedMaxConcurrency: undefined,
567
- followRobots: undefined,
568
- });
569
-
570
- (async () => {
571
- const browser = await chromium.launch({
572
- headless: false,
573
- });
574
- const context = await browser.newContext();
575
- const page = await context.newPage();
576
-
577
- const runOobeeA11yScan = async (elementsToScan, gradingReadabilityFlag) => {
578
- const scanRes = await page.evaluate(
579
- async ({ elementsToScan, gradingReadabilityFlag }) => await runA11yScan(elementsToScan, gradingReadabilityFlag),
580
- { elementsToScan, gradingReadabilityFlag },
581
- );
582
- await oobeeA11y.pushScanResults(scanRes);
583
- oobeeA11y.testThresholds(); // test the accumulated number of issue occurrences against specified thresholds. If exceed, terminate oobeeA11y instance.
584
- };
585
-
586
- await page.goto('https://govtechsg.github.io/purple-banner-embeds/purple-integrated-scan-example.htm');
587
- await page.evaluate(oobeeA11y.getScripts());
588
-
589
- const sentences = await page.evaluate(() => extractText());
590
- const gradingReadabilityFlag = await oobeeA11y.gradeReadability(sentences);
591
-
592
- await runOobeeA11yScan([], gradingReadabilityFlag);
593
-
594
- await page.getByRole('button', { name: 'Click Me' }).click();
595
- // Run a scan on <input> and <button> elements
596
- await runOobeeA11yScan(['input', 'button'])
597
-
598
-
599
- // ---------------------
600
- await context.close();
601
- await browser.close();
602
- await oobeeA11y.terminate();
603
- })();
604
-
605
- Run your test with <code>node oobee-playwright-demo.js</code> .
248
+ Run your test with `node oobee-playwright-demo.js` .
606
249
 
607
- You will see Oobee results generated in <code>results</code> folder.
250
+ You will see Oobee results generated in results folder.
608
251
 
609
252
  </details>
253
+
610
254
  <details>
611
255
  <summary>Click here to see an example usage in Playwright (typescript)</summary>
612
256
 
613
- Create a <code>package.json</code> by running <code>npm init</code> . Accept the default options or customise it as needed.
257
+ Copy the examples provided in `./examples/oobee-playwright-integration-ts` to a folder and set that as a working directory.
614
258
 
615
- Change the type of npm package to module by running <code>npm pkg set type="module"</code>
259
+ Install any dependencies with `npm install`.
616
260
 
617
- Install the following node dependencies by running <code>npm install playwright @govtechsg/oobee typescript --save-dev</code> and <code>npx playwright install</code>
618
-
619
- Create a <code>tsconfig.json</code> in the root directory and add the following:
620
-
621
- ```
622
- {
623
- "compilerOptions": {
624
- "outDir": "./dist",
625
- "allowJs": true,
626
- "target": "es2021",
627
- "module": "nodenext",
628
- "rootDir": "./src",
629
- "skipLibCheck": true
630
- },
631
- "include": ["./src/**/*"]
632
- }
633
- ```
261
+ Install Playwright Chromium by running <code>npx playwright install chromium</code>
634
262
 
635
263
  Navigate to <code>node_modules/@govtechsg/oobee</code> and run <code>npm install</code> and <code>npm run build</code> within the folder to install remaining Oobee dependencies:
636
264
 
265
+ ```
637
266
  cd node_modules/@govtechsg/oobee
638
267
  npm install
639
268
  npm run build
640
269
  cd ../../..
270
+ ```
641
271
 
642
- Create a sub-folder and Playwright test file <code>src/oobee-playwright-demo.ts</code> with the following contents:
643
-
644
- import { Browser, BrowserContext, Page, chromium } from "playwright";
645
- import oobeeA11yInit from "@govtechsg/oobee";
646
- import { extractText } from "@govtechsg/oobee/dist/crawlers/custom/extractText.js";
647
-
648
- declare const runA11yScan: (
649
- elementsToScan?: string[],
650
- gradingReadabilityFlag?: string,
651
- ) => Promise<any>;
652
-
653
- interface ViewportSettings {
654
- width: number;
655
- height: number;
656
- }
657
-
658
- interface Thresholds {
659
- mustFix: number;
660
- goodToFix: number;
661
- }
662
-
663
- interface ScanAboutMetadata {
664
- browser: string;
665
- }
666
-
667
- // viewport used in tests to optimise screenshots
668
- const viewportSettings: ViewportSettings = { width: 1920, height: 1040 };
669
- // specifies the number of occurrences before error is thrown for test failure
670
- const thresholds: Thresholds = { mustFix: 20, goodToFix: 25 };
671
- // additional information to include in the "Scan About" section of the report
672
- const scanAboutMetadata: ScanAboutMetadata = { browser: 'Chrome (Desktop)' };
673
- // name of the generated zip of the results at the end of scan
674
- const resultsZipName: string = "oobee-scan-results.zip";
675
-
676
- const oobeeA11y = await oobeeA11yInit({
677
- entryUrl: "https://govtechsg.github.io", // initial url to start scan
678
- testLabel: "Demo Cypress Scan", // label for test
679
- name: "Your Name",
680
- email: "email@domain.com",
681
- includeScreenshots: true, // include screenshots of affected elements in the report
682
- viewportSettings,
683
- thresholds: { mustFix: undefined, goodToFix: undefined },
684
- scanAboutMetadata: undefined,
685
- zip: resultsZipName,
686
- deviceChosen: "",
687
- strategy: undefined,
688
- ruleset: ["enable-wcag-aaa"],
689
- specifiedMaxConcurrency: undefined,
690
- followRobots: undefined,
691
- });
692
-
693
- (async () => {
694
- const browser: Browser = await chromium.launch({
695
- headless: false,
696
- });
697
- const context: BrowserContext = await browser.newContext();
698
- const page: Page = await context.newPage();
699
-
700
- const runOobeeA11yScan = async (elementsToScan?: string[], gradingReadabilityFlag?: string) => {
701
- const scanRes = await page.evaluate(
702
- async ({ elementsToScan, gradingReadabilityFlag }) => await runA11yScan(elementsToScan, gradingReadabilityFlag),
703
- { elementsToScan, gradingReadabilityFlag },
704
- );
705
- await oobeeA11y.pushScanResults(scanRes);
706
- oobeeA11y.testThresholds(); // test the accumulated number of issue occurrences against specified thresholds. If exceed, terminate oobeeA11y instance.
707
- };
708
-
709
- await page.goto('https://govtechsg.github.io/purple-banner-embeds/purple-integrated-scan-example.htm');
710
- await page.evaluate(oobeeA11y.getScripts());
711
-
712
- const sentences = await page.evaluate(() => extractText());
713
- const gradingReadabilityFlag = await oobeeA11y.gradeReadability(sentences);
714
-
715
- await runOobeeA11yScan([], gradingReadabilityFlag);
716
-
717
- await page.getByRole('button', { name: 'Click Me' }).click();
718
- // Run a scan on <input> and <button> elements
719
- await runOobeeA11yScan(['input', 'button'])
720
-
272
+ Compile your typescript code with <code>npx tsc</code>.
721
273
 
722
- // ---------------------
723
- await context.close();
724
- await browser.close();
725
- await oobeeA11y.terminate();
726
- })();
727
-
728
- Compile your typescript code with <code>npx tsc</code>.
729
- Run your test with <code>node dist/oobee-playwright-demo.js</code>.
274
+ Run your test with <code>npm test</code>
730
275
 
731
276
  You will see Oobee results generated in <code>results</code> folder.
732
277
 
@@ -805,6 +350,7 @@ You will see Oobee results generated in <code>results</code> folder.
805
350
  runScript();
806
351
 
807
352
  </details>
353
+
808
354
  <details>
809
355
  <summary>Click here to see an example automated web crawler login (typescript)</summary>
810
356
  <code>automated-web-crawler-login.ts</code>: