-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
205 lines (180 loc) · 5.72 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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
const chromium = require('chrome-aws-lambda');
const screenshots = require('./screenshots');
const navigateToCustomChart = require('./navigateToCustomChart');
const removeChild = require('./removeChild');
const validateQueryStringParameters = require('./validateQueryStringParameters');
const removeUnwantedCards = require('./removeUnwantedCards.js');
const { setMulticardHeight } = require('./setMulticardHeight');
module.exports.handler = async (event, context, callback) => {
if (!event.queryStringParameters) {
return callback(undefined, 'No target');
}
const {
type: _type,
screen: chosenScreenshot,
custom: customChartName,
hoverIndex,
hideLegend,
dateFrom,
dateTo,
immediateDownload = 'true',
} = event?.queryStringParameters || {
type: '',
screen: '',
custom: '',
hoverIndex: '',
hideLegend: '',
dateFrom: '',
dateTo: '',
immediateDownload: '',
};
const type = _type.toUpperCase();
const error = validateQueryStringParameters(
type,
chosenScreenshot,
customChartName,
hoverIndex
);
if (error instanceof Error) {
console.log('ERROR msg: ', error.message);
return callback(undefined, error.message);
}
const { viewport, getSelector, getUrl, selectorsToRemove } =
screenshots.OPTIONS[type];
const possibleScreenshots = screenshots.SCREENSHOTS[type];
const screenshot = possibleScreenshots[chosenScreenshot];
const _url = screenshot?.path ?? screenshot.name;
const url = getUrl(_url);
const selector = getSelector(screenshot.name);
let result = null;
let browser = null;
try {
browser = await chromium.puppeteer.launch({
args: chromium.args,
defaultViewport: chromium.defaultViewport,
executablePath: await chromium.executablePath,
headless: event.headless || chromium.headless,
ignoreHTTPSErrors: true,
});
console.log('Browser launched');
const page = await browser.newPage();
console.log('Made Page');
await page.setViewport(viewport);
console.log('Set viewport');
await page.emulateTimezone('Europe/Ljubljana');
await page.goto(url, { waitUntil: 'networkidle0' });
console.log('Went to ', url);
const element = await page.$(selector);
if (!element) {
console.log(`No element with selector: ${selector}`);
return callback(undefined, "Wrong selector or it's not visible");
}
// multicard
if (screenshot.include) {
const error = await removeUnwantedCards({
page,
screenshots,
screenshot,
selector,
viewport,
});
if (error instanceof Error) {
console.log('Has ERROR');
return callback(undefined, error.message);
}
/**
* calling setMulticardHeight() makes sense if elements with selectors are not present:
* 'div.posts',
* 'div.row',
* 'div.float-nav-btn',
* 'div.float-list',
* 'div.overlay'.
* See: ./screenshots.OPTIONS.MULTICARD.selectorsToRemove
*/
await setMulticardHeight(page, viewport);
}
if (customChartName) {
const error = await navigateToCustomChart({
page,
element,
screenshot,
chosenScreenshot,
customChartName,
hoverIndex,
dateFrom,
dateTo,
});
if (error instanceof Error) {
console.log('Has ERROR');
return callback(undefined, error.message);
}
}
const isChart = type === 'CHART';
const isChartAndHideLegend = hideLegend == String(true) && isChart;
if (isChartAndHideLegend || !isChart) {
console.log(`Selectors for type: ${type} will be removed!`);
const removedSelectors = [];
for (const selectorToRemove of selectorsToRemove) {
const [error, result] = await removeChild(page, selectorToRemove);
if (error instanceof Error) {
console.log('Has ERROR');
return callback(undefined, error.message);
}
removedSelectors.push(result);
}
for (const selector of removedSelectors) {
for (item of Object.entries(selector)) {
const [key, value] = item;
value === null && console.log(`No element for selector: ${key}`);
if (value !== null) {
console.log(
`Selector: ${key}. Length before: ${value.lengthBefore}, length after: ${value.lengthAfter}`
);
}
}
}
console.log(`Selectors for type: ${type} removed!`);
}
await page.waitForTimeout(1500);
let image;
image =
type === 'MULTICARD'
? await page.screenshot({ type: 'png', encoding: 'base64' })
: await element.screenshot({ type: 'png', encoding: 'base64' });
console.log('Made screenshot');
const filename = `${new Date().toISOString()}---${chosenScreenshot}.png`;
console.log('Filename is ', filename);
const download = {
statusCode: 200,
headers: {
'Content-Type': 'image/png',
'Content-Disposition': `attachment; filename="${filename}"`,
},
body: image.toString('base64'),
isBase64Encoded: true,
};
immediateDownload === String(true) &&
console.log('Immediate download request');
result =
immediateDownload === String(true)
? download
: {
headers: {
'Content-Type': 'image/png',
},
body: image,
isBase64Encoded: true,
};
} catch (error) {
return callback(error);
} finally {
if (browser !== null) {
let pages = await browser.pages();
await Promise.all(pages.map(page => page.close()));
console.log('All pages closed');
await browser.close();
console.log('Browser closed');
}
}
return callback(null, result);
};