* feat(testing): add generator to aid in the migration to cypress 10 cypress 10 introduces a new configuration format and new layout that requires update settings and files for e2e projects * feat(testing): cypress component tests for react/next initial work for cypress component tests for react and next * feat(testing): add support for v10 e2e cypress projects create the correct files for cypress projects >v10 and reorganize tests based on version to allow easier parsing of tests * feat(testing): add utils for modifying cypress v10 config provide ts transformers to take in an existing cypress config and update/add properties within the given configuration * fix(testing): fix tests affected by the cypress v10 changes update tests to assert the correct files/folders/file contents due to the cypress changes in v10 * cleanup(testing): move cypress component testing plugins into the respective packages move the plugins into out of cypress plugins into the specific vertical plugin to prevent issues with circular refs * cleanup(testing): bump cypress version bump to latest cypress v10 release * docs(testing): update docs for cypress 10 update cypress docs to include info about component testing and migration to cypress v10 * fix(repo): revert cypress version bump keep v9 of cypress installed for nx repo until v10 release * fix(testing): update cypress gen tsconfig and infer targets with converter * fix(testing): make sure tests use the cypress v10 (for the intermediate) * fix(testing): update target name after feedback * fix(testing): support multiple target w/custom configs for cypress v10 migration * fix(testing): refactor cy component tests into seperate verticals * feat(testing): create storybook cypress preset * fix(testing): clean up cy v10 migration * fix(testing): don't branch for cypress executor testingType * fix(testing): move cy comp test generator to next * fix(testing): bump cypress deps * fix(testing): clean up cy component testing generators * fix(testing): update cy component testing docs * fix(testign): dep check. runtime plugin pulls from @nrwl/react * fix(testing): move e2e into verticals * fix(testing): address PR feedback * fix(testing): clean up unit tests * feat(angular): support migrating angular cli workspaces using cypress v10 * chore(testing): update e2e tests * fix(testing): address pr feedback * chore(testing): remove cypress component testing for next.js * fix(testing): address pr feedback Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
153 lines
3.7 KiB
TypeScript
153 lines
3.7 KiB
TypeScript
import { cypressComponentProject } from '@nrwl/cypress';
|
|
import {
|
|
formatFiles,
|
|
generateFiles,
|
|
joinPathFragments,
|
|
ProjectConfiguration,
|
|
readProjectConfiguration,
|
|
Tree,
|
|
updateJson,
|
|
visitNotIgnoredFiles,
|
|
} from '@nrwl/devkit';
|
|
import * as ts from 'typescript';
|
|
import { getComponentNode } from '../../utils/ast-utils';
|
|
import componentTestGenerator from '../component-test/component-test';
|
|
import { CypressComponentConfigurationSchema } from './schema';
|
|
|
|
const allowedFileExt = new RegExp(/\.[jt]sx?/g);
|
|
const isSpecFile = new RegExp(/(spec|test)\./g);
|
|
|
|
/**
|
|
* This is for using cypresses own Component testing, if you want to use test
|
|
* storybook components then use componentCypressGenerator instead.
|
|
*
|
|
*/
|
|
export async function cypressComponentConfigGenerator(
|
|
tree: Tree,
|
|
options: CypressComponentConfigurationSchema
|
|
) {
|
|
const projectConfig = readProjectConfiguration(tree, options.project);
|
|
const installTask = await cypressComponentProject(tree, {
|
|
project: options.project,
|
|
skipFormat: true,
|
|
});
|
|
|
|
addFiles(tree, projectConfig, options);
|
|
updateTsConfig(tree, projectConfig);
|
|
if (options.skipFormat) {
|
|
await formatFiles(tree);
|
|
}
|
|
|
|
return () => {
|
|
installTask();
|
|
};
|
|
}
|
|
|
|
function addFiles(
|
|
tree: Tree,
|
|
projectConfig: ProjectConfiguration,
|
|
options: CypressComponentConfigurationSchema
|
|
) {
|
|
const cypressConfigPath = joinPathFragments(
|
|
projectConfig.root,
|
|
'cypress.config.ts'
|
|
);
|
|
if (tree.exists(cypressConfigPath)) {
|
|
tree.delete(cypressConfigPath);
|
|
}
|
|
|
|
generateFiles(
|
|
tree,
|
|
joinPathFragments(__dirname, 'files'),
|
|
projectConfig.root,
|
|
{
|
|
tpl: '',
|
|
}
|
|
);
|
|
|
|
if (options.generateTests) {
|
|
visitNotIgnoredFiles(tree, projectConfig.sourceRoot, (filePath) => {
|
|
if (isComponent(tree, filePath)) {
|
|
componentTestGenerator(tree, {
|
|
project: options.project,
|
|
componentPath: filePath,
|
|
});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function updateTsConfig(tree: Tree, projectConfig: ProjectConfiguration) {
|
|
const tsConfigPath = joinPathFragments(
|
|
projectConfig.root,
|
|
projectConfig.projectType === 'library'
|
|
? 'tsconfig.lib.json'
|
|
: 'tsconfig.app.json'
|
|
);
|
|
if (tree.exists(tsConfigPath)) {
|
|
updateJson(tree, tsConfigPath, (json) => {
|
|
const excluded = new Set([
|
|
...(json.exclude || []),
|
|
'cypress/**/*',
|
|
'cypress.config.ts',
|
|
'**/*.cy.ts',
|
|
'**/*.cy.js',
|
|
'**/*.cy.tsx',
|
|
'**/*.cy.jsx',
|
|
]);
|
|
|
|
json.exclude = Array.from(excluded);
|
|
return json;
|
|
});
|
|
}
|
|
|
|
const projectBaseTsConfig = joinPathFragments(
|
|
projectConfig.root,
|
|
'tsconfig.json'
|
|
);
|
|
if (tree.exists(projectBaseTsConfig)) {
|
|
updateJson(tree, projectBaseTsConfig, (json) => {
|
|
if (json.references) {
|
|
const hasCyTsConfig = json.references.some(
|
|
(r) => r.path === './tsconfig.cy.json'
|
|
);
|
|
if (!hasCyTsConfig) {
|
|
json.references.push({ path: './tsconfig.cy.json' });
|
|
}
|
|
} else {
|
|
const excluded = new Set([
|
|
...(json.exclude || []),
|
|
'cypress/**/*',
|
|
'cypress.config.ts',
|
|
'**/*.cy.ts',
|
|
'**/*.cy.js',
|
|
'**/*.cy.tsx',
|
|
'**/*.cy.jsx',
|
|
]);
|
|
|
|
json.exclude = Array.from(excluded);
|
|
}
|
|
return json;
|
|
});
|
|
}
|
|
}
|
|
|
|
function isComponent(tree: Tree, filePath: string): boolean {
|
|
if (isSpecFile.test(filePath) || !allowedFileExt.test(filePath)) {
|
|
return false;
|
|
}
|
|
|
|
const content = tree.read(filePath, 'utf-8');
|
|
const sourceFile = ts.createSourceFile(
|
|
filePath,
|
|
content,
|
|
ts.ScriptTarget.Latest,
|
|
true
|
|
);
|
|
|
|
const cmpDeclaration = getComponentNode(sourceFile);
|
|
return !!cmpDeclaration;
|
|
}
|
|
|
|
export default cypressComponentConfigGenerator;
|