test(@angular/cli): support running E2E tests with yarn

With this change, the E2E test suite can be run using yarn as the package manager instead of npm by using the `--yarn` command line option.
This commit is contained in:
Charles Lyding 2020-10-14 19:57:22 -04:00 committed by Alan Agius
parent 706451284a
commit 33ad5e87aa
31 changed files with 145 additions and 69 deletions

View File

@ -1,6 +1,7 @@
import { getGlobalVariable } from '../../utils/env';
import { appendToFile, expectFileToMatch } from '../../utils/fs';
import { ng, silentNpm } from '../../utils/process';
import { installPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
const snapshots = require('../../ng-snapshot/package.json');
@ -23,7 +24,7 @@ export default async function () {
});
for (const pkg of packagesToInstall) {
await silentNpm('install', pkg);
await installPackage(pkg);
}
}

View File

@ -1,7 +1,8 @@
import { stripIndent } from 'common-tags';
import { getGlobalVariable } from '../../utils/env';
import { expectFileToMatch, writeFile } from '../../utils/fs';
import { ng, npm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { readNgVersion } from '../../utils/version';
@ -159,7 +160,7 @@ export default function() {
updateJsonFile('package.json', packageJson => {
const dependencies = packageJson['dependencies'];
dependencies['@angular/platform-server'] = platformServerVersion;
}).then(() => npm('install')),
}).then(() => installWorkspacePackages()),
)
.then(() => ng('run', 'test-project:app-shell'))
.then(() => expectFileToMatch('dist/test-project/index.html', /shell Works!/));

View File

@ -1,6 +1,7 @@
import { getGlobalVariable } from '../../utils/env';
import { replaceInFile } from '../../utils/fs';
import { ng, silentNpm } from '../../utils/process';
import { installPackage, installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { isPrereleaseCli, updateJsonFile } from '../../utils/project';
const snapshots = require('../../ng-snapshot/package.json');
@ -25,12 +26,12 @@ export default async function () {
snapshots.dependencies['@angular/material-moment-adapter'];
});
await silentNpm('install');
await installWorkspacePackages();
} else {
await silentNpm('install', '@angular/material-moment-adapter');
await installPackage('@angular/material-moment-adapter');
}
await silentNpm('install', 'moment');
await installPackage('moment');
await ng('build', '--prod');

View File

@ -1,6 +1,7 @@
import { normalize } from 'path';
import { getGlobalVariable } from '../../utils/env';
import { appendToFile, expectFileToMatch, writeFile } from '../../utils/fs';
import { installPackage } from '../../utils/packages';
import { exec, ng, silentNpm } from '../../utils/process';
import { isPrereleaseCli, updateJsonFile } from '../../utils/project';
@ -37,7 +38,7 @@ export default async function () {
});
for (const pkg of packagesToInstall) {
await silentNpm('install', pkg);
await installPackage(pkg);
}
}

View File

@ -1,7 +1,8 @@
import {join} from 'path';
import {getGlobalVariable} from '../../utils/env';
import {expectFileNotToExist, expectFileToExist, expectFileToMatch, writeFile} from '../../utils/fs';
import {ng, npm, silentNpm} from '../../utils/process';
import { installPackage, uninstallPackage } from '../../utils/packages';
import {ng} from '../../utils/process';
const MANIFEST = {
index: '/index.html',
@ -25,8 +26,8 @@ const MANIFEST = {
export default function() {
// Can't use the `ng` helper because somewhere the environment gets
// stuck to the first build done
return silentNpm('remove', '@angular/service-worker')
.then(() => silentNpm('install', '@angular/service-worker'))
return uninstallPackage('@angular/service-worker')
.then(() => installPackage('@angular/service-worker'))
.then(() => ng('config', 'projects.test-project.architect.build.options.serviceWorker', 'true'))
.then(() => writeFile('src/ngsw-config.json', JSON.stringify(MANIFEST, null, 2)))
.then(() => ng('build', '--optimization'))

View File

@ -4,7 +4,8 @@ import {
replaceInFile,
writeMultipleFiles,
} from '../../../utils/fs';
import { ng, silentNpm } from '../../../utils/process';
import { installWorkspacePackages } from '../../../utils/packages';
import { ng } from '../../../utils/process';
import { updateJsonFile } from '../../../utils/project';
const snapshots = require('../../../ng-snapshot/package.json');
@ -19,7 +20,7 @@ export default async function () {
dependencies['@angular/cdk'] = isSnapshotBuild ? snapshots.dependencies['@angular/cdk'] : 'latest';
});
await silentNpm('install');
await installWorkspacePackages();
for (const ext of ['css', 'scss', 'less', 'styl']) {
await writeMultipleFiles({

View File

@ -4,7 +4,8 @@ import {
replaceInFile,
writeMultipleFiles,
} from '../../../utils/fs';
import { ng, silentExec, silentNpm } from '../../../utils/process';
import { installPackage } from '../../../utils/packages';
import { ng, silentExec } from '../../../utils/process';
import { updateJsonFile } from '../../../utils/project';
import { expectToFail } from '../../../utils/utils';
@ -32,7 +33,7 @@ export default async function () {
await silentExec('rm', '-rf', 'node_modules/sass');
await expectToFail(() => ng('build', '--extract-css', '--source-map'));
await silentNpm('install', 'node-sass');
await installPackage('node-sass');
await silentExec('rm', '-rf', 'node_modules/sass');
await ng('build', '--extract-css', '--source-map');
@ -41,9 +42,9 @@ export default async function () {
await expectToFail(() => expectFileToMatch('dist/test-project/styles.css', '"mappings":""'));
await expectFileToMatch('dist/test-project/main.js', /.outer.*.inner.*background:\s*#[fF]+/);
await silentNpm('install', 'node-gyp');
await silentNpm('install', 'fibers');
await silentNpm('install', 'sass');
await installPackage('node-gyp');
await installPackage('fibers');
await installPackage('sass');
await silentExec('rm', '-rf', 'node_modules/node-sass');
await ng('build', '--extract-css', '--source-map');

View File

@ -1,8 +1,13 @@
import { join } from 'path';
import { getGlobalVariable } from '../../../utils/env';
import { expectFileToExist, readFile, rimraf } from '../../../utils/fs';
import { ng, npm } from '../../../utils/process';
export default async function () {
if (getGlobalVariable('package-manager') === 'yarn') {
return;
}
// forcibly remove in case another test doesn't clean itself up
await rimraf('node_modules/@angular/pwa');

View File

@ -1,6 +1,7 @@
import { getGlobalVariable } from '../../utils/env';
import { expectFileToMatch, replaceInFile, writeFile } from '../../utils/fs';
import { ng, npm } from '../../utils/process';
import { installPackage, uninstallPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import { readNgVersion } from '../../utils/version';
export default async function() {
@ -57,7 +58,7 @@ export default async function() {
if (getGlobalVariable('argv')['ng-snapshots']) {
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
}
await npm('install', `${localizeVersion}`);
await installPackage(localizeVersion);
// Extract messages
await ng('xi18n', '--ivy');
@ -69,5 +70,5 @@ export default async function() {
'projects/i18n-lib-test/src/lib/i18n-lib-test.component.ts',
);
await npm('uninstall', '@angular/localize');
await uninstallPackage('@angular/localize');
}

View File

@ -1,7 +1,8 @@
import { join } from 'path';
import { getGlobalVariable } from '../../utils/env';
import { writeFile } from '../../utils/fs';
import { ng, npm } from '../../utils/process';
import { installPackage, uninstallPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
import { readNgVersion } from '../../utils/version';
@ -30,7 +31,7 @@ export default async function() {
if (getGlobalVariable('argv')['ng-snapshots']) {
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
}
await npm('install', `${localizeVersion}`);
await installPackage(localizeVersion);
// Should show ivy enabled application warning without --ivy flag
const { stderr: message3 } = await ng('xi18n', '--no-ivy');
@ -57,5 +58,5 @@ export default async function() {
throw new Error('Expected ivy disabled application warning');
}
await npm('uninstall', '@angular/localize');
await uninstallPackage('@angular/localize');
}

View File

@ -7,7 +7,8 @@ import {
replaceInFile,
writeFile,
} from '../../utils/fs';
import { ng, silentNpm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { readNgVersion } from '../../utils/version';
@ -38,7 +39,7 @@ export default async function () {
});
}
await silentNpm('install');
await installWorkspacePackages();
const browserBaseDir = 'dist/test-project/browser';

View File

@ -2,7 +2,8 @@ import * as express from 'express';
import { join } from 'path';
import { getGlobalVariable } from '../../utils/env';
import { appendToFile, expectFileToMatch, writeFile } from '../../utils/fs';
import { ng, silentNpm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
import { langTranslations, setupI18nConfig } from './legacy';
@ -27,7 +28,7 @@ export default async function () {
});
}
await silentNpm('install');
await installWorkspacePackages();
const serverbaseDir = 'dist/test-project/server';
const serverBuildArgs = ['run', 'test-project:server'];

View File

@ -8,7 +8,8 @@ import {
replaceInFile,
writeFile,
} from '../../utils/fs';
import { ng, npm } from '../../utils/process';
import { installPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
import { readNgVersion } from '../../utils/version';
@ -22,7 +23,7 @@ export default async function() {
if (getGlobalVariable('argv')['ng-snapshots']) {
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
}
await npm('install', `${localizeVersion}`);
await installPackage(localizeVersion);
let serviceWorkerVersion = '@angular/service-worker@' + readNgVersion();
if (getGlobalVariable('argv')['ng-snapshots']) {
@ -30,7 +31,7 @@ export default async function() {
'@angular/service-worker'
];
}
await npm('install', `${serviceWorkerVersion}`);
await installPackage(serviceWorkerVersion);
await updateJsonFile('tsconfig.json', config => {
config.compilerOptions.target = 'es2015';

View File

@ -2,7 +2,8 @@ import * as express from 'express';
import { resolve } from 'path';
import { getGlobalVariable } from '../../utils/env';
import { appendToFile, copyFile, expectFileToExist, expectFileToMatch, replaceInFile, writeFile } from '../../utils/fs';
import { ng, npm } from '../../utils/process';
import { installPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
import { readNgVersion } from '../../utils/version';
@ -213,7 +214,7 @@ export async function setupI18nConfig(useLocalize = true, format: keyof typeof f
if (getGlobalVariable('argv')['ng-snapshots']) {
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
}
await npm('install', `${localizeVersion}`);
await installPackage(localizeVersion);
}
// Extract the translation messages.

View File

@ -1,10 +1,11 @@
import { getGlobalVariable } from '../../utils/env';
import { expectFileToMatch, writeFile } from '../../utils/fs';
import { execAndWaitForOutputToMatch, ng, npm } from '../../utils/process';
import { installPackage } from '../../utils/packages';
import { execAndWaitForOutputToMatch, ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
import { readNgVersion } from '../../utils/version';
import { baseDir, externalServer, langTranslations, setupI18nConfig } from './legacy';
import { externalServer, langTranslations, setupI18nConfig } from './legacy';
export default async function() {
if (!getGlobalVariable('argv')['ve']) {
@ -19,7 +20,7 @@ export default async function() {
if (getGlobalVariable('argv')['ng-snapshots']) {
localizeVersion = require('../../ng-snapshot/package.json').dependencies['@angular/localize'];
}
await npm('install', `${localizeVersion}`);
await installPackage(localizeVersion);
// Ensure a ES2015 build is used.
await writeFile('.browserslistrc', 'Chrome 65');

View File

@ -1,7 +1,7 @@
import {readdirSync} from 'fs';
import {oneLine} from 'common-tags';
import {ng, silentNpm} from '../../utils/process';
import { installPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import {appendToFile, expectFileToExist, prependToFile, replaceInFile} from '../../utils/fs';
import {expectToFail} from '../../utils/utils';
@ -32,7 +32,7 @@ export default function() {
}
oldNumberOfFiles = currentNumberOfDistFiles;
})
.then(() => silentNpm('install', 'moment'))
.then(() => installPackage('moment'))
.then(() => appendToFile('src/app/lazy-a/lazy-a.module.ts', `
import * as moment from 'moment';
console.log(moment);

View File

@ -1,5 +1,6 @@
import { expectFileToMatch, writeFile } from '../../utils/fs';
import { ng, silentNpm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
@ -14,7 +15,7 @@ export default async function () {
};
});
await silentNpm('install');
await installWorkspacePackages();
await writeFile('./src/main.ts',
`

View File

@ -1,6 +1,6 @@
import {readdirSync} from 'fs';
import {ng, silentNpm} from '../../utils/process';
import { installPackage } from '../../utils/packages';
import {ng} from '../../utils/process';
import {appendToFile, writeFile, prependToFile, replaceInFile} from '../../utils/fs';
@ -53,7 +53,7 @@ export default function() {
oldNumberOfFiles = currentNumberOfDistFiles;
})
// verify 'import *' syntax doesn't break lazy modules
.then(() => silentNpm('install', 'moment'))
.then(() => installPackage('moment'))
.then(() => appendToFile('src/app/app.component.ts', `
import * as moment from 'moment';
console.log(moment);

View File

@ -1,5 +1,6 @@
import { appendToFile, createDir, moveFile, prependToFile } from '../../utils/fs';
import { ng, silentNpm } from '../../utils/process';
import { installPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
@ -50,11 +51,11 @@ export default async function () {
await prependToFile('src/app/app.module.ts', 'import * as firebase from \'firebase\';');
await appendToFile('src/app/app.module.ts', 'firebase.initializeApp({});');
await silentNpm('install', 'firebase@3.7.8');
await installPackage('firebase@3.7.8');
await ng('build', '--aot');
await ng('test', '--watch=false');
await silentNpm('install', 'firebase@4.9.0');
await installPackage('firebase@4.9.0');
await ng('build', '--aot');
await ng('test', '--watch=false');

View File

@ -1,5 +1,6 @@
import { writeMultipleFiles } from '../../utils/fs';
import { ng, npm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
export default function () {
@ -10,7 +11,7 @@ export default function () {
packageJson['dependencies']['@ngrx/store'] = '^9.1.0';
packageJson['dependencies']['@ngrx/store-devtools'] = '^9.1.0';
})
.then(() => npm('install'))
.then(() => installWorkspacePackages())
// Create an app that uses ngrx decorators and has e2e tests.
.then(_ => writeMultipleFiles({
'./e2e/src/app.po.ts': `

View File

@ -1,4 +1,5 @@
import {silentNpm, ng} from '../../utils/process';
import { installPackage } from '../../utils/packages';
import {ng} from '../../utils/process';
import {updateJsonFile} from '../../utils/project';
import {expectFileToMatch} from '../../utils/fs';
import {oneLineTrim} from 'common-tags';
@ -8,7 +9,7 @@ export default function() {
// TODO(architect): Delete this test. It is now in devkit/build-angular.
return Promise.resolve()
.then(() => silentNpm('install', 'bootstrap@4.0.0-beta.3'))
.then(() => installPackage('bootstrap@4.0.0-beta.3'))
.then(() => updateJsonFile('angular.json', workspaceJson => {
const appArchitect = workspaceJson.projects['test-project'].architect;
appArchitect.build.options.styles = [

View File

@ -1,10 +1,11 @@
import { expectFileToMatch } from '../../utils/fs';
import { ng, silentNpm } from '../../utils/process';
import { installPackage } from '../../utils/packages';
import { ng } from '../../utils/process';
import { updateJsonFile } from '../../utils/project';
export default async function() {
// Install material design icons
await silentNpm('install', 'material-design-icons@3.0.1');
await installPackage('material-design-icons@3.0.1');
// Add icon stylesheet to application
await updateJsonFile('angular.json', workspaceJson => {

View File

@ -1,5 +1,6 @@
import { createProjectFromAsset } from '../../utils/assets';
import { ng, silentNpm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { isPrereleaseCli, useBuiltPackages, useCIChrome, useCIDefaults } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
@ -12,7 +13,7 @@ export default async function() {
await expectToFail(() => ng('build'));
await ng('update', '@angular/cli');
await useBuiltPackages();
await silentNpm('install');
await installWorkspacePackages(false);
await ng('update', '@angular/core', ...extraUpdateArgs);
await useCIDefaults('one-oh-project');
await ng('generate', 'component', 'my-comp');

View File

@ -1,5 +1,6 @@
import { createProjectFromAsset } from '../../utils/assets';
import { ng, silentNpm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { isPrereleaseCli, useBuiltPackages } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
@ -11,7 +12,7 @@ export default async function() {
await expectToFail(() => ng('build'));
await ng('update', '@angular/cli', '--migrate-only', '--from=1.7.1');
await useBuiltPackages();
await silentNpm('install');
await installWorkspacePackages(false);
await ng('update', '@angular/core', ...extraUpdateArgs);
await ng('build');
}

View File

@ -1,6 +1,7 @@
import * as fs from 'fs';
import { createProjectFromAsset } from '../../utils/assets';
import { ng, silentNpm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { isPrereleaseCli, useBuiltPackages, useCIChrome, useCIDefaults } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
@ -14,7 +15,7 @@ export default async function() {
await expectToFail(() => ng('build'));
await ng('update', '@angular/cli');
await useBuiltPackages();
await silentNpm('install');
await installWorkspacePackages(false);
await ng('update', '@angular/core', ...extraUpdateArgs);
await useCIDefaults('latest-project');
await ng('generate', 'component', 'my-comp');

View File

@ -1,5 +1,6 @@
import { createProjectFromAsset } from '../../utils/assets';
import { expectFileMatchToExist, expectFileToExist, expectFileToMatch } from '../../utils/fs';
import { installWorkspacePackages } from '../../utils/packages';
import { ng, noSilentNg, silentNpm } from '../../utils/process';
import { isPrereleaseCli, useBuiltPackages, useCIChrome, useCIDefaults } from '../../utils/project';
import { expectToFail } from '../../utils/utils';
@ -27,11 +28,12 @@ export default async function() {
await useCIChrome('src/');
await useCIChrome('e2e/');
await useCIDefaults('seven-oh-project');
await silentNpm('install');
await installWorkspacePackages(false);
// Update Angular.
const extraUpdateArgs = (await isPrereleaseCli()) ? ['--next', '--force'] : [];
await ng('update', '@angular/core', ...extraUpdateArgs);
await silentNpm('run', 'webdriver-update');
// Run CLI commands.
await ng('generate', 'component', 'my-comp');

View File

@ -1,4 +1,5 @@
import { ng, silentNpm } from '../../utils/process';
import { installWorkspacePackages } from '../../utils/packages';
import { ng } from '../../utils/process';
import { readFile, writeFile } from '../../utils/fs';
import { updateJsonFile } from '../../utils/project';
@ -45,5 +46,5 @@ export default function () {
}
})
.then(() => writeFile('package.json', origPackageJson))
.then(() => silentNpm('install'));
.then(() => installWorkspacePackages());
}

View File

@ -3,8 +3,8 @@ import * as glob from 'glob';
import { getGlobalVariable } from './env';
import { relative, resolve } from 'path';
import { copyFile, writeFile } from './fs';
import { installWorkspacePackages } from './packages';
import { useBuiltPackages } from './project';
import { silentNpm } from './process';
export function assetDir(assetName: string) {
return join(__dirname, '../assets', assetName);
@ -53,7 +53,7 @@ export async function createProjectFromAsset(
}
if (!skipInstall) {
await silentNpm('install');
await installWorkspacePackages(false);
}
return dir;

View File

@ -0,0 +1,46 @@
import { getGlobalVariable } from './env';
import { ProcessOutput, silentNpm, silentYarn } from './process';
export function getActivePackageManager(): 'npm' | 'yarn' {
const value = getGlobalVariable('package-manager');
if (value && value !== 'npm' && value !== 'yarn') {
throw new Error('Invalid package manager value: ' + value);
}
return value || 'npm';
}
export async function installWorkspacePackages(updateWebdriver = true): Promise<void> {
switch (getActivePackageManager()) {
case 'npm':
await silentNpm('install');
if (updateWebdriver) {
await silentNpm('run', 'webdriver-update');
}
break;
case 'yarn':
await silentYarn();
if (updateWebdriver) {
await silentYarn('webdriver-update');
}
break;
}
}
export async function installPackage(specifier: string): Promise<ProcessOutput> {
switch (getActivePackageManager()) {
case 'npm':
return silentNpm('install', specifier);
case 'yarn':
return silentYarn('add', specifier);
}
}
export async function uninstallPackage(name: string): Promise<ProcessOutput> {
switch (getActivePackageManager()) {
case 'npm':
return silentNpm('uninstall', name);
case 'yarn':
return silentYarn('remove', name);
}
}

View File

@ -4,7 +4,8 @@ import { packages } from '../../../../lib/packages';
import { getGlobalVariable } from './env';
import { prependToFile, readFile, replaceInFile, writeFile } from './fs';
import { gitCommit } from './git';
import { execAndWaitForOutputToMatch, git, ng, npm, silentNpm } from './process';
import { installWorkspacePackages } from './packages';
import { execAndWaitForOutputToMatch, git, ng, npm } from './process';
const tsConfigPath = 'tsconfig.json';
@ -94,9 +95,7 @@ export async function prepareProjectForE2e(name) {
console.log(
`Project ${name} created... Installing npm.`,
);
await silentNpm(
'install',
);
await installWorkspacePackages(false);
await useCIDefaults(
name,
);

View File

@ -143,6 +143,7 @@ if (testsToRun.length == allTests.length) {
}
setGlobalVariable('argv', argv);
setGlobalVariable('package-manager', argv.yarn ? 'yarn' : 'npm');
// Setup local package registry
const registryPath =