Skip to content

Commit

Permalink
Fix conflict, add pollyjs dependecies (#7084)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
esanuandra authored May 31, 2021
1 parent cd6ae1a commit a49e15d
Show file tree
Hide file tree
Showing 10 changed files with 3,369 additions and 870 deletions.
5 changes: 5 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ module.exports = {
env: {
browser: true,
},
globals: {
page: true,
browser: true,
jestPuppeteer: true,
},
rules: {
'class-methods-use-this': 'off',
'consistent-return': 'off',
Expand Down
49 changes: 37 additions & 12 deletions .neutrinorc.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,42 @@

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 = {
options: {
source: 'ui/',
Expand Down Expand Up @@ -90,18 +126,7 @@ module.exports = {
require('@neutrinojs/copy')({
patterns: ['ui/contribute.json', 'ui/revision.txt', 'ui/robots.txt'],
}),
process.env.NODE_ENV === 'test' &&
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',
},
}),
neutrinojest,
(neutrino) => {
neutrino.config
.plugin('provide')
Expand Down
12 changes: 9 additions & 3 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,22 @@ yarn format

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

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

```shell
Expand Down
8 changes: 8 additions & 0 deletions jest-puppeteer.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
launch: {
headless: true,
},
server: {
command: 'yarn start',
},
};
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@fortawesome/free-solid-svg-icons": "5.12.1",
"@fortawesome/react-fontawesome": "0.1.14",
"@neutrinojs/copy": "9.2.0",
"@neutrinojs/jest": "^9.5.0",
"@neutrinojs/react": "9.2.0",
"@types/prop-types": "*",
"@types/react": "*",
Expand Down Expand Up @@ -65,7 +66,11 @@
},
"devDependencies": {
"@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/react": "11.0.4",
"codecov": "3.7.2",
Expand All @@ -81,9 +86,13 @@
"eslint-plugin-react": "7.16.0",
"fetch-mock": "9.4.0",
"jest": "26.0.1",
"jest-environment-puppeteer": "^4.4.0",
"jest-puppeteer": "^4.4.0",
"markdownlint-cli": "0.23.2",
"node-fetch": "2.6.1",
"path": "^0.12.7",
"prettier": "2.0.5",
"puppeteer": "^8.0.0",
"setup-polly-jest": "^0.9.1",
"webpack-dev-server": "3.11.2"
},
"scripts": {
Expand All @@ -102,6 +111,7 @@
"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": "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"
},
"resolutions": {
Expand Down
63 changes: 63 additions & 0 deletions tests/ui/integration/graphs-view/graphs_view_integration_test.jsx
Original file line number Diff line number Diff line change
@@ -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();
});
});
Loading

0 comments on commit a49e15d

Please sign in to comment.