fix(testing): deprecate cypress tsconfig option (#17165)
This commit is contained in:
parent
5af50b966e
commit
f74ff4bddc
@ -32,6 +32,7 @@
|
|||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"tsConfig": {
|
"tsConfig": {
|
||||||
|
"x-deprecated": "This option no longer has any effect. Cypress supports typescript out of the box. Add any options directly to <projectRoot>/tsconfig.json or <projectRoot>/cypress/tsconfig.json",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The path of the Cypress tsconfig configuration json file.",
|
"description": "The path of the Cypress tsconfig configuration json file.",
|
||||||
"x-completion-type": "file",
|
"x-completion-type": "file",
|
||||||
|
|||||||
@ -53,6 +53,12 @@
|
|||||||
"version": "16.2.0-beta.0",
|
"version": "16.2.0-beta.0",
|
||||||
"description": "Normalize tsconfig.cy.json files to be located at '<projectRoot>/cypress/tsconfig.json'",
|
"description": "Normalize tsconfig.cy.json files to be located at '<projectRoot>/cypress/tsconfig.json'",
|
||||||
"implementation": "./src/migrations/update-16-2-0/update-cy-tsconfig"
|
"implementation": "./src/migrations/update-16-2-0/update-cy-tsconfig"
|
||||||
|
},
|
||||||
|
"update-16-3-0-remove-old-tsconfigs": {
|
||||||
|
"cli": "nx",
|
||||||
|
"version": "16.4.0-beta.10",
|
||||||
|
"description": "Remove tsconfig.e2e.json and add settings to project tsconfig.json. tsConfigs executor option is now deprecated. The project level tsconfig.json file should be used instead.",
|
||||||
|
"implementation": "./src/migrations/update-16-4-0/tsconfig-sourcemaps"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packageJsonUpdates": {
|
"packageJsonUpdates": {
|
||||||
|
|||||||
@ -24,7 +24,6 @@ export type Json = { [k: string]: any };
|
|||||||
export interface CypressExecutorOptions extends Json {
|
export interface CypressExecutorOptions extends Json {
|
||||||
cypressConfig: string;
|
cypressConfig: string;
|
||||||
watch?: boolean;
|
watch?: boolean;
|
||||||
tsConfig?: string;
|
|
||||||
devServerTarget?: string;
|
devServerTarget?: string;
|
||||||
headed?: boolean;
|
headed?: boolean;
|
||||||
/**
|
/**
|
||||||
@ -91,11 +90,6 @@ function normalizeOptions(
|
|||||||
context: ExecutorContext
|
context: ExecutorContext
|
||||||
): NormalizedCypressExecutorOptions {
|
): NormalizedCypressExecutorOptions {
|
||||||
options.env = options.env || {};
|
options.env = options.env || {};
|
||||||
if (options.tsConfig) {
|
|
||||||
const tsConfigPath = join(context.root, options.tsConfig);
|
|
||||||
options.env.tsConfig = tsConfigPath;
|
|
||||||
process.env.TS_NODE_PROJECT = tsConfigPath;
|
|
||||||
}
|
|
||||||
if (options.testingType === 'component') {
|
if (options.testingType === 'component') {
|
||||||
const project = context?.projectGraph?.nodes?.[context.projectName];
|
const project = context?.projectGraph?.nodes?.[context.projectName];
|
||||||
if (project?.data?.root) {
|
if (project?.data?.root) {
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"tsConfig": {
|
"tsConfig": {
|
||||||
|
"x-deprecated": "This option no longer has any effect. Cypress supports typescript out of the box. Add any options directly to <projectRoot>/tsconfig.json or <projectRoot>/cypress/tsconfig.json",
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The path of the Cypress tsconfig configuration json file.",
|
"description": "The path of the Cypress tsconfig configuration json file.",
|
||||||
"x-completion-type": "file",
|
"x-completion-type": "file",
|
||||||
|
|||||||
@ -0,0 +1,175 @@
|
|||||||
|
import {
|
||||||
|
Tree,
|
||||||
|
addProjectConfiguration,
|
||||||
|
readJson,
|
||||||
|
readProjectConfiguration,
|
||||||
|
updateJson,
|
||||||
|
updateProjectConfiguration,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
|
||||||
|
import { fixLegacyCypressTsconfig } from './tsconfig-sourcemaps';
|
||||||
|
|
||||||
|
describe('Cypress Migration: tsconfig-sourcemaps', () => {
|
||||||
|
let tree: Tree;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
tree = createTreeWithEmptyWorkspace();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove tsconfig.e2e.json and update tsconfig.json', async () => {
|
||||||
|
addLegacyProject(tree);
|
||||||
|
|
||||||
|
await fixLegacyCypressTsconfig(tree);
|
||||||
|
expect(readProjectConfiguration(tree, 'legacy-e2e').targets.e2e)
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"devServerTarget": "legacy-e2e:serve:production",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"executor": "@nx/cypress:cypress",
|
||||||
|
"options": {
|
||||||
|
"cypressConfig": "apps/legacy-e2e/cypress.config.ts",
|
||||||
|
"devServerTarget": "legacy-e2e:serve",
|
||||||
|
"testingType": "e2e",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
expect(readJson(tree, 'apps/legacy-e2e/tsconfig.json'))
|
||||||
|
.toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../../dist/out-tsc",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"sourceMap": false,
|
||||||
|
"strict": true,
|
||||||
|
"types": [
|
||||||
|
"cypress",
|
||||||
|
"node",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"exclude": [],
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"files": [],
|
||||||
|
"include": [
|
||||||
|
"cypress.ci.1.config.ts",
|
||||||
|
"cypress.ci.2.config.ts",
|
||||||
|
"cypress.ci.3.config.ts",
|
||||||
|
"cypress.ci.4.config.ts",
|
||||||
|
"src/**/*.ts",
|
||||||
|
"cypress.config.ts",
|
||||||
|
],
|
||||||
|
"references": [],
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
expect(tree.exists('apps/legacy-e2e/tsconfig.e2e.json')).toBeFalsy();
|
||||||
|
expect(tree.exists('apps/legacy-e2e/tsconfig.e2e.prod.json')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if tsconfig option is not used', async () => {
|
||||||
|
addLegacyProject(tree);
|
||||||
|
|
||||||
|
tree.delete('apps/legacy-e2e/tsconfig.e2e.json');
|
||||||
|
tree.delete('apps/legacy-e2e/tsconfig.e2e.prod.json');
|
||||||
|
const pc = readProjectConfiguration(tree, 'legacy-e2e');
|
||||||
|
|
||||||
|
delete pc.targets.e2e.options.tsConfig;
|
||||||
|
delete pc.targets.e2e.configurations;
|
||||||
|
|
||||||
|
const existingProjectConfig = pc.targets.e2e;
|
||||||
|
|
||||||
|
updateProjectConfiguration(tree, 'legacy-e2e', pc);
|
||||||
|
|
||||||
|
updateJson(tree, 'apps/legacy-e2e/tsconfig.json', (json) => {
|
||||||
|
json.references = [];
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
|
||||||
|
const existingTsConfig = readJson(tree, 'apps/legacy-e2e/tsconfig.json');
|
||||||
|
|
||||||
|
await fixLegacyCypressTsconfig(tree);
|
||||||
|
|
||||||
|
expect(readProjectConfiguration(tree, 'legacy-e2e').targets.e2e).toEqual(
|
||||||
|
existingProjectConfig
|
||||||
|
);
|
||||||
|
expect(readJson(tree, 'apps/legacy-e2e/tsconfig.json')).toEqual(
|
||||||
|
existingTsConfig
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function addLegacyProject(tree: Tree) {
|
||||||
|
addProjectConfiguration(tree, 'legacy-e2e', {
|
||||||
|
root: 'apps/legacy-e2e',
|
||||||
|
sourceRoot: 'apps/legacy-e2e/src',
|
||||||
|
targets: {
|
||||||
|
e2e: {
|
||||||
|
executor: '@nx/cypress:cypress',
|
||||||
|
options: {
|
||||||
|
cypressConfig: 'apps/legacy-e2e/cypress.config.ts',
|
||||||
|
tsConfig: 'apps/legacy-e2e/tsconfig.e2e.json',
|
||||||
|
devServerTarget: 'legacy-e2e:serve',
|
||||||
|
testingType: 'e2e',
|
||||||
|
},
|
||||||
|
configurations: {
|
||||||
|
production: {
|
||||||
|
devServerTarget: 'legacy-e2e:serve:production',
|
||||||
|
tsConfig: 'apps/legacy-e2e/tsconfig.e2e.prod.json',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
tree.write(
|
||||||
|
'apps/legacy-e2e/tsconfig.e2e.json',
|
||||||
|
JSON.stringify({
|
||||||
|
extends: './tsconfig.json',
|
||||||
|
compilerOptions: {
|
||||||
|
sourceMap: false,
|
||||||
|
outDir: '../../dist/out-tsc',
|
||||||
|
types: ['cypress', 'node'],
|
||||||
|
},
|
||||||
|
include: ['src/**/*.ts', 'cypress.config.ts'],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
tree.write(
|
||||||
|
'apps/legacy-e2e/tsconfig.e2e.prod.json',
|
||||||
|
JSON.stringify({
|
||||||
|
extends: './tsconfig.e2e.json',
|
||||||
|
compilerOptions: {
|
||||||
|
sourceMap: false,
|
||||||
|
outDir: '../../dist/out-tsc',
|
||||||
|
types: ['cypress', 'node'],
|
||||||
|
strict: true,
|
||||||
|
},
|
||||||
|
include: ['src/**/*.ts', 'cypress.config.ts'],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
tree.write(
|
||||||
|
'apps/legacy-e2e/tsconfig.json',
|
||||||
|
JSON.stringify({
|
||||||
|
extends: '../../tsconfig.base.json',
|
||||||
|
compilerOptions: {
|
||||||
|
types: ['cypress', 'node'],
|
||||||
|
resolveJsonModule: true,
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
'cypress.ci.1.config.ts',
|
||||||
|
'cypress.ci.2.config.ts',
|
||||||
|
'cypress.ci.3.config.ts',
|
||||||
|
'cypress.ci.4.config.ts',
|
||||||
|
],
|
||||||
|
files: [],
|
||||||
|
references: [
|
||||||
|
{
|
||||||
|
path: './tsconfig.e2e.json',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: './tsconfig.e2e.prod.json',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
import { forEachExecutorOptions } from '@nx/devkit/src/generators/executor-options-utils';
|
||||||
|
import { CypressExecutorOptions } from '../../executors/cypress/cypress.impl';
|
||||||
|
import {
|
||||||
|
updateJson,
|
||||||
|
Tree,
|
||||||
|
getProjects,
|
||||||
|
joinPathFragments,
|
||||||
|
readJson,
|
||||||
|
updateProjectConfiguration,
|
||||||
|
formatFiles,
|
||||||
|
} from '@nx/devkit';
|
||||||
|
import { posix } from 'path';
|
||||||
|
|
||||||
|
export async function fixLegacyCypressTsconfig(tree: Tree) {
|
||||||
|
const projects = getProjects(tree);
|
||||||
|
forEachExecutorOptions<CypressExecutorOptions>(
|
||||||
|
tree,
|
||||||
|
'@nx/cypress:cypress',
|
||||||
|
(options, projectName, targetName, configName) => {
|
||||||
|
const projectConfig = projects.get(projectName);
|
||||||
|
|
||||||
|
if (
|
||||||
|
options.testingType !== 'e2e' &&
|
||||||
|
projectConfig.targets[targetName]?.options?.testingType !== 'e2e'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tsconfigToRemove =
|
||||||
|
options.tsConfig ??
|
||||||
|
joinPathFragments(projectConfig.root, 'tsconfig.e2e.json');
|
||||||
|
|
||||||
|
const projectLevelConfigPath = joinPathFragments(
|
||||||
|
projectConfig.root,
|
||||||
|
'tsconfig.json'
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
!tree.exists(projectLevelConfigPath) ||
|
||||||
|
!tree.exists(tsconfigToRemove)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tsconfigToRemove === projectLevelConfigPath) {
|
||||||
|
updateJson(tree, projectLevelConfigPath, (json) => {
|
||||||
|
json.compilerOptions = {
|
||||||
|
sourceMap: false,
|
||||||
|
...json.compilerOptions,
|
||||||
|
};
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const e2eConfig = readJson(tree, tsconfigToRemove);
|
||||||
|
|
||||||
|
updateJson(tree, projectLevelConfigPath, (json) => {
|
||||||
|
json.compilerOptions = {
|
||||||
|
sourceMap: false,
|
||||||
|
...json.compilerOptions,
|
||||||
|
...e2eConfig.compilerOptions,
|
||||||
|
};
|
||||||
|
json.files = Array.from(
|
||||||
|
new Set([...(json.files ?? []), ...(e2eConfig.files ?? [])])
|
||||||
|
);
|
||||||
|
json.include = Array.from(
|
||||||
|
new Set([...(json.include ?? []), ...(e2eConfig.include ?? [])])
|
||||||
|
);
|
||||||
|
json.exclude = Array.from(
|
||||||
|
new Set([...(json.exclude ?? []), ...(e2eConfig.exclude ?? [])])
|
||||||
|
);
|
||||||
|
|
||||||
|
// these paths will always be 'unix style'
|
||||||
|
// and on windows relative will not work on these paths
|
||||||
|
const tsConfigFromProjRoot = posix.relative(
|
||||||
|
projectConfig.root,
|
||||||
|
tsconfigToRemove
|
||||||
|
);
|
||||||
|
|
||||||
|
json.references = (json.references ?? []).filter(
|
||||||
|
({ path }) => !path.includes(tsConfigFromProjRoot)
|
||||||
|
);
|
||||||
|
return json;
|
||||||
|
});
|
||||||
|
|
||||||
|
tree.delete(tsconfigToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configName) {
|
||||||
|
delete projectConfig.targets[targetName].configurations[configName]
|
||||||
|
.tsConfig;
|
||||||
|
} else {
|
||||||
|
delete projectConfig.targets[targetName].options.tsConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateProjectConfiguration(tree, projectName, projectConfig);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await formatFiles(tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default fixLegacyCypressTsconfig;
|
||||||
Loading…
x
Reference in New Issue
Block a user