Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(react): add playwright to e2eTestRunner option #18200

Merged
merged 1 commit into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/generated/packages/react/generators/application.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,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": {
Expand Down
2 changes: 1 addition & 1 deletion docs/generated/packages/react/generators/init.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"e2eTestRunner": {
"description": "Adds the specified E2E test runner.",
"type": "string",
"enum": ["cypress", "none"],
"enum": ["cypress", "playwright", "none"],
"default": "cypress"
},
"skipFormat": {
Expand Down
1 change: 1 addition & 0 deletions packages/react/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"react",
// These are installed by ensurePackage so missing in package.json
"@nx/cypress",
"@nx/playwright",
"@nx/jest",
"@nx/rollup",
"@nx/storybook",
Expand Down
60 changes: 56 additions & 4 deletions packages/react/src/generators/application/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,24 @@ describe('app', () => {
},
].forEach(hasJsonValue);
});

it('should setup playwright', async () => {
await applicationGenerator(appTree, {
...schema,
directory: 'myDir',
e2eTestRunner: 'playwright',
});

expect(
appTree.exists('apps/my-dir/my-app-e2e/playwright.config.ts')
).toBeTruthy();
expect(
appTree.exists('apps/my-dir/my-app-e2e/src/example.spec.ts')
).toBeTruthy();
expect(
readProjectConfiguration(appTree, 'my-app-e2e')?.targets?.e2e?.executor
).toEqual('@nx/playwright:playwright');
});
});

it('should create Nx specific template', async () => {
Expand Down Expand Up @@ -332,7 +350,7 @@ describe('app', () => {
);
});

it('should setup the nrwl web build builder', async () => {
it('should setup the nx web build builder', async () => {
await applicationGenerator(appTree, {
...schema,
name: 'my-app',
Expand Down Expand Up @@ -372,7 +390,7 @@ describe('app', () => {
});
});

it('should setup the nrwl vite builder if bundler is vite', async () => {
it('should setup the nx vite builder if bundler is vite', async () => {
await applicationGenerator(appTree, {
...schema,
name: 'my-app',
Expand All @@ -394,7 +412,7 @@ describe('app', () => {
).toBeFalsy();
});

it('should setup the nrwl web dev server builder', async () => {
it('should setup the nx web dev server builder', async () => {
await applicationGenerator(appTree, {
...schema,
name: 'my-app',
Expand All @@ -414,7 +432,7 @@ describe('app', () => {
});
});

it('should setup the nrwl vite dev server builder if bundler is vite', async () => {
it('should setup the nx vite dev server builder if bundler is vite', async () => {
await applicationGenerator(appTree, {
...schema,
name: 'my-app',
Expand Down Expand Up @@ -486,6 +504,25 @@ describe('app', () => {
});
});

describe('--e2e-test-runner playwright', () => {
it('should setup playwright', async () => {
await applicationGenerator(appTree, {
...schema,
e2eTestRunner: 'playwright',
});

expect(
appTree.exists('apps/my-app-e2e/playwright.config.ts')
).toBeTruthy();
expect(
appTree.exists('apps/my-app-e2e/src/example.spec.ts')
).toBeTruthy();
expect(
readProjectConfiguration(appTree, 'my-app-e2e')?.targets?.e2e?.executor
).toEqual('@nx/playwright:playwright');
});
});

describe('--pascalCaseFiles', () => {
it('should use upper case app file', async () => {
await applicationGenerator(appTree, { ...schema, pascalCaseFiles: true });
Expand Down Expand Up @@ -950,6 +987,21 @@ describe('app', () => {
]
).toEqual('dist/my-app2');
});

it('should setup playwright', async () => {
await applicationGenerator(appTree, {
...schema,
name: 'my-app3',
rootProject: true,
e2eTestRunner: 'playwright',
});

expect(appTree.exists('e2e/playwright.config.ts')).toBeTruthy();
expect(appTree.exists('e2e/src/example.spec.ts')).toBeTruthy();
expect(
readProjectConfiguration(appTree, 'e2e')?.targets?.e2e?.executor
).toEqual('@nx/playwright:playwright');
});
});

describe('setup React app with --bundler=vite', () => {
Expand Down
8 changes: 4 additions & 4 deletions packages/react/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { createApplicationFiles } from './lib/create-application-files';
import { updateSpecConfig } from './lib/update-jest-config';
import { normalizeOptions } from './lib/normalize-options';
import { addProject, maybeJs } from './lib/add-project';
import { addCypress } from './lib/add-cypress';
import { addJest } from './lib/add-jest';
import { addRouting } from './lib/add-routing';
import { setDefaults } from './lib/set-defaults';
Expand Down Expand Up @@ -39,6 +38,7 @@ import { extractTsConfigBase } from '../../utils/create-ts-config';
import { addSwcDependencies } from '@nx/js/src/utils/swc/add-swc-dependencies';
import * as chalk from 'chalk';
import { showPossibleWarnings } from './lib/show-possible-warnings';
import { addE2e } from './lib/add-e2e';

async function addLinting(host: Tree, options: NormalizedSchema) {
const tasks: GeneratorCallback[] = [];
Expand Down Expand Up @@ -70,7 +70,7 @@ async function addLinting(host: Tree, options: NormalizedSchema) {
);

if (!options.skipPackageJson) {
const installTask = await addDependenciesToPackageJson(
const installTask = addDependenciesToPackageJson(
host,
extraEslintDependencies.dependencies,
extraEslintDependencies.devDependencies
Expand Down Expand Up @@ -189,8 +189,8 @@ export async function applicationGenerator(
const lintTask = await addLinting(host, options);
tasks.push(lintTask);

const cypressTask = await addCypress(host, options);
tasks.push(cypressTask);
const e2eTask = await addE2e(host, options);
tasks.push(e2eTask);

if (options.unitTestRunner === 'jest') {
const jestTask = await addJest(host, options);
Expand Down
28 changes: 0 additions & 28 deletions packages/react/src/generators/application/lib/add-cypress.ts

This file was deleted.

63 changes: 63 additions & 0 deletions packages/react/src/generators/application/lib/add-e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { GeneratorCallback, Tree } from '@nx/devkit';
import {
addProjectConfiguration,
ensurePackage,
getPackageManagerCommand,
joinPathFragments,
readProjectConfiguration,
} from '@nx/devkit';
import { webStaticServeGenerator } from '@nx/web';

import { nxVersion } from '../../../utils/versions';
import { NormalizedSchema } from '../schema';

export async function addE2e(
tree: Tree,
options: NormalizedSchema
): Promise<GeneratorCallback> {
switch (options.e2eTestRunner) {
case 'cypress':
webStaticServeGenerator(tree, {
buildTarget: `${options.projectName}:build`,
targetName: 'serve-static',
});

const { cypressProjectGenerator } = ensurePackage<
typeof import('@nx/cypress')
>('@nx/cypress', nxVersion);

return await cypressProjectGenerator(tree, {
...options,
name: options.e2eProjectName,
directory: options.directory,
project: options.projectName,
bundler: options.bundler === 'rspack' ? 'webpack' : options.bundler,
skipFormat: true,
});
case 'playwright':
const { configurationGenerator } = ensurePackage<
typeof import('@nx/playwright')
>('@nx/playwright', nxVersion);
addProjectConfiguration(tree, options.e2eProjectName, {
root: options.e2eProjectRoot,
sourceRoot: joinPathFragments(options.e2eProjectRoot, 'src'),
targets: {},
implicitDependencies: [options.projectName],
});
return configurationGenerator(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
}`,
});
case 'none':
default:
return () => {};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { assertValidStyle } from '../../../utils/assertion';
import {
extractLayoutDirectory,
getWorkspaceLayout,
joinPathFragments,
names,
normalizePath,
Tree,
Expand Down Expand Up @@ -36,6 +37,9 @@ export function normalizeOptions<T extends Schema = Schema>(
const appProjectRoot = options.rootProject
? '.'
: normalizePath(`${appsDir}/${appDirectory}`);
const e2eProjectRoot = options.rootProject
? 'e2e'
: joinPathFragments(appsDir, `${appDirectory}-e2e`);

const parsedTags = options.tags
? options.tags.split(',').map((s) => s.trim())
Expand All @@ -59,6 +63,7 @@ export function normalizeOptions<T extends Schema = Schema>(
projectName: appProjectName,
appProjectRoot,
e2eProjectName,
e2eProjectRoot,
parsedTags,
fileName,
styledModule,
Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/generators/application/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export interface Schema {
tags?: string;
unitTestRunner?: 'jest' | 'vitest' | 'none';
inSourceTests?: boolean;
e2eTestRunner: 'cypress' | 'none';
e2eTestRunner: 'cypress' | 'playwright' | 'none';
linter: Linter;
pascalCaseFiles?: boolean;
classComponent?: boolean;
Expand All @@ -32,6 +32,7 @@ export interface NormalizedSchema<T extends Schema = Schema> extends T {
projectName: string;
appProjectRoot: string;
e2eProjectName: string;
e2eProjectRoot: string;
parsedTags: string[];
fileName: string;
styledModule: null | SupportedStyles;
Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/generators/application/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@
},
"e2eTestRunner": {
"type": "string",
"enum": ["cypress", "none"],
"enum": ["cypress", "playwright", "none"],
xiongemi marked this conversation as resolved.
Show resolved Hide resolved
"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": {
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/generators/init/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export interface InitSchema {
unitTestRunner?: 'jest' | 'vitest' | 'none';
e2eTestRunner?: 'cypress' | 'none';
e2eTestRunner?: 'cypress' | 'playwright' | 'none';
skipFormat?: boolean;
skipPackageJson?: boolean;
skipHelperLibs?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/generators/init/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"e2eTestRunner": {
"description": "Adds the specified E2E test runner.",
"type": "string",
"enum": ["cypress", "none"],
"enum": ["cypress", "playwright", "none"],
"default": "cypress"
},
"skipFormat": {
Expand Down