@govtechsg/oobee 0.10.94 → 0.10.95
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/dist/combine.js +7 -0
- package/dist/constants/common.js +12 -0
- package/dist/generateHtmlReport.js +12 -1
- package/dist/logs.js +6 -0
- package/dist/mergeAxeResults/jsonArtifacts.js +6 -1
- package/dist/mergeAxeResults.js +41 -15
- package/dist/utils.js +7 -0
- package/oobee-client-scanner.js +2 -2
- package/package.json +1 -1
- package/src/combine.ts +7 -0
- package/src/constants/common.ts +13 -0
- package/src/generateHtmlReport.ts +13 -1
- package/src/logs.ts +6 -0
- package/src/mergeAxeResults/jsonArtifacts.ts +6 -1
- package/src/mergeAxeResults.ts +41 -15
- package/src/utils.ts +6 -0
- /package/{67e8137b-1939-4253-8f11-a82bc833cfcb.txt → fb5db217-5ab7-4120-b33b-71fa69b454d0.txt} +0 -0
package/dist/combine.js
CHANGED
|
@@ -45,6 +45,13 @@ const combineRun = async (details, deviceToScan) => {
|
|
|
45
45
|
consoleLogger.info(`Suppressed Crawlee ps-tree locale error: ${err.message}`);
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
|
+
// Suppress stale Playwright in-process connection errors that fire asynchronously
|
|
49
|
+
// after the browser is closed in writeSummaryPdf. The deferred IPC message arrives
|
|
50
|
+
// via setImmediate after the browser instance has already been disposed.
|
|
51
|
+
if (err.message?.includes('was not bound in the connection')) {
|
|
52
|
+
consoleLogger.info(`Suppressed Playwright post-close connection error: ${err.message}`);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
48
55
|
throw err;
|
|
49
56
|
};
|
|
50
57
|
process.on('uncaughtException', psTreeHandler);
|
package/dist/constants/common.js
CHANGED
|
@@ -1238,6 +1238,18 @@ export const getBrowserToRun = (randomToken, preferredBrowser, isCli = false) =>
|
|
|
1238
1238
|
* after checkingUrl and unable to utilise same cookie for scan
|
|
1239
1239
|
* */
|
|
1240
1240
|
export const getClonedProfilesWithRandomToken = (browser, randomToken) => {
|
|
1241
|
+
// In Docker, redirect browser temp files away from /tmp to avoid ENOSPC.
|
|
1242
|
+
// Keep the path short — Chrome creates Unix sockets inside TMPDIR-based paths,
|
|
1243
|
+
// and socket paths are limited to 107 bytes on Linux.
|
|
1244
|
+
// Use process.pid to isolate concurrent scan instances.
|
|
1245
|
+
if (fs.existsSync('/.dockerenv')) {
|
|
1246
|
+
const baseDir = getDefaultChromiumDataDir();
|
|
1247
|
+
if (baseDir) {
|
|
1248
|
+
const scanTmpDir = path.join(baseDir, 'tmp', String(process.pid));
|
|
1249
|
+
fs.mkdirSync(scanTmpDir, { recursive: true });
|
|
1250
|
+
process.env.TMPDIR = scanTmpDir;
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1241
1253
|
if (browser === BrowserTypes.CHROME) {
|
|
1242
1254
|
return cloneChromeProfiles(randomToken);
|
|
1243
1255
|
}
|
|
@@ -66,6 +66,17 @@ export const generateHtmlReport = async (resultDir, htmlFilename = 'report') =>
|
|
|
66
66
|
}
|
|
67
67
|
const scanData = JSON.parse(await fs.readFile(scanDataJsonPath, 'utf8'));
|
|
68
68
|
const scanItemsAll = JSON.parse(await fs.readFile(scanItemsJsonPath, 'utf8'));
|
|
69
|
+
// Disk space: passed may be absent from scanItems.json (excluded to reduce disk usage).
|
|
70
|
+
// Provide an empty-category fallback so convertItemsToReferences does not crash.
|
|
71
|
+
// To revert (when passed is restored in scanItems.json), remove this block.
|
|
72
|
+
if (!scanItemsAll.passed) {
|
|
73
|
+
scanItemsAll.passed = {
|
|
74
|
+
description: itemTypeDescription.passed,
|
|
75
|
+
totalItems: 0,
|
|
76
|
+
totalRuleIssues: 0,
|
|
77
|
+
rules: [],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
69
80
|
// Build the lighter scanItems payload used by the HTML report.
|
|
70
81
|
const lightScanItemsPayload = convertItemsToReferences({
|
|
71
82
|
items: scanItemsAll,
|
|
@@ -75,7 +86,7 @@ export const generateHtmlReport = async (resultDir, htmlFilename = 'report') =>
|
|
|
75
86
|
mustFix: ensureCategory(mustFix, 'mustFix'),
|
|
76
87
|
goodToFix: ensureCategory(goodToFix, 'goodToFix'),
|
|
77
88
|
needsReview: ensureCategory(needsReview, 'needsReview'),
|
|
78
|
-
passed: ensureCategory(scanItemsAll.passed
|
|
89
|
+
passed: ensureCategory(scanItemsAll.passed, 'passed'),
|
|
79
90
|
};
|
|
80
91
|
const pagesScanned = Array.isArray(scanData.pagesScanned) ? scanData.pagesScanned : [];
|
|
81
92
|
const pagesNotScanned = Array.isArray(scanData.pagesNotScanned) ? scanData.pagesNotScanned : [];
|
package/dist/logs.js
CHANGED
|
@@ -35,6 +35,10 @@ else {
|
|
|
35
35
|
export const errorsTxtPath = path.join(basePath, `${uuid}.txt`);
|
|
36
36
|
const consoleLogger = createLogger({
|
|
37
37
|
silent: !(process.env.RUNNING_FROM_PH_GUI || process.env.OOBEE_VERBOSE),
|
|
38
|
+
// exitOnError: false — Winston logs uncaught exceptions but does not call process.exit().
|
|
39
|
+
// Process lifecycle is controlled by psTreeHandler in combine.ts, which suppresses known
|
|
40
|
+
// benign errors (e.g. Playwright post-close connection errors) and rethrows real ones.
|
|
41
|
+
exitOnError: false,
|
|
38
42
|
format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat),
|
|
39
43
|
transports: [
|
|
40
44
|
new transports.Console({ level: 'info' }),
|
|
@@ -49,6 +53,8 @@ const consoleLogger = createLogger({
|
|
|
49
53
|
// Also used in common functions to not link internal information
|
|
50
54
|
// if running from mass scanner, log out errors in console
|
|
51
55
|
const silentLogger = createLogger({
|
|
56
|
+
// exitOnError: false — see consoleLogger comment above.
|
|
57
|
+
exitOnError: false,
|
|
52
58
|
format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat),
|
|
53
59
|
transports: [
|
|
54
60
|
new transports.File({
|
|
@@ -227,7 +227,12 @@ const writeJsonFileAndCompressedJsonFile = async (data, storagePath, filename, i
|
|
|
227
227
|
const writeJsonAndBase64Files = async (allIssues, storagePath, itemsStore) => {
|
|
228
228
|
const { items, ...rest } = allIssues;
|
|
229
229
|
const { jsonFilePath: scanDataJsonFilePath, base64FilePath: scanDataBase64FilePath } = await writeJsonFileAndCompressedJsonFile(rest, storagePath, 'scanData');
|
|
230
|
-
|
|
230
|
+
// Disk space: passed items excluded from scanItems.json to reduce disk usage.
|
|
231
|
+
// Passed counts are still in scanData.json and the embedded report payload (scanItems-light).
|
|
232
|
+
// To revert, remove the destructure line and restore the original argument:
|
|
233
|
+
// { oobeeAppVersion: allIssues.oobeeAppVersion, ...items }
|
|
234
|
+
const { passed: _passedItems, ...itemsWithoutPassed } = items;
|
|
235
|
+
const { jsonFilePath: scanItemsJsonFilePath, base64FilePath: scanItemsBase64FilePath } = await writeJsonFileAndCompressedJsonFile({ oobeeAppVersion: allIssues.oobeeAppVersion, ...itemsWithoutPassed }, storagePath, 'scanItems', itemsStore);
|
|
231
236
|
['mustFix', 'goodToFix', 'needsReview', 'passed'].forEach(category => {
|
|
232
237
|
if (items[category].rules && Array.isArray(items[category].rules)) {
|
|
233
238
|
items[category].rules.forEach(rule => {
|
package/dist/mergeAxeResults.js
CHANGED
|
@@ -256,6 +256,16 @@ const cleanUpJsonFiles = async (filesToDelete) => {
|
|
|
256
256
|
});
|
|
257
257
|
};
|
|
258
258
|
const writeSummaryPdf = async (storagePath, pagesScanned, filename = 'summary', browser, _userDataDirectory) => {
|
|
259
|
+
// Flush stale browser temp files before launching PDF browser (Docker only,
|
|
260
|
+
// where TMPDIR is a per-scan subdirectory we control).
|
|
261
|
+
if (process.env.TMPDIR && fs.existsSync('/.dockerenv')) {
|
|
262
|
+
try {
|
|
263
|
+
fs.emptyDirSync(process.env.TMPDIR);
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
// Best-effort; locked files from prior browser sessions are non-fatal.
|
|
267
|
+
}
|
|
268
|
+
}
|
|
259
269
|
const renderPdfWithBrowser = async (browserToUse) => {
|
|
260
270
|
let browserInstance;
|
|
261
271
|
let context;
|
|
@@ -390,14 +400,21 @@ const pushResults = async (pageResults, allIssues, isCustomFlow, itemsStore) =>
|
|
|
390
400
|
metadata,
|
|
391
401
|
itemsCount: items.length,
|
|
392
402
|
};
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
403
|
+
// Disk space: skip storing passed items in itemsStore.
|
|
404
|
+
// To revert, remove the `if` guard and use the original call directly:
|
|
405
|
+
// await itemsStore.appendPageItems(category, rule, {
|
|
406
|
+
// url, pageTitle, items, pageIndex, pageImagePath, metadata,
|
|
407
|
+
// });
|
|
408
|
+
if (category !== 'passed') {
|
|
409
|
+
await itemsStore.appendPageItems(category, rule, {
|
|
410
|
+
url,
|
|
411
|
+
pageTitle,
|
|
412
|
+
items,
|
|
413
|
+
pageIndex,
|
|
414
|
+
pageImagePath,
|
|
415
|
+
metadata,
|
|
416
|
+
});
|
|
417
|
+
}
|
|
401
418
|
}
|
|
402
419
|
else if (!(url in currRuleFromAllIssues.pagesAffected)) {
|
|
403
420
|
currRuleFromAllIssues.pagesAffected[url] = {
|
|
@@ -405,12 +422,19 @@ const pushResults = async (pageResults, allIssues, isCustomFlow, itemsStore) =>
|
|
|
405
422
|
itemsCount: items.length,
|
|
406
423
|
...(filePath && { filePath }),
|
|
407
424
|
};
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
425
|
+
// Disk space: skip storing passed items in itemsStore.
|
|
426
|
+
// To revert, remove the `if` guard and use the original call directly:
|
|
427
|
+
// await itemsStore.appendPageItems(category, rule, {
|
|
428
|
+
// url, pageTitle, items, ...(filePath && { filePath }),
|
|
429
|
+
// });
|
|
430
|
+
if (category !== 'passed') {
|
|
431
|
+
await itemsStore.appendPageItems(category, rule, {
|
|
432
|
+
url,
|
|
433
|
+
pageTitle,
|
|
434
|
+
items,
|
|
435
|
+
...(filePath && { filePath }),
|
|
436
|
+
});
|
|
437
|
+
}
|
|
414
438
|
}
|
|
415
439
|
}
|
|
416
440
|
}
|
|
@@ -708,7 +732,9 @@ generateJsonFiles = false, preferredBrowser) => {
|
|
|
708
732
|
}
|
|
709
733
|
populateScanPagesDetail(allIssues);
|
|
710
734
|
// Build htmlGroups in a second pass from disk-backed items
|
|
711
|
-
|
|
735
|
+
// Disk space: 'passed' removed from this loop (no items stored in itemsStore for passed).
|
|
736
|
+
// To revert, restore: ['mustFix', 'goodToFix', 'needsReview', 'passed']
|
|
737
|
+
for (const category of ['mustFix', 'goodToFix', 'needsReview']) {
|
|
712
738
|
for (const rule of allIssues.items[category].rules) {
|
|
713
739
|
for await (const entry of itemsStore.readRuleItems(category, rule.rule)) {
|
|
714
740
|
buildHtmlGroups(rule, entry.items, entry.url);
|
package/dist/utils.js
CHANGED
|
@@ -345,6 +345,13 @@ export const cleanUp = async (randomToken, isError = false) => {
|
|
|
345
345
|
catch (error) {
|
|
346
346
|
consoleLogger.warn(`Unable to force remove userDataDirectory: ${error.message}`);
|
|
347
347
|
}
|
|
348
|
+
if (process.env.TMPDIR && fs.existsSync('/.dockerenv'))
|
|
349
|
+
try {
|
|
350
|
+
fs.rmSync(process.env.TMPDIR, { recursive: true, force: true });
|
|
351
|
+
}
|
|
352
|
+
catch (error) {
|
|
353
|
+
consoleLogger.warn(`Unable to force remove browser tmp dir: ${error.message}`);
|
|
354
|
+
}
|
|
348
355
|
if (randomToken !== undefined) {
|
|
349
356
|
const storagePath = getStoragePath(randomToken);
|
|
350
357
|
try {
|
package/oobee-client-scanner.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* DO NOT EDIT MANUALLY. Re-generate with: node dist/generateOobeeClientScanner.js
|
|
4
4
|
*
|
|
5
5
|
* Embedded at generation time:
|
|
6
|
-
* App version : 0.10.
|
|
6
|
+
* App version : 0.10.95
|
|
7
7
|
* Sentry DSN : (from OOBEE_SENTRY_DSN env var or constants.ts default)
|
|
8
8
|
* Sentry SDK : @sentry/browser 10.58.0 (loaded from CDN at runtime)
|
|
9
9
|
*
|
|
@@ -34883,7 +34883,7 @@
|
|
|
34883
34883
|
// ── Sentry browser telemetry (Sentry JS SDK, loaded from CDN) ────────────
|
|
34884
34884
|
|
|
34885
34885
|
var _oobeeSentryDsn = "https://3b8c7ee46b06f33815a1301b6713ebc3@o4509047624761344.ingest.us.sentry.io/4509327783559168";
|
|
34886
|
-
var _oobeeAppVersion = "0.10.
|
|
34886
|
+
var _oobeeAppVersion = "0.10.95";
|
|
34887
34887
|
var _oobeeSentryVersion = "10.58.0";
|
|
34888
34888
|
var _oobeeSentryInitialized = false;
|
|
34889
34889
|
var _oobeeSentryLoadPromise = null;
|
package/package.json
CHANGED
package/src/combine.ts
CHANGED
|
@@ -89,6 +89,13 @@ const combineRun = async (details: Data, deviceToScan: string) => {
|
|
|
89
89
|
consoleLogger.info(`Suppressed Crawlee ps-tree locale error: ${err.message}`);
|
|
90
90
|
return;
|
|
91
91
|
}
|
|
92
|
+
// Suppress stale Playwright in-process connection errors that fire asynchronously
|
|
93
|
+
// after the browser is closed in writeSummaryPdf. The deferred IPC message arrives
|
|
94
|
+
// via setImmediate after the browser instance has already been disposed.
|
|
95
|
+
if (err.message?.includes('was not bound in the connection')) {
|
|
96
|
+
consoleLogger.info(`Suppressed Playwright post-close connection error: ${err.message}`);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
92
99
|
throw err;
|
|
93
100
|
};
|
|
94
101
|
process.on('uncaughtException', psTreeHandler);
|
package/src/constants/common.ts
CHANGED
|
@@ -1497,6 +1497,19 @@ export const getBrowserToRun = (
|
|
|
1497
1497
|
* after checkingUrl and unable to utilise same cookie for scan
|
|
1498
1498
|
* */
|
|
1499
1499
|
export const getClonedProfilesWithRandomToken = (browser: string, randomToken: string): string => {
|
|
1500
|
+
// In Docker, redirect browser temp files away from /tmp to avoid ENOSPC.
|
|
1501
|
+
// Keep the path short — Chrome creates Unix sockets inside TMPDIR-based paths,
|
|
1502
|
+
// and socket paths are limited to 107 bytes on Linux.
|
|
1503
|
+
// Use process.pid to isolate concurrent scan instances.
|
|
1504
|
+
if (fs.existsSync('/.dockerenv')) {
|
|
1505
|
+
const baseDir = getDefaultChromiumDataDir();
|
|
1506
|
+
if (baseDir) {
|
|
1507
|
+
const scanTmpDir = path.join(baseDir, 'tmp', String(process.pid));
|
|
1508
|
+
fs.mkdirSync(scanTmpDir, { recursive: true });
|
|
1509
|
+
process.env.TMPDIR = scanTmpDir;
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1500
1513
|
if (browser === BrowserTypes.CHROME) {
|
|
1501
1514
|
return cloneChromeProfiles(randomToken);
|
|
1502
1515
|
}
|
|
@@ -126,6 +126,18 @@ export const generateHtmlReport = async (
|
|
|
126
126
|
const scanData = JSON.parse(await fs.readFile(scanDataJsonPath, 'utf8'));
|
|
127
127
|
const scanItemsAll = JSON.parse(await fs.readFile(scanItemsJsonPath, 'utf8'));
|
|
128
128
|
|
|
129
|
+
// Disk space: passed may be absent from scanItems.json (excluded to reduce disk usage).
|
|
130
|
+
// Provide an empty-category fallback so convertItemsToReferences does not crash.
|
|
131
|
+
// To revert (when passed is restored in scanItems.json), remove this block.
|
|
132
|
+
if (!scanItemsAll.passed) {
|
|
133
|
+
scanItemsAll.passed = {
|
|
134
|
+
description: itemTypeDescription.passed,
|
|
135
|
+
totalItems: 0,
|
|
136
|
+
totalRuleIssues: 0,
|
|
137
|
+
rules: [],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
129
141
|
// Build the lighter scanItems payload used by the HTML report.
|
|
130
142
|
const lightScanItemsPayload = convertItemsToReferences({
|
|
131
143
|
items: scanItemsAll,
|
|
@@ -141,7 +153,7 @@ export const generateHtmlReport = async (
|
|
|
141
153
|
mustFix: ensureCategory(mustFix, 'mustFix'),
|
|
142
154
|
goodToFix: ensureCategory(goodToFix, 'goodToFix'),
|
|
143
155
|
needsReview: ensureCategory(needsReview, 'needsReview'),
|
|
144
|
-
passed: ensureCategory(scanItemsAll.passed
|
|
156
|
+
passed: ensureCategory(scanItemsAll.passed, 'passed'),
|
|
145
157
|
};
|
|
146
158
|
|
|
147
159
|
const pagesScanned = Array.isArray(scanData.pagesScanned) ? scanData.pagesScanned : [];
|
package/src/logs.ts
CHANGED
|
@@ -39,6 +39,10 @@ export const errorsTxtPath = path.join(basePath, `${uuid}.txt`);
|
|
|
39
39
|
|
|
40
40
|
const consoleLogger = createLogger({
|
|
41
41
|
silent: !(process.env.RUNNING_FROM_PH_GUI || process.env.OOBEE_VERBOSE),
|
|
42
|
+
// exitOnError: false — Winston logs uncaught exceptions but does not call process.exit().
|
|
43
|
+
// Process lifecycle is controlled by psTreeHandler in combine.ts, which suppresses known
|
|
44
|
+
// benign errors (e.g. Playwright post-close connection errors) and rethrows real ones.
|
|
45
|
+
exitOnError: false,
|
|
42
46
|
format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat),
|
|
43
47
|
transports: [
|
|
44
48
|
new transports.Console({ level: 'info' }),
|
|
@@ -54,6 +58,8 @@ const consoleLogger = createLogger({
|
|
|
54
58
|
// Also used in common functions to not link internal information
|
|
55
59
|
// if running from mass scanner, log out errors in console
|
|
56
60
|
const silentLogger = createLogger({
|
|
61
|
+
// exitOnError: false — see consoleLogger comment above.
|
|
62
|
+
exitOnError: false,
|
|
57
63
|
format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormat),
|
|
58
64
|
transports: [
|
|
59
65
|
new transports.File({
|
|
@@ -292,9 +292,14 @@ const writeJsonAndBase64Files = async (
|
|
|
292
292
|
const { items, ...rest } = allIssues;
|
|
293
293
|
const { jsonFilePath: scanDataJsonFilePath, base64FilePath: scanDataBase64FilePath } =
|
|
294
294
|
await writeJsonFileAndCompressedJsonFile(rest, storagePath, 'scanData');
|
|
295
|
+
// Disk space: passed items excluded from scanItems.json to reduce disk usage.
|
|
296
|
+
// Passed counts are still in scanData.json and the embedded report payload (scanItems-light).
|
|
297
|
+
// To revert, remove the destructure line and restore the original argument:
|
|
298
|
+
// { oobeeAppVersion: allIssues.oobeeAppVersion, ...items }
|
|
299
|
+
const { passed: _passedItems, ...itemsWithoutPassed } = items;
|
|
295
300
|
const { jsonFilePath: scanItemsJsonFilePath, base64FilePath: scanItemsBase64FilePath } =
|
|
296
301
|
await writeJsonFileAndCompressedJsonFile(
|
|
297
|
-
{ oobeeAppVersion: allIssues.oobeeAppVersion, ...
|
|
302
|
+
{ oobeeAppVersion: allIssues.oobeeAppVersion, ...itemsWithoutPassed },
|
|
298
303
|
storagePath,
|
|
299
304
|
'scanItems',
|
|
300
305
|
itemsStore,
|
package/src/mergeAxeResults.ts
CHANGED
|
@@ -359,6 +359,16 @@ const writeSummaryPdf = async (
|
|
|
359
359
|
browser: string,
|
|
360
360
|
_userDataDirectory: string,
|
|
361
361
|
) => {
|
|
362
|
+
// Flush stale browser temp files before launching PDF browser (Docker only,
|
|
363
|
+
// where TMPDIR is a per-scan subdirectory we control).
|
|
364
|
+
if (process.env.TMPDIR && fs.existsSync('/.dockerenv')) {
|
|
365
|
+
try {
|
|
366
|
+
fs.emptyDirSync(process.env.TMPDIR);
|
|
367
|
+
} catch {
|
|
368
|
+
// Best-effort; locked files from prior browser sessions are non-fatal.
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
362
372
|
const renderPdfWithBrowser = async (browserToUse: string) => {
|
|
363
373
|
let browserInstance;
|
|
364
374
|
let context;
|
|
@@ -525,26 +535,40 @@ const pushResults = async (pageResults, allIssues, isCustomFlow, itemsStore: Ite
|
|
|
525
535
|
metadata,
|
|
526
536
|
itemsCount: items.length,
|
|
527
537
|
};
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
538
|
+
// Disk space: skip storing passed items in itemsStore.
|
|
539
|
+
// To revert, remove the `if` guard and use the original call directly:
|
|
540
|
+
// await itemsStore.appendPageItems(category, rule, {
|
|
541
|
+
// url, pageTitle, items, pageIndex, pageImagePath, metadata,
|
|
542
|
+
// });
|
|
543
|
+
if (category !== 'passed') {
|
|
544
|
+
await itemsStore.appendPageItems(category, rule, {
|
|
545
|
+
url,
|
|
546
|
+
pageTitle,
|
|
547
|
+
items,
|
|
548
|
+
pageIndex,
|
|
549
|
+
pageImagePath,
|
|
550
|
+
metadata,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
536
553
|
} else if (!(url in currRuleFromAllIssues.pagesAffected)) {
|
|
537
554
|
currRuleFromAllIssues.pagesAffected[url] = {
|
|
538
555
|
pageTitle,
|
|
539
556
|
itemsCount: items.length,
|
|
540
557
|
...(filePath && { filePath }),
|
|
541
558
|
};
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
559
|
+
// Disk space: skip storing passed items in itemsStore.
|
|
560
|
+
// To revert, remove the `if` guard and use the original call directly:
|
|
561
|
+
// await itemsStore.appendPageItems(category, rule, {
|
|
562
|
+
// url, pageTitle, items, ...(filePath && { filePath }),
|
|
563
|
+
// });
|
|
564
|
+
if (category !== 'passed') {
|
|
565
|
+
await itemsStore.appendPageItems(category, rule, {
|
|
566
|
+
url,
|
|
567
|
+
pageTitle,
|
|
568
|
+
items,
|
|
569
|
+
...(filePath && { filePath }),
|
|
570
|
+
});
|
|
571
|
+
}
|
|
548
572
|
}
|
|
549
573
|
}
|
|
550
574
|
}
|
|
@@ -924,7 +948,9 @@ const generateArtifacts = async (
|
|
|
924
948
|
populateScanPagesDetail(allIssues);
|
|
925
949
|
|
|
926
950
|
// Build htmlGroups in a second pass from disk-backed items
|
|
927
|
-
|
|
951
|
+
// Disk space: 'passed' removed from this loop (no items stored in itemsStore for passed).
|
|
952
|
+
// To revert, restore: ['mustFix', 'goodToFix', 'needsReview', 'passed']
|
|
953
|
+
for (const category of ['mustFix', 'goodToFix', 'needsReview'] as const) {
|
|
928
954
|
for (const rule of allIssues.items[category].rules) {
|
|
929
955
|
for await (const entry of itemsStore.readRuleItems(category, rule.rule)) {
|
|
930
956
|
buildHtmlGroups(rule, entry.items, entry.url);
|
package/src/utils.ts
CHANGED
|
@@ -388,6 +388,12 @@ export const cleanUp = async (randomToken?: string, isError: boolean = false): P
|
|
|
388
388
|
consoleLogger.warn(`Unable to force remove userDataDirectory: ${error.message}`);
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
+
if (process.env.TMPDIR && fs.existsSync('/.dockerenv')) try {
|
|
392
|
+
fs.rmSync(process.env.TMPDIR, { recursive: true, force: true });
|
|
393
|
+
} catch (error) {
|
|
394
|
+
consoleLogger.warn(`Unable to force remove browser tmp dir: ${error.message}`);
|
|
395
|
+
}
|
|
396
|
+
|
|
391
397
|
if (randomToken !== undefined) {
|
|
392
398
|
const storagePath = getStoragePath(randomToken);
|
|
393
399
|
|
/package/{67e8137b-1939-4253-8f11-a82bc833cfcb.txt → fb5db217-5ab7-4120-b33b-71fa69b454d0.txt}
RENAMED
|
File without changes
|