* feat(testing): add generator to aid in the migration to cypress 10 cypress 10 introduces a new configuration format and new layout that requires update settings and files for e2e projects * feat(testing): cypress component tests for react/next initial work for cypress component tests for react and next * feat(testing): add support for v10 e2e cypress projects create the correct files for cypress projects >v10 and reorganize tests based on version to allow easier parsing of tests * feat(testing): add utils for modifying cypress v10 config provide ts transformers to take in an existing cypress config and update/add properties within the given configuration * fix(testing): fix tests affected by the cypress v10 changes update tests to assert the correct files/folders/file contents due to the cypress changes in v10 * cleanup(testing): move cypress component testing plugins into the respective packages move the plugins into out of cypress plugins into the specific vertical plugin to prevent issues with circular refs * cleanup(testing): bump cypress version bump to latest cypress v10 release * docs(testing): update docs for cypress 10 update cypress docs to include info about component testing and migration to cypress v10 * fix(repo): revert cypress version bump keep v9 of cypress installed for nx repo until v10 release * fix(testing): update cypress gen tsconfig and infer targets with converter * fix(testing): make sure tests use the cypress v10 (for the intermediate) * fix(testing): update target name after feedback * fix(testing): support multiple target w/custom configs for cypress v10 migration * fix(testing): refactor cy component tests into seperate verticals * feat(testing): create storybook cypress preset * fix(testing): clean up cy v10 migration * fix(testing): don't branch for cypress executor testingType * fix(testing): move cy comp test generator to next * fix(testing): bump cypress deps * fix(testing): clean up cy component testing generators * fix(testing): update cy component testing docs * fix(testign): dep check. runtime plugin pulls from @nrwl/react * fix(testing): move e2e into verticals * fix(testing): address PR feedback * fix(testing): clean up unit tests * feat(angular): support migrating angular cli workspaces using cypress v10 * chore(testing): update e2e tests * fix(testing): address pr feedback * chore(testing): remove cypress component testing for next.js * fix(testing): address pr feedback Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
215 lines
6.4 KiB
TypeScript
215 lines
6.4 KiB
TypeScript
import { installedCypressVersion } from '@nrwl/cypress/src/utils/cypress-version';
|
|
import { logger, Tree } from '@nrwl/devkit';
|
|
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
|
|
import { Linter } from '@nrwl/linter';
|
|
import applicationGenerator from '../application/application';
|
|
import componentGenerator from '../component/component';
|
|
import libraryGenerator from '../library/library';
|
|
import storybookConfigurationGenerator from './configuration';
|
|
// need to mock cypress otherwise it'll use the nx installed version from package.json
|
|
// which is v9 while we are testing for the new v10 version
|
|
jest.mock('@nrwl/cypress/src/utils/cypress-version');
|
|
describe('react:storybook-configuration', () => {
|
|
let appTree;
|
|
let mockedInstalledCypressVersion: jest.Mock<
|
|
ReturnType<typeof installedCypressVersion>
|
|
> = installedCypressVersion as never;
|
|
beforeEach(async () => {
|
|
// jest.spyOn(fileUtils, 'readPackageJson').mockReturnValue({
|
|
// devDependencies: {
|
|
// '@storybook/addon-essentials': '^6.0.21',
|
|
// '@storybook/react': '^6.0.21',
|
|
// },
|
|
// });
|
|
mockedInstalledCypressVersion.mockReturnValue(10);
|
|
jest.spyOn(logger, 'warn').mockImplementation(() => {});
|
|
jest.spyOn(logger, 'debug').mockImplementation(() => {});
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
it('should configure everything at once', async () => {
|
|
appTree = await createTestUILib('test-ui-lib');
|
|
await storybookConfigurationGenerator(appTree, {
|
|
name: 'test-ui-lib',
|
|
configureCypress: true,
|
|
standaloneConfig: false,
|
|
});
|
|
|
|
expect(appTree.exists('libs/test-ui-lib/.storybook/main.js')).toBeTruthy();
|
|
expect(
|
|
appTree.exists('libs/test-ui-lib/.storybook/tsconfig.json')
|
|
).toBeTruthy();
|
|
expect(
|
|
appTree.exists('apps/test-ui-lib-e2e/cypress.config.ts')
|
|
).toBeTruthy();
|
|
});
|
|
|
|
it('should generate stories for components', async () => {
|
|
appTree = await createTestUILib('test-ui-lib');
|
|
await storybookConfigurationGenerator(appTree, {
|
|
name: 'test-ui-lib',
|
|
generateStories: true,
|
|
configureCypress: false,
|
|
standaloneConfig: false,
|
|
});
|
|
|
|
expect(
|
|
appTree.exists('libs/test-ui-lib/src/lib/test-ui-lib.stories.tsx')
|
|
).toBeTruthy();
|
|
});
|
|
|
|
it('should generate stories for components written in plain JS', async () => {
|
|
appTree = await createTestUILib('test-ui-lib', true);
|
|
|
|
appTree.write(
|
|
'libs/test-ui-lib/src/lib/test-ui-libplain.js',
|
|
`import React from 'react';
|
|
|
|
import './test.scss';
|
|
|
|
export const Test = (props) => {
|
|
return (
|
|
<div>
|
|
<h1>Welcome to test component</h1>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Test;
|
|
`
|
|
);
|
|
await storybookConfigurationGenerator(appTree, {
|
|
name: 'test-ui-lib',
|
|
generateCypressSpecs: true,
|
|
generateStories: true,
|
|
configureCypress: false,
|
|
js: true,
|
|
standaloneConfig: false,
|
|
});
|
|
|
|
expect(
|
|
appTree.exists('libs/test-ui-lib/src/lib/test-ui-libplain.stories.js')
|
|
).toBeTruthy();
|
|
});
|
|
|
|
it('should configure everything at once', async () => {
|
|
appTree = await createTestAppLib('test-ui-app');
|
|
await storybookConfigurationGenerator(appTree, {
|
|
name: 'test-ui-app',
|
|
configureCypress: true,
|
|
standaloneConfig: false,
|
|
});
|
|
|
|
expect(appTree.exists('apps/test-ui-app/.storybook/main.js')).toBeTruthy();
|
|
expect(
|
|
appTree.exists('apps/test-ui-app/.storybook/tsconfig.json')
|
|
).toBeTruthy();
|
|
|
|
/**
|
|
* Note on the removal of
|
|
* expect(tree.exists('apps/test-ui-app-e2e/cypress.json')).toBeTruthy();
|
|
*
|
|
* When calling createTestAppLib() we do not generate an e2e suite.
|
|
* The storybook schematic for apps does not generate e2e test.
|
|
* So, there exists no test-ui-app-e2e!
|
|
*/
|
|
});
|
|
|
|
it('should generate stories for components', async () => {
|
|
appTree = await createTestAppLib('test-ui-app');
|
|
await storybookConfigurationGenerator(appTree, {
|
|
name: 'test-ui-app',
|
|
generateStories: true,
|
|
configureCypress: false,
|
|
standaloneConfig: false,
|
|
});
|
|
|
|
// Currently the auto-generate stories feature only picks up components under the 'lib' directory.
|
|
// In our 'createTestAppLib' function, we call @nrwl/react:component to generate a component
|
|
// under the specified 'lib' directory
|
|
expect(
|
|
appTree.exists(
|
|
'apps/test-ui-app/src/app/my-component/my-component.stories.tsx'
|
|
)
|
|
).toBeTruthy();
|
|
});
|
|
|
|
it('should generate cypress tests in the correct folder', async () => {
|
|
appTree = await createTestUILib('test-ui-lib');
|
|
await componentGenerator(appTree, {
|
|
name: 'my-component',
|
|
project: 'test-ui-lib',
|
|
style: 'css',
|
|
});
|
|
await storybookConfigurationGenerator(appTree, {
|
|
name: 'test-ui-lib',
|
|
generateStories: true,
|
|
configureCypress: true,
|
|
generateCypressSpecs: true,
|
|
cypressDirectory: 'one/two',
|
|
standaloneConfig: false,
|
|
});
|
|
[
|
|
'apps/one/two/test-ui-lib-e2e/cypress.config.ts',
|
|
'apps/one/two/test-ui-lib-e2e/src/fixtures/example.json',
|
|
'apps/one/two/test-ui-lib-e2e/src/support/commands.ts',
|
|
'apps/one/two/test-ui-lib-e2e/src/support/e2e.ts',
|
|
'apps/one/two/test-ui-lib-e2e/tsconfig.json',
|
|
'apps/one/two/test-ui-lib-e2e/.eslintrc.json',
|
|
'apps/one/two/test-ui-lib-e2e/src/e2e/test-ui-lib/test-ui-lib.cy.ts',
|
|
'apps/one/two/test-ui-lib-e2e/src/e2e/my-component/my-component.cy.ts',
|
|
].forEach((file) => {
|
|
expect(appTree.exists(file)).toBeTruthy();
|
|
});
|
|
});
|
|
});
|
|
|
|
export async function createTestUILib(
|
|
libName: string,
|
|
plainJS = false
|
|
): Promise<Tree> {
|
|
let appTree = createTreeWithEmptyWorkspace();
|
|
|
|
await libraryGenerator(appTree, {
|
|
linter: Linter.EsLint,
|
|
component: true,
|
|
skipFormat: true,
|
|
skipTsConfig: false,
|
|
style: 'css',
|
|
unitTestRunner: 'none',
|
|
name: libName,
|
|
standaloneConfig: false,
|
|
});
|
|
return appTree;
|
|
}
|
|
|
|
export async function createTestAppLib(
|
|
libName: string,
|
|
plainJS = false
|
|
): Promise<Tree> {
|
|
let appTree = createTreeWithEmptyWorkspace();
|
|
|
|
await applicationGenerator(appTree, {
|
|
e2eTestRunner: 'none',
|
|
linter: Linter.EsLint,
|
|
skipFormat: false,
|
|
style: 'css',
|
|
unitTestRunner: 'none',
|
|
name: libName,
|
|
js: plainJS,
|
|
standaloneConfig: false,
|
|
});
|
|
|
|
await componentGenerator(appTree, {
|
|
name: 'my-component',
|
|
project: libName,
|
|
directory: 'app',
|
|
style: 'css',
|
|
});
|
|
|
|
return appTree;
|
|
}
|