html-snapshots 0.18.2 → 0.19.0
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/.eslintrc.json +4 -5
- package/README.md +73 -68
- package/examples/custom/myFilter.js +2 -2
- package/examples/custom/package-lock.json +1012 -77
- package/examples/custom/package.json +1 -1
- package/examples/custom/snapshot.js +8 -10
- package/examples/debug-phantomjs/package-lock.json +76 -76
- package/examples/debug-phantomjs/package.json +1 -1
- package/examples/debug-phantomjs/snapshot.js +12 -14
- package/examples/html5rocks/package-lock.json +1379 -78
- package/examples/html5rocks/package.json +1 -1
- package/examples/html5rocks/snapshot.js +15 -18
- package/examples/process-limit/package-lock.json +1379 -78
- package/examples/process-limit/package.json +1 -1
- package/examples/process-limit/snapshot.js +8 -10
- package/examples/simple-promise/package-lock.json +1379 -78
- package/examples/simple-promise/package.json +1 -1
- package/examples/simple-promise/snapshot.js +6 -8
- package/examples/sitemap-index/package-lock.json +1378 -77
- package/examples/sitemap-index/package.json +1 -1
- package/examples/sitemap-index/snapshot.js +6 -6
- package/examples/utils/index.js +2 -4
- package/examples/verbose/package-lock.json +1380 -78
- package/examples/verbose/package.json +1 -1
- package/examples/verbose/snapshot.js +11 -14
- package/lib/async/index.js +0 -1
- package/lib/common/index.js +1 -1
- package/lib/common/sitemap/index.js +16 -0
- package/lib/common/sitemap/sitemap-collection.js +94 -0
- package/lib/common/sitemap/sitemap-index.js +68 -0
- package/lib/common/{sitemap.js → sitemap/sitemap.js} +68 -57
- package/lib/html-snapshots.js +0 -1
- package/lib/input-generators/array.js +0 -1
- package/lib/input-generators/robots.js +98 -58
- package/lib/input-generators/sitemap-index.js +3 -124
- package/lib/input-generators/sitemap.js +3 -7
- package/lib/input-generators/textfile.js +2 -6
- package/package.json +6 -6
- package/test/helpers/options.js +4 -2
- package/test/mocha/html-snapshots/process-limit.js +46 -48
- package/test/mocha/html-snapshots/robots.js +156 -138
- package/test/mocha/html-snapshots/server/test_robots.txt +13 -0
- package/test/mocha/html-snapshots/server/test_robots_sitemap.txt +15 -0
- package/test/mocha/html-snapshots/server/test_robots_sitemap.xml +22 -0
- package/test/mocha/html-snapshots/sitemap-index.js +58 -57
- package/test/mocha/html-snapshots/snapshot-scripts.js +55 -54
- package/test/mocha/html-snapshots/test.js +16 -16
- package/test/mocha/html-snapshots/test_robots.txt +0 -2
- package/test/mocha/html-snapshots/utils.js +0 -1
- package/test/mocha/input-generators/server/test_robots.txt +0 -2
- package/test/mocha/input-generators/server/test_robots_bad.txt +0 -2
- package/test/mocha/input-generators/server/test_robots_sitemap.txt +17 -0
- package/test/mocha/input-generators/server/test_robots_sitemap_bad.txt +17 -0
- package/test/mocha/input-generators/server/test_robots_sitemap_multi.txt +18 -0
- package/test/mocha/input-generators/server/test_sitemap_index_empty.xml +3 -0
- package/test/mocha/input-generators/server/test_sitemap_index_malformed.xml +2 -0
- package/test/mocha/input-generators/sitemap-index.js +65 -9
- package/test/mocha/input-generators/test.js +276 -280
- package/test/mocha/input-generators/test_robots.txt +0 -2
- package/test/mocha/input-generators/test_robots_bad.txt +0 -2
- package/test/mocha/input-generators/test_robots_sitemap.txt +17 -0
- package/test/mocha/input-generators/test_robots_sitemap_bad.txt +17 -0
- package/test/mocha/input-generators/test_robots_sitemap_multi.txt +18 -0
- package/lib/common/node.js +0 -26
- package/test/mocha/common/node.js +0 -100
|
@@ -7,16 +7,8 @@
|
|
|
7
7
|
* Copyright (c) 2013 - 2022 Alex Grant, LocalNerve, contributors
|
|
8
8
|
* Licensed under the MIT license.
|
|
9
9
|
*/
|
|
10
|
-
/* global Promise */
|
|
11
|
-
|
|
12
|
-
const fs = require("fs");
|
|
13
|
-
const pathLib = require("path");
|
|
14
|
-
const _ = require("lodash");
|
|
15
|
-
const mkdirp = require("mkdirp");
|
|
16
|
-
const xml2js = require("xml2js");
|
|
17
10
|
const common = require("../common");
|
|
18
|
-
const
|
|
19
|
-
const smLib = require("../common/sitemap");
|
|
11
|
+
const { sitemap: sm } = require("../common/sitemap");
|
|
20
12
|
const base = require("./_base");
|
|
21
13
|
|
|
22
14
|
// The default options
|
|
@@ -44,116 +36,6 @@ const sitemapIndex = {
|
|
|
44
36
|
}
|
|
45
37
|
};
|
|
46
38
|
|
|
47
|
-
/**
|
|
48
|
-
* Make sure path exists so a sitemap write can succeed.
|
|
49
|
-
*
|
|
50
|
-
* @param {String} outputPath - File path and name.
|
|
51
|
-
* @param {Function} callback - Completion callback.
|
|
52
|
-
*/
|
|
53
|
-
function prepareWrite (outputPath, callback) {
|
|
54
|
-
const path = pathLib.parse(outputPath);
|
|
55
|
-
const dir = pathLib.join(path.root, path.dir);
|
|
56
|
-
mkdirp(dir).then(() => callback()).catch(callback);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Parse a sitemap, generate input, and optionally update the local file
|
|
61
|
-
* for sitemapPolicy purposes.
|
|
62
|
-
* This writes the sitemap files out EVEN IF sitemapPolicy is false.
|
|
63
|
-
* The thinking is that it's better/cheaper to do this b/c if sitemapPolicy is
|
|
64
|
-
* enabled later, then there is something to compare against, for more savings.
|
|
65
|
-
*
|
|
66
|
-
* @param {Object} options - Sitemap options.
|
|
67
|
-
* @param {Object} options.__sitemapIndex - Sitemap Index options.
|
|
68
|
-
* @param {String} document - xml document string.
|
|
69
|
-
* @param {Function} callback - A completion callback.
|
|
70
|
-
*/
|
|
71
|
-
function processSitemap (options, document, callback) {
|
|
72
|
-
smLib.parse(options, document, err => {
|
|
73
|
-
const sitemapIndexOpts = options.__sitemapIndex;
|
|
74
|
-
const outputPath = base.outputFile(sitemapIndexOpts, options.source);
|
|
75
|
-
|
|
76
|
-
if (!err && sitemapIndexOpts.sitemapOutputDir) {
|
|
77
|
-
prepareWrite(outputPath, err => {
|
|
78
|
-
if (!err) {
|
|
79
|
-
fs.writeFile(outputPath, document, callback);
|
|
80
|
-
} else {
|
|
81
|
-
callback(common.prependMsgToErr(err, outputPath, true));
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
} else {
|
|
85
|
-
callback(err);
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Parse a sitemap index document
|
|
92
|
-
* For each qualifying sitemap element, download, parse the sitemap.
|
|
93
|
-
* Stops processing if an error occurs.
|
|
94
|
-
*
|
|
95
|
-
* @param {Object} options - Sitemap options.
|
|
96
|
-
* @param {Boolean} options.sitemapPolicy - True if sitemap policy should be used.
|
|
97
|
-
* @param {String} document - xml document string.
|
|
98
|
-
* @param {Function} callback - A completion callback.
|
|
99
|
-
*/
|
|
100
|
-
function parse (options, document, callback) {
|
|
101
|
-
xml2js.parseString(document, {
|
|
102
|
-
trim: true,
|
|
103
|
-
normalizeTags: true,
|
|
104
|
-
normalize: true
|
|
105
|
-
}, (err, result) => {
|
|
106
|
-
const sitemapUrls = [];
|
|
107
|
-
const sitemapIndexOptions = Object.assign({}, options, {
|
|
108
|
-
outputPath: undefined
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
if (!err) {
|
|
112
|
-
// Check if we should process each sitemap in the index.
|
|
113
|
-
_.forEach(
|
|
114
|
-
// if the sitemap index is malformed, just blow up
|
|
115
|
-
result.sitemapindex.sitemap,
|
|
116
|
-
sitemapNode => {
|
|
117
|
-
// optionally ignore current sitemaps by sitemap policy
|
|
118
|
-
const shouldProcess = !options.sitemapPolicy ||
|
|
119
|
-
!smLib.stillCurrent(sitemapNode, sitemapIndexOptions);
|
|
120
|
-
|
|
121
|
-
if (shouldProcess) {
|
|
122
|
-
// if sitemap index is malformed, just blow up
|
|
123
|
-
sitemapUrls.push(sitemapNode.loc[0]);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
// Edge case message for clarity
|
|
129
|
-
if (sitemapUrls.length === 0) {
|
|
130
|
-
console.log("[*] No sitemaps qualified for processing");
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Get all the sitemaps, parse them, and generate input for each
|
|
134
|
-
Promise.all(sitemapUrls.map(sitemapUrl => {
|
|
135
|
-
const sitemapOptions = Object.assign({}, options, {
|
|
136
|
-
source: sitemapUrl,
|
|
137
|
-
input: "sitemap",
|
|
138
|
-
sitemapOutputDir: false,
|
|
139
|
-
__sitemapIndex: sitemapIndexOptions
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
console.log(`[+] Loading the sitemap: '${sitemapUrl}'`);
|
|
143
|
-
|
|
144
|
-
return nodeCall(smLib.getUrl, sitemapOptions, processSitemap);
|
|
145
|
-
}))
|
|
146
|
-
.then(() => {
|
|
147
|
-
// Ignore the array of results to this function
|
|
148
|
-
callback();
|
|
149
|
-
})
|
|
150
|
-
.catch(callback);
|
|
151
|
-
} else {
|
|
152
|
-
callback(err);
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
39
|
/**
|
|
158
40
|
* generateInput
|
|
159
41
|
*
|
|
@@ -165,11 +47,8 @@ function parse (options, document, callback) {
|
|
|
165
47
|
* @param {String} options.source - Sitemap URL or file path.
|
|
166
48
|
*/
|
|
167
49
|
function generateInput (options) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
options,
|
|
171
|
-
parse
|
|
172
|
-
)
|
|
50
|
+
const retrieve = common.isUrl(options.source) ? sm.getUrl : sm.getFile;
|
|
51
|
+
return retrieve(options, sm.parse)
|
|
173
52
|
.catch(err => {
|
|
174
53
|
options._abort(err);
|
|
175
54
|
})
|
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const common = require("../common");
|
|
12
|
-
const
|
|
13
|
-
const smLib = require("../common/sitemap");
|
|
12
|
+
const { sitemap: sm } = require("../common/sitemap");
|
|
14
13
|
const base = require("./_base");
|
|
15
14
|
|
|
16
15
|
// The default options
|
|
@@ -48,11 +47,8 @@ const sitemap = {
|
|
|
48
47
|
* @returns {Promise} Resolves to undefined on completion.
|
|
49
48
|
*/
|
|
50
49
|
function generateInput (options) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
options,
|
|
54
|
-
smLib.parse
|
|
55
|
-
)
|
|
50
|
+
const retrieve = common.isUrl(options.source) ? sm.getUrl : sm.getFile;
|
|
51
|
+
return retrieve(options, sm.parse)
|
|
56
52
|
.catch(err => {
|
|
57
53
|
options._abort(err);
|
|
58
54
|
})
|
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
* Licensed under the MIT license.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const fs = require("fs");
|
|
11
|
+
const fs = require("fs").promises;
|
|
12
12
|
const base = require("./_base");
|
|
13
13
|
const common = require("../common");
|
|
14
|
-
const nodeCall = require("../common/node");
|
|
15
14
|
|
|
16
15
|
// The default options
|
|
17
16
|
const defaults = Object.freeze({
|
|
@@ -44,10 +43,7 @@ const textfile = {
|
|
|
44
43
|
* @returns {Promise} resolves when complete.
|
|
45
44
|
*/
|
|
46
45
|
function generateInput (options) {
|
|
47
|
-
return
|
|
48
|
-
fs.readFile,
|
|
49
|
-
options.source
|
|
50
|
-
)
|
|
46
|
+
return fs.readFile(options.source)
|
|
51
47
|
.catch(err => {
|
|
52
48
|
options._abort(err);
|
|
53
49
|
})
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "html-snapshots",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Alex Grant",
|
|
6
6
|
"email": "alex@localnerve.com",
|
|
7
|
-
"url": "
|
|
7
|
+
"url": "https://www.localnerve.com"
|
|
8
8
|
},
|
|
9
9
|
"homepage": "https://github.com/localnerve/html-snapshots",
|
|
10
10
|
"description": "A selector-based html snapshot tool using PhantomJS that sources sitemap.xml, robots.txt, or arbitrary input",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"test:common": "mocha test/mocha/common/*.js --exit --reporter spec",
|
|
25
25
|
"test:input-generators": "mocha test/mocha/input-generators/*.js --exit --reporter spec",
|
|
26
26
|
"test:html-snapshots": "mocha test/mocha/html-snapshots/*.js --exit --reporter spec",
|
|
27
|
+
"test:html-snapshots:debug": "mocha --inspect-brk test/mocha/html-snapshots/*.js --exit --reporter spec",
|
|
27
28
|
"test:cover": "c8 -- npm test",
|
|
28
29
|
"validate": "npm ls"
|
|
29
30
|
},
|
|
@@ -52,16 +53,15 @@
|
|
|
52
53
|
"lodash": "4.17.21",
|
|
53
54
|
"mkdirp": "1.0.4",
|
|
54
55
|
"phantomjs-prebuilt": "2.1.16",
|
|
55
|
-
"
|
|
56
|
+
"got": "12.5.0",
|
|
56
57
|
"rimraf": "3.0.2",
|
|
57
58
|
"xml2js": "0.4.23"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
|
-
"
|
|
61
|
-
"eslint": "8.14.0",
|
|
61
|
+
"eslint": "8.23.1",
|
|
62
62
|
"express": "4.18.1",
|
|
63
63
|
"mocha": "10.0.0",
|
|
64
|
-
"c8": "7.
|
|
64
|
+
"c8": "7.12.0",
|
|
65
65
|
"precommit-hook": "3.0.0",
|
|
66
66
|
"server-destroy": "1.0.1",
|
|
67
67
|
"sitemap-xml": "0.1.0",
|
package/test/helpers/options.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* If a global phantomjs is defined, decorates html-snapshots options to specify that global
|
|
10
10
|
* In some test environments (travis), local phantomjs will not install if a global is found.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
const assert = require("assert");
|
|
13
13
|
|
|
14
14
|
// @0.12.0, on Travis-ci phantomjs2 WILL install local WITH the older global.
|
|
15
15
|
// So reverting back to decorateLocal only.
|
|
@@ -19,7 +19,9 @@ var assert = require("assert");
|
|
|
19
19
|
function fillAbort (options) {
|
|
20
20
|
if (!options._abort) {
|
|
21
21
|
options._abort = function (err) {
|
|
22
|
-
|
|
22
|
+
const msg = `[options._abort] called: ${err.toString()}`;
|
|
23
|
+
console.log(`@@@ ${msg}`);
|
|
24
|
+
assert.fail(msg);
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
}
|
|
@@ -4,41 +4,41 @@
|
|
|
4
4
|
* Copyright (c) 2013 - 2022, Alex Grant, LocalNerve, contributors
|
|
5
5
|
*/
|
|
6
6
|
/* global it */
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
7
|
+
const assert = require("assert");
|
|
8
|
+
const rimraf = require("rimraf").sync;
|
|
9
|
+
const utils = require("./utils");
|
|
10
|
+
const optHelp = require("../../helpers/options");
|
|
11
|
+
const ss = require("../../../lib/html-snapshots");
|
|
12
|
+
const robotsTests = require("./robots");
|
|
13
|
+
|
|
14
|
+
const {
|
|
15
|
+
timeout,
|
|
16
|
+
outputDir,
|
|
17
|
+
cleanup,
|
|
18
|
+
killSpawnedProcesses,
|
|
19
|
+
countSpawnedProcesses,
|
|
20
|
+
unexpectedError,
|
|
21
|
+
multiError,
|
|
22
|
+
checkActualFiles
|
|
23
|
+
} = utils;
|
|
24
|
+
|
|
25
|
+
const urls = robotsTests.urlCount;
|
|
26
26
|
|
|
27
27
|
function processLimitTests (options) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
const { port, localRobotsFile: inputFile } = options;
|
|
29
|
+
const pollInterval = 50;
|
|
30
|
+
let phantomCount = 0;
|
|
31
|
+
let timer;
|
|
32
32
|
|
|
33
33
|
function completeTest (done, processLimit, e, files) {
|
|
34
|
-
|
|
35
|
-
new Error(phantomCount
|
|
34
|
+
const countError = phantomCount ?
|
|
35
|
+
new Error(`${phantomCount} exceeded processLimit ${processLimit}`) :
|
|
36
36
|
undefined;
|
|
37
37
|
|
|
38
38
|
clearInterval(timer);
|
|
39
39
|
|
|
40
40
|
if (files) {
|
|
41
|
-
checkActualFiles(files).then(
|
|
41
|
+
checkActualFiles(files).then(() => {
|
|
42
42
|
cleanup(done, multiError(e, countError));
|
|
43
43
|
});
|
|
44
44
|
} else {
|
|
@@ -48,8 +48,8 @@ function processLimitTests (options) {
|
|
|
48
48
|
|
|
49
49
|
return function () {
|
|
50
50
|
it("should limit as expected", function (done) {
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
const processLimit = urls - 1;
|
|
52
|
+
const complete = completeTest.bind(null, done, processLimit);
|
|
53
53
|
|
|
54
54
|
if (process.platform === "win32") {
|
|
55
55
|
assert.ok(true, "Skipping posix compliant tests for processLimit");
|
|
@@ -58,15 +58,15 @@ function processLimitTests (options) {
|
|
|
58
58
|
rimraf(outputDir);
|
|
59
59
|
|
|
60
60
|
killSpawnedProcesses(function (err) {
|
|
61
|
-
|
|
61
|
+
const options = {
|
|
62
62
|
source: inputFile,
|
|
63
63
|
hostname: "localhost",
|
|
64
|
-
port: port,
|
|
65
64
|
selector: "#dynamic-content",
|
|
66
|
-
outputDir: outputDir,
|
|
67
65
|
outputDirClean: true,
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
outputDir,
|
|
67
|
+
timeout,
|
|
68
|
+
processLimit,
|
|
69
|
+
port
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
if (err) {
|
|
@@ -74,14 +74,14 @@ function processLimitTests (options) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
ss.run(optHelp.decorate(options))
|
|
77
|
-
.then(
|
|
77
|
+
.then(() => {
|
|
78
78
|
complete();
|
|
79
79
|
})
|
|
80
|
-
.catch(
|
|
80
|
+
.catch(e => {
|
|
81
81
|
complete(e || unexpectedError, e.notCompleted);
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
-
timer = setInterval(
|
|
84
|
+
timer = setInterval(() => {
|
|
85
85
|
countSpawnedProcesses(function (count) {
|
|
86
86
|
// console.log("@@@ DEBUG @@@ phantom count: "+count);
|
|
87
87
|
if (count > processLimit) {
|
|
@@ -95,8 +95,8 @@ function processLimitTests (options) {
|
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
it("should limit to just one process", function (done) {
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
const processLimit = 1;
|
|
99
|
+
const complete = completeTest.bind(null, done, processLimit);
|
|
100
100
|
|
|
101
101
|
if (process.platform === "win32") {
|
|
102
102
|
assert.ok(true, "Skipping posix compliant tests for processLimit");
|
|
@@ -105,15 +105,15 @@ function processLimitTests (options) {
|
|
|
105
105
|
rimraf(outputDir);
|
|
106
106
|
|
|
107
107
|
killSpawnedProcesses(function (err) {
|
|
108
|
-
|
|
108
|
+
const options = {
|
|
109
109
|
source: inputFile,
|
|
110
110
|
hostname: "localhost",
|
|
111
|
-
port: port,
|
|
112
111
|
selector: "#dynamic-content",
|
|
113
|
-
outputDir: outputDir,
|
|
114
112
|
outputDirClean: true,
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
outputDir,
|
|
114
|
+
timeout,
|
|
115
|
+
processLimit,
|
|
116
|
+
port
|
|
117
117
|
};
|
|
118
118
|
|
|
119
119
|
if (err) {
|
|
@@ -121,10 +121,10 @@ function processLimitTests (options) {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
ss.run(optHelp.decorate(options))
|
|
124
|
-
.then(
|
|
124
|
+
.then(() => {
|
|
125
125
|
complete();
|
|
126
126
|
})
|
|
127
|
-
.catch(
|
|
127
|
+
.catch(e => {
|
|
128
128
|
complete(e || unexpectedError, e.notCompleted);
|
|
129
129
|
});
|
|
130
130
|
|
|
@@ -144,7 +144,5 @@ function processLimitTests (options) {
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
module.exports = {
|
|
147
|
-
testSuite: processLimitTests
|
|
148
|
-
inputFile: inputFile,
|
|
149
|
-
urlCount: urls
|
|
147
|
+
testSuite: processLimitTests
|
|
150
148
|
};
|