-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
183 lines (156 loc) · 6.29 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
'use strict';
/*
Web Page Snapshot Tool - This utility will take a number snapshots
of a webpage and save them.
This application uses -
* simple-text-log - https://www.npmjs.com/package/simple-text-log
* puppeteer - https://www.npmjs.com/package/puppeteer
When this application runs, it will:
* Iterate through a list of view port dimensions
* Take a snapshot of each
* Each file is named with the domain name and the viewport
dimensions: "domain_name-WWWxHHH.png
* Usage:
node index.js target_cfg.js
Where: 'target_cfg.js' is a configuration for the target web
page. That file should contain:
'use strict';
module.exports = {
target:'http[s]://somedomain.something/',
fullpage:true
};
NOTE: For most single-page sites 'fullpage' should be true.
* Run-time Results:
* Creates an image for each entry in views[]
* Creates a run-time log of operations
*/
// set up run-time logging first...
const Log = require('simple-text-log');
const logOut = new Log(require('./runlogopt.js'));
// optionally also write to the console
const logcon = true;
function log(payload) {
if(logcon) console.log(payload);
logOut.writeTS(payload);
};
log('***********************************');
log('begin....');
// get the target config file name from the args...
let targetopt = null;
const fs = require('fs')
if(process.argv.length > 2) {
try {
fs.accessSync(process.argv[2], fs.constants.F_OK);
} catch(err) {
if(err.code === 'ENOENT') {
log(`ERROR - file does not exist: ${process.argv[2]}`);
} else {
log(`ERROR - ${err.code}`);
}
process.exit(0);
}
targetopt = require(process.argv[2]);
} else {
log('ERROR - missing target config file argument');
process.exit(0);
}
// https://try-puppeteer.appspot.com/ <-- OUT OF DATE VERSION!!!
// use instead -
// https://github.com/puppeteer/puppeteer/tree/main/examples
// docs -
// https://pptr.dev/#?product=Puppeteer&version=v9.1.1&show=outline
const puppeteer = require('puppeteer');
// the destination of the screenshot images...
// make sure it's a valid path, if not then exit
const imgpath = ((typeof targetopt.imgpath === 'string') && (targetopt.imgpath.length >= 2) ? targetopt.imgpath : './');
try {
var dir = fs.statSync(imgpath);
} catch(err) {
throw new Error(`ERROR - "${imgpath}", not found. ${err.code}`);
}
if (!dir.isDirectory()) {
throw new Error(`ERROR - "${imgpath}", is not a directory.`);
}
// default screenshot image extension
const imgextn = (typeof targetopt.imgextn === 'string' ? targetopt.imgextn : '.png');
log(`saving screenshots to ${imgextn}`);
// full size for screenshot?
const fullpage = targetopt.fullpage;
// where?
const target = targetopt.target;
// here we go...
log(`beginning ${targetopt.views.length} desktop snapshots....`);
for(let idx = 0; idx < targetopt.views.length; idx++) {
// create the name of the screenshot file
let name;
// grab the domain name from the target
if(target.includes('www.')) {
name = target.split('//www.')[1].split('.')[0];
} else {
// add extensions as needed, be sure to include
// the leading '.'
if((target.includes('.')) && (!target.includes('.php')) && (!target.includes('.htm'))) {
name = target.split('//')[1].split('.')[0];
} else {
name = target.split('//')[1].split('/')[0];
}
}
/*
targetopt.views[] can contain either viewport dimensions:
{width:950, height:1080}
OR device names:
{device:'Nexus 6P'}
*/
if(targetopt.views[idx].width) {
// add the viewport dimensions to the name
name = name + '-' + targetopt.views[idx].width + 'x' + targetopt.views[idx].height;
log(`queuing: target = ${target} snapshot file = ${imgpath}${name}${imgextn}`);
}
if(targetopt.views[idx].device) {
// add the device name to the file name
name = name + '-' + targetopt.views[idx].device.replace(/ /g,'_');
log(`queuing: target = ${target} snapshot file = ${imgpath}${name}${imgextn}`);
}
(async () => {
const browser = await puppeteer.launch({headless:true});
const page = await browser.newPage();
// use a device viewport or a custome one
if(targetopt.views[idx].device) {
await page.emulate(puppeteer.devices[targetopt.views[idx].device]);
}
// get the page and wait for things to settle
await page.goto(target,{waitUntil:'networkidle0'});
// give time for page load and render
if(targetopt.godelay && targetopt.godelay > 0) {
await page.waitForTimeout(targetopt.godelay);
}
log(`fullpage = ${(fullpage ? 'true' : 'false')}`);
// custom viewport, render full page?
if(fullpage === true) {
// NOTE: this is an attempt to get a Bootstrap 4
// sticky footer to render at the bottom.
let height = await page.evaluate(
() => document.documentElement.offsetHeight
//() => document.documentElement.scrollHeight
);
if(targetopt.views[idx].device) {
let w = puppeteer.devices[targetopt.views[idx].device].viewport.width;
await page.setViewport({width:w, height:height+1})
.then(log(`viewport set: ${w} X ${height+1}`));
} else {
await page.setViewport({width:targetopt.views[idx].width, height:height+1})
.then(log(`viewport set: ${targetopt.views[idx].width} X ${height+1}`));
}
} else {
if(!targetopt.views[idx].device) {
// not full page, use the viewport settings
await page.setViewport(targetopt.views[idx])
.then(log(`viewport set: ${targetopt.views[idx].width} X ${targetopt.views[idx].height}`));
}
}
await page.screenshot({path:`${imgpath}${name}${imgextn}`, fullPage: fullpage}).then(log(`saved - ${name}${imgextn}`));
// we're done with this one
await browser.close();
})();
}
log(`snapshots in the queue - ${targetopt.views.length}`);