html-snapshots 0.19.0 → 1.0.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.
Files changed (44) hide show
  1. package/.github/workflows/verify.yml +2 -2
  2. package/HISTORY.md +42 -0
  3. package/README.md +92 -244
  4. package/examples/README.md +149 -0
  5. package/examples/custom/package-lock.json +1090 -9
  6. package/examples/custom/package.json +1 -1
  7. package/examples/debug-phantomjs/package.json +1 -1
  8. package/examples/debug-phantomjs/snapshot.js +1 -0
  9. package/examples/debug-puppeteer/README.md +18 -0
  10. package/examples/debug-puppeteer/package-lock.json +2804 -0
  11. package/examples/debug-puppeteer/package.json +12 -0
  12. package/examples/debug-puppeteer/snapshot.js +30 -0
  13. package/examples/html5rocks/package-lock.json +2 -2
  14. package/examples/html5rocks/package.json +1 -1
  15. package/examples/html5rocks/snapshot.js +0 -6
  16. package/examples/process-limit/package-lock.json +2 -2
  17. package/examples/process-limit/package.json +1 -1
  18. package/examples/simple-promise/package-lock.json +2 -2
  19. package/examples/simple-promise/package.json +1 -1
  20. package/examples/sitemap-index/package-lock.json +2 -2
  21. package/examples/sitemap-index/package.json +1 -1
  22. package/examples/verbose/package-lock.json +3 -4
  23. package/examples/verbose/package.json +1 -1
  24. package/examples/verbose/snapshot.js +1 -0
  25. package/lib/html-snapshots.js +87 -4
  26. package/lib/input-generators/_base.js +7 -1
  27. package/lib/puppeteer/index.js +98 -0
  28. package/lib/puppeteer/removeScripts.js +8 -0
  29. package/package.json +6 -2
  30. package/test/mocha/browsers/puppeteer.js +106 -0
  31. package/test/mocha/browsers/server/index.html +9 -0
  32. package/test/mocha/browsers/test.js +11 -0
  33. package/test/mocha/html-snapshots/basics.js +60 -47
  34. package/test/mocha/html-snapshots/phantomjs-options.js +54 -60
  35. package/test/mocha/html-snapshots/process-limit.js +100 -92
  36. package/test/mocha/html-snapshots/puppeteer.js +47 -0
  37. package/test/mocha/html-snapshots/robots.js +137 -120
  38. package/test/mocha/html-snapshots/server/public/page-sitemap.xml +16 -0
  39. package/test/mocha/html-snapshots/sitemap-index.js +89 -80
  40. package/test/mocha/html-snapshots/sitemap.js +75 -31
  41. package/test/mocha/html-snapshots/snapshot-scripts.js +124 -120
  42. package/test/mocha/html-snapshots/test.js +11 -2
  43. package/test/mocha/html-snapshots/use-jquery.js +65 -64
  44. package/test/mocha/html-snapshots/utils.js +29 -29
@@ -29,7 +29,11 @@ const urls = 3; // must match url # in robots files test fixtures.
29
29
  * The robots test suite.
30
30
  */
31
31
  function robotsTests (options) {
32
- const { port, localRobotsFile } = options;
32
+ const {
33
+ port,
34
+ localRobotsFile,
35
+ browsers
36
+ } = options;
33
37
 
34
38
  // Robots.txt fixtures
35
39
  const inputFiles = [
@@ -39,133 +43,146 @@ function robotsTests (options) {
39
43
  ];
40
44
 
41
45
  return function () {
42
- inputFiles.forEach(inputFile => {
43
- it(`should succeed, no output dir pre-exists, ${inputFile}`, function (done) {
44
- const options = {
45
- source: inputFile,
46
- hostname: "localhost",
47
- selector: "#dynamic-content",
48
- outputDirClean: true,
49
- outputDir,
50
- timeout,
51
- port
52
- };
53
- const twice = _.after(2, cleanupSuccess.bind(null, done));
54
-
55
- rimraf(outputDir);
56
-
57
- ss.run(optHelp.decorate(options), twice)
58
- .then(testSuccess.bind(null, twice))
59
- .catch(e => {
60
- checkActualFiles(e.notCompleted)
61
- .then(() => {
62
- cleanup(done, e);
63
- });
46
+ function createOptions (newOptions) {
47
+ const options = {
48
+ hostname: "localhost",
49
+ selector: "#dynamic-content",
50
+ outputDirClean: true,
51
+ outputDir,
52
+ timeout,
53
+ port
54
+ };
55
+ return {
56
+ ...options,
57
+ ...newOptions
58
+ };
59
+ }
60
+ browsers.forEach(browser => {
61
+ inputFiles.forEach(inputFile => {
62
+ it(`should succeed, no output dir pre-exists, ${browser}, ${inputFile}`, function (done) {
63
+ const options = createOptions({
64
+ source: inputFile,
65
+ browser
64
66
  });
65
- });
66
67
 
67
- it(`should succeed, output dir does pre-exist, ${inputFile}`, function (done) {
68
- const options = {
69
- source: inputFile,
70
- hostname: "localhost",
71
- selector: "#dynamic-content",
72
- outputDirClean: true,
73
- outputDir,
74
- timeout,
75
- port
76
- };
77
- const twice = _.after(2, cleanupSuccess.bind(null, done));
78
-
79
- ss.run(optHelp.decorate(options), twice)
80
- .then(testSuccess.bind(null, twice))
81
- .catch(e => {
82
- checkActualFiles(e.notCompleted)
83
- .then(() => {
84
- cleanup(done, e);
85
- });
68
+ const twice = _.after(2, cleanupSuccess.bind(null, done));
69
+
70
+ rimraf(outputDir);
71
+
72
+ ss.run(optHelp.decorate(options), twice)
73
+ .then(testSuccess.bind(null, twice))
74
+ .catch(e => {
75
+ checkActualFiles(e.notCompleted)
76
+ .then(() => {
77
+ cleanup(done, e);
78
+ });
79
+ });
80
+ });
81
+
82
+ it(`should succeed, output dir does pre-exist, ${browser}, ${inputFile}`, function (done) {
83
+ const options = createOptions({
84
+ source: inputFile,
85
+ browser
86
86
  });
87
- });
88
87
 
89
- it(`should fail with bad phantomjs process to spawn, ${inputFile}`,
90
- function (done) {
91
- const options = {
92
- source: inputFile,
93
- hostname: "localhost",
94
- selector: "#dynamic-content",
95
- outputDirClean: true,
96
- phantomjs: bogusFile,
97
- timeout: 1000,
98
- outputDir,
99
- port
100
- };
101
- const twice = _.after(2, cleanupError.bind(null, done, 0));
102
-
103
- ss.run(options, twice)
104
- .then(unexpectedSuccess.bind(null, done))
105
- .catch(twice);
106
- });
88
+ const twice = _.after(2, cleanupSuccess.bind(null, done));
89
+
90
+ ss.run(optHelp.decorate(options), twice)
91
+ .then(testSuccess.bind(null, twice))
92
+ .catch(e => {
93
+ checkActualFiles(e.notCompleted)
94
+ .then(() => {
95
+ cleanup(done, e);
96
+ });
97
+ });
98
+ });
99
+
100
+ it(`should fail with bad phantomjs process to spawn, succeed otherwise, ${browser}, ${inputFile}`,
101
+ function (done) {
102
+ const options = createOptions({
103
+ source: inputFile,
104
+ browser,
105
+ phantomjs: bogusFile,
106
+ timeout: 1000
107
+ });
107
108
 
108
- it(`should fail, bad remote robots, ${inputFile}`, function (done) {
109
- const options = {
110
- input: "robots",
111
- source: `http://localhost:${port}/index.html`,
112
- selector: "#dynamic-content",
113
- outputDirClean: true,
114
- timeout: 6000,
115
- outputDir,
116
- port
117
- };
118
- const twice = _.after(2, cleanupError.bind(null, done, 0));
119
-
120
- ss.run(optHelp.decorate(options), twice)
121
- .then(unexpectedSuccess.bind(null, done))
122
- .catch(twice);
123
- });
109
+ if (browser === "phantomjs") {
110
+ const twice = _.after(2, cleanupError.bind(null, done, 0));
111
+
112
+ ss.run(options, twice)
113
+ .then(unexpectedSuccess.bind(null, done))
114
+ .catch(twice);
115
+ } else {
116
+ options.timeout = utils.timeout;
117
+ const twice = _.after(2, cleanupSuccess.bind(null, done));
118
+
119
+ ss.run(optHelp.decorate(options), twice)
120
+ .then(testSuccess.bind(null, twice))
121
+ .catch(e => {
122
+ checkActualFiles(e.notCompleted)
123
+ .then(() => {
124
+ cleanup(done, e);
125
+ });
126
+ });
127
+ }
128
+ });
129
+
130
+ it(`should fail, bad remote robots, ${browser}, ${inputFile}`, function (done) {
131
+ const options = createOptions({
132
+ input: "robots",
133
+ source: `http://localhost:${port}/index.html`,
134
+ timeout: 5000,
135
+ browser
136
+ });
124
137
 
125
- it(`should fail, non-existent selector, ${inputFile}`, function (done) {
126
- const options = {
127
- source: inputFile,
128
- hostname: "localhost",
129
- selector: "#dynamic-content-notexist",
130
- outputDirClean: true,
131
- timeout: 6000,
132
- outputDir,
133
- port
134
- };
135
- const twice = _.after(2, cleanupError.bind(null, done, 0));
136
-
137
- ss.run(optHelp.decorate(options), twice)
138
- .then(unexpectedSuccess.bind(null, done))
139
- .catch(twice);
140
- });
138
+ const twice = _.after(2, cleanupError.bind(null, done, 0));
141
139
 
142
- it(`should fail one snapshot, one non-existent selector, ${inputFile}`, function (done) {
143
- let exceptionUrl = "/";
144
- if (common.isUrl(inputFile)) {
145
- // assume the origin of the inputFile is the same as the contents of the remote urls within it.
146
- const url = new URL(inputFile);
147
- const isSitemap = url.pathname.includes('sitemap');
148
- if (isSitemap) {
149
- exceptionUrl = `${url.origin}${exceptionUrl}`;
140
+ ss.run(optHelp.decorate(options), twice)
141
+ .then(unexpectedSuccess.bind(null, done))
142
+ .catch(twice);
143
+ });
144
+
145
+ it(`should fail, non-existent selector, ${browser}, ${inputFile}`, function (done) {
146
+ const options = createOptions({
147
+ source: inputFile,
148
+ selector: "#dynamic-content-notexist",
149
+ timeout: 5000,
150
+ browser
151
+ });
152
+
153
+ const twice = _.after(2, cleanupError.bind(null, done, 0));
154
+
155
+ ss.run(optHelp.decorate(options), twice)
156
+ .then(unexpectedSuccess.bind(null, done))
157
+ .catch(twice);
158
+ });
159
+
160
+ it(`should fail one snapshot, one non-existent selector, ${browser}, ${inputFile}`, function (done) {
161
+ let exceptionUrl = "/";
162
+ if (common.isUrl(inputFile)) {
163
+ // assume the origin of the inputFile is the same as the contents of the remote urls within it.
164
+ const url = new URL(inputFile);
165
+ const isSitemap = url.pathname.includes('sitemap');
166
+ if (isSitemap) {
167
+ exceptionUrl = `${url.origin}${exceptionUrl}`;
168
+ }
150
169
  }
151
- }
152
- const options = {
153
- source: inputFile,
154
- hostname: "localhost",
155
- selector: {
156
- "__default": "#dynamic-content",
157
- [exceptionUrl]: "#dynamic-content-notexist"
158
- },
159
- outputDirClean: true,
160
- timeout: 6000,
161
- outputDir,
162
- port
163
- };
164
- const twice = _.after(2, cleanupError.bind(null, done, urls - 1));
165
-
166
- ss.run(optHelp.decorate(options), twice)
167
- .then(unexpectedSuccess.bind(null, done))
168
- .catch(twice);
170
+ const options = createOptions({
171
+ source: inputFile,
172
+ selector: {
173
+ "__default": "#dynamic-content",
174
+ [exceptionUrl]: "#dynamic-content-notexist"
175
+ },
176
+ timeout: 5000,
177
+ browser
178
+ });
179
+
180
+ const twice = _.after(2, cleanupError.bind(null, done, urls - 1));
181
+
182
+ ss.run(optHelp.decorate(options), twice)
183
+ .then(unexpectedSuccess.bind(null, done))
184
+ .catch(twice);
185
+ });
169
186
  });
170
187
  });
171
188
  };
@@ -0,0 +1,16 @@
1
+ <?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="//core.codekraft.it/public/wordpress/main-sitemap.xsl"?>
2
+ <urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3
+ <url>
4
+ <loc>http://localhost:8039/</loc>
5
+ </url>
6
+ <url>
7
+ <loc>http://localhost:8039/contact</loc>
8
+ <lastmod>2017-01-06T21:06:08+01:00</lastmod>
9
+ </url>
10
+ <url>
11
+ <loc>http://localhost:8039/services/carpets</loc>
12
+ <lastmod>2017-01-09T22:38:33+01:00</lastmod>
13
+ </url>
14
+ </urlset>
15
+ <!-- XML Sitemap generated by Yoast SEO -->
16
+ <!-- 24.04MB | Served from transient cache -->
@@ -31,95 +31,104 @@ function getClass (obj) {
31
31
  }
32
32
 
33
33
  function sitemapIndexTests (options) {
34
- const port = options.port;
34
+ const {
35
+ port,
36
+ browsers
37
+ } = options;
35
38
 
36
- return function () {
37
- it("should succeed for typical sitemap-index usage", function (done) {
38
- const options = {
39
- source: `http://localhost:${port}/${sitemapIndexFile}`,
40
- input: "sitemap-index",
41
- selector: "#dynamic-content",
42
- outputDirClean: true,
43
- outputDir,
44
- timeout
45
- };
39
+ function createOptions (newOptions) {
40
+ const options = {
41
+ source: `http://localhost:${port}/${sitemapIndexFile}`,
42
+ input: "sitemap-index",
43
+ selector: "#dynamic-content",
44
+ outputDirClean: true,
45
+ outputDir,
46
+ timeout
47
+ };
48
+
49
+ return {
50
+ ...options,
51
+ ...newOptions
52
+ };
53
+ }
46
54
 
47
- ss.run(optHelp.decorate(options))
48
- .then(function (completed) {
49
- let assertionError;
50
- try {
51
- assert.equal(getClass(completed), "Array");
52
- assert.equal(completed.length, urls);
53
- } catch (e) {
54
- assertionError = e;
55
- }
56
- cleanup(done, assertionError);
57
- })
58
- .catch(err => {
59
- checkActualFiles(err.notCompleted)
60
- .then(() => {
61
- cleanup(done, err || unexpectedError);
62
- });
55
+ return function () {
56
+ browsers.forEach(browser => {
57
+ it(`should succeed for typical sitemap-index usage - ${browser}`, function (done) {
58
+ const options = createOptions({
59
+ browser
63
60
  });
64
- });
65
61
 
66
- it("should fail fast for bad sitemap url", function (done) {
67
- const sitemapIndexFile3 = path.basename(sitemapIndexFile, ".xml") + "-3" +
68
- path.extname(sitemapIndexFile);
69
- const options = {
70
- source: `http://localhost:${port}/${sitemapIndexFile3}`,
71
- input: "sitemap-index",
72
- selector: "#dynamic-content",
73
- outputDirClean: true,
74
- outputDir,
75
- timeout
76
- };
62
+ ss.run(optHelp.decorate(options))
63
+ .then(function (completed) {
64
+ let assertionError;
65
+ try {
66
+ assert.equal(getClass(completed), "Array");
67
+ assert.equal(completed.length, urls);
68
+ } catch (e) {
69
+ assertionError = e;
70
+ }
71
+ cleanup(done, assertionError);
72
+ })
73
+ .catch(err => {
74
+ checkActualFiles(err.notCompleted)
75
+ .then(() => {
76
+ cleanup(done, err || unexpectedError);
77
+ });
78
+ });
79
+ });
77
80
 
78
- ss.run(optHelp.decorate(options))
79
- .then(unexpectedSuccess)
80
- .catch(err => {
81
- let assertionError;
82
- try {
83
- assert.equal(getClass(err.notCompleted), "Array");
84
- // fails fast:
85
- assert.equal(err.notCompleted.length, 0);
86
- } catch (e) {
87
- assertionError = e;
88
- }
89
- cleanup(done, assertionError);
81
+ it(`should fail fast for bad sitemap url - ${browser}`, function (done) {
82
+ const sitemapIndexFile3 = path.basename(sitemapIndexFile, ".xml") + "-3" +
83
+ path.extname(sitemapIndexFile);
84
+ const options = createOptions({
85
+ source: `http://localhost:${port}/${sitemapIndexFile3}`,
86
+ browser
90
87
  });
91
- });
92
88
 
93
- it("should eventually fail for bad page url", function (done) {
94
- const eventually = 1000;
95
- const sitemapIndexFile2 = path.basename(sitemapIndexFile, ".xml") + "-2" +
96
- path.extname(sitemapIndexFile);
97
- const options = {
98
- source: `http://localhost:${port}/${sitemapIndexFile2}`,
99
- input: "sitemap-index",
100
- selector: "#dynamic-content",
101
- outputDirClean: true,
102
- timeout: {
103
- "http://localhost:8040/services/bad": eventually,
104
- __default: timeout
105
- },
106
- outputDir
107
- };
89
+ ss.run(optHelp.decorate(options))
90
+ .then(unexpectedSuccess)
91
+ .catch(err => {
92
+ let assertionError;
93
+ try {
94
+ assert.equal(getClass(err.notCompleted), "Array");
95
+ // fails fast:
96
+ assert.equal(err.notCompleted.length, 0);
97
+ } catch (e) {
98
+ assertionError = e;
99
+ }
100
+ cleanup(done, assertionError);
101
+ });
102
+ });
108
103
 
109
- ss.run(optHelp.decorate(options))
110
- .then(unexpectedSuccess)
111
- .catch(err => {
112
- let assertionError;
113
- try {
114
- assert.equal(getClass(err.completed), "Array");
115
- assert.equal(err.completed.length, urls - 1);
116
- assert.equal(getClass(err.notCompleted), "Array");
117
- assert.equal(err.notCompleted.length, 1);
118
- } catch (e) {
119
- assertionError = e;
120
- }
121
- cleanup(done, assertionError);
104
+ it(`should eventually fail for bad page url - ${browser}`, function (done) {
105
+ const eventually = 1000;
106
+ const sitemapIndexFile2 = path.basename(sitemapIndexFile, ".xml") + "-2" +
107
+ path.extname(sitemapIndexFile);
108
+ const options = createOptions({
109
+ source: `http://localhost:${port}/${sitemapIndexFile2}`,
110
+ timeout: {
111
+ "http://localhost:8040/services/bad": eventually,
112
+ __default: timeout
113
+ },
114
+ browser
122
115
  });
116
+
117
+ ss.run(optHelp.decorate(options))
118
+ .then(unexpectedSuccess)
119
+ .catch(err => {
120
+ let assertionError;
121
+ try {
122
+ assert.equal(getClass(err.completed), "Array");
123
+ assert.equal(err.completed.length, urls - 1);
124
+ assert.equal(getClass(err.notCompleted), "Array");
125
+ assert.equal(err.notCompleted.length, 1);
126
+ } catch (e) {
127
+ assertionError = e;
128
+ }
129
+ cleanup(done, assertionError);
130
+ });
131
+ });
123
132
  });
124
133
  };
125
134
  }
@@ -4,52 +4,96 @@
4
4
  * Copyright (c) 2013 - 2022, Alex Grant, LocalNerve, contributors
5
5
  */
6
6
  /* global it */
7
- var assert = require("assert");
8
- var path = require("path");
9
- var _ = require("lodash");
10
- var optHelp = require("../../helpers/options");
11
- var ss = require("../../../lib/html-snapshots");
12
- var utils = require("./utils");
7
+ const assert = require("assert");
8
+ const path = require("path");
9
+ const _ = require("lodash");
10
+ const optHelp = require("../../helpers/options");
11
+ const ss = require("../../../lib/html-snapshots");
12
+ const utils = require("./utils");
13
13
 
14
14
  // missing destructuring, will write postcard...
15
- var outputDir = utils.outputDir;
16
- var cleanupError = utils.cleanupError;
17
- var unexpectedSuccess = utils.unexpectedSuccess;
15
+ const {
16
+ outputDir,
17
+ cleanup,
18
+ cleanupError,
19
+ cleanupSuccess,
20
+ unexpectedSuccess,
21
+ testSuccess,
22
+ checkActualFiles
23
+ } = utils;
18
24
 
19
25
  // Sitemap constants
20
- var inputFile = path.join(__dirname, "./test_sitemap.xml");
21
- var urls = 3; // must match test_sitemap.xml
26
+ const inputFile = path.join(__dirname, "./test_sitemap.xml");
27
+ const urls = 3; // must match public/page_sitemap.xml
22
28
 
23
29
  function sitemapTests (options) {
24
- var port = options.port;
30
+ const {
31
+ port,
32
+ browsers
33
+ } = options;
25
34
 
26
35
  return function () {
27
- it("should all fail, bad remote sitemap", function (done) {
28
- var options = {
36
+ function createOptions(newOptions) {
37
+ const defaultOptions = {
29
38
  input: "sitemap",
30
- source: "http://localhost:"+port+"/index.html",
31
- port: port,
39
+ source: `http://localhost:${port}/index.html`,
32
40
  selector: "#dynamic-content",
33
- outputDir: outputDir,
34
41
  outputDirClean: true,
35
- timeout: 6000
42
+ timeout: 4000,
43
+ outputDir,
44
+ port
36
45
  };
37
- var twice = _.after(2, cleanupError.bind(null, done, 0));
46
+ return {
47
+ ...defaultOptions,
48
+ ...newOptions
49
+ };
50
+ }
38
51
 
39
- ss.run(optHelp.decorate(options), twice)
40
- .then(unexpectedSuccess.bind(null, done))
41
- .catch(twice);
42
- });
52
+ browsers.forEach(browser => {
53
+ it(`should all fail, bad remote sitemap - ${browser}`, function (done) {
54
+ const options = createOptions({
55
+ browser
56
+ });
43
57
 
44
- it("TODO: write failure tests", function (done) {
45
- assert.ok(true, "TODO");
46
- done();
47
- });
58
+ const twice = _.after(2, cleanupError.bind(null, done, 0));
59
+
60
+ ss.run(optHelp.decorate(options), twice)
61
+ .then(unexpectedSuccess.bind(null, done))
62
+ .catch(twice);
63
+ });
48
64
 
49
- it("TODO: write success tests", function (done) {
50
- assert.ok(true, "TODO");
51
- done();
52
- })
65
+ it("TODO: write more failure tests", function (done) {
66
+ assert.ok(true, "TODO");
67
+ done();
68
+ });
69
+
70
+ it(`should succeed simple case - ${browser}`, function (done) {
71
+ const options = createOptions({
72
+ source: `http://localhost:${port}/public/page-sitemap.xml`,
73
+ browser
74
+ });
75
+
76
+ const twice = _.after(2, cleanupSuccess.bind(null, done));
77
+ const success = (err, completed) => {
78
+ assert.equal(completed.length, urls);
79
+ testSuccess(twice, completed);
80
+ };
81
+
82
+ ss.run(optHelp.decorate(options), success)
83
+ .then(success.bind(null, undefined))
84
+ .catch(e => {
85
+ checkActualFiles(e.notCompleted)
86
+ .then(() => {
87
+ cleanup(done, e);
88
+ });
89
+ });
90
+ });
91
+
92
+ it("TODO: write more success tests", function (done) {
93
+ assert.ok(true, "TODO");
94
+ done();
95
+ });
96
+ });
53
97
  };
54
98
  }
55
99