This code automates screenshot capture from Selenium WebDriver sessions and uploads them to an AWS S3 bucket for storage.
npm run import -- "screenshot all sessions"
var AWS = require('aws-sdk');
var fs = require('fs');
var path = require('path');
var importer = require('../Core');
var runSeleniumCell = importer.import("selenium cell");
var unidecode = require('unidecode');
// For dev purposes only
var PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
var SCREENSHOTS_DIR = path.join(PROFILE_PATH, 'Collections/screenshots');
AWS.config.update(JSON.parse(fs.readFileSync(path.join(PROFILE_PATH, '.credentials/aws-sdk.json')).toString()));
function uploadS3(file) {
var base64data = fs.readFileSync(file);
var s3 = new AWS.S3();
return new Promise((resolve, reject) => s3.putObject({
Bucket: 'selenium-bots',
Key: path.basename(file),
Body: base64data,
ACL: 'public-read'
},function (err, resp) {
if(err) {
return reject(err);
}
return resolve(resp);
}));
}
function getScreenshots(client) {
if(typeof client === 'undefined') {
var client = runSeleniumCell(null, false);
}
var session, paths;
return client
.catch(e => {
if((e + '').indexOf('Already') > -1) {
// ignore because we don't need a valid session to start
return;
}
throw e;
})
.then(() => {
session = client.sessionId;
})
.then(() => importer.runAllPromises([client.getSessions(false), client.getSessions(true)]))
.then(sess => [].concat(...sess))
.then(r => {
console.log(r);
return importer.runAllPromises(r.map(s => resolve => {
return client
.then(() => client.sessionId = s)
.then(() => client.getWindowHandles())
.then(h => importer.runAllPromises(h.map(hwnd => resolve => {
const time = new Date();
// TODO: include address in image?
let filepath = path.join(SCREENSHOTS_DIR, 'screenshot-'
+ time.getFullYear() + '-'
+ (time.getMonth() + 1) + '-'
+ time.getDate() + '-'
+ time.getHours() + '-'
+ time.getMinutes() + '-'
+ time.getSeconds());
return client
.switchToWindow(hwnd)
.then(() => client.getUrl())
.then(url => filepath += '-' + unidecode(url).replace(/[^a-z0-9_-]/igm, '_'))
.then(() => client.saveScreenshot(filepath + '.png'))
// TODO: create thumbnails
.then(() => uploadS3(filepath + '.png'))
.catch(e => console.log(e))
.then(() => resolve(filepath + '.png'))
})))
.catch(e => console.log(e))
.then(r => resolve(r))
}));
})
.then(r => {
client.sessionId = session;
paths = r;
})
.catch(e => console.log(e))
.then(() => paths)
}
module.exports = getScreenshots;
if(typeof $ !== 'undefined') {
$.async();
getScreenshots()
.then(r => $.sendResult(r))
.catch(e => $.sendError(e))
}
const AWS = require('aws-sdk');
const fs = require('fs');
const path = require('path');
const { runSeleniumCell, runAllPromises } = require('../Core');
const unidecode = require('unidecode');
// Constants
const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
const SCREENSHOTS_DIR = path.join(PROFILE_PATH, 'Collections/screenshots');
// AWS Config
const awsConfig = JSON.parse(fs.readFileSync(path.join(PROFILE_PATH, '.credentials/aws-sdk.json')).toString());
AWS.config.update(awsConfig);
const s3 = new AWS.S3();
/**
* Uploads a file to S3
* @param {string} file - path to the file to upload
* @returns {Promise} - resolved with the upload response
*/
function uploadS3(file) {
const base64data = fs.readFileSync(file);
return s3.putObject({
Bucket:'selenium-bots',
Key: path.basename(file),
Body: base64data,
ACL: 'public-read'
}).promise();
}
/**
* Gets screenshots of a selenium cell
* @param {object} client - selenium client (optional, defaults to new instance)
* @returns {Promise} - resolved with an array of screenshot paths
*/
function getScreenshots(client = runSeleniumCell()) {
// Handle missing client
if (!client) {
client = runSeleniumCell();
}
// Get session ID and sessions
let session, sessions;
return client
.catch(e => {
if ((e + '').indexOf('Already') > -1) {
// Ignore because we don't need a valid session to start
return;
}
throw e;
})
.then(() => client.sessionId)
.then(sessionId => {
session = sessionId;
return runAllPromises([client.getSessions(false), client.getSessions(true)]);
})
.then(sess => [].concat(...sess))
.then(sessions => {
// Map each session to its corresponding screenshot paths
return runAllPromises(sessions.map(s => resolve => {
const time = new Date();
const filePath = path.join(SCREENSHOTS_DIR, `screenshot-${time.getFullYear()}-${time.getMonth() + 1}-${time.getDate()}-${time.getHours()}-${time.getMinutes()}-${time.getSeconds()}`);
return client
.switchToWindow(s)
.then(() => client.getUrl())
.then(url => {
const fileName = `${filePath}-${unidecode(url).replace(/[^a-z0-9_-]/igm, '_')}.png`;
return client.saveScreenshot(fileName);
})
.then(() => uploadS3(fileName))
.then(() => resolve(fileName))
.catch(e => console.log(e))
.then(() => resolve(fileName));
}));
})
.then(paths => {
client.sessionId = session;
return paths;
})
.catch(e => console.log(e));
}
module.exports = getScreenshots;
if (typeof $!== 'undefined') {
$.async();
getScreenshots()
.then(r => $.sendResult(r))
.catch(e => $.sendError(e));
}
This code snippet focuses on capturing and uploading screenshots from Selenium WebDriver sessions to an Amazon S3 bucket.
Here's a breakdown:
Imports:
aws-sdk
for interacting with AWS S3, fs
for file system operations, path
for path manipulation, importer
(likely a custom module), and unidecode
for handling Unicode characters.Configuration:
uploadS3
Function:
getScreenshots
Function:
SCREENSHOTS_DIR
.uploadS3
to upload the screenshot to S3.Execution:
getScreenshots
to capture and upload screenshots from Selenium sessions.In essence, this code automates the process of taking screenshots from Selenium WebDriver sessions and uploading them to an AWS S3 bucket for storage and sharing.