chore(react): improve react e2e tests speed (#15997)

This commit is contained in:
Emily Xiong 2023-04-14 16:43:58 -04:00 committed by GitHub
parent d54f848810
commit 5f86929f34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 377 additions and 312 deletions

View File

@ -118,7 +118,8 @@ jobs:
- e2e-nx-misc - e2e-nx-misc
- e2e-nx-plugin - e2e-nx-plugin
- e2e-nx-run - e2e-nx-run
- e2e-react - e2e-react-core
- e2e-react-extensions
- e2e-react-native - e2e-react-native
- e2e-web - e2e-web
- e2e-rollup - e2e-rollup
@ -172,7 +173,9 @@ jobs:
codeowners: 'S04SYHYKGNP' codeowners: 'S04SYHYKGNP'
- project: e2e-nx-run - project: e2e-nx-run
codeowners: 'S04SYHYKGNP' codeowners: 'S04SYHYKGNP'
- project: e2e-react - project: e2e-react-core
codeowners: 'S04TNCNJG5N'
- project: e2e-react-extensions
codeowners: 'S04TNCNJG5N' codeowners: 'S04TNCNJG5N'
- project: e2e-react-native - project: e2e-react-native
codeowners: 'S04TNCNJG5N' codeowners: 'S04TNCNJG5N'
@ -232,7 +235,9 @@ jobs:
- node_version: 16 - node_version: 16
project: e2e-lerna-smoke-tests project: e2e-lerna-smoke-tests
- node_version: 16 - node_version: 16
project: e2e-react project: e2e-react-core
- node_version: 16
project: e2e-react-extensions
- node_version: 16 - node_version: 16
project: e2e-react-native project: e2e-react-native
- node_version: 16 - node_version: 16
@ -278,7 +283,9 @@ jobs:
- node_version: 19 - node_version: 19
project: e2e-lerna-smoke-tests project: e2e-lerna-smoke-tests
- node_version: 19 - node_version: 19
project: e2e-react project: e2e-react-core
- node_version: 19
project: e2e-react-extensions
- node_version: 19 - node_version: 19
project: e2e-react-native project: e2e-react-native
- node_version: 19 - node_version: 19

View File

@ -87,7 +87,8 @@ jobs:
- e2e-nx-misc - e2e-nx-misc
- e2e-nx-plugin - e2e-nx-plugin
- e2e-nx-run - e2e-nx-run
- e2e-react - e2e-react-core
- e2e-react-extensions
- e2e-web - e2e-web
- e2e-rollup - e2e-rollup
- e2e-storybook - e2e-storybook
@ -126,7 +127,9 @@ jobs:
codeowners: 'S04SYHYKGNP' codeowners: 'S04SYHYKGNP'
- project: e2e-nx-run - project: e2e-nx-run
codeowners: 'S04SYHYKGNP' codeowners: 'S04SYHYKGNP'
- project: e2e-react - project: e2e-react-core
codeowners: 'S04TNCNJG5N'
- project: e2e-react-extensions
codeowners: 'S04TNCNJG5N' codeowners: 'S04TNCNJG5N'
- project: e2e-web - project: e2e-web
codeowners: 'S04SJ6PL98X' codeowners: 'S04SJ6PL98X'
@ -173,7 +176,9 @@ jobs:
- node_version: 16 - node_version: 16
project: e2e-lerna-smoke-tests project: e2e-lerna-smoke-tests
- node_version: 16 - node_version: 16
project: e2e-react project: e2e-react-core
- node_version: 16
project: e2e-react-extensions
- node_version: 16 - node_version: 16
project: e2e-web project: e2e-web
- node_version: 16 - node_version: 16
@ -213,7 +218,9 @@ jobs:
- node_version: 19 - node_version: 19
project: e2e-lerna-smoke-tests project: e2e-lerna-smoke-tests
- node_version: 19 - node_version: 19
project: e2e-react project: e2e-react-core
- node_version: 19
project: e2e-react-extensions
- node_version: 19 - node_version: 19
project: e2e-web project: e2e-web
- node_version: 19 - node_version: 19

View File

@ -33,7 +33,8 @@ yarn.lock @FrozenPandaz @vsavkin @AgentEnder @jaysoo @JamesHenry
/docs/shared/packages/react/** @jaysoo @ndcunningham @mandarini @xiongemi /docs/shared/packages/react/** @jaysoo @ndcunningham @mandarini @xiongemi
/docs/shared/packages/next/** @jaysoo @ndcunningham @xiongemi /docs/shared/packages/next/** @jaysoo @ndcunningham @xiongemi
/packages/react/** @jaysoo @ndcunningham @mandarini @xiongemi /packages/react/** @jaysoo @ndcunningham @mandarini @xiongemi
/e2e/react/** @jaysoo @mandarini @xiongemi @ndcunningham /e2e/react-core/** @jaysoo @mandarini @xiongemi @ndcunningham
/e2e/react-extensions/** @jaysoo @mandarini @xiongemi @ndcunningham
/packages/next/** @ndcunningham @jaysoo @xiongemi /packages/next/** @ndcunningham @jaysoo @xiongemi
/e2e/next/** @ndcunningham @jaysoo @xiongemi /e2e/next/** @ndcunningham @jaysoo @xiongemi
/packages/react/plugins/component-testing/** @jaysoo @ndcunningham @barbados-clemens /packages/react/plugins/component-testing/** @jaysoo @ndcunningham @barbados-clemens

View File

@ -6,6 +6,6 @@ export default {
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1, maxWorkers: 1,
globals: {}, globals: {},
displayName: 'e2e-react', displayName: 'e2e-react-core',
preset: '../../jest.preset.js', preset: '../../jest.preset.js',
}; };

View File

@ -1,7 +1,7 @@
{ {
"name": "e2e-react", "name": "e2e-react-core",
"$schema": "../../node_modules/nx/schemas/project-schema.json", "$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "e2e/react", "sourceRoot": "e2e/react-core",
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": {}, "e2e": {},

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -15,9 +15,9 @@ import {
describe('React Module Federation', () => { describe('React Module Federation', () => {
let proj: string; let proj: string;
beforeEach(() => (proj = newProject())); beforeAll(() => (proj = newProject()));
afterEach(() => cleanupProject()); afterAll(() => cleanupProject());
it('should generate host and remote apps', async () => { it('should generate host and remote apps', async () => {
const shell = uniq('shell'); const shell = uniq('shell');

View File

@ -264,130 +264,3 @@ export async function h() { return 'c'; }
}, 250000); }, 250000);
}); });
}); });
describe('Build React applications and libraries with Vite', () => {
let proj: string;
beforeEach(() => {
proj = newProject();
});
it('should test and lint app with bundler=vite', async () => {
const viteApp = uniq('viteapp');
runCLI(
`generate @nrwl/react:app ${viteApp} --bundler=vite --unitTestRunner=vitest --no-interactive`
);
const appTestResults = await runCLIAsync(`test ${viteApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);
const appLintResults = await runCLIAsync(`lint ${viteApp}`);
expect(appLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);
await runCLIAsync(`build ${viteApp}`);
checkFilesExist(`dist/apps/${viteApp}/index.html`);
}, 300_000);
it('should test and lint app with bundler=vite and inSourceTests', async () => {
const viteApp = uniq('viteapp');
const viteLib = uniq('vitelib');
runCLI(
`generate @nrwl/react:app ${viteApp} --bundler=vite --unitTestRunner=vitest --inSourceTests --no-interactive`
);
expect(() => {
checkFilesExist(`apps/${viteApp}/src/app/app.spec.tsx`);
}).toThrow();
const appTestResults = await runCLIAsync(`test ${viteApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);
const appLintResults = await runCLIAsync(`lint ${viteApp}`);
expect(appLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);
await runCLIAsync(`build ${viteApp}`);
checkFilesExist(`dist/apps/${viteApp}/index.html`);
runCLI(
`generate @nrwl/react:lib ${viteLib} --bundler=vite --inSourceTests --unitTestRunner=vitest --no-interactive`
);
expect(() => {
checkFilesExist(`libs/${viteLib}/src/lib/${viteLib}.spec.tsx`);
}).toThrow();
runCLI(
`generate @nrwl/react:component comp1 --inSourceTests --export --project=${viteLib} --no-interactive`
);
expect(() => {
checkFilesExist(`libs/${viteLib}/src/lib/comp1/comp1.spec.tsx`);
}).toThrow();
runCLI(
`generate @nrwl/react:component comp2 --export --project=${viteLib} --no-interactive`
);
checkFilesExist(`libs/${viteLib}/src/lib/comp2/comp2.spec.tsx`);
const libTestResults = await runCLIAsync(`test ${viteLib}`);
expect(libTestResults.combinedOutput).toContain(
'Successfully ran target test'
);
const libLintResults = await runCLIAsync(`lint ${viteLib}`);
expect(libLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);
await runCLIAsync(`build ${viteLib}`);
checkFilesExist(
`dist/libs/${viteLib}/index.d.ts`,
`dist/libs/${viteLib}/index.js`,
`dist/libs/${viteLib}/index.mjs`
);
}, 300_000);
it('should support bundling with Vite', async () => {
const viteLib = uniq('vitelib');
runCLI(
`generate @nrwl/react:lib ${viteLib} --bundler=vite --no-interactive --unit-test-runner=none`
);
const packageJson = readJson('package.json');
// Vite does not need these libraries to work.
expect(packageJson.dependencies['core-js']).toBeUndefined();
expect(packageJson.dependencies['tslib']).toBeUndefined();
await runCLIAsync(`build ${viteLib}`);
checkFilesExist(
`dist/libs/${viteLib}/package.json`,
`dist/libs/${viteLib}/index.d.ts`,
`dist/libs/${viteLib}/index.js`,
`dist/libs/${viteLib}/index.mjs`
);
// Convert non-buildable lib to buildable one
const nonBuildableLib = uniq('nonbuildablelib');
runCLI(
`generate @nrwl/react:lib ${nonBuildableLib} --no-interactive --unitTestRunner=jest`
);
runCLI(
`generate @nrwl/vite:configuration ${nonBuildableLib} --uiFramework=react --no-interactive`
);
await runCLIAsync(`build ${nonBuildableLib}`);
checkFilesExist(
`dist/libs/${nonBuildableLib}/index.d.ts`,
`dist/libs/${nonBuildableLib}/index.js`,
`dist/libs/${nonBuildableLib}/index.mjs`
);
}, 300_000);
});

View File

@ -21,12 +21,12 @@ import { join } from 'path';
describe('React Applications', () => { describe('React Applications', () => {
let proj: string; let proj: string;
beforeEach(() => { beforeAll(() => {
proj = newProject(); proj = newProject();
ensureCypressInstallation(); ensureCypressInstallation();
}); });
afterEach(() => cleanupProject()); afterAll(() => cleanupProject());
it('should be able to generate a react app + lib (with CSR and SSR)', async () => { it('should be able to generate a react app + lib (with CSR and SSR)', async () => {
const appName = uniq('app'); const appName = uniq('app');
@ -187,152 +187,183 @@ describe('React Applications', () => {
expect(await killPorts()).toBeTruthy(); expect(await killPorts()).toBeTruthy();
}, 250_000); }, 250_000);
async function testGeneratedApp( it('should generate app with routing', async () => {
appName,
opts: {
checkStyles: boolean;
checkLinter: boolean;
checkE2E: boolean;
checkSourceMap?: boolean;
}
) {
if (opts.checkLinter) {
const lintResults = runCLI(`lint ${appName}`);
expect(lintResults).toContain('All files pass linting.');
}
runCLI(
`build ${appName} --outputHashing none ${
opts.checkSourceMap ? '--sourceMap' : ''
}`
);
const filesToCheck = [
`dist/apps/${appName}/index.html`,
`dist/apps/${appName}/runtime.js`,
`dist/apps/${appName}/main.js`,
];
if (opts.checkSourceMap) {
filesToCheck.push(`dist/apps/${appName}/main.js.map`);
}
if (opts.checkStyles) {
filesToCheck.push(`dist/apps/${appName}/styles.css`);
}
checkFilesExist(...filesToCheck);
if (opts.checkStyles) {
expect(readFile(`dist/apps/${appName}/index.html`)).toContain(
'<link rel="stylesheet" href="styles.css">'
);
}
const testResults = await runCLIAsync(`test ${appName}`);
expect(testResults.combinedOutput).toContain(
'Test Suites: 1 passed, 1 total'
);
if (opts.checkE2E && runCypressTests()) {
const e2eResults = runCLI(`e2e ${appName}-e2e --no-watch`);
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();
}
}
});
describe('React Applications: --style option', () => {
// Only create workspace once
beforeAll(() => newProject());
it.each`
style
${'css'}
${'scss'}
${'less'}
${'styl'}
`('should support global and css modules', ({ style }) => {
const appName = uniq('app'); const appName = uniq('app');
runCLI(
`generate @nrwl/react:app ${appName} --style=${style} --bundler=webpack --no-interactive`
);
// make sure stylePreprocessorOptions works runCLI(
updateProjectConfig(appName, (config) => { `generate @nrwl/react:app ${appName} --routing --bundler=webpack --no-interactive`
config.targets.build.options.stylePreprocessorOptions = {
includePaths: ['libs/shared/lib'],
};
return config;
});
updateFile(
`apps/${appName}/src/styles.${style}`,
`@import 'base.${style}';`
);
updateFile(
`apps/${appName}/src/app/app.module.${style}`,
(s) => `@import 'base.${style}';\n${s}`
);
updateFile(
`libs/shared/lib/base.${style}`,
`body { font-family: "Comic Sans MS"; }`
); );
runCLI(`build ${appName} --outputHashing none`); runCLI(`build ${appName} --outputHashing none`);
expect(readFile(`dist/apps/${appName}/styles.css`)).toMatch( checkFilesExist(
/Comic Sans MS/ `dist/apps/${appName}/index.html`,
`dist/apps/${appName}/runtime.js`,
`dist/apps/${appName}/main.js`
); );
}); }, 250_000);
});
describe('React Applications and Libs with PostCSS', () => { it('should be able to add a redux slice', async () => {
let proj: string;
beforeAll(() => (proj = newProject()));
it('should support single path or auto-loading of PostCSS config files', async () => {
const appName = uniq('app'); const appName = uniq('app');
const libName = uniq('lib'); const libName = uniq('lib');
runCLI(`g @nrwl/react:app ${appName} --bundler=webpack --no-interactive`); runCLI(`g @nrwl/react:app ${appName} --bundler=webpack --no-interactive`);
runCLI(`g @nrwl/react:redux lemon --project=${appName}`);
runCLI( runCLI(
`g @nrwl/react:lib ${libName} --no-interactive --unit-test-runner=none` `g @nrwl/react:lib ${libName} --unit-test-runner=jest --no-interactive`
);
runCLI(`g @nrwl/react:redux orange --project=${libName}`);
const appTestResults = await runCLIAsync(`test ${appName}`);
expect(appTestResults.combinedOutput).toContain(
'Test Suites: 2 passed, 2 total'
); );
const mainPath = `apps/${appName}/src/main.tsx`; const libTestResults = await runCLIAsync(`test ${libName}`);
updateFile( expect(libTestResults.combinedOutput).toContain(
mainPath, 'Test Suites: 2 passed, 2 total'
`import '@${proj}/${libName}';\n${readFile(mainPath)}`
); );
}, 250_000);
createFile( describe('React Applications: --style option', () => {
`apps/${appName}/postcss.config.js`, it.each`
` style
${'css'}
${'scss'}
${'less'}
${'styl'}
`('should support global and css modules', ({ style }) => {
const appName = uniq('app');
runCLI(
`generate @nrwl/react:app ${appName} --style=${style} --bundler=webpack --no-interactive`
);
// make sure stylePreprocessorOptions works
updateProjectConfig(appName, (config) => {
config.targets.build.options.stylePreprocessorOptions = {
includePaths: ['libs/shared/lib'],
};
return config;
});
updateFile(
`apps/${appName}/src/styles.${style}`,
`@import 'base.${style}';`
);
updateFile(
`apps/${appName}/src/app/app.module.${style}`,
(s) => `@import 'base.${style}';\n${s}`
);
updateFile(
`libs/shared/lib/base.${style}`,
`body { font-family: "Comic Sans MS"; }`
);
runCLI(`build ${appName} --outputHashing none`);
expect(readFile(`dist/apps/${appName}/styles.css`)).toMatch(
/Comic Sans MS/
);
});
});
describe('React Applications and Libs with PostCSS', () => {
it('should support single path or auto-loading of PostCSS config files', async () => {
const appName = uniq('app');
const libName = uniq('lib');
runCLI(`g @nrwl/react:app ${appName} --bundler=webpack --no-interactive`);
runCLI(
`g @nrwl/react:lib ${libName} --no-interactive --unit-test-runner=none`
);
const mainPath = `apps/${appName}/src/main.tsx`;
updateFile(
mainPath,
`import '@${proj}/${libName}';\n${readFile(mainPath)}`
);
createFile(
`apps/${appName}/postcss.config.js`,
`
console.log('HELLO FROM APP'); // need this output for e2e test console.log('HELLO FROM APP'); // need this output for e2e test
module.exports = {}; module.exports = {};
` `
); );
createFile( createFile(
`libs/${libName}/postcss.config.js`, `libs/${libName}/postcss.config.js`,
` `
console.log('HELLO FROM LIB'); // need this output for e2e test console.log('HELLO FROM LIB'); // need this output for e2e test
module.exports = {}; module.exports = {};
` `
); );
let buildResults = await runCLIAsync(`build ${appName}`); let buildResults = await runCLIAsync(`build ${appName}`);
expect(buildResults.combinedOutput).toMatch(/HELLO FROM APP/); expect(buildResults.combinedOutput).toMatch(/HELLO FROM APP/);
expect(buildResults.combinedOutput).toMatch(/HELLO FROM LIB/); expect(buildResults.combinedOutput).toMatch(/HELLO FROM LIB/);
// Only load app PostCSS config // Only load app PostCSS config
updateJson(`apps/${appName}/project.json`, (json) => { updateJson(`apps/${appName}/project.json`, (json) => {
json.targets.build.options.postcssConfig = `apps/${appName}/postcss.config.js`; json.targets.build.options.postcssConfig = `apps/${appName}/postcss.config.js`;
return json; return json;
}); });
buildResults = await runCLIAsync(`build ${appName}`); buildResults = await runCLIAsync(`build ${appName}`);
expect(buildResults.combinedOutput).toMatch(/HELLO FROM APP/); expect(buildResults.combinedOutput).toMatch(/HELLO FROM APP/);
expect(buildResults.combinedOutput).not.toMatch(/HELLO FROM LIB/); expect(buildResults.combinedOutput).not.toMatch(/HELLO FROM LIB/);
}, 250_000); }, 250_000);
});
}); });
async function testGeneratedApp(
appName,
opts: {
checkStyles: boolean;
checkLinter: boolean;
checkE2E: boolean;
checkSourceMap?: boolean;
}
) {
if (opts.checkLinter) {
const lintResults = runCLI(`lint ${appName}`);
expect(lintResults).toContain('All files pass linting.');
}
runCLI(
`build ${appName} --outputHashing none ${
opts.checkSourceMap ? '--sourceMap' : ''
}`
);
const filesToCheck = [
`dist/apps/${appName}/index.html`,
`dist/apps/${appName}/runtime.js`,
`dist/apps/${appName}/main.js`,
];
if (opts.checkSourceMap) {
filesToCheck.push(`dist/apps/${appName}/main.js.map`);
}
if (opts.checkStyles) {
filesToCheck.push(`dist/apps/${appName}/styles.css`);
}
checkFilesExist(...filesToCheck);
if (opts.checkStyles) {
expect(readFile(`dist/apps/${appName}/index.html`)).toContain(
'<link rel="stylesheet" href="styles.css">'
);
}
const testResults = await runCLIAsync(`test ${appName}`);
expect(testResults.combinedOutput).toContain(
'Test Suites: 1 passed, 1 total'
);
if (opts.checkE2E && runCypressTests()) {
const e2eResults = runCLI(`e2e ${appName}-e2e --no-watch`);
expect(e2eResults).toContain('All specs passed!');
expect(await killPorts()).toBeTruthy();
}
}

View File

@ -0,0 +1,11 @@
/* eslint-disable */
export default {
transform: {
'^.+\\.[tj]sx?$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: {},
displayName: 'e2e-react-extensions',
preset: '../../jest.preset.js',
};

View File

@ -0,0 +1,11 @@
{
"name": "e2e-react-extensions",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "e2e/react-extensions",
"projectType": "application",
"targets": {
"e2e": {},
"run-e2e-tests": {}
},
"implicitDependencies": ["react"]
}

View File

@ -0,0 +1,140 @@
import {
checkFilesExist,
cleanupProject,
newProject,
readJson,
runCLI,
runCLIAsync,
uniq,
} from '@nrwl/e2e/utils';
describe('Build React applications and libraries with Vite', () => {
let proj: string;
beforeEach(() => {
proj = newProject();
});
afterAll(() => {
cleanupProject();
});
it('should test and lint app with bundler=vite', async () => {
const viteApp = uniq('viteapp');
runCLI(
`generate @nrwl/react:app ${viteApp} --bundler=vite --unitTestRunner=vitest --no-interactive`
);
const appTestResults = await runCLIAsync(`test ${viteApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);
const appLintResults = await runCLIAsync(`lint ${viteApp}`);
expect(appLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);
await runCLIAsync(`build ${viteApp}`);
checkFilesExist(`dist/apps/${viteApp}/index.html`);
}, 300_000);
it('should test and lint app with bundler=vite and inSourceTests', async () => {
const viteApp = uniq('viteapp');
const viteLib = uniq('vitelib');
runCLI(
`generate @nrwl/react:app ${viteApp} --bundler=vite --unitTestRunner=vitest --inSourceTests --no-interactive`
);
expect(() => {
checkFilesExist(`apps/${viteApp}/src/app/app.spec.tsx`);
}).toThrow();
const appTestResults = await runCLIAsync(`test ${viteApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);
const appLintResults = await runCLIAsync(`lint ${viteApp}`);
expect(appLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);
await runCLIAsync(`build ${viteApp}`);
checkFilesExist(`dist/apps/${viteApp}/index.html`);
runCLI(
`generate @nrwl/react:lib ${viteLib} --bundler=vite --inSourceTests --unitTestRunner=vitest --no-interactive`
);
expect(() => {
checkFilesExist(`libs/${viteLib}/src/lib/${viteLib}.spec.tsx`);
}).toThrow();
runCLI(
`generate @nrwl/react:component comp1 --inSourceTests --export --project=${viteLib} --no-interactive`
);
expect(() => {
checkFilesExist(`libs/${viteLib}/src/lib/comp1/comp1.spec.tsx`);
}).toThrow();
runCLI(
`generate @nrwl/react:component comp2 --export --project=${viteLib} --no-interactive`
);
checkFilesExist(`libs/${viteLib}/src/lib/comp2/comp2.spec.tsx`);
const libTestResults = await runCLIAsync(`test ${viteLib}`);
expect(libTestResults.combinedOutput).toContain(
'Successfully ran target test'
);
const libLintResults = await runCLIAsync(`lint ${viteLib}`);
expect(libLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);
await runCLIAsync(`build ${viteLib}`);
checkFilesExist(
`dist/libs/${viteLib}/index.d.ts`,
`dist/libs/${viteLib}/index.js`,
`dist/libs/${viteLib}/index.mjs`
);
}, 300_000);
it('should support bundling with Vite', async () => {
const viteLib = uniq('vitelib');
runCLI(
`generate @nrwl/react:lib ${viteLib} --bundler=vite --no-interactive --unit-test-runner=none`
);
const packageJson = readJson('package.json');
// Vite does not need these libraries to work.
expect(packageJson.dependencies['core-js']).toBeUndefined();
expect(packageJson.dependencies['tslib']).toBeUndefined();
await runCLIAsync(`build ${viteLib}`);
checkFilesExist(
`dist/libs/${viteLib}/package.json`,
`dist/libs/${viteLib}/index.d.ts`,
`dist/libs/${viteLib}/index.js`,
`dist/libs/${viteLib}/index.mjs`
);
// Convert non-buildable lib to buildable one
const nonBuildableLib = uniq('nonbuildablelib');
runCLI(
`generate @nrwl/react:lib ${nonBuildableLib} --no-interactive --unitTestRunner=jest`
);
runCLI(
`generate @nrwl/vite:configuration ${nonBuildableLib} --uiFramework=react --no-interactive`
);
await runCLIAsync(`build ${nonBuildableLib}`);
checkFilesExist(
`dist/libs/${nonBuildableLib}/index.d.ts`,
`dist/libs/${nonBuildableLib}/index.js`,
`dist/libs/${nonBuildableLib}/index.mjs`
);
}, 300_000);
});

View File

@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node", "jest"]
},
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@ -0,0 +1,20 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"**/*.d.ts",
"jest.config.ts"
]
}

View File

@ -1,49 +0,0 @@
import {
checkFilesExist,
newProject,
runCLI,
runCLIAsync,
uniq,
} from '@nrwl/e2e/utils';
describe('React Applications: additional packages', () => {
beforeAll(() => newProject());
it('should generate app with routing', async () => {
const appName = uniq('app');
runCLI(
`generate @nrwl/react:app ${appName} --routing --bundler=webpack --no-interactive`
);
runCLI(`build ${appName} --outputHashing none`);
checkFilesExist(
`dist/apps/${appName}/index.html`,
`dist/apps/${appName}/runtime.js`,
`dist/apps/${appName}/main.js`
);
}, 250_000);
it('should be able to add a redux slice', async () => {
const appName = uniq('app');
const libName = uniq('lib');
runCLI(`g @nrwl/react:app ${appName} --bundler=webpack --no-interactive`);
runCLI(`g @nrwl/react:redux lemon --project=${appName}`);
runCLI(
`g @nrwl/react:lib ${libName} --unit-test-runner=jest --no-interactive`
);
runCLI(`g @nrwl/react:redux orange --project=${libName}`);
const appTestResults = await runCLIAsync(`test ${appName}`);
expect(appTestResults.combinedOutput).toContain(
'Test Suites: 2 passed, 2 total'
);
const libTestResults = await runCLIAsync(`test ${libName}`);
expect(libTestResults.combinedOutput).toContain(
'Test Suites: 2 passed, 2 total'
);
}, 250_000);
});