@nx/cypress
Version:
189 lines (187 loc) • 7.12 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = cypressExecutor;
const devkit_1 = require("@nx/devkit");
const fs_1 = require("fs");
const path_1 = require("path");
const ct_helpers_1 = require("../../utils/ct-helpers");
const versions_1 = require("../../utils/versions");
const start_dev_server_1 = require("../../utils/start-dev-server");
const Cypress = require('cypress'); // @NOTE: Importing via ES6 messes the whole test dependencies.
async function cypressExecutor(options, context) {
const installedCypressMajorVersion = (0, versions_1.getInstalledCypressMajorVersion)();
options = normalizeOptions(options, context, installedCypressMajorVersion);
// this is used by cypress component testing presets to build the executor contexts with the correct configuration options.
process.env.NX_CYPRESS_TARGET_CONFIGURATION = context.configurationName;
let success;
const generatorInstance = (0, start_dev_server_1.startDevServer)(options, context);
for await (const devServerValues of generatorInstance) {
try {
success = await runCypress(devServerValues.baseUrl, {
...options,
portLockFilePath: devServerValues.portLockFilePath,
}, installedCypressMajorVersion);
if (!options.watch) {
generatorInstance.return();
break;
}
}
catch (e) {
devkit_1.logger.error(e.message);
success = false;
if (!options.watch)
break;
}
}
return { success };
}
function normalizeOptions(options, context, installedCypressMajorVersion) {
options.env = options.env || {};
if (options.testingType === 'component') {
const project = context?.projectGraph?.nodes?.[context.projectName];
if (project?.data?.root) {
options.ctTailwindPath = (0, ct_helpers_1.getTempTailwindPath)(context);
}
}
checkSupportedBrowser(options, installedCypressMajorVersion);
warnDeprecatedHeadless(options, installedCypressMajorVersion);
warnDeprecatedCypressVersion(installedCypressMajorVersion);
return options;
}
function checkSupportedBrowser({ browser }, installedCypressMajorVersion) {
// Browser was not passed in as an option, cypress will use whatever default it has set and we dont need to check it
if (!browser) {
return;
}
if (installedCypressMajorVersion >= 4 && browser == 'canary') {
devkit_1.logger.warn((0, devkit_1.stripIndents) `
Warning:
You are using a browser that is not supported by cypress v4+.
Read here for more info:
https://docs.cypress.io/guides/references/migration-guide.html#Launching-Chrome-Canary-with-browser
`);
return;
}
const supportedV3Browsers = ['electron', 'chrome', 'canary', 'chromium'];
if (installedCypressMajorVersion <= 3 &&
!supportedV3Browsers.includes(browser)) {
devkit_1.logger.warn((0, devkit_1.stripIndents) `
Warning:
You are using a browser that is not supported by cypress v3.
`);
return;
}
}
function warnDeprecatedHeadless({ headless }, installedCypressMajorVersion) {
if (installedCypressMajorVersion < 8 || headless === undefined) {
return;
}
if (headless) {
const deprecatedMsg = (0, devkit_1.stripIndents) `
NOTE:
You can now remove the use of the '--headless' flag during 'cypress run' as this is the default for all browsers.`;
devkit_1.logger.warn(deprecatedMsg);
}
}
function warnDeprecatedCypressVersion(installedCypressMajorVersion) {
if (installedCypressMajorVersion < 10) {
devkit_1.logger.warn((0, devkit_1.stripIndents) `
NOTE:
Support for Cypress versions < 10 is deprecated. Please upgrade to at least Cypress version 10.
A generator to migrate from v8 to v10 is provided. See https://nx.dev/cypress/v10-migration-guide
`);
}
}
/**
* @whatItDoes Initialize the Cypress test runner with the provided project configuration.
* By default, Cypress will run tests from the CLI without the GUI and provide directly the results in the console output.
* If `watch` is `true`: Open Cypress in the interactive GUI to interact directly with the application.
*/
async function runCypress(baseUrl, opts, installedCypressMajorVersion) {
// Cypress expects the folder where a cypress config is present
const projectFolderPath = (0, path_1.dirname)(opts.cypressConfig);
const options = {
project: projectFolderPath,
configFile: (0, path_1.basename)(opts.cypressConfig),
};
// If not, will use the `baseUrl` normally from `cypress.json`
if (baseUrl) {
options.config = { baseUrl };
}
if (opts.browser) {
options.browser = opts.browser;
}
if (opts.env) {
options.env = {
...options.env,
...opts.env,
};
}
if (opts.spec) {
options.spec = opts.spec;
}
options.tag = opts.tag;
options.exit = opts.exit;
options.headed = opts.headed;
options.runnerUi = opts.runnerUi;
if (opts.headless) {
options.headless = opts.headless;
}
options.record = opts.record;
options.key = opts.key;
options.parallel = opts.parallel;
options.ciBuildId = opts.ciBuildId?.toString();
options.group = opts.group;
// renamed in cy 10
if (installedCypressMajorVersion >= 10) {
options.config ??= {};
options.config[opts.testingType] = {
excludeSpecPattern: opts.ignoreTestFiles,
};
}
else {
options.ignoreTestFiles = opts.ignoreTestFiles;
}
if (opts.reporter) {
options.reporter = opts.reporter;
}
if (opts.reporterOptions) {
options.reporterOptions = opts.reporterOptions;
}
if (opts.quiet) {
options.quiet = opts.quiet;
}
if (opts.autoCancelAfterFailures !== undefined) {
options.autoCancelAfterFailures = opts.autoCancelAfterFailures;
}
options.testingType = opts.testingType;
const result = await (opts.watch
? Cypress.open(options)
: Cypress.run(options));
cleanupTmpFile(opts.ctTailwindPath);
cleanupTmpFile(opts.portLockFilePath);
if (process.env.NX_VERBOSE_LOGGING === 'true' && opts.portLockFilePath) {
(0, fs_1.readdirSync)((0, path_1.dirname)(opts.portLockFilePath)).forEach((f) => {
if (f.endsWith('.txt')) {
devkit_1.logger.debug(`Lock file ${f} still present`);
}
});
}
/**
* `cypress.open` is returning `0` and is not of the same type as `cypress.run`.
* `cypress.open` is the graphical UI, so it will be obvious to know what wasn't
* working. Forcing the build to success when `cypress.open` is used.
*/
return !result.totalFailed && !result.failures;
}
function cleanupTmpFile(path) {
try {
if (path && (0, fs_1.existsSync)(path)) {
(0, fs_1.unlinkSync)(path);
}
return true;
}
catch (err) {
return false;
}
}
;