fix(testing): convert-to-inferred generator should handle legacy cypress executor (#23151)

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

## Current Behavior
<!-- This is the behavior we have today -->
The `convert-to-inferred` generator does not handle
`@nrwl/cypress:cypress`.


## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The generator should handle the legacy executor

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
This commit is contained in:
Colum Ferry 2024-05-02 23:05:59 +01:00 committed by GitHub
parent eddd0d61c1
commit dbad02afe4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 90 additions and 30 deletions

View File

@ -91,6 +91,7 @@ interface CreateCypressTestProjectOptions {
appName: string;
appRoot: string;
e2eTargetName: string;
legacyExecutor?: boolean;
}
const defaultCreateCypressTestProjectOptions: CreateCypressTestProjectOptions =
@ -98,6 +99,7 @@ const defaultCreateCypressTestProjectOptions: CreateCypressTestProjectOptions =
appName: 'myapp-e2e',
appRoot: 'myapp-e2e',
e2eTargetName: 'e2e',
legacyExecutor: false,
};
function createTestProject(
@ -111,7 +113,9 @@ function createTestProject(
projectType: 'application',
targets: {
[projectOpts.e2eTargetName]: {
executor: '@nx/cypress:cypress',
executor: projectOpts.legacyExecutor
? '@nrwl/cypress:cypress'
: '@nx/cypress:cypress',
options: {
cypressConfig: `${projectOpts.appRoot}/cypress.config.ts`,
testingType: `e2e`,
@ -217,7 +221,7 @@ describe('Cypress - Convert Executors To Plugin', () => {
// project.json modifications
const updatedProject = readProjectConfiguration(tree, project.name);
const targetKeys = Object.keys(updatedProject.targets);
['test'].forEach((key) => expect(targetKeys).not.toContain(key));
expect(targetKeys).not.toContain('test');
// nx.json modifications
const nxJsonPlugins = readNxJson(tree).plugins;
@ -305,6 +309,42 @@ describe('Cypress - Convert Executors To Plugin', () => {
}
});
it('should setup handle legacy executor', async () => {
// ARRANGE
const project = createTestProject(tree, {
e2eTargetName: 'test',
legacyExecutor: true,
});
// ACT
await convertToInferred(tree, { skipFormat: true });
// ASSERT
// project.json modifications
const updatedProject = readProjectConfiguration(tree, project.name);
const targetKeys = Object.keys(updatedProject.targets);
['test'].forEach((key) => expect(targetKeys).not.toContain(key));
// nx.json modifications
const nxJsonPlugins = readNxJson(tree).plugins;
const hasCypressPlugin = nxJsonPlugins.find((plugin) =>
typeof plugin === 'string'
? plugin === '@nx/cypress/plugin'
: plugin.plugin === '@nx/cypress/plugin'
);
expect(hasCypressPlugin).toBeTruthy();
if (typeof hasCypressPlugin !== 'string') {
[
['targetName', 'test'],
['ciTargetName', 'e2e-ci'],
].forEach(([targetOptionName, targetName]) => {
expect(hasCypressPlugin.options[targetOptionName]).toEqual(
targetName
);
});
}
});
it('should setup a new Cypress plugin to match only projects migrated', async () => {
// ARRANGE
const existingProject = createTestProject(tree, {

View File

@ -21,7 +21,7 @@ interface Schema {
export async function convertToInferred(tree: Tree, options: Schema) {
const projectGraph = await createProjectGraphAsync();
await migrateExecutorToPlugin(
let migratedProjects = await migrateExecutorToPlugin(
tree,
projectGraph,
'@nx/cypress:cypress',
@ -35,6 +35,24 @@ export async function convertToInferred(tree: Tree, options: Schema) {
options.project
);
migratedProjects += await migrateExecutorToPlugin(
tree,
projectGraph,
'@nrwl/cypress:cypress',
'@nx/cypress/plugin',
(targetName) => ({
targetName,
ciTargetName: 'e2e-ci',
}),
postTargetTransformer,
createNodes,
options.project
);
if (migratedProjects === 0) {
throw new Error('Could not find any targets to migrate.');
}
if (!options.skipFormat) {
await formatFiles(tree);
}

View File

@ -74,12 +74,15 @@ class ExecutorToPluginMigrator<T> {
this.#skipTargetFilter = skipTargetFilter ?? ((...args) => [false, '']);
}
async run(): Promise<void> {
async run(): Promise<Map<string, Set<string>>> {
await this.#init();
for (const targetName of this.#targetAndProjectsToMigrate.keys()) {
this.#migrateTarget(targetName);
if (this.#targetAndProjectsToMigrate.size > 0) {
for (const targetName of this.#targetAndProjectsToMigrate.keys()) {
this.#migrateTarget(targetName);
}
this.#addPlugins();
}
this.#addPlugins();
return this.#targetAndProjectsToMigrate;
}
async #init() {
@ -239,17 +242,6 @@ class ExecutorToPluginMigrator<T> {
}
}
);
if (this.#targetAndProjectsToMigrate.size === 0) {
const errorMsg = this.#specificProjectToMigrate
? `Project "${
this.#specificProjectToMigrate
}" does not contain any targets using the "${
this.#executor
}" executor. Please select a project that does.`
: `Could not find any targets using the "${this.#executor}" executor.`;
throw new Error(errorMsg);
}
}
#getTargetDefaultsForExecutor() {
@ -270,6 +262,10 @@ class ExecutorToPluginMigrator<T> {
}
async #getCreateNodesResults() {
if (this.#targetAndProjectsToMigrate.size === 0) {
return;
}
for (const targetName of this.#targetAndProjectsToMigrate.keys()) {
const loadedPlugin = new LoadedNxPlugin(
{
@ -312,7 +308,7 @@ export async function migrateExecutorToPlugin<T>(
createNodes: CreateNodes<T>,
specificProjectToMigrate?: string,
skipTargetFilter?: SkipTargetFilter
): Promise<void> {
): Promise<number> {
const migrator = new ExecutorToPluginMigrator<T>(
tree,
projectGraph,
@ -324,5 +320,6 @@ export async function migrateExecutorToPlugin<T>(
specificProjectToMigrate,
skipTargetFilter
);
await migrator.run();
const migratedProjectsAndTargets = await migrator.run();
return migratedProjectsAndTargets.size;
}

View File

@ -16,16 +16,21 @@ interface Schema {
export async function convertToInferred(tree: Tree, options: Schema) {
const projectGraph = await createProjectGraphAsync();
await migrateExecutorToPlugin<PlaywrightPluginOptions>(
tree,
projectGraph,
'@nx/playwright:playwright',
'@nx/playwright/plugin',
(targetName) => ({ targetName, ciTargetName: 'e2e-ci' }),
postTargetTransformer,
createNodes,
options.project
);
const migratedProjects =
await migrateExecutorToPlugin<PlaywrightPluginOptions>(
tree,
projectGraph,
'@nx/playwright:playwright',
'@nx/playwright/plugin',
(targetName) => ({ targetName, ciTargetName: 'e2e-ci' }),
postTargetTransformer,
createNodes,
options.project
);
if (migratedProjects === 0) {
throw new Error('Could not find any targets to migrate.');
}
if (!options.skipFormat) {
await formatFiles(tree);