owncast/test/automated/screenshots/index.js
2023-02-11 18:41:31 -08:00

280 lines
5.5 KiB
JavaScript

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);
});
}
}