@johnf/react-native-owl
Version:
Visual regression testing for React Native
184 lines (151 loc) • 4.71 kB
text/typescript
import path from 'path';
import execa from 'execa';
import { promises as fs } from 'fs';
import { cleanupScreenshots } from '../screenshot';
import type { CliRunOptions, Config } from '../types';
import { generateReport, cleanupReport } from '../report';
import { getConfig } from './config';
import { Logger } from '../logger';
import { waitFor } from '../utils/wait-for';
import { adbInstall, adbLaunch } from '../utils/adb';
import {
xcrunInstall,
xcrunLaunch,
xcrunRestore,
xcrunStatusBar,
xcrunUi,
} from '../utils/xcrun';
export const runIOS = async (config: Config) => {
if (!config.ios) {
return;
}
await xcrunStatusBar({
debug: config.debug,
device: config.ios.device,
configuration: config.ios.configuration,
binaryPath: config.ios.binaryPath,
});
await xcrunInstall({
debug: config.debug,
device: config.ios.device,
configuration: config.ios.configuration,
binaryPath: config.ios.binaryPath,
scheme: config.ios.scheme,
});
await xcrunLaunch({
debug: config.debug,
device: config.ios.device,
configuration: config.ios.configuration,
binaryPath: config.ios.binaryPath,
scheme: config.ios.scheme,
});
await waitFor(1000);
// Workaround to force the virtual home button's color to become consistent
await xcrunUi({
debug: config.debug,
device: config.ios.device,
configuration: config.ios.configuration,
binaryPath: config.ios.binaryPath,
});
};
export const restoreIOSUI = async (config: Config, logger: Logger) => {
if (!config.ios) {
return;
}
await xcrunRestore({
debug: config.debug,
device: config.ios.device,
configuration: config.ios.configuration,
binaryPath: config.ios.binaryPath,
});
logger.print(`[OWL - CLI] Restored status bar time`);
};
export const runAndroid = async (config: Config) => {
if (!config.android) {
return;
}
await adbInstall({
debug: config.debug,
buildType: config.android.buildType,
binaryPath: config.android.binaryPath,
});
await adbLaunch({
debug: config.debug,
packageName: config.android.packageName,
});
await waitFor(500);
};
export const runHandler = async (args: CliRunOptions) => {
const cwd = process.cwd();
const config = await getConfig(args.config);
const logger = new Logger(config.debug);
const runProject = args.platform === 'ios' ? runIOS : runAndroid;
const restoreSimulatorUI = args.platform === 'ios' && restoreIOSUI;
// Remove old report and screenshots
await cleanupReport();
await cleanupScreenshots();
logger.print(`[OWL - CLI] Starting websocket server.`);
const webSocketProcess = execa.command('node scripts/websocket-server.js', {
stdio: 'inherit',
cwd: path.join(__dirname, '..', '..', '..'),
env: {
OWL_DEBUG: String(!!config.debug),
},
});
logger.print(`[OWL - CLI] Running tests on ${args.platform}.`);
await runProject(config);
const jestCommandArgs = [
'jest',
`--testMatch="**/?(*.)+(owl).[jt]s?(x)"`,
'--verbose',
`--roots=${cwd}`,
'--runInBand',
`--globals='${JSON.stringify({ OWL_CLI_ARGS: args })}'`,
];
if (args.testPathPattern) {
jestCommandArgs.push('--testPathPattern="' + args.testPathPattern + '"');
}
if (config.report) {
const reportDirPath = path.join(cwd, '.owl', 'report');
const outputFile = path.join(reportDirPath, 'jest-report.json');
await fs.mkdir(reportDirPath, { recursive: true });
jestCommandArgs.push(`--json --outputFile=${outputFile}`);
}
const jestCommand = jestCommandArgs.join(' ');
logger.print(
`[OWL - CLI] ${
args.update
? '(Update mode) Updating baseline images'
: '(Tests mode) Will compare latest images with the baseline'
}.`
);
logger.info(`[OWL - CLI] Will set the jest root to ${process.cwd()}.`);
try {
await execa.commandSync(jestCommand, {
stdio: 'inherit',
env: {
OWL_PLATFORM: args.platform,
OWL_DEBUG: String(!!config.debug),
OWL_UPDATE_BASELINE: String(!!args.update),
OWL_IOS_SIMULATOR: config.ios?.device,
},
});
} catch (error) {
// Throw the error again, so that ci will fail when the jest tests fail
throw error;
} finally {
if (config.report) {
await generateReport(logger, args.platform);
}
webSocketProcess.kill();
if (restoreSimulatorUI) {
await restoreSimulatorUI(config, logger);
}
logger.print(`[OWL - CLI] Tests completed on ${args.platform}.`);
if (args.update) {
logger.print(
`[OWL - CLI] All baseline images for ${args.platform} have been updated successfully.`
);
}
}
};