@testlio/cli
Version:
Official Testlio platform command-line interface
184 lines (160 loc) • 7.01 kB
JavaScript
#! /usr/bin/env node
const axios = require('axios');
const Joi = require('joi');
const fs = require('fs');
const { allAllowedProviders } = require('./utils');
const FAILURE = 1;
const SUCCESS = 0;
const printHelp = () => {
console.log(`Create automated browser
Usage:
testlio create-automated-browser
Options:
--checkExisting (optional) If set, will return list of browsers found, you can additionally narrow down the search by passing [externalId, browserName, platformName]. If no options are passed, it will return all the browsers.
When --checkExisting is set to true:
--externalId (optional) (e.g windows-chrome-latest)
--browserName (optional) (e.g Google Chrome/Microsoft Edge (Chromium)/Mozilla Firefox)
--platformName (optional) (e.g Macintosh/Microsoft Windows/Linux/Android/iOS)
--provider (optional) (e.g aws/browserstack/local/sauce-labs/azure-playwright/bitbar)
When --checkExisting is not set or set to false:
--externalId (required) To create a new automated-browser please provide externalId (e.g windows-MicrosoftEdge-latest)
--browserName (required) To create a new automated-browser please provide browserName (e.g Turbo Browser/Google Chrome/Microsoft Edge (Chromium)/Firefox)
--platformName (required) To create a new automated-browser please provide platformName (e.g Macintosh/Microsoft Windows/Linux/Android/iOS)
--provider (required) To create a new automated-browser please provide the provider (e.g browserstack/local/sauce-labs/azure-playwright/bitbar)
--projectConfig [path] (optional) path to project config (default: project-config.json)
`);
};
const allowedProviders = ['browserstack', 'local', 'sauce-labs', 'azure-playwright', 'bitbar'];
const allowedPlatforms = ['Microsoft Windows', 'Macintosh', 'Linux', 'Android', 'iOS'];
const setAuthorizationToken = (token) => {
axios.defaults.headers.common.Authorization = `Bearer ${token}`;
};
const setBaseUri = (baseURI) => {
axios.defaults.baseURL = baseURI;
};
const projectConfigSchema = Joi.object({
baseURI: Joi.string().required()
});
const createAutomatedBrowserSchema = Joi.object({
checkExisting: Joi.boolean().optional(),
externalId: Joi.string().when('checkExisting', {
is: true,
then: Joi.optional(),
otherwise: Joi.required().label(
'To create new automated-browser please provider externalId (e.g windows-MicrosoftEdge-latest)'
)
}),
browserName: Joi.string().when('checkExisting', {
is: true,
then: Joi.optional(),
otherwise: Joi.required().label(
'To create new automated-browser please provider browserName (e.g Turbo Browser/Google Chrome/Microsoft Edge (Chromium)/Firefox)'
)
}),
platformName: Joi.string().when('checkExisting', {
is: true,
then: Joi.optional().valid(...allowedPlatforms),
otherwise: Joi.required()
.valid(...allowedPlatforms)
.label(
'To create new automated-browser please provider platformName (e.g Macintosh/Microsoft Windows/Linux/Android/iOS)'
)
}),
provider: Joi.string().when('checkExisting', {
is: true,
then: Joi.optional().valid(...allAllowedProviders),
otherwise: Joi.required()
.valid(...allowedProviders)
.label(
'To create new automated-browser please provider provider (e.g aws/browserstack/local/sauce-labs/azure-playwright/bitbar)'
)
}),
projectConfig: Joi.string().default('project-config.json')
});
const createAutomatedBrowser = async (externalId, provider, { browserName, platformName }) => {
const payload = { provider, externalId, browser: { name: browserName }, platform: { name: platformName } };
const { data, status } = await axios.post(`/browser/v1/automated-browsers`, payload);
if (status !== 200) {
throw new Error(`Failed find the browser with external id ${externalId}`);
}
return data.id;
};
const constructBrowserServiceSearchPayload = (platformName, browserName, provider, browserId) => {
const payload = {};
if (browserId) {
payload.id = [{ id: browserId }];
}
if (provider) {
payload.provider = provider;
}
if (platformName) {
payload.platforms = [{ name: platformName }];
}
if (browserName) {
payload.browsers = [{ name: browserName }];
}
return payload;
};
const checkExistingAutomatedBrowser = async (provider, browserName, platform, browserId) => {
const { data } = await axios.post(
`/browser/v1/automated-browsers/search`,
constructBrowserServiceSearchPayload(platform, browserName, provider, browserId)
);
return data?.data;
};
module.exports = async (params) => {
if (params.h || params.help) {
printHelp();
return;
}
const {
checkExisting,
externalId,
browserId,
browserName,
platformName,
provider,
projectConfig: projectConfigFilePath
} = Joi.attempt(params, createAutomatedBrowserSchema);
if (!fs.existsSync(projectConfigFilePath)) {
console.log(`File "${projectConfigFilePath}" not found!`);
return FAILURE;
}
try {
const projectConfig = JSON.parse(fs.readFileSync(projectConfigFilePath).toString());
const { baseURI } = Joi.attempt(projectConfig, projectConfigSchema.unknown());
if (!process.env.RUN_API_TOKEN) {
console.log('Please provide RUN API TOKEN');
return FAILURE;
}
setBaseUri(baseURI);
setAuthorizationToken(process.env.RUN_API_TOKEN);
if (checkExisting) {
const browsers = await checkExistingAutomatedBrowser(provider, browserName, platformName, browserId);
if (browsers.length) {
console.log(`Found following browsers: Please select the browser you want`);
console.log(JSON.stringify(browsers, null, 4));
return SUCCESS;
}
console.log(
`No browser found, please check your search parameters or create a new browser without checkExisting flag`
);
return FAILURE;
}
const browserGuid = await createAutomatedBrowser(externalId, provider, {
browserName,
platformName
});
console.log(`Browser created successfully, here is the guid: ${browserGuid}`);
return SUCCESS;
} catch (e) {
if (e.response?.data?.message.includes('already exists')) {
console.log(
`${e.response.data.message}. Please use --checkExisting flag to find the browser you are looking for`
);
return FAILURE;
}
console.log('Something went wrong while crating an automated Browser', e);
return FAILURE;
}
};