@nx/cypress
Version:
124 lines (123 loc) • 5.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = updateAngularComponentTestingSupport;
const devkit_1 = require("@nx/devkit");
const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
const tsquery_1 = require("@phenomnomnominal/tsquery");
const semver_1 = require("semver");
const config_1 = require("../../utils/config");
const migrations_1 = require("../../utils/migrations");
const DEPRECATED_MAX_ANGULAR_VERSION = '18.0.0';
const CYPRESS_ANGULAR_FALLBACK_VERSION = '^3.0.0';
let printer;
let ts;
async function updateAngularComponentTestingSupport(tree) {
const projectGraph = await (0, devkit_1.createProjectGraphAsync)();
let wereProjectsMigrated = false;
for await (const { projectConfig, projectName, cypressConfigPath, } of (0, migrations_1.cypressProjectConfigs)(tree)) {
if (!tree.exists(cypressConfigPath)) {
continue;
}
const migrationInfo = await getMigrationInfo(tree, cypressConfigPath, projectName, projectGraph);
if (!migrationInfo) {
continue;
}
migrateProject(tree, projectConfig);
wereProjectsMigrated = true;
}
if (wereProjectsMigrated) {
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
'@cypress/angular': CYPRESS_ANGULAR_FALLBACK_VERSION,
});
}
await (0, devkit_1.formatFiles)(tree);
}
async function getMigrationInfo(tree, cypressConfigPath, projectName, projectGraph) {
ts ??= (0, ensure_typescript_1.ensureTypescript)();
const cypressConfig = tree.read(cypressConfigPath, 'utf-8');
const config = (0, config_1.resolveCypressConfigObject)(cypressConfig);
if (!config) {
return false;
}
const component = (0, migrations_1.getObjectProperty)(config, 'component');
if (!component) {
return false;
}
const framework = resolveFramework(cypressConfig, config, projectName, projectGraph);
if (framework !== 'angular') {
return false;
}
const angularVersion = resolveAngularVersion(projectName, projectGraph);
if (!angularVersion || !(0, semver_1.valid)(angularVersion)) {
return false;
}
return (0, semver_1.lt)(angularVersion, DEPRECATED_MAX_ANGULAR_VERSION);
}
function migrateProject(tree, projectConfig) {
ts ??= (0, ensure_typescript_1.ensureTypescript)();
printer ??= ts.createPrinter();
(0, devkit_1.visitNotIgnoredFiles)(tree, projectConfig.root, (filePath) => {
if (!isJsTsFile(filePath) || !tree.exists(filePath)) {
return;
}
const originalContent = tree.read(filePath, 'utf-8');
const sourceFile = tsquery_1.tsquery.ast(originalContent);
const updatedContent = tsquery_1.tsquery.replace(originalContent, 'ImportDeclaration', (node) => {
if (!ts.isStringLiteral(node.moduleSpecifier) ||
node.moduleSpecifier.text !== 'cypress/angular') {
return node.getText();
}
const updatedImport = ts.factory.updateImportDeclaration(node, node.modifiers, node.importClause, ts.factory.createStringLiteral('@cypress/angular'), node.attributes);
return printer.printNode(ts.EmitHint.Unspecified, updatedImport, sourceFile);
});
if (updatedContent !== originalContent) {
tree.write(filePath, updatedContent);
}
});
}
function resolveFramework(cypressConfig, config, projectName, projectGraph) {
ts ??= (0, ensure_typescript_1.ensureTypescript)();
const frameworkProperty = tsquery_1.tsquery.query(config, 'PropertyAssignment:has(Identifier[name=component]) PropertyAssignment:has(Identifier[name=devServer]) PropertyAssignment:has(Identifier[name=framework])')[0];
if (frameworkProperty) {
return ts.isStringLiteral(frameworkProperty.initializer)
? frameworkProperty.initializer.text
: null;
}
const sourceFile = tsquery_1.tsquery.ast(cypressConfig);
const nxPresetModuleSpecifiers = [
'@nx/angular/plugins/component-testing',
'@nx/react/plugins/component-testing',
'@nx/next/plugins/component-testing',
'@nx/remix/plugins/component-testing',
];
const imports = tsquery_1.tsquery.query(sourceFile, 'ImportDeclaration');
const nxPresetImport = imports.find((decl) => {
const moduleSpec = decl.moduleSpecifier.getText().replace(/['"`]/g, '');
return nxPresetModuleSpecifiers.includes(moduleSpec);
});
if (nxPresetImport) {
const moduleSpecifier = nxPresetImport.moduleSpecifier
.getText()
.replace(/['"`]/g, '');
const plugin = moduleSpecifier.split('/').at(1);
return plugin === 'angular' ? 'angular' : 'react';
}
if (projectGraph.dependencies[projectName]?.some((dependency) => dependency.target.startsWith('npm:@angular/core'))) {
return 'angular';
}
if (projectGraph.dependencies[projectName]?.some((dependency) => dependency.target.startsWith('npm:react') ||
dependency.target.startsWith('npm:next'))) {
return 'react';
}
return null;
}
function resolveAngularVersion(projectName, projectGraph) {
const angularDep = projectGraph.dependencies[projectName]?.find((dependency) => dependency.target.startsWith('npm:@angular/core'));
if (!angularDep) {
return null;
}
return projectGraph.externalNodes?.[angularDep.target]?.data?.version ?? null;
}
function isJsTsFile(filePath) {
return /\.[cm]?[jt]sx?$/.test(filePath);
}