UNPKG

@nxextensions/firebase-cypress

Version:

An NX Plugin for Firebase Applications that would like to use emulators for E2E testing with Cypress

310 lines 13.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createNodesV2 = exports.NX_PLUGIN_OPTIONS = void 0; const devkit_1 = require("@nx/devkit"); const fs_1 = require("fs"); const devkit_internals_1 = require("nx/src/devkit-internals"); const path_1 = require("path"); const cache_directory_1 = require("nx/src/utils/cache-directory"); const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes"); const js_1 = require("@nx/js"); const config_utils_1 = require("@nx/devkit/src/utils/config-utils"); const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs"); const workspace_context_1 = require("nx/src/utils/workspace-context"); exports.NX_PLUGIN_OPTIONS = '__NX_PLUGIN_OPTIONS__'; function readTargetsCache(cachePath) { return (0, fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {}; } function writeTargetsToCache(cachePath, targets) { (0, devkit_1.writeJsonFile)(cachePath, targets); } const cypressConfigGlob = '**/cypress.config.{js,ts,mjs,cjs}'; const pmc = (0, devkit_1.getPackageManagerCommand)(); exports.createNodesV2 = [ cypressConfigGlob, async (configFiles, options, context) => { const optionsHash = (0, devkit_internals_1.hashObject)(options); const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `cypress-${optionsHash}.hash`); const targetsCache = readTargetsCache(cachePath); try { return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, targetsCache), configFiles, options, context); } finally { writeTargetsToCache(cachePath, targetsCache); } } ]; async function createNodesInternal(configFile, options, context, targetsCache) { var _a; options = normalizeOptions(options); const projectRoot = (0, path_1.dirname)(configFile); const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot)); if (!siblingFiles.includes('package.json') && !siblingFiles.includes('project.json')) { return {}; } const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context, [(0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot))]); (_a = targetsCache[hash]) !== null && _a !== void 0 ? _a : (targetsCache[hash] = await buildCypressTargets(configFile, projectRoot, options, context)); const { targets, metadata } = targetsCache[hash]; const project = { projectType: 'application', targets, metadata }; return { projects: { [projectRoot]: project } }; } async function buildCypressTargets(configFile, projectRoot, options, context) { var _a, _b, _c, _d; var _e, _f; const cypressConfig = await (0, config_utils_1.loadConfigFile)((0, path_1.join)(context.workspaceRoot, configFile)); const pluginPresetOptions = { ...(_a = cypressConfig.e2e) === null || _a === void 0 ? void 0 : _a[exports.NX_PLUGIN_OPTIONS], ...cypressConfig.env, ...(_b = cypressConfig.e2e) === null || _b === void 0 ? void 0 : _b.env }; const webServerCommands = pluginPresetOptions.webServerCommands; const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context); const targets = {}; let metadata; if ('e2e' in cypressConfig) { const opts = buildCypressOptions(configFile, cypressConfig, projectRoot, 'e2e', false); targets[options.targetName] = { executor: '@nxextensions/firebase-cypress:run', options: opts, cache: true, inputs: getInputs(namedInputs), outputs: getOutputs(projectRoot, cypressConfig, 'e2e'), parallelism: false, metadata: { technologies: ['cypress'], description: 'Runs Cypress Tests', help: { command: `${pmc.exec} cypress run --help`, example: { args: ['--dev', '--headed'] } } } }; if (Object.keys(webServerCommands !== null && webServerCommands !== void 0 ? webServerCommands : {}).length > 0) { (_c = (_e = targets[options.targetName]).configurations) !== null && _c !== void 0 ? _c : (_e.configurations = {}); for (const [configuration, webServerCommand] of Object.entries(webServerCommands !== null && webServerCommands !== void 0 ? webServerCommands : {})) { if (configuration !== 'default') { targets[options.targetName].configurations[configuration] = { env: { webServerCommand } }; } } } const ciWebServerCommand = pluginPresetOptions === null || pluginPresetOptions === void 0 ? void 0 : pluginPresetOptions.ciWebServerCommand; if (ciWebServerCommand) { const specPatterns = Array.isArray(cypressConfig.e2e.specPattern) ? cypressConfig.e2e.specPattern.map((p) => (0, path_1.join)(projectRoot, p)) : [(0, path_1.join)(projectRoot, cypressConfig.e2e.specPattern)]; const excludeSpecPatterns = !cypressConfig.e2e .excludeSpecPattern ? cypressConfig.e2e.excludeSpecPattern : Array.isArray(cypressConfig.e2e.excludeSpecPattern) ? cypressConfig.e2e.excludeSpecPattern.map((p) => (0, path_1.join)(projectRoot, p)) : [(0, path_1.join)(projectRoot, cypressConfig.e2e.excludeSpecPattern)]; const specFiles = await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, specPatterns, excludeSpecPatterns); const dependsOn = []; const outputs = getOutputs(projectRoot, cypressConfig, 'e2e'); const inputs = getInputs(namedInputs); const groupName = 'E2E (CI)'; metadata = { targetGroups: { [groupName]: [] } }; const ciTargetGroup = metadata.targetGroups[groupName]; for (const file of specFiles) { const relativeSpecPath = (0, devkit_1.normalizePath)((0, path_1.relative)(projectRoot, file)); const targetName = `${options.ciTargetName}--${relativeSpecPath}`; const opt = buildCypressOptions(configFile, cypressConfig, projectRoot, 'e2e', true); ciTargetGroup.push(targetName); targets[targetName] = { outputs, inputs, cache: true, executor: '@nxextensions/firebase-cypress:run-ci', options: { ...opt, cwd: projectRoot, env: { webServerCommand: ciWebServerCommand, spec: relativeSpecPath } }, parallelism: false, metadata: { technologies: ['cypress'], description: `Runs Cypress Tests in ${relativeSpecPath} in CI`, help: { command: `${pmc.exec} cypress run --help`, example: { args: ['--dev', '--headed'] } } } }; dependsOn.push({ target: targetName, projects: 'self', params: 'forward' }); } const opt = buildCypressOptions(configFile, cypressConfig, projectRoot, 'e2e', true); targets[options.ciTargetName] = { executor: 'nx:noop', cache: true, inputs, outputs, dependsOn, options: opt, parallelism: false, metadata: { technologies: ['cypress'], description: 'Runs Cypress Tests in CI', nonAtomizedTarget: options.targetName, help: { command: `${pmc.exec} cypress run --help`, example: { args: ['--dev', '--headed'] } } } }; ciTargetGroup.push(options.ciTargetName); } } if ('component' in cypressConfig) { (_d = targets[_f = options.componentTestingTargetName]) !== null && _d !== void 0 ? _d : (targets[_f] = { executor: '@nxextensions/firebase-cypress:run-component', options: { cwd: projectRoot }, cache: true, inputs: getInputs(namedInputs), outputs: getOutputs(projectRoot, cypressConfig, 'component'), metadata: { technologies: ['cypress'], description: 'Runs Cypress Component Tests', help: { command: `${pmc.exec} cypress run --help`, example: { args: ['--dev', '--headed'] } } } }); } targets[options.openTargetName] = { executor: '@nxextensions/firebase-cypress:open', options: { ...buildCypressOptions(configFile, cypressConfig, projectRoot, undefined, false), cwd: projectRoot }, metadata: { technologies: ['cypress'], description: 'Opens Cypress', help: { command: `${pmc.exec} cypress open --help`, example: { args: ['--dev', '--e2e'] } } } }; return { targets, metadata }; } function normalizeOptions(options) { var _a, _b, _c, _d; options !== null && options !== void 0 ? options : (options = {}); (_a = options.ciTargetName) !== null && _a !== void 0 ? _a : (options.ciTargetName = 'e2e-ci'); (_b = options.componentTestingTargetName) !== null && _b !== void 0 ? _b : (options.componentTestingTargetName = 'component'); (_c = options.openTargetName) !== null && _c !== void 0 ? _c : (options.openTargetName = 'open-cypress'); (_d = options.targetName) !== null && _d !== void 0 ? _d : (options.targetName = 'e2e'); return options; } function getInputs(namedInputs) { return [ ...('production' in namedInputs ? ['default', '^production'] : ['default', '^default']), { externalDependencies: ['cypress'] } ]; } function getOutputs(projectRoot, // eslint-disable-next-line @typescript-eslint/no-explicit-any cypressConfig, testingType) { function getOutput(path) { if (path.startsWith('..')) { return (0, devkit_1.joinPathFragments)('{workspaceRoot}', projectRoot, path, path); } else { return (0, devkit_1.joinPathFragments)('{projectRoot}', path); } } const { screenshotsFolder, videosFolder, e2e, component } = cypressConfig; const outputs = []; if (videosFolder) { outputs.push(getOutput(videosFolder)); } if (screenshotsFolder) { outputs.push(getOutput(screenshotsFolder)); } switch (testingType) { case 'e2e': if (e2e.videosFolder) { outputs.push(getOutput(e2e.videosFolder)); } if (e2e.screenshotsFolder) { outputs.push(getOutput(e2e.screenshotsFolder)); } break; case 'component': if (component.videosFolder) { outputs.push(getOutput(component.videosFolder)); } if (component.screenshotsFolder) { outputs.push(getOutput(component.screenshotsFolder)); } break; } return outputs; } function buildCypressOptions(configFilePath, // eslint-disable-next-line @typescript-eslint/no-explicit-any cypressConfig, _projectRoot, testingType, isCi) { const config = testingType && testingType in cypressConfig ? cypressConfig[testingType] : {}; if (config === null || config === void 0 ? void 0 : config.baseUrl) { return { devServerTarget: isCi ? config[exports.NX_PLUGIN_OPTIONS].ciWebServerCommand : config[exports.NX_PLUGIN_OPTIONS].webServerCommands.default, baseUrl: config.baseUrl, cypressConfig: configFilePath, testingType, emulatorCommand: config[exports.NX_PLUGIN_OPTIONS].emulatorCommand }; } return { devServerTarget: isCi ? cypressConfig["e2e"][exports.NX_PLUGIN_OPTIONS].ciWebServerCommand : 'default' in cypressConfig["e2e"][exports.NX_PLUGIN_OPTIONS].webServerCommands ? cypressConfig["e2e"][exports.NX_PLUGIN_OPTIONS].webServerCommands.default : cypressConfig["e2e"][exports.NX_PLUGIN_OPTIONS].webServerCommands[Object.keys(cypressConfig["e2e"][exports.NX_PLUGIN_OPTIONS].webServerCommands)[0]], cypressConfig: configFilePath, testingType, baseUrl: 'e2e' in cypressConfig ? cypressConfig['e2e'].baseUrl : undefined, emulatorCommand: 'e2e' in cypressConfig ? cypressConfig['e2e'][exports.NX_PLUGIN_OPTIONS].emulatorCommand : cypressConfig['component'][exports.NX_PLUGIN_OPTIONS].emulatorCommand }; } //# sourceMappingURL=index.js.map