@govtechsg/oobee 0.10.58 → 0.10.61
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/DETAILS.md +1 -1
- package/package.json +1 -1
- package/src/cli.ts +17 -64
- package/src/combine.ts +18 -4
- package/src/constants/common.ts +193 -293
- package/src/constants/constants.ts +2 -1
- package/src/constants/questions.ts +12 -4
- package/src/crawlers/commonCrawlerFunc.ts +9 -3
- package/src/crawlers/crawlDomain.ts +31 -83
- package/src/crawlers/crawlIntelligentSitemap.ts +16 -11
- package/src/crawlers/crawlLocalFile.ts +6 -17
- package/src/crawlers/crawlSitemap.ts +27 -93
- package/src/crawlers/custom/utils.ts +4 -4
- package/src/index.ts +2 -5
- package/src/logs.ts +1 -2
- package/src/mergeAxeResults.ts +35 -30
- package/src/npmIndex.ts +4 -4
- package/src/utils.ts +56 -14
package/DETAILS.md
CHANGED
@@ -41,7 +41,7 @@ Note: Level AAA are disabled by default. Please specify `enable-wcag-aaa` in ru
|
|
41
41
|
| WCAG 1.4.2 | A | Yes | | |
|
42
42
|
| WCAG 1.4.3 | AA | Yes | | |
|
43
43
|
| WCAG 1.4.4 | AA | Yes | | |
|
44
|
-
| WCAG 1.4.6 | AAA | Yes
|
44
|
+
| WCAG 1.4.6 | AAA | | Yes | |
|
45
45
|
| WCAG 1.4.12 | AA | Yes | | |
|
46
46
|
| WCAG 2.1.1 | A | Yes | | |
|
47
47
|
| WCAG 2.1.3 | AAA | Yes * | | |
|
package/package.json
CHANGED
package/src/cli.ts
CHANGED
@@ -12,11 +12,8 @@ import {
|
|
12
12
|
getFileSitemap,
|
13
13
|
validEmail,
|
14
14
|
validName,
|
15
|
-
getBrowserToRun,
|
16
|
-
getPlaywrightDeviceDetailsObject,
|
17
15
|
deleteClonedProfiles,
|
18
16
|
getScreenToScan,
|
19
|
-
getClonedProfilesWithRandomToken,
|
20
17
|
validateDirPath,
|
21
18
|
validateFilePath,
|
22
19
|
validateCustomFlowLabel,
|
@@ -207,7 +204,7 @@ Usage: npm run cli -- -c <crawler> -d <device> -w <viewport> -u <url> OPTIONS`,
|
|
207
204
|
return duration;
|
208
205
|
})
|
209
206
|
.check(argvs => {
|
210
|
-
if (argvs.scanner === ScannerTypes.CUSTOM && argvs.scanDuration > 0) {
|
207
|
+
if (argvs.scanner === ScannerTypes.CUSTOM && typeof argvs.scanDuration === 'number' && argvs.scanDuration > 0) {
|
211
208
|
throw new Error('-l or --scanDuration is not allowed for custom flow scans.');
|
212
209
|
}
|
213
210
|
return true;
|
@@ -225,45 +222,26 @@ const scanInit = async (argvs: Answers): Promise<string> => {
|
|
225
222
|
|
226
223
|
// Cannot use data.browser and data.isHeadless as the connectivity check comes first before prepareData
|
227
224
|
setHeadlessMode(updatedArgvs.browserToRun, updatedArgvs.headless);
|
228
|
-
|
229
|
-
// let chromeDataDir = null;
|
230
|
-
// let edgeDataDir = null;
|
231
|
-
// Empty string for profile directory will use incognito mode in playwright
|
232
|
-
let clonedDataDir = '';
|
233
225
|
const statuses = constants.urlCheckStatuses;
|
234
226
|
|
235
|
-
const
|
236
|
-
updatedArgvs.browserToRun = browserToRun;
|
237
|
-
clonedDataDir = clonedBrowserDataDir;
|
238
|
-
|
239
|
-
if (updatedArgvs.customDevice === 'Desktop' || updatedArgvs.customDevice === 'Mobile') {
|
240
|
-
updatedArgvs.deviceChosen = argvs.customDevice;
|
241
|
-
delete updatedArgvs.customDevice;
|
242
|
-
}
|
227
|
+
const data = await prepareData(updatedArgvs);
|
243
228
|
|
244
|
-
|
245
|
-
// for use in crawlDomain & crawlSitemap's preLaunchHook
|
246
|
-
updatedArgvs.playwrightDeviceDetailsObject = getPlaywrightDeviceDetailsObject(
|
247
|
-
updatedArgvs.deviceChosen,
|
248
|
-
updatedArgvs.customDevice,
|
249
|
-
updatedArgvs.viewportWidth,
|
250
|
-
);
|
229
|
+
constants.userDataDirectory = data.userDataDirectory;
|
251
230
|
|
252
231
|
const res = await checkUrl(
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
parseHeaders(updatedArgvs.header),
|
232
|
+
data.type,
|
233
|
+
data.entryUrl,
|
234
|
+
data.browser,
|
235
|
+
data.userDataDirectory,
|
236
|
+
data.playwrightDeviceDetailsObject,
|
237
|
+
data.extraHTTPHeaders
|
260
238
|
);
|
261
239
|
|
262
240
|
if (res.httpStatus) consoleLogger.info(`Connectivity Check HTTP Response Code: ${res.httpStatus}`);
|
263
241
|
|
264
242
|
switch (res.status) {
|
265
243
|
case statuses.success.code: {
|
266
|
-
|
244
|
+
data.url = res.url;
|
267
245
|
if (process.env.OOBEE_VALIDATE_URL) {
|
268
246
|
console.log('Url is valid');
|
269
247
|
process.exit(0);
|
@@ -298,8 +276,8 @@ const scanInit = async (argvs: Answers): Promise<string> => {
|
|
298
276
|
|
299
277
|
const finalFilePath = getFileSitemap(updatedArgvs.url);
|
300
278
|
if (finalFilePath) {
|
301
|
-
|
302
|
-
|
279
|
+
data.isLocalFileScan = true;
|
280
|
+
data.url = finalFilePath;
|
303
281
|
|
304
282
|
if (process.env.OOBEE_VALIDATE_URL) {
|
305
283
|
console.log('Url is valid');
|
@@ -335,25 +313,9 @@ const scanInit = async (argvs: Answers): Promise<string> => {
|
|
335
313
|
break;
|
336
314
|
}
|
337
315
|
|
338
|
-
|
339
|
-
updatedArgvs.strategy = 'same-domain';
|
340
|
-
}
|
341
|
-
|
342
|
-
const data = await prepareData(updatedArgvs);
|
316
|
+
deleteClonedProfiles(data.browser, data.randomToken);
|
343
317
|
|
344
|
-
// File clean up after url check
|
345
|
-
// files will clone a second time below if url check passes
|
346
318
|
if (process.env.OOBEE_VERBOSE) {
|
347
|
-
deleteClonedProfiles(data.browser, data.randomToken);
|
348
|
-
} else {
|
349
|
-
deleteClonedProfiles(data.browser); // first deletion
|
350
|
-
}
|
351
|
-
|
352
|
-
if (updatedArgvs.exportDirectory) {
|
353
|
-
constants.exportDirectory = updatedArgvs.exportDirectory;
|
354
|
-
}
|
355
|
-
|
356
|
-
if (process.env.RUNNING_FROM_PH_GUI || process.env.OOBEE_VERBOSE) {
|
357
319
|
const randomTokenMessage = {
|
358
320
|
type: 'randomToken',
|
359
321
|
payload: `${data.randomToken}`,
|
@@ -364,25 +326,16 @@ const scanInit = async (argvs: Answers): Promise<string> => {
|
|
364
326
|
}
|
365
327
|
|
366
328
|
const screenToScan = getScreenToScan(
|
367
|
-
|
368
|
-
|
369
|
-
|
329
|
+
data.deviceChosen,
|
330
|
+
data.customDevice,
|
331
|
+
data.viewportWidth,
|
370
332
|
);
|
371
333
|
|
372
|
-
// Clone profiles a second time
|
373
|
-
clonedDataDir = getClonedProfilesWithRandomToken(data.browser, data.randomToken);
|
374
|
-
data.userDataDirectory = clonedDataDir;
|
375
|
-
|
376
334
|
printMessage([`Oobee version: ${appVersion}`, 'Starting scan...'], messageOptions);
|
377
335
|
|
378
336
|
await combineRun(data, screenToScan);
|
379
337
|
|
380
|
-
|
381
|
-
if (process.env.OOBEE_VERBOSE) {
|
382
|
-
deleteClonedProfiles(data.browser, data.randomToken);
|
383
|
-
} else {
|
384
|
-
deleteClonedProfiles(data.browser); // second deletion
|
385
|
-
}
|
338
|
+
deleteClonedProfiles(data.browser, data.randomToken);
|
386
339
|
|
387
340
|
// Delete dataset and request queues
|
388
341
|
cleanUp(data.randomToken);
|
package/src/combine.ts
CHANGED
@@ -5,9 +5,9 @@ import crawlDomain from './crawlers/crawlDomain.js';
|
|
5
5
|
import crawlLocalFile from './crawlers/crawlLocalFile.js';
|
6
6
|
import crawlIntelligentSitemap from './crawlers/crawlIntelligentSitemap.js';
|
7
7
|
import generateArtifacts from './mergeAxeResults.js';
|
8
|
-
import { getHost, createAndUpdateResultsFolders, createDetailsAndLogs } from './utils.js';
|
8
|
+
import { getHost, createAndUpdateResultsFolders, createDetailsAndLogs, cleanUp } from './utils.js';
|
9
9
|
import { ScannerTypes, UrlsCrawled } from './constants/constants.js';
|
10
|
-
import { getBlackListedPatterns, submitForm
|
10
|
+
import { getBlackListedPatterns, submitForm } from './constants/common.js';
|
11
11
|
import { consoleLogger, silentLogger } from './logs.js';
|
12
12
|
import runCustom from './crawlers/runCustom.js';
|
13
13
|
import { alertMessageOptions } from './constants/cliFunctions.js';
|
@@ -55,7 +55,7 @@ const combineRun = async (details: Data, deviceToScan: string) => {
|
|
55
55
|
includeScreenshots, // Include screenshots: if checked, = 'true'
|
56
56
|
followRobots, // Adhere to robots.txt: if checked, = 'true'
|
57
57
|
metadata,
|
58
|
-
customFlowLabel = '
|
58
|
+
customFlowLabel = 'None',
|
59
59
|
extraHTTPHeaders,
|
60
60
|
safeMode,
|
61
61
|
zip,
|
@@ -67,6 +67,12 @@ const combineRun = async (details: Data, deviceToScan: string) => {
|
|
67
67
|
process.env.CRAWLEE_LOG_LEVEL = 'ERROR';
|
68
68
|
process.env.CRAWLEE_STORAGE_DIR = randomToken;
|
69
69
|
|
70
|
+
if (process.env.CRAWLEE_SYSTEM_INFO_V2 === undefined) {
|
71
|
+
// Set the environment variable to enable system info v2
|
72
|
+
// Resolves issue with when wmic is not installed on Windows
|
73
|
+
process.env.CRAWLEE_SYSTEM_INFO_V2 = '1';
|
74
|
+
}
|
75
|
+
|
70
76
|
const host = type === ScannerTypes.SITEMAP || type === ScannerTypes.LOCALFILE ? '' : getHost(url);
|
71
77
|
|
72
78
|
let blacklistedPatterns: string[] | null = null;
|
@@ -79,7 +85,7 @@ const combineRun = async (details: Data, deviceToScan: string) => {
|
|
79
85
|
|
80
86
|
// remove basic-auth credentials from URL
|
81
87
|
const finalUrl = !(type === ScannerTypes.SITEMAP || type === ScannerTypes.LOCALFILE)
|
82
|
-
?
|
88
|
+
? new URL(url)
|
83
89
|
: new URL(pathToFileURL(url));
|
84
90
|
|
85
91
|
// Use the string version of finalUrl to reduce logic at submitForm
|
@@ -252,10 +258,18 @@ const combineRun = async (details: Data, deviceToScan: string) => {
|
|
252
258
|
metadata,
|
253
259
|
);
|
254
260
|
} else {
|
261
|
+
|
262
|
+
// No page were scanned because the URL loaded does not meet the crawler requirements
|
255
263
|
printMessage([`No pages were scanned.`], alertMessageOptions);
|
264
|
+
cleanUp(randomToken);
|
265
|
+
process.exit(1);
|
256
266
|
}
|
257
267
|
} else {
|
268
|
+
|
269
|
+
// No page were scanned because the URL loaded does not meet the crawler requirements
|
258
270
|
printMessage([`No pages were scanned.`], alertMessageOptions);
|
271
|
+
cleanUp(randomToken);
|
272
|
+
process.exit(1);
|
259
273
|
}
|
260
274
|
};
|
261
275
|
|