@wdio/lambda-runner
Version:
A WebdriverIO plugin that allows you to run tests on AWS
98 lines (97 loc) • 4.57 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const tmp_1 = __importDefault(require("tmp"));
const path_1 = __importDefault(require("path"));
const shelljs_1 = __importDefault(require("shelljs"));
const events_1 = __importDefault(require("events"));
const find_node_modules_1 = __importDefault(require("find-node-modules"));
const logger_1 = __importDefault(require("@wdio/logger"));
const constants_1 = require("./constants");
const log = logger_1.default('@wdio/lambda-runner');
class AWSLambdaRunner extends events_1.default {
constructor(configFile, config, capabilities, specs) {
super();
const { AWS_ACCESS_KEY, AWS_ACCESS_KEY_ID } = process.env;
if (!AWS_ACCESS_KEY || !AWS_ACCESS_KEY_ID) {
throw new Error('Please provide AWS_ACCESS_KEY, AWS_ACCESS_KEY_ID, AWS_BUCKET in your environment');
}
this.instances = [];
this.configFile = configFile;
this.config = config;
this.capabilities = capabilities;
this.specs = specs;
this.nodeModulesDir = path_1.default.resolve(find_node_modules_1.default()[0]);
this.pwd = shelljs_1.default.pwd().stdout;
this.serverlessBinPath = path_1.default.resolve(require.resolve('serverless'), '..', '..', 'bin', 'serverless');
}
async initialise() {
this.serviceDir = tmp_1.default.dirSync({
prefix: '.wdio-runner-service',
dir: process.cwd(),
mode: '0750'
});
log.info('Generating temporary AWS Lamdba service directory at %s', this.serviceDir.name);
this.link(this.nodeModulesDir, path_1.default.resolve(this.serviceDir.name, 'node_modules'));
this.link(path_1.default.resolve(process.cwd(), this.configFile), path_1.default.resolve(this.serviceDir.name, this.configFile));
this.specs.forEach((spec) => {
this.link(spec, path_1.default.join(this.serviceDir.name, spec.replace(process.cwd(), '')));
});
const runnerConfig = Object.assign(constants_1.DEFAULT_CONFIG, {
environment: { DEBUG: 1 },
package: {
include: [],
exclude: []
}
});
shelljs_1.default.cp(path_1.default.resolve(__dirname, '..', 'config', 'serverless.yml'), path_1.default.resolve(this.serviceDir.name, 'serverless.yml'));
shelljs_1.default.cp(path_1.default.resolve(__dirname, 'handler.js'), path_1.default.resolve(this.serviceDir.name, 'handler.js'));
fs_1.default.writeFileSync(path_1.default.resolve(this.serviceDir.name, 'runner-config.json'), JSON.stringify(runnerConfig, null, 4));
shelljs_1.default.cd(this.serviceDir.name);
await this.exec(`${this.serverlessBinPath} deploy --verbose`);
shelljs_1.default.cd(this.pwd);
}
kill() {
}
async run(options) {
options.specs = options.specs.map((spec) => spec.replace(process.cwd(), '.'));
shelljs_1.default.cd(this.serviceDir.name);
let result;
try {
result = await this.exec(`${this.serverlessBinPath} invoke -f run --data '${JSON.stringify(options)}' --verbose`);
}
catch (e) {
log.error(`Failed to run Lambda process for cid ${options.cid}`);
}
shelljs_1.default.cd(this.pwd);
this.emit(this.cid, result.failures === 0 ? 0 : 1);
}
link(source, dest) {
log.debug('Linking: ', source, dest);
fs_1.default.symlinkSync(source, dest);
}
exec(script) {
log.debug(`Run script "${script}"`);
return new Promise((resolve, reject) => {
const child = shelljs_1.default.exec(script, { async: true, silent: true });
child.stdout.on('data', (stdout) => {
const trimmedStdout = stdout.trim().replace(/^Serverless: /, '');
if (trimmedStdout.startsWith('{')) {
return resolve(JSON.parse(trimmedStdout));
}
log.debug(trimmedStdout);
});
child.stderr.on('data', log.error.bind(log));
child.on('close', (code) => {
if (code === 0) {
return resolve(code);
}
reject(new Error(`script failed with exit code ${code}`));
});
});
}
}
exports.default = AWSLambdaRunner;