feat(angular): add playwright to e2eTestRunner option (#18163)
This commit is contained in:
parent
b5305604cd
commit
1dcb80d447
@ -102,8 +102,9 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"description": "Test runner to use for end to end (E2E) tests.",
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"default": "cypress"
|
||||
},
|
||||
"tags": {
|
||||
|
||||
@ -109,8 +109,9 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"description": "Test runner to use for end to end (E2E) tests.",
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"default": "cypress"
|
||||
},
|
||||
"tags": {
|
||||
|
||||
@ -24,7 +24,8 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"description": "Test runner to use for end to end (e2e) tests.",
|
||||
"default": "cypress",
|
||||
"x-priority": "important"
|
||||
|
||||
@ -103,8 +103,9 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"description": "Test runner to use for end to end (E2E) tests.",
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"default": "cypress"
|
||||
},
|
||||
"tags": {
|
||||
|
||||
@ -438,8 +438,8 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
|
||||
// add other projects
|
||||
const app1 = uniq('app1');
|
||||
const lib1 = uniq('lib1');
|
||||
runCommand(`ng g @schematics/angular:application ${app1}`);
|
||||
runCommand(`ng g @schematics/angular:library ${lib1}`);
|
||||
runCommand(`ng g @schematics/angular:application ${app1} --no-interactive`);
|
||||
runCommand(`ng g @schematics/angular:library ${lib1} --no-interactive`);
|
||||
|
||||
runNgAdd('@nx/angular', '--npm-scope projscope');
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import { names } from '@nx/devkit';
|
||||
import {
|
||||
checkFilesExist,
|
||||
cleanupProject,
|
||||
ensurePlaywrightBrowsersInstallation,
|
||||
getSize,
|
||||
killPorts,
|
||||
killProcessAndPorts,
|
||||
@ -123,6 +124,23 @@ describe('Angular Projects', () => {
|
||||
await killProcessAndPorts(esbProcess.pid, appPort);
|
||||
}, 1000000);
|
||||
|
||||
it('should successfully work with playwright for e2e tests', async () => {
|
||||
const app = uniq('app');
|
||||
|
||||
runCLI(
|
||||
`generate @nx/angular:app ${app} --e2eTestRunner=playwright --no-interactive`
|
||||
);
|
||||
|
||||
if (runCypressTests()) {
|
||||
ensurePlaywrightBrowsersInstallation();
|
||||
const e2eResults = runCLI(`e2e ${app}-e2e`);
|
||||
expect(e2eResults).toContain(
|
||||
`Successfully ran target e2e for project ${app}-e2e`
|
||||
);
|
||||
expect(await killPorts()).toBeTruthy();
|
||||
}
|
||||
}, 1000000);
|
||||
|
||||
it('should lint correctly with eslint and handle external HTML files and inline templates', async () => {
|
||||
// check apps and lib pass linting for initial generated code
|
||||
runCLI(`run-many --target lint --projects=${app1},${lib1} --parallel`);
|
||||
|
||||
@ -49,6 +49,7 @@
|
||||
"semver",
|
||||
// These are installed by ensurePackage so missing in package.json
|
||||
"@nx/cypress",
|
||||
"@nx/playwright",
|
||||
"@nx/jest",
|
||||
"@nx/rollup",
|
||||
"@nx/storybook",
|
||||
|
||||
@ -57,8 +57,8 @@
|
||||
"webpack": "^5.80.0",
|
||||
"webpack-merge": "^5.8.0",
|
||||
"enquirer": "^2.3.6",
|
||||
"@nx/cypress": "file:../cypress",
|
||||
"@nx/devkit": "file:../devkit",
|
||||
"@nx/cypress": "file:../cypress",
|
||||
"@nx/jest": "file:../jest",
|
||||
"@nx/js": "file:../js",
|
||||
"@nx/linter": "file:../linter",
|
||||
|
||||
@ -74,5 +74,5 @@
|
||||
},
|
||||
"lint": {}
|
||||
},
|
||||
"implicitDependencies": ["workspace", "cypress", "jest"]
|
||||
"implicitDependencies": ["workspace", "playwright", "cypress", "jest"]
|
||||
}
|
||||
|
||||
@ -26,6 +26,13 @@ import type { Schema } from './schema';
|
||||
// which is v9 while we are testing for the new v10 version
|
||||
jest.mock('@nx/cypress/src/utils/cypress-version');
|
||||
jest.mock('enquirer');
|
||||
jest.mock('@nx/devkit', () => {
|
||||
const original = jest.requireActual('@nx/devkit');
|
||||
return {
|
||||
...original,
|
||||
ensurePackage: (pkg: string) => jest.requireActual(pkg),
|
||||
};
|
||||
});
|
||||
|
||||
describe('app', () => {
|
||||
let appTree: Tree;
|
||||
@ -128,6 +135,23 @@ describe('app', () => {
|
||||
expect(tsconfigE2E).toMatchSnapshot('e2e tsconfig.json');
|
||||
});
|
||||
|
||||
it('should setup playwright', async () => {
|
||||
await generateApp(appTree, 'playwright-app', {
|
||||
e2eTestRunner: E2eTestRunner.Playwright,
|
||||
});
|
||||
|
||||
expect(
|
||||
appTree.exists('apps/playwright-app-e2e/playwright.config.ts')
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
appTree.exists('apps/playwright-app-e2e/src/example.spec.ts')
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
readProjectConfiguration(appTree, 'playwright-app-e2e')?.targets?.e2e
|
||||
?.executor
|
||||
).toEqual('@nx/playwright:playwright');
|
||||
});
|
||||
|
||||
it('should setup jest with serializers', async () => {
|
||||
await generateApp(appTree);
|
||||
|
||||
@ -869,6 +893,18 @@ describe('app', () => {
|
||||
const project = readProjectConfiguration(appTree, 'my-app');
|
||||
expect(project.targets.build.options['outputPath']).toBe('dist/my-app');
|
||||
});
|
||||
|
||||
it('should generate playwright with root project', async () => {
|
||||
await generateApp(appTree, 'root-app', {
|
||||
e2eTestRunner: E2eTestRunner.Playwright,
|
||||
rootProject: true,
|
||||
});
|
||||
expect(
|
||||
readProjectConfiguration(appTree, 'e2e').targets.e2e.executor
|
||||
).toEqual('@nx/playwright:playwright');
|
||||
expect(appTree.exists('e2e/playwright.config.ts')).toBeTruthy();
|
||||
expect(appTree.exists('e2e/src/example.spec.ts')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('should error correctly when Angular version does not support standalone', async () => {
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
import { cypressProjectGenerator } from '@nx/cypress';
|
||||
import type { Tree } from '@nx/devkit';
|
||||
import {
|
||||
addDependenciesToPackageJson,
|
||||
addProjectConfiguration,
|
||||
ensurePackage,
|
||||
getPackageManagerCommand,
|
||||
joinPathFragments,
|
||||
readProjectConfiguration,
|
||||
updateProjectConfiguration,
|
||||
} from '@nx/devkit';
|
||||
@ -13,6 +16,9 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
|
||||
removeScaffoldedE2e(tree, options, options.ngCliSchematicE2ERoot);
|
||||
|
||||
if (options.e2eTestRunner === 'cypress') {
|
||||
const { cypressProjectGenerator } = ensurePackage<
|
||||
typeof import('@nx/cypress')
|
||||
>('@nx/cypress', nxVersion);
|
||||
// TODO: This can call `@nx/web:static-config` generator when ready
|
||||
addFileServerTarget(tree, options, 'serve-static');
|
||||
|
||||
@ -25,6 +31,31 @@ export async function addE2e(tree: Tree, options: NormalizedSchema) {
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
skipFormat: true,
|
||||
});
|
||||
} else if (options.e2eTestRunner === 'playwright') {
|
||||
const { configurationGenerator: playwrightConfigurationGenerator } =
|
||||
ensurePackage<typeof import('@nx/playwright')>(
|
||||
'@nx/playwright',
|
||||
nxVersion
|
||||
);
|
||||
addProjectConfiguration(tree, options.e2eProjectName, {
|
||||
root: options.e2eProjectRoot,
|
||||
sourceRoot: joinPathFragments(options.e2eProjectRoot, 'src'),
|
||||
targets: {},
|
||||
implicitDependencies: [options.name],
|
||||
});
|
||||
await playwrightConfigurationGenerator(tree, {
|
||||
project: options.e2eProjectName,
|
||||
skipFormat: true,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
directory: 'src',
|
||||
js: false,
|
||||
linter: options.linter,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
webServerCommand: `${getPackageManagerCommand().exec} nx serve ${
|
||||
options.name
|
||||
}`,
|
||||
webServerAddress: `http://localhost:${options.port ?? 4200}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -105,8 +105,9 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"description": "Test runner to use for end to end (E2E) tests.",
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"default": "cypress"
|
||||
},
|
||||
"tags": {
|
||||
|
||||
@ -112,8 +112,9 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"description": "Test runner to use for end to end (E2E) tests.",
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"default": "cypress"
|
||||
},
|
||||
"tags": {
|
||||
|
||||
@ -2,9 +2,13 @@ jest.mock('@nx/devkit', () => ({
|
||||
...jest.requireActual('@nx/devkit'),
|
||||
// need to mock so it doesn't resolve what the workspace has installed
|
||||
// and be able to test with different versions
|
||||
ensurePackage: jest.fn(),
|
||||
ensurePackage: jest.fn(() => ({
|
||||
cypressInitGenerator: jest.fn(),
|
||||
initGenerator: jest.fn(),
|
||||
})),
|
||||
}));
|
||||
import {
|
||||
ensurePackage,
|
||||
NxJsonConfiguration,
|
||||
readJson,
|
||||
readNxJson,
|
||||
@ -171,8 +175,41 @@ describe('init', () => {
|
||||
});
|
||||
|
||||
describe('--e2e-test-runner', () => {
|
||||
describe('playwright', () => {
|
||||
it('should call @nx/playwright:init', async () => {
|
||||
// ACT
|
||||
await init(tree, {
|
||||
unitTestRunner: UnitTestRunner.None,
|
||||
e2eTestRunner: E2eTestRunner.Playwright,
|
||||
linter: Linter.EsLint,
|
||||
skipFormat: false,
|
||||
});
|
||||
|
||||
expect(ensurePackage).toHaveBeenLastCalledWith(
|
||||
'@nx/playwright',
|
||||
'0.0.1'
|
||||
);
|
||||
});
|
||||
|
||||
it('should set defaults', async () => {
|
||||
// ACT
|
||||
await init(tree, {
|
||||
unitTestRunner: UnitTestRunner.None,
|
||||
e2eTestRunner: E2eTestRunner.Playwright,
|
||||
linter: Linter.EsLint,
|
||||
skipFormat: false,
|
||||
});
|
||||
|
||||
const { generators } = readJson<NxJsonConfiguration>(tree, 'nx.json');
|
||||
|
||||
// ASSERT
|
||||
expect(generators['@nx/angular:application'].e2eTestRunner).toEqual(
|
||||
'playwright'
|
||||
);
|
||||
});
|
||||
});
|
||||
describe('cypress', () => {
|
||||
it('should add cypress dependencies', async () => {
|
||||
it('should call @nx/cypress:init', async () => {
|
||||
// ACT
|
||||
await init(tree, {
|
||||
unitTestRunner: UnitTestRunner.None,
|
||||
@ -181,11 +218,7 @@ describe('init', () => {
|
||||
skipFormat: false,
|
||||
});
|
||||
|
||||
const { devDependencies } = readJson(tree, 'package.json');
|
||||
|
||||
// ASSERT
|
||||
expect(devDependencies['@nx/cypress']).toBeDefined();
|
||||
expect(devDependencies['cypress']).toBeDefined();
|
||||
expect(ensurePackage).toHaveBeenLastCalledWith('@nx/cypress', '0.0.1');
|
||||
});
|
||||
|
||||
it('should set defaults', async () => {
|
||||
@ -523,6 +556,38 @@ bar
|
||||
});
|
||||
|
||||
describe('--e2e-test-runner', () => {
|
||||
it('should call @nx/playwright:init', async () => {
|
||||
// ACT
|
||||
await init(tree, {
|
||||
unitTestRunner: UnitTestRunner.None,
|
||||
e2eTestRunner: E2eTestRunner.Playwright,
|
||||
linter: Linter.EsLint,
|
||||
skipFormat: false,
|
||||
});
|
||||
|
||||
expect(ensurePackage).toHaveBeenLastCalledWith(
|
||||
'@nx/playwright',
|
||||
'0.0.1'
|
||||
);
|
||||
});
|
||||
|
||||
it('should set defaults', async () => {
|
||||
// ACT
|
||||
await init(tree, {
|
||||
unitTestRunner: UnitTestRunner.None,
|
||||
e2eTestRunner: E2eTestRunner.Playwright,
|
||||
linter: Linter.EsLint,
|
||||
skipFormat: false,
|
||||
});
|
||||
|
||||
const { generators } = readJson<NxJsonConfiguration>(tree, 'nx.json');
|
||||
|
||||
// ASSERT
|
||||
expect(generators['@nx/angular:application'].e2eTestRunner).toEqual(
|
||||
'playwright'
|
||||
);
|
||||
});
|
||||
|
||||
describe('cypress', () => {
|
||||
it('should add cypress dependencies', async () => {
|
||||
// ACT
|
||||
@ -532,12 +597,11 @@ bar
|
||||
linter: Linter.EsLint,
|
||||
skipFormat: false,
|
||||
});
|
||||
|
||||
const { devDependencies } = readJson(tree, 'package.json');
|
||||
|
||||
// ASSERT
|
||||
expect(devDependencies['@nx/cypress']).toBeDefined();
|
||||
expect(devDependencies['cypress']).toBeDefined();
|
||||
expect(ensurePackage).toHaveBeenLastCalledWith(
|
||||
'@nx/cypress',
|
||||
'0.0.1'
|
||||
);
|
||||
});
|
||||
|
||||
it('should set defaults', async () => {
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { cypressInitGenerator } from '@nx/cypress';
|
||||
import {
|
||||
addDependenciesToPackageJson,
|
||||
ensurePackage,
|
||||
@ -21,6 +20,7 @@ import {
|
||||
} from '../utils/version-utils';
|
||||
import type { PackageVersions } from '../../utils/backward-compatible-versions';
|
||||
import { Schema } from './schema';
|
||||
import { nxVersion } from '../../utils/versions';
|
||||
|
||||
export async function angularInitGenerator(
|
||||
tree: Tree,
|
||||
@ -198,9 +198,20 @@ async function addE2ETestRunner(
|
||||
): Promise<GeneratorCallback> {
|
||||
switch (options.e2eTestRunner) {
|
||||
case E2eTestRunner.Cypress:
|
||||
const { cypressInitGenerator } = ensurePackage<
|
||||
typeof import('@nx/cypress')
|
||||
>('@nx/cypress', nxVersion);
|
||||
return cypressInitGenerator(tree, {
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
});
|
||||
case E2eTestRunner.Playwright:
|
||||
const { initGenerator: playwrightInitGenerator } = ensurePackage<
|
||||
typeof import('@nx/playwright')
|
||||
>('@nx/playwright', nxVersion);
|
||||
return playwrightInitGenerator(tree, {
|
||||
skipFormat: true,
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
});
|
||||
default:
|
||||
return () => {};
|
||||
}
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"description": "Test runner to use for end to end (e2e) tests.",
|
||||
"default": "cypress",
|
||||
"x-priority": "important"
|
||||
|
||||
@ -106,8 +106,9 @@
|
||||
},
|
||||
"e2eTestRunner": {
|
||||
"type": "string",
|
||||
"enum": ["cypress", "none"],
|
||||
"enum": ["cypress", "playwright", "none"],
|
||||
"description": "Test runner to use for end to end (E2E) tests.",
|
||||
"x-prompt": "Which E2E test runner would you like to use?",
|
||||
"default": "cypress"
|
||||
},
|
||||
"tags": {
|
||||
|
||||
@ -5,5 +5,6 @@ export enum UnitTestRunner {
|
||||
|
||||
export enum E2eTestRunner {
|
||||
Cypress = 'cypress',
|
||||
Playwright = 'playwright',
|
||||
None = 'none',
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user