зеркало из https://github.com/mozilla/treeherder.git
Fix conflict, add pollyjs dependecies (#7084)
Bug 1698835 - Add puppeteer adapter, add sample test for graphs view Bug 1698835 - Update sample test with puppeteer Bug 1698835 - Fix UnhandledPromiseRejectionWarning Bug 1698835 - Configure jest-puppeteer Bug 1698835 - Separate integration tests from unit tests Bug 1698835 - Update yarn.lock Bug 1698835 - Fix lint errors Bug 1698835 - Update yarn.lock Bug 1698835 - Add @neutrinojs/jest to dependencies Bug 1698835 - Update yarn.lock Bug 1698835 - Address pr requests, move recordings folder Bug 1698835 - Fix chromium error Bug 1698835 - Clean up and update recordings Bug 1698835 - Add documentation Bug 1698835 - Update docs
This commit is contained in:
Родитель
cd6ae1a467
Коммит
a49e15df68
|
@ -23,6 +23,11 @@ module.exports = {
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
},
|
},
|
||||||
|
globals: {
|
||||||
|
page: true,
|
||||||
|
browser: true,
|
||||||
|
jestPuppeteer: true,
|
||||||
|
},
|
||||||
rules: {
|
rules: {
|
||||||
'class-methods-use-this': 'off',
|
'class-methods-use-this': 'off',
|
||||||
'consistent-return': 'off',
|
'consistent-return': 'off',
|
||||||
|
|
|
@ -8,6 +8,42 @@
|
||||||
|
|
||||||
const BACKEND = process.env.BACKEND || 'https://treeherder.mozilla.org';
|
const BACKEND = process.env.BACKEND || 'https://treeherder.mozilla.org';
|
||||||
|
|
||||||
|
let neutrinojest = {
|
||||||
|
// For more info, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1523376#c3
|
||||||
|
moduleNameMapper: {
|
||||||
|
// Hawk's browser and Node APIs differ, and taskcluster-client-web uses APIs that
|
||||||
|
// exist only in the browser version. As such we must force Jest (which runs tests
|
||||||
|
// under Node, not the browser) to use the browser version of Hawk. See:
|
||||||
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1523376#c6
|
||||||
|
'^hawk$': 'hawk/dist/browser.js',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
process.env.NODE_ENV === 'test' &&
|
||||||
|
process.env.TEST_TYPE &&
|
||||||
|
process.env.TEST_TYPE.trim() === 'integration'
|
||||||
|
) {
|
||||||
|
neutrinojest = require('@neutrinojs/jest')({
|
||||||
|
...neutrinojest,
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/tests/ui/integration/test-setup.js'],
|
||||||
|
testRegex: '/tests/ui/integration/',
|
||||||
|
testPathIgnorePatterns: ['tests/ui/integration/test-setup.js'],
|
||||||
|
globalSetup: 'jest-environment-puppeteer/setup',
|
||||||
|
globalTeardown: 'jest-environment-puppeteer/teardown',
|
||||||
|
testEnvironment: 'jest-environment-puppeteer',
|
||||||
|
globals: {
|
||||||
|
URL: 'http://localhost:5000',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
neutrinojest = require('@neutrinojs/jest')({
|
||||||
|
...neutrinojest,
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/tests/ui/test-setup.js'],
|
||||||
|
testPathIgnorePatterns: ['tests/ui/integration'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
options: {
|
options: {
|
||||||
source: 'ui/',
|
source: 'ui/',
|
||||||
|
@ -90,18 +126,7 @@ module.exports = {
|
||||||
require('@neutrinojs/copy')({
|
require('@neutrinojs/copy')({
|
||||||
patterns: ['ui/contribute.json', 'ui/revision.txt', 'ui/robots.txt'],
|
patterns: ['ui/contribute.json', 'ui/revision.txt', 'ui/robots.txt'],
|
||||||
}),
|
}),
|
||||||
process.env.NODE_ENV === 'test' &&
|
neutrinojest,
|
||||||
require('@neutrinojs/jest')({
|
|
||||||
setupFilesAfterEnv: ['<rootDir>/tests/ui/test-setup.js'],
|
|
||||||
// For more info, see: https://bugzilla.mozilla.org/show_bug.cgi?id=1523376#c3
|
|
||||||
moduleNameMapper: {
|
|
||||||
// Hawk's browser and Node APIs differ, and taskcluster-client-web uses APIs that
|
|
||||||
// exist only in the browser version. As such we must force Jest (which runs tests
|
|
||||||
// under Node, not the browser) to use the browser version of Hawk. See:
|
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1523376#c6
|
|
||||||
'^hawk$': 'hawk/dist/browser.js',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
(neutrino) => {
|
(neutrino) => {
|
||||||
neutrino.config
|
neutrino.config
|
||||||
.plugin('provide')
|
.plugin('provide')
|
||||||
|
|
|
@ -37,16 +37,22 @@ yarn format
|
||||||
|
|
||||||
See the [code style](code_style.md#ui) section for more details.
|
See the [code style](code_style.md#ui) section for more details.
|
||||||
|
|
||||||
### Running the Jest front-end unit tests
|
### Running the Jest front-end tests
|
||||||
|
|
||||||
The unit tests for the UI are run with [Jest].
|
The unit tests for the UI are run with [Jest].
|
||||||
|
The tests are written with react testing library. For the integration tests PollyJS is used to mock APIs.
|
||||||
|
|
||||||
|
Integration tests are useful when testing higher level components that would be hard to setup with fetch mock.
|
||||||
|
They use PollyJS because it helps to automatically record and replay requests/responses.
|
||||||
|
To refresh the PollyJS recordings (usually when an endpoint response changes), just delete the recordings folder and run `yarn test:integration` again like described below.
|
||||||
|
|
||||||
To run the tests:
|
To run the tests:
|
||||||
|
|
||||||
- If you haven't already done so, install local dependencies by running `yarn install` from the project root.
|
- If you haven't already done so, install local dependencies by running `yarn install` from the project root.
|
||||||
- Then run `yarn test` to execute the tests.
|
- For unit tests run `yarn test` to execute the tests.
|
||||||
|
- For integration tests run `yarn test:integration` to execute the tests.
|
||||||
|
|
||||||
While working on the frontend, you may wish to watch JavaScript files and re-run tests
|
While working on the frontend, you may wish to watch JavaScript files and re-run the unit tests
|
||||||
automatically when files change. To do this, you may run one of the following commands:
|
automatically when files change. To do this, you may run one of the following commands:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
launch: {
|
||||||
|
headless: true,
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
command: 'yarn start',
|
||||||
|
},
|
||||||
|
};
|
14
package.json
14
package.json
|
@ -17,6 +17,7 @@
|
||||||
"@fortawesome/free-solid-svg-icons": "5.12.1",
|
"@fortawesome/free-solid-svg-icons": "5.12.1",
|
||||||
"@fortawesome/react-fontawesome": "0.1.14",
|
"@fortawesome/react-fontawesome": "0.1.14",
|
||||||
"@neutrinojs/copy": "9.2.0",
|
"@neutrinojs/copy": "9.2.0",
|
||||||
|
"@neutrinojs/jest": "^9.5.0",
|
||||||
"@neutrinojs/react": "9.2.0",
|
"@neutrinojs/react": "9.2.0",
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/react": "*",
|
"@types/react": "*",
|
||||||
|
@ -65,7 +66,11 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@neutrinojs/eslint": "9.2.0",
|
"@neutrinojs/eslint": "9.2.0",
|
||||||
"@neutrinojs/jest": "9.2.0",
|
"@pollyjs/adapter-fetch": "^5.1.0",
|
||||||
|
"@pollyjs/adapter-node-http": "^5.1.0",
|
||||||
|
"@pollyjs/adapter-puppeteer": "^5.1.0",
|
||||||
|
"@pollyjs/core": "^5.1.0",
|
||||||
|
"@pollyjs/persister-fs": "^5.0.0",
|
||||||
"@testing-library/jest-dom": "5.0.2",
|
"@testing-library/jest-dom": "5.0.2",
|
||||||
"@testing-library/react": "11.0.4",
|
"@testing-library/react": "11.0.4",
|
||||||
"codecov": "3.7.2",
|
"codecov": "3.7.2",
|
||||||
|
@ -81,9 +86,13 @@
|
||||||
"eslint-plugin-react": "7.16.0",
|
"eslint-plugin-react": "7.16.0",
|
||||||
"fetch-mock": "9.4.0",
|
"fetch-mock": "9.4.0",
|
||||||
"jest": "26.0.1",
|
"jest": "26.0.1",
|
||||||
|
"jest-environment-puppeteer": "^4.4.0",
|
||||||
|
"jest-puppeteer": "^4.4.0",
|
||||||
"markdownlint-cli": "0.23.2",
|
"markdownlint-cli": "0.23.2",
|
||||||
"node-fetch": "2.6.1",
|
"path": "^0.12.7",
|
||||||
"prettier": "2.0.5",
|
"prettier": "2.0.5",
|
||||||
|
"puppeteer": "^8.0.0",
|
||||||
|
"setup-polly-jest": "^0.9.1",
|
||||||
"webpack-dev-server": "3.11.2"
|
"webpack-dev-server": "3.11.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -102,6 +111,7 @@
|
||||||
"start:local": "node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --mode development --env.BACKEND=http://localhost:8000",
|
"start:local": "node ./node_modules/webpack-dev-server/bin/webpack-dev-server.js --mode development --env.BACKEND=http://localhost:8000",
|
||||||
"test:coverage": "node ./node_modules/jest/bin/jest -w 1 --silent --coverage",
|
"test:coverage": "node ./node_modules/jest/bin/jest -w 1 --silent --coverage",
|
||||||
"test": "node ./node_modules/jest/bin/jest",
|
"test": "node ./node_modules/jest/bin/jest",
|
||||||
|
"test:integration": "node node_modules/puppeteer/install.js && set TEST_TYPE=integration && node ./node_modules/jest/bin/jest",
|
||||||
"test:watch": "node ./node_modules/jest/bin/jest --watch"
|
"test:watch": "node ./node_modules/jest/bin/jest --watch"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
import { Polly } from '@pollyjs/core';
|
||||||
|
import PuppeteerAdapter from '@pollyjs/adapter-puppeteer';
|
||||||
|
import FsPersister from '@pollyjs/persister-fs';
|
||||||
|
import { setupPolly } from 'setup-polly-jest';
|
||||||
|
|
||||||
|
Polly.register(PuppeteerAdapter);
|
||||||
|
Polly.register(FsPersister);
|
||||||
|
|
||||||
|
describe('GraphsViewRecord Test Pupeteer', () => {
|
||||||
|
const context = setupPolly({
|
||||||
|
adapters: ['puppeteer'],
|
||||||
|
adapterOptions: {
|
||||||
|
puppeteer: { page },
|
||||||
|
},
|
||||||
|
persister: 'fs',
|
||||||
|
persisterOptions: {
|
||||||
|
fs: {
|
||||||
|
recordingsDir: path.resolve(__dirname, '../recordings'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
recordIfMissing: true,
|
||||||
|
matchRequestsBy: {
|
||||||
|
headers: {
|
||||||
|
exclude: ['user-agent'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
jest.setTimeout(60000);
|
||||||
|
|
||||||
|
await page.setRequestInterception(true);
|
||||||
|
await page.goto(`${URL}/perfherder/graphs`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Record requests', async () => {
|
||||||
|
expect(context.polly).not.toBeNull();
|
||||||
|
|
||||||
|
// Set selector Add test data
|
||||||
|
const addTestDataSelector = 'button[title="Add test data"]';
|
||||||
|
|
||||||
|
// Wait for selector to appear in the page
|
||||||
|
await page.waitForSelector(addTestDataSelector);
|
||||||
|
|
||||||
|
// Click button Add test data
|
||||||
|
await page.click(addTestDataSelector, { clickCount: 1 });
|
||||||
|
|
||||||
|
// Check details from Add Test Data Modal
|
||||||
|
await page.waitForSelector('div[title="Framework"]');
|
||||||
|
|
||||||
|
const frameworks = await page.$$eval(
|
||||||
|
'div[title="Framework"] a.dropdown-item',
|
||||||
|
(element) => element.length,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(frameworks).toBe(9);
|
||||||
|
|
||||||
|
// Wait for all requests to resolve
|
||||||
|
await context.polly.flush();
|
||||||
|
});
|
||||||
|
});
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,6 @@
|
||||||
|
// Entry point for Jest tests
|
||||||
|
import { configure } from 'enzyme/build';
|
||||||
|
import Adapter from 'enzyme-adapter-react-16/build';
|
||||||
|
import '@testing-library/jest-dom/extend-expect';
|
||||||
|
|
||||||
|
configure({ adapter: new Adapter() });
|
|
@ -114,7 +114,7 @@ export default class GraphsViewControls extends React.Component {
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="auto" className="p-2">
|
<Col sm="auto" className="p-2">
|
||||||
<Button color="darker-info" onClick={toggle}>
|
<Button color="darker-info" title="Add test data" onClick={toggle}>
|
||||||
Add test data
|
Add test data
|
||||||
</Button>
|
</Button>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
3065
yarn.lock
3065
yarn.lock
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче