Skip to content

Commit

Permalink
ci: consolidate test-utils and add easy e2e script (#2688)
Browse files Browse the repository at this point in the history
* rename e2e script to e2e-ci

* [wip] start cross env e2e script

* add assertion on visit page method

* add @bfc/test-utils package

* update visual designer to use test-utils

* mark test-utils private

* update adaptive-form to use test-utils

* migrate extension to test-utils

* migrate client to test-utils

* update config function interfaces

* add node configuration

* update lockfile

* migrate electron-server to test-utils

* migrate lib to test-utils

* migrate server to test-utils

* migrate tools to test-utils

* migrate ui-plugins to test-utils

* update lock file

* update documentation

* add typings for test-utils

Keep this as a JS module to reduce compile steps, but at least consumers get type info

* convert all test imports to test-utils

* allow configuration of babel options

* convert missing js files to jsx

* remove ability for babel overrides

packages can include their own babel config instead

* remove babel overrides from type

* migrate ui-shared to test-utils

* do not load other babel configs for tests

* add e2e scripts to run app and clean artifacts in cross plat way

* add more logging

* add yarn script to start composer for e2e
  • Loading branch information
a-b-r-o-w-n authored Apr 20, 2020
1 parent 4704385 commit 2936a71
Show file tree
Hide file tree
Showing 132 changed files with 2,647 additions and 2,613 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
- If the change includes non-trivial changes in UI, include a screenshot and tag a designer on the project. Be sure to show any border or layout changes clearly. Use your best judgement if you would like a designer to explicitly sign off on it, such as a deviation from the design artifacts.
- If the change includes a non-trivial change in UX, include a gif demonstrating the interaction. Tag a designer and use your judgement if you would like explicit sign off from them on it.
- At least one approver is required on a pull-request prior to merging it.
- Programatic testing for each change is a requirement. Comprehensive unit tests for every change is not. _"Write tests, not too many, mostly integration"_. We should be using [Jest](https://jestjs.io/) & [react-testing-library](https://github.com/kentcdodds/react-testing-library) for this in the client. Code coverage benchmarks will be introduced and need to be met with each change (TBD).
- Programatic testing for each change is a requirement. Comprehensive unit tests for every change is not. _"Write tests, not too many, mostly integration"_. We should be using [Jest](https://jestjs.io/) & [@testing-library/react](https://github.com/testing-library/react-testing-library) for this in the client. Code coverage benchmarks will be introduced and need to be met with each change (TBD).
- Write code with Internationalization & Accessibility in mind. Every rendered string should be wrapped in an i18n API. Scrub through each UI change for keyboard-navigation and focus-indication. This will prevent most accessibility bugs.
- Use `rebase` when merging changes into to the master branch. This can be done using the _“Squash and Merge”_ technique in the GitHub UI. Local branches will need to be updated using rebase as well. This will keep a clean commit history. Reach out to me if you need help understanding rebase.

Expand Down
14 changes: 7 additions & 7 deletions Composer/TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Tests can be run in two ways:

> **IMPORTANT:** Any new code being checked in should also come with new tests!
When writing tests for any React components, we will be using the `react-testing-library` ([documentation](https://testing-library.com/docs/react-testing-library/api)).
When writing tests for any React components, we will be using the `@testing-library/react` ([documentation](https://testing-library.com/docs/@testing-library/react/api)).

For some examples of how to write React component tests, look at the tests under the `<root>/Composer/packages/client/__tests__/` directory, or at the below examples.

Expand Down Expand Up @@ -73,7 +73,7 @@ export const Header = props => {
### Testing for text content:

**client/\_\_tests__/header.test.js**

```
it('should render the header', async () => {
const { getByText } = render(<Header />);
Expand All @@ -89,7 +89,7 @@ export const Header = props => {
```
const { getByText } = render(<Header />);
```

This method allows us to search the rendered component for nodes containing text matching a string, regular expression, or matching function. The next 3 lines search for nodes containing "Composer," "New," and "Open:"

```
Expand All @@ -98,7 +98,7 @@ export const Header = props => {
await waitForElement(() => getByText(/Open/));
```


> **NOTE:** The method `waitForElement` simply waits until the component is rendered, performs the inner function, and returns the result.
> **NOTE:** Queries such as `getByText()` will throw an error if the DOM node is not found, so there is no need to assert anything.
Expand All @@ -117,17 +117,17 @@ export const Header = props => {
expect(mockOpenStorageExplorer).toHaveBeenCalled();
});
```

In this example, the first two lines create a mock Jest function to pass into the component as the prop `openStorageExplorer`, and then render the component:

```
const mockOpenStorageExplorer = jest.fn(() => null);
const { getByText } = render(<Header openStorageExplorer={mockOpenStorageExplorer} />);
```

The next line grabs a reference to the button labelled "Open" from the rendered component:

```
```
const openButton = await waitForElement(() => getByText(/Open/));
```

Expand Down
2 changes: 2 additions & 0 deletions Composer/cypress/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__test_bots__
__e2e_data.json
1 change: 1 addition & 0 deletions Composer/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Cypress.Commands.add('withinEditor', (editorName, cb) => {

Cypress.Commands.add('visitPage', page => {
cy.findByTestId(`LeftNav-CommandBarButton${page}`).click();
cy.findByTestId('ActiveLeftNavItem').should('contain', page);
});

Cypress.on('uncaught:exception', err => {
Expand Down
15 changes: 7 additions & 8 deletions Composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
"node": ">=12"
},
"workspaces": [
"packages/server",
"packages/client",
"packages/electron-server",
"packages/extensions",
"packages/extensions/*",
"packages/client",
"packages/lib",
"packages/lib/*",
"packages/server",
"packages/test-utils",
"packages/tools",
"packages/tools/language-servers",
"packages/tools/language-servers/*",
Expand All @@ -42,8 +43,9 @@
"test": "yarn typecheck && jest",
"test:coverage": "yarn test --coverage --no-cache --reporters=default",
"test:integration": "cypress run --browser chrome",
"test:integration:start-server": "node scripts/e2e.sh",
"test:integration:open": "cypress open",
"test:integration:clean": "rimraf ../MyBots/__Test*",
"test:integration:clean": "node scripts/clean-e2e.js",
"lint": "wsrun --exclude-missing --collect-logs --report lint",
"lint:fix": "wsrun --exclude-missing --collect-logs --report lint:fix",
"typecheck": "concurrently --kill-others-on-fail \"npm:typecheck:*\"",
Expand Down Expand Up @@ -74,10 +76,9 @@
"@cypress/webpack-preprocessor": "^4.1.1",
"@emotion/babel-preset-css-prop": "^10.0.17",
"@testing-library/cypress": "^5.2.1",
"@types/jest": "^25.1.3",
"@typescript-eslint/eslint-plugin": "2.10.0",
"@typescript-eslint/parser": "2.10.0",
"babel-jest": "24.0.0",
"chalk": "^4.0.0",
"concurrently": "^4.1.0",
"coveralls": "^3.0.7",
"cypress": "^3.8.3",
Expand All @@ -95,10 +96,8 @@
"eslint-plugin-react": "^7.17.0",
"eslint-plugin-react-hooks": "^2.3.0",
"eslint-plugin-security": "^1.4.0",
"get-port": "^5.1.1",
"husky": "^1.3.1",
"jest": "24.0.0",
"jest-dom": "^3.1.3",
"jest-junit": "^6.4.0",
"lint-staged": "^8.1.0",
"mocha": "5.2.0",
"mocha-junit-reporter": "^1.22.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import { DialogWrapper } from '../../../src/components/DialogWrapper';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render, fireEvent } from 'react-testing-library';
import { render, fireEvent } from '@bfc/test-utils';

import { EmulatorOpenButton } from '../../../src/components/TestController/emulatorOpenButton';
import { BotStatus } from '../../../src/constants/index';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render, fireEvent, getByText } from 'react-testing-library';
import { render, fireEvent, getByText } from '@bfc/test-utils';

import { ErrorCallout } from '../../../src/components/TestController/errorCallout';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render, fireEvent } from 'react-testing-library';
import { render, fireEvent } from '@bfc/test-utils';

import { ErrorInfo } from '../../../src/components/TestController/errorInfo';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import { Loading } from '../../../src/components/TestController/loading';
import { BotStatus } from '../../../src/constants';
Expand Down
19 changes: 0 additions & 19 deletions Composer/packages/client/__tests__/components/conversation.test.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import * as React from 'react';
import { render } from '@bfc/test-utils';

import '../../src/components/Conversation';

describe('<Conversation/>', () => {
it('should render the conversation', async () => {
// const { findByText } = render(
// <Conversation>
// <div>test</div>
// </Conversation>
// );
// await findByText(/test/);
// expect(true).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render, fireEvent } from 'react-testing-library';
import { render, fireEvent } from '@bfc/test-utils';

import { renderWithStore } from '../testUtils';
import { dialogs } from '../constants.json';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import { ErrorBoundary } from '../../src/components/ErrorBoundary/index';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import { Header } from '../../src/components/Header';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { fireEvent, render } from 'react-testing-library';
import { fireEvent, render } from '@bfc/test-utils';

import { RecentBotList } from '../../src/pages/home/RecentBotList';
import { ExampleList } from '../../src/pages/home/ExampleList';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { fireEvent, render } from 'react-testing-library';
import { fireEvent, render } from '@bfc/test-utils';

import { NotificationHeader } from '../../src/pages/notifications/NotificationHeader';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';
import formatMessage from 'format-message';

import { NotificationList } from '../../src/pages/notifications/NotificationList';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import OnboardingContext from '../../src/Onboarding/context';
import { StoreContext } from '../../src/store';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { fireEvent } from 'react-testing-library';
import { fireEvent } from '@bfc/test-utils';

import { dialogs } from '../constants.json';
import { ProjectTree } from '../../src/components/ProjectTree/index.tsx';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render, fireEvent } from 'react-testing-library';
import { render, fireEvent } from '@bfc/test-utils';

import SkillList from '../../src/pages/skills/skill-list';
import SkillForm from '../../src/pages/skills/skill-form';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { fireEvent, render } from 'react-testing-library';
import { fireEvent, render } from '@bfc/test-utils';

import { ToolBar } from '../../src/components/ToolBar';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import { NavItem } from '../src/components/NavItem';
import { StoreProvider } from '../src/store';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import * as React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import { BASEPATH } from '../src/constants/index';
import { NotFound } from '../src/components/NotFound';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';
import { createHistory, createMemorySource, LocationProvider } from '@reach/router';

import { StoreProvider } from '../src/store';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

import React from 'react';
import { render } from 'react-testing-library';
import { render } from '@bfc/test-utils';

import { StoreProvider } from '../../src/store';

Expand Down
49 changes: 10 additions & 39 deletions Composer/packages/client/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,13 @@
// eslint-disable-next-line
const path = require('path');
module.exports = {
displayName: 'client',
preset: 'ts-jest/presets/js-with-ts',
// transform: {
// '^.+\\.tsx?$': 'ts-jest',
// '^.+\\.jsx?$': 'babel-jest',
// },
moduleNameMapper: {
// Any imports of .scss / .css files will instead import styleMock.js which is an empty object
'\\.(jpg|jpeg|png|svg|gif)$': '<rootDir>/__tests__/jestMocks/styleMock.js',
'\\.(s)?css$': '<rootDir>/__tests__/jestMocks/styleMock.js',
// lsp code editor
vscode$: 'monaco-languageclient/lib/vscode-compatibility',
const { createConfig } = require('@bfc/test-utils');

// use commonjs modules for test so they do not need to be compiled
'office-ui-fabric-react/lib/(.*)$': 'office-ui-fabric-react/lib-commonjs/$1',
'@uifabric/fluent-theme/lib/(.*)$': '@uifabric/fluent-theme/lib-commonjs/$1',
module.exports = createConfig(
'client',
'react',
{
setupFilesAfterEnv: [path.resolve(__dirname, 'setupTests.ts')],
},
testPathIgnorePatterns: [
'/node_modules/',
'/jestMocks/',
'__mocks__',
'/testUtils/',
'__tests__/setupTests.ts',
'.*\\.d\\.ts',
],
// Some node modules are packaged and distributed in a non-transpiled form
// (ex. contain import & export statements); and Jest won't be able to
// understand them because node_modules aren't transformed by default. So
// we can specify that they need to be transformed here.
transformIgnorePatterns: ['/node_modules/'],

setupFilesAfterEnv: [path.resolve(__dirname, './__tests__/setupTests.ts')],
globals: {
'ts-jest': {
tsConfig: path.resolve(__dirname, './tsconfig.json'),
diagnostics: false,
},
},
};
{
presets: ['react-app', '@emotion/babel-preset-css-prop'],
}
);
Loading

0 comments on commit 2936a71

Please sign in to comment.