Files
appium/packages/plugin-test-support/lib/harness.js
2024-12-28 09:30:05 +01:00

172 lines
5.3 KiB
JavaScript

/* eslint-disable no-console */
import {fs} from 'appium/support';
import {main as appiumServer} from 'appium';
import getPort from 'get-port';
// eslint-disable-next-line import/named
import {info, success, warning} from 'log-symbols';
import {exec} from 'teen_process';
const APPIUM_BIN = require.resolve('appium');
/**
* Creates hooks to install a driver and a plugin and starts an Appium server w/ the given extensions.
* @param {E2ESetupOpts} opts
* @returns {void}
*/
export function pluginE2EHarness(opts) {
let {
appiumHome,
before,
after,
serverArgs = {},
driverSource,
driverPackage,
driverName,
driverSpec,
pluginSource,
pluginPackage,
pluginSpec,
pluginName,
port,
host,
} = opts;
/**
* @type {AppiumServer}
*/
let server;
// eslint-disable-next-line mocha/no-top-level-hooks
before(async function () {
const chai = await import('chai');
const chaiAsPromised = await import('chai-as-promised');
chai.use(chaiAsPromised.default);
chai.should();
const setupAppiumHome = async () => {
/**
* @type {AppiumEnv}
*/
const env = {...process.env};
if (appiumHome) {
env.APPIUM_HOME = appiumHome;
await fs.mkdirp(appiumHome);
console.log(`${info} Set \`APPIUM_HOME\` to ${appiumHome}`);
}
return env;
};
/**
*
* @param {AppiumEnv} env
*/
const installDriver = async (env) => {
console.log(`${info} Checking if driver "${driverName}" is installed...`);
const driverListArgs = [APPIUM_BIN, 'driver', 'list', '--json'];
console.log(`${info} Running: ${process.execPath} ${driverListArgs.join(' ')}`);
const {stdout: driverListJson} = await exec(process.execPath, driverListArgs, {
env,
});
const installedDrivers = JSON.parse(driverListJson);
if (!installedDrivers[driverName]?.installed) {
console.log(`${warning} Driver "${driverName}" not installed; installing...`);
const driverArgs = [APPIUM_BIN, 'driver', 'install', '--source', driverSource, driverSpec];
if (driverPackage) {
driverArgs.push('--package', driverPackage);
}
console.log(`${info} Running: ${process.execPath} ${driverArgs.join(' ')}`);
await exec(process.execPath, driverArgs, {
env,
});
}
console.log(`${success} Installed driver "${driverName}"`);
};
/**
*
* @param {AppiumEnv} env
*/
const installPlugin = async (env) => {
console.log(`${info} Checking if plugin "${pluginName}" is installed...`);
const pluginListArgs = [APPIUM_BIN, 'plugin', 'list', '--json'];
const {stdout: pluginListJson} = await exec(process.execPath, pluginListArgs, {
env,
});
const installedPlugins = JSON.parse(pluginListJson);
if (!installedPlugins[pluginName]?.installed) {
console.log(`${warning} Plugin "${pluginName}" not installed; installing...`);
const pluginArgs = [APPIUM_BIN, 'plugin', 'install', '--source', pluginSource, pluginSpec];
if (pluginPackage) {
pluginArgs.push('--package', pluginPackage);
}
console.log(`${info} Running: ${process.execPath} ${pluginArgs.join(' ')}`);
await exec(process.execPath, pluginArgs, {
env,
});
}
console.log(`${success} Installed plugin "${pluginName}"`);
};
const createServer = async () => {
if (!port) {
port = await getPort();
}
console.log(`${info} Will use port ${port} for Appium server`);
this.port = port;
/** @type {import('appium/types').Args} */
const args = {
port,
address: host,
usePlugins: [pluginName],
useDrivers: [driverName],
appiumHome,
...serverArgs,
};
server = /** @type {AppiumServer} */ (await appiumServer(args));
};
const env = await setupAppiumHome();
await installDriver(env);
await installPlugin(env);
await createServer();
});
// eslint-disable-next-line mocha/no-top-level-hooks
after(async function () {
if (server) {
await server.close();
}
});
}
/**
* @typedef E2ESetupOpts
* @property {string} [appiumHome] - Path to Appium home directory
* @property {Mocha.before} before - Mocha "before all" hook function
* @property {Mocha.after} after - Mocha "after all" hook function
* @property {Partial<import('appium/types').Args>} [serverArgs] - Arguments to pass to Appium server
* @property {import('appium/types').InstallType & string} driverSource - Source of driver to install
* @property {string} [driverPackage] - Package name of driver to install
* @property {string} driverName - Name of driver to install
* @property {string} driverSpec - Spec of driver to install
* @property {import('appium/types').InstallType & string} pluginSource - Source of plugin to install
* @property {string} [pluginPackage] - Package name of plugin to install
* @property {string} pluginSpec - Spec of plugin to install
* @property {string} pluginName - Name of plugin to install
* @property {number} [port] - Port to use for Appium server
* @property {string} [host] - Host to use for Appium server
*/
/**
* @typedef {import('@appium/types').AppiumServer} AppiumServer
*/
/**
* @typedef {import('appium/types').AppiumEnv} AppiumEnv
*/