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:
esanuandra 2021-05-31 15:12:57 +03:00 коммит произвёл GitHub
Родитель cd6ae1a467
Коммит a49e15df68
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 3366 добавлений и 867 удалений

Просмотреть файл

@ -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

8
jest-puppeteer.config.js Normal file
Просмотреть файл

@ -0,0 +1,8 @@
module.exports = {
launch: {
headless: true,
},
server: {
command: 'yarn start',
},
};

Просмотреть файл

@ -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

Разница между файлами не показана из-за своего большого размера Загрузить разницу