fix(testing): playwright plugin clean up (#18447)

This commit is contained in:
Caleb Ukle 2023-08-02 15:14:17 -05:00 committed by GitHub
parent 1dcb80d447
commit 5e51cd6eb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 112 additions and 53 deletions

View File

@ -132,7 +132,7 @@ jobs:
GIT_COMMITTER_NAME: Test
NX_E2E_CI_CACHE_KEY: e2e-circleci-<< parameters.os >>
SELECTED_PM: << parameters.pm >>
NX_E2E_RUN_CYPRESS: 'true'
NX_E2E_RUN_E2E: 'true'
NX_VERBOSE_LOGGING: 'false'
NX_NATIVE_LOGGING: 'false'
NX_PERF_LOGGING: 'false'

View File

@ -415,7 +415,7 @@ jobs:
YARN_REGISTRY: http://localhost:4872
NX_CACHE_DIRECTORY: 'tmp'
NX_E2E_SKIP_BUILD_CLEANUP: 'true'
NX_E2E_RUN_CYPRESS: 'true'
NX_E2E_RUN_E2E: 'true'
NX_E2E_VERBOSE_LOGGING: 'true'
NX_PERF_LOGGING: 'false'
NX_DAEMON: 'true'

View File

@ -303,7 +303,7 @@ jobs:
npm_config_registry: http://localhost:4872
NX_CACHE_DIRECTORY: 'tmp'
NX_E2E_SKIP_BUILD_CLEANUP: 'true'
NX_E2E_RUN_CYPRESS: 'true'
NX_E2E_RUN_E2E: 'true'
NX_E2E_VERBOSE_LOGGING: 'true'
NX_PERF_LOGGING: 'false'
NX_DAEMON: 'true'

View File

@ -150,6 +150,11 @@
"uiPort": {
"type": "string",
"description": "Port to serve UI on, 0 for any free port; specifying this option opens UI in a browser tab"
},
"skipInstall": {
"type": "boolean",
"description": "Skip running playwright install before running playwright tests. This is to ensure that playwright browsers are installed before running tests.",
"default": false
}
},
"required": [],

View File

@ -19,6 +19,11 @@
"default": false,
"description": "Do not add dependencies to `package.json`.",
"x-priority": "internal"
},
"skipInstall": {
"type": "boolean",
"description": "Skip running `playwright install`. This is to ensure that playwright browsers are installed.",
"default": false
}
},
"required": [],

View File

@ -2,7 +2,6 @@ import { names } from '@nx/devkit';
import {
checkFilesExist,
cleanupProject,
ensurePlaywrightBrowsersInstallation,
getSize,
killPorts,
killProcessAndPorts,
@ -11,7 +10,7 @@ import {
removeFile,
runCLI,
runCommandUntil,
runCypressTests,
runE2ETests,
tmpProjPath,
uniq,
updateFile,
@ -98,7 +97,7 @@ describe('Angular Projects', () => {
);
// check e2e tests
if (runCypressTests()) {
if (runE2ETests()) {
const e2eResults = runCLI(`e2e ${app1}-e2e --no-watch`);
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();
@ -131,8 +130,7 @@ describe('Angular Projects', () => {
`generate @nx/angular:app ${app} --e2eTestRunner=playwright --no-interactive`
);
if (runCypressTests()) {
ensurePlaywrightBrowsersInstallation();
if (runE2ETests()) {
const e2eResults = runCLI(`e2e ${app}-e2e`);
expect(e2eResults).toContain(
`Successfully ran target e2e for project ${app}-e2e`

View File

@ -4,7 +4,7 @@ import {
createFile,
newProject,
runCLI,
runCypressTests,
runE2ETests,
uniq,
updateFile,
updateProjectConfig,
@ -39,7 +39,7 @@ describe('Angular Cypress Component Tests', () => {
runCLI(
`generate @nx/angular:cypress-component-configuration --project=${appName} --generate-tests --no-interactive`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${appName} --no-watch`)).toContain(
'All specs passed!'
);
@ -50,7 +50,7 @@ describe('Angular Cypress Component Tests', () => {
runCLI(
`generate @nx/angular:cypress-component-configuration --project=${usedInAppLibName} --generate-tests --no-interactive`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${usedInAppLibName} --no-watch`)).toContain(
'All specs passed!'
);
@ -70,7 +70,7 @@ describe('Angular Cypress Component Tests', () => {
runCLI(
`generate @nx/angular:cypress-component-configuration --project=${buildableLibName} --generate-tests --build-target=${appName}:build --no-interactive`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);
@ -92,7 +92,7 @@ describe('Angular Cypress Component Tests', () => {
}
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);
@ -108,7 +108,7 @@ describe('Angular Cypress Component Tests', () => {
updateBuilableLibTestsToAssertAppStyles(appName, buildableLibName);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);
@ -122,7 +122,7 @@ describe('Angular Cypress Component Tests', () => {
checkFilesExist('tailwind.config.js');
checkFilesDoNotExist(`libs/${buildableLibName}/tailwind.config.js`);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);

View File

@ -8,7 +8,7 @@ import {
newProject,
readJson,
runCLI,
runCypressTests,
runE2ETests,
uniq,
updateFile,
updateJson,
@ -200,7 +200,7 @@ async function testCtAndE2eInProject(
`generate @nx/${projectType}:cypress-component-configuration --project=${appName} --generate-tests --no-interactive`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`run ${appName}:component-test --no-watch`)).toContain(
'All specs passed!'
);
@ -208,7 +208,7 @@ async function testCtAndE2eInProject(
runCLI(`generate @nx/cypress:e2e --project=${appName} --no-interactive`);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`run ${appName}:e2e --no-watch`)).toContain(
'All specs passed!'
);

View File

@ -2,7 +2,7 @@ import {
createFile,
newProject,
runCLI,
runCypressTests,
runE2ETests,
uniq,
updateFile,
} from '@nx/e2e/utils';
@ -17,13 +17,13 @@ describe('NextJs Component Testing', () => {
it('should test a NextJs app', () => {
const appName = uniq('next-app');
createAppWithCt(appName);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${appName} --no-watch`)).toContain(
'All specs passed!'
);
}
addTailwindToApp(appName);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${appName} --no-watch`)).toContain(
'All specs passed!'
);
@ -33,13 +33,13 @@ describe('NextJs Component Testing', () => {
it('should test a NextJs lib', async () => {
const libName = uniq('next-lib');
createLibWithCt(libName, false);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${libName} --no-watch`)).toContain(
'All specs passed!'
);
}
addTailwindToLib(libName);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${libName} --no-watch`)).toContain(
'All specs passed!'
);
@ -49,14 +49,14 @@ describe('NextJs Component Testing', () => {
it('should test a NextJs buildable lib', async () => {
const buildableLibName = uniq('next-buildable-lib');
createLibWithCt(buildableLibName, true);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);
}
addTailwindToLib(buildableLibName);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);

View File

@ -4,7 +4,7 @@ import {
readJson,
runCLI,
runCLIAsync,
runCypressTests,
runE2ETests,
} from '../../utils';
export async function checkApp(
@ -40,7 +40,7 @@ export async function checkApp(
expect(packageJson.dependencies['react-dom']).toBeDefined();
expect(packageJson.dependencies.next).toBeDefined();
if (opts.checkE2E && runCypressTests()) {
if (opts.checkE2E && runE2ETests()) {
const e2eResults = runCLI(
`e2e ${appName}-e2e --no-watch --configuration=production`
);

View File

@ -7,7 +7,6 @@ import {
readProjectConfig,
runCLI,
runCLIAsync,
runCypressTests,
uniq,
updateFile,
} from '@nx/e2e/utils';

View File

@ -9,7 +9,7 @@ import {
readFile,
runCLI,
runCLIAsync,
runCypressTests,
runE2ETests,
uniq,
updateFile,
updateJson,
@ -363,7 +363,7 @@ async function testGeneratedApp(
'Test Suites: 1 passed, 1 total'
);
if (opts.checkE2E && runCypressTests()) {
if (opts.checkE2E && runE2ETests()) {
const e2eResults = runCLI(`e2e ${appName}-e2e --no-watch`);
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();

View File

@ -4,7 +4,7 @@ import {
ensureCypressInstallation,
newProject,
runCLI,
runCypressTests,
runE2ETests,
uniq,
updateFile,
updateJson,
@ -147,7 +147,7 @@ export default Input;
runCLI(
`generate @nx/react:cypress-component-configuration --project=${appName} --generate-tests`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${appName} --no-watch`)).toContain(
'All specs passed!'
);
@ -158,7 +158,7 @@ export default Input;
runCLI(
`generate @nx/react:cypress-component-configuration --project=${usedInAppLibName} --generate-tests`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${usedInAppLibName} --no-watch`)).toContain(
'All specs passed!'
);
@ -190,7 +190,7 @@ describe(Input.name, () => {
`generate @nx/react:cypress-component-configuration --project=${buildableLibName} --generate-tests --build-target=${appName}:build`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);
@ -221,7 +221,7 @@ ${content}`;
}
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${buildableLibName} --no-watch`)).toContain(
'All specs passed!'
);
@ -260,7 +260,7 @@ ${content}`;
return config;
});
if (runCypressTests()) {
if (runE2ETests()) {
const results = runCLI(`component-test ${appName}`);
expect(results).toContain('I am from the custom async Webpack config');
expect(results).toContain('All specs passed!');
@ -291,7 +291,7 @@ export default MyComponent;`;
runCLI(
`generate @nrwl/react:cypress-component-configuration --project=${viteLibName} --generate-tests --bundler=vite --build-target=${appName}:build`
);
if (runCypressTests()) {
if (runE2ETests()) {
expect(runCLI(`component-test ${viteLibName}`)).toContain(
'All specs passed!'
);

View File

@ -3,6 +3,7 @@ import { packageInstall, tmpProjPath } from './create-project-utils';
import {
detectPackageManager,
ensureCypressInstallation,
ensurePlaywrightBrowsersInstallation,
getNpmMajorVersion,
getPublishedVersion,
getStrippedEnvironmentVariables,
@ -175,15 +176,23 @@ export function getPackageManagerCommand({
}[packageManager.trim() as PackageManager];
}
export function runCypressTests() {
if (process.env.NX_E2E_RUN_CYPRESS === 'true') {
export function runE2ETests() {
if (process.env.NX_E2E_RUN_E2E === 'true') {
ensureCypressInstallation();
ensurePlaywrightBrowsersInstallation();
return true;
} else {
}
console.warn(
'Not running Cypress because NX_E2E_RUN_CYPRESS is not set to true.'
'Not running E2E tests because NX_E2E_RUN_E2E is not set to true.'
);
if (process.env.NX_E2E_RUN_CYPRESS) {
console.warn(
'NX_E2E_RUN_CYPRESS is deprecated, use NX_E2E_RUN_E2E instead.'
);
}
return false;
}

View File

@ -9,7 +9,7 @@ import {
removeFile,
runCLI,
runCLIAsync,
runCypressTests,
runE2ETests,
uniq,
} from '@nx/e2e/utils';
@ -35,7 +35,7 @@ describe('Web Components Applications with bundler set as vite', () => {
expect(lintE2eResults).toContain('All files pass linting.');
if (isNotWindows() && runCypressTests()) {
if (isNotWindows() && runE2ETests()) {
const e2eResults = runCLI(`e2e ${appName}-e2e --no-watch`);
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();

View File

@ -12,7 +12,7 @@ import {
rmDist,
runCLI,
runCLIAsync,
runCypressTests,
runE2ETests,
tmpProjPath,
uniq,
updateFile,
@ -43,7 +43,7 @@ describe('Web Components Applications', () => {
expect(lintE2eResults).toContain('All files pass linting.');
if (isNotWindows() && runCypressTests()) {
if (isNotWindows() && runE2ETests()) {
const e2eResults = runCLI(`e2e ${appName}-e2e --no-watch`);
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();
@ -109,7 +109,7 @@ describe('Web Components Applications', () => {
expect(lintE2eResults).toContain('All files pass linting.');
if (isNotWindows() && runCypressTests()) {
if (isNotWindows() && runE2ETests()) {
ensurePlaywrightBrowsersInstallation();
const e2eResults = runCLI(`e2e ${appName}-e2e`);
expect(e2eResults).toContain(

View File

@ -74,5 +74,5 @@
},
"lint": {}
},
"implicitDependencies": ["workspace", "playwright", "cypress", "jest"]
"implicitDependencies": []
}

View File

@ -11,14 +11,12 @@ import {
import { nxVersion } from '../../../utils/versions';
import type { NormalizedSchema } from './normalized-schema';
import { removeScaffoldedE2e } from './remove-scaffolded-e2e';
import { cypressProjectGenerator } from '@nx/cypress';
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');

View File

@ -4,6 +4,9 @@
"type": "commonjs",
"homepage": "https://nx.dev",
"private": false,
"publishConfig": {
"access": "public"
},
"description": "The Nx Plugin for Playwright contains executors and generators allowing your workspace to use the powerful Playwright integration testing capabilities.",
"keywords": [
"Monorepo",

View File

@ -1,6 +1,11 @@
import { fork } from 'child_process';
import { ExecutorContext, names } from '@nx/devkit';
import { join } from 'path';
import { execSync, fork } from 'child_process';
import {
ExecutorContext,
getPackageManagerCommand,
names,
output,
workspaceRoot,
} from '@nx/devkit';
export interface PlaywrightExecutorSchema {
/*
@ -49,6 +54,7 @@ export interface PlaywrightExecutorSchema {
ui?: boolean;
uiHost?: string;
uiPort?: string;
skipInstall?: boolean;
}
export async function playwrightExecutor(
@ -63,6 +69,16 @@ export async function playwrightExecutor(
`Unable to find the Project Root for ${context.projectName}. Is it set in the project.json?`
);
}
if (!options.skipInstall) {
output.log({
title: 'Ensuring Playwright is installed.',
bodyLines: ['use --skipInstall to skip installation.'],
});
const pmc = getPackageManagerCommand();
execSync(`${pmc.exec} playwright install`, { cwd: workspaceRoot });
}
const args = createArgs(options);
const p = runPlaywright(args, context.root);

View File

@ -149,6 +149,11 @@
"uiPort": {
"type": "string",
"description": "Port to serve UI on, 0 for any free port; specifying this option opens UI in a browser tab"
},
"skipInstall": {
"type": "boolean",
"description": "Skip running playwright install before running playwright tests. This is to ensure that playwright browsers are installed before running tests.",
"default": false
}
},
"required": []

View File

@ -3,12 +3,16 @@ import {
convertNxGenerator,
formatFiles,
GeneratorCallback,
getPackageManagerCommand,
output,
runTasksInSerial,
Tree,
updateJson,
workspaceRoot,
} from '@nx/devkit';
import { InitGeneratorSchema } from './schema';
import { nxVersion, playwrightVersion } from '../../utils/versions';
import { execSync } from 'child_process';
export async function initGenerator(tree: Tree, options: InitGeneratorSchema) {
const tasks: GeneratorCallback[] = [];
@ -51,6 +55,17 @@ export async function initGenerator(tree: Tree, options: InitGeneratorSchema) {
);
}
if (!options.skipInstall) {
tasks.push(() => {
output.log({
title: 'Ensuring Playwright is installed.',
bodyLines: ['use --skipInstall to skip installation.'],
});
const pmc = getPackageManagerCommand();
execSync(`${pmc.exec} playwright install`, { cwd: workspaceRoot });
});
}
return runTasksInSerial(...tasks);
}

View File

@ -1,4 +1,5 @@
export interface InitGeneratorSchema {
skipFormat: boolean;
skipPackageJson: boolean;
skipInstall?: boolean;
}

View File

@ -16,6 +16,11 @@
"default": false,
"description": "Do not add dependencies to `package.json`.",
"x-priority": "internal"
},
"skipInstall": {
"type": "boolean",
"description": "Skip running `playwright install`. This is to ensure that playwright browsers are installed.",
"default": false
}
},
"required": []