Run nightly automated screenshots. Closes #2699
This commit is contained in:
279
test/automated/screenshots/index.js
Normal file
279
test/automated/screenshots/index.js
Normal file
@@ -0,0 +1,279 @@
|
||||
const fs = require('fs');
|
||||
const BrowserStack = require('browserstack');
|
||||
const https = require('https');
|
||||
|
||||
let portraitJobId = null;
|
||||
let landscapeJobId = null;
|
||||
let finished = false;
|
||||
|
||||
const testBrowsersPortrait = [
|
||||
{
|
||||
os: 'OS X',
|
||||
os_version: 'Ventura',
|
||||
browser: 'chrome',
|
||||
device: null,
|
||||
browser_version: '71.0',
|
||||
real_mobile: null,
|
||||
},
|
||||
{
|
||||
os: 'OS X',
|
||||
os_version: 'Ventura',
|
||||
browser: 'safari',
|
||||
device: null,
|
||||
browser_version: '16.0',
|
||||
real_mobile: null,
|
||||
},
|
||||
// {
|
||||
// os: 'OS X',
|
||||
// os_version: 'Ventura',
|
||||
// browser: 'firefox',
|
||||
// device: null,
|
||||
// browser_version: '90.0',
|
||||
// real_mobile: null,
|
||||
// },
|
||||
// {
|
||||
// os: 'Windows',
|
||||
// os_version: '10',
|
||||
// browser: 'firefox',
|
||||
// device: null,
|
||||
// browser_version: '90.0',
|
||||
// real_mobile: null,
|
||||
// },
|
||||
{
|
||||
os: 'Windows',
|
||||
os_version: '11',
|
||||
browser: 'chrome',
|
||||
device: null,
|
||||
browser_version: '71.0',
|
||||
real_mobile: null,
|
||||
},
|
||||
{
|
||||
os: 'Windows',
|
||||
os_version: '10',
|
||||
browser: 'edge',
|
||||
device: null,
|
||||
browser_version: '18.0',
|
||||
real_mobile: null,
|
||||
},
|
||||
{
|
||||
os: 'ios',
|
||||
os_version: '16',
|
||||
browser: 'Mobile Safari',
|
||||
device: 'iPhone 14 Pro',
|
||||
browser_version: null,
|
||||
real_mobile: true,
|
||||
},
|
||||
{
|
||||
os: 'ios',
|
||||
os_version: '16',
|
||||
browser: 'Mobile Safari',
|
||||
device: 'iPad Pro 11 2022',
|
||||
browser_version: null,
|
||||
real_mobile: true,
|
||||
},
|
||||
{
|
||||
os: 'android',
|
||||
os_version: '13.0',
|
||||
browser: 'Android Browser',
|
||||
device: 'Google Pixel 7 Pro',
|
||||
browser_version: null,
|
||||
real_mobile: true,
|
||||
},
|
||||
];
|
||||
|
||||
const testBrowsersLandscape = [
|
||||
// {
|
||||
// os: 'android',
|
||||
// os_version: '13.0',
|
||||
// browser: 'Android Browser',
|
||||
// device: 'Google Pixel 7 Pro',
|
||||
// browser_version: null,
|
||||
// real_mobile: true,
|
||||
// },
|
||||
{
|
||||
os: 'ios',
|
||||
os_version: '16',
|
||||
browser: 'Mobile Safari',
|
||||
device: 'iPad Pro 11 2022',
|
||||
browser_version: null,
|
||||
real_mobile: true,
|
||||
},
|
||||
// {
|
||||
// os: 'ios',
|
||||
// os_version: '16',
|
||||
// browser: 'Mobile Safari',
|
||||
// device: 'iPhone 14 Pro',
|
||||
// browser_version: null,
|
||||
// real_mobile: true,
|
||||
// },
|
||||
];
|
||||
|
||||
const USERNAME = process.env.BROWSERSTACK_USERNAME;
|
||||
const PASSWORD = process.env.BROWSERSTACK_PASSWORD;
|
||||
const URL = process.env.TEST_URL;
|
||||
const FILE_SUFFIX = process.env.FILE_SUFFIX;
|
||||
|
||||
if (!URL) {
|
||||
console.error('Missing URL');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!USERNAME || !PASSWORD) {
|
||||
console.error('Missing BrowserStack credentials');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!FILE_SUFFIX) {
|
||||
console.error('Missing file suffix');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { exit } = require('process');
|
||||
var browserStackCredentials = {
|
||||
username: USERNAME,
|
||||
password: PASSWORD,
|
||||
};
|
||||
|
||||
let screenshotClient = BrowserStack.createScreenshotClient(
|
||||
browserStackCredentials
|
||||
);
|
||||
|
||||
function start() {
|
||||
console.log(
|
||||
`creating screenshots for ${URL} using ${
|
||||
[...testBrowsersPortrait, ...testBrowsersLandscape].length
|
||||
} browsers...`
|
||||
);
|
||||
|
||||
const portraitOptions = {
|
||||
url: URL,
|
||||
orientation: 'portrait',
|
||||
mac_res: '1920x1080',
|
||||
win_res: '1280x1024',
|
||||
browsers: testBrowsersPortrait,
|
||||
wait_time: 20,
|
||||
local: true,
|
||||
};
|
||||
|
||||
const landscapeOptions = {
|
||||
url: URL,
|
||||
orientation: 'landscape',
|
||||
mac_res: '1920x1080',
|
||||
win_res: '1280x1024',
|
||||
browsers: testBrowsersLandscape,
|
||||
wait_time: 20,
|
||||
local: true,
|
||||
};
|
||||
|
||||
screenshotClient.generateScreenshots(
|
||||
portraitOptions,
|
||||
function (error, response) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
exit(0);
|
||||
} else {
|
||||
const { job_id } = response;
|
||||
portraitJobId = job_id;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
screenshotClient.generateScreenshots(
|
||||
landscapeOptions,
|
||||
function (error, response) {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
exit(0);
|
||||
} else {
|
||||
const { job_id } = response;
|
||||
landscapeJobId = job_id;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
setTimeout(check, 30000);
|
||||
}
|
||||
|
||||
async function checkJob(jobId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
screenshotClient.getJob(jobId, function (error, job) {
|
||||
if (error) {
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
return resolve(job);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function check() {
|
||||
if (finished) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!portraitJobId || !landscapeJobId) {
|
||||
setTimeout(check, 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const portraitStatus = await checkJob(portraitJobId);
|
||||
const landscapeStatus = await checkJob(landscapeJobId);
|
||||
|
||||
const { screenshots: portraitScreenshots } = portraitStatus;
|
||||
const { screenshots: landscapeScreenshots } = landscapeStatus;
|
||||
const screenshots = [...portraitScreenshots, ...landscapeScreenshots];
|
||||
|
||||
const completed = screenshots.filter((s) => s.state === 'done');
|
||||
console.log(`completed ${completed.length} of ${screenshots.length}...`);
|
||||
console.log(screenshots.filter((s) => s.state !== 'done'));
|
||||
|
||||
if (completed.length === screenshots.length) {
|
||||
complete(screenshots);
|
||||
}
|
||||
|
||||
const timedOut = screenshots.filter((s) => s.state === 'timed-out');
|
||||
if (timedOut.length > 0) {
|
||||
console.log('timed out');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
setTimeout(check, 5000);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
start();
|
||||
|
||||
function complete(screenshots) {
|
||||
console.log('downloading screenshots...');
|
||||
var saveCounter = 0;
|
||||
for (const screenshot of screenshots) {
|
||||
const { os, os_version, browser, device, orientation, image_url } =
|
||||
screenshot;
|
||||
const name = `${os} ${os_version} ${browser} ${device || 'desktop'} ${
|
||||
orientation || 'default'
|
||||
} ${FILE_SUFFIX}`;
|
||||
|
||||
const filename = name.replace(/ /g, '-').toLowerCase();
|
||||
|
||||
const file = fs.createWriteStream(`./screenshots/${filename}.png`);
|
||||
https
|
||||
.get(image_url, function (response) {
|
||||
response.pipe(file);
|
||||
|
||||
file.on('finish', () => {
|
||||
file.close();
|
||||
saveCounter++;
|
||||
if (saveCounter === screenshots.length) {
|
||||
finished = true;
|
||||
}
|
||||
});
|
||||
})
|
||||
.on('error', function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user