Skip to content

Commit 93d7ce9

Browse files
authored
test: added jest test setup (#1)
* test: added jest test setup * chore: move button stories inside folder * chore: added test workflow action * test: added axe test case * chore: remove check-type command from action * chore: jest eslint rules
1 parent f94cd32 commit 93d7ce9

File tree

13 files changed

+1504
-37
lines changed

13 files changed

+1504
-37
lines changed

.eslintrc.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
"prettier/@typescript-eslint"
1010
],
1111
"rules": {
12-
"no-console": "off"
12+
"no-console": "off",
13+
"testing-library/prefer-explicit-assert": ["error"],
14+
"testing-library/consistent-data-testid": [
15+
2,
16+
{
17+
"testIdPattern": "^testid(-.*\\w)?$"
18+
}
19+
]
1320
}
1421
}

.github/workflows/test.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- "*"
7+
pull_request:
8+
branches:
9+
- master
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- uses: actions/checkout@v2
17+
18+
- name: Setup Node
19+
uses: actions/setup-node@v1
20+
with:
21+
node-version: "12.x"
22+
23+
- name: Get yarn cache directory path
24+
id: yarn-cache-dir-path
25+
run: echo "::set-output name=dir::$(yarn cache dir)"
26+
27+
- uses: actions/cache@v2
28+
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
29+
with:
30+
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
31+
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
32+
restore-keys: |
33+
${{ runner.os }}-yarn-
34+
35+
- name: Setup timezone
36+
uses: zcong1993/setup-timezone@master
37+
with:
38+
timezone: Asia/Kolkata
39+
40+
- name: Install deps
41+
run: yarn
42+
- name: Test
43+
run: yarn test

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"typescript.tsdk": "node_modules\\typescript\\lib"
3+
}

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "@testing-library/jest-dom/extend-expect";

jest.config.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* For a detailed explanation regarding each configuration property and type check, visit:
3+
* https://jestjs.io/docs/en/configuration.html
4+
*/
5+
const { join } = require("path");
6+
const pkg = require("./package.json");
7+
8+
// eslint-disable-next-line import/no-anonymous-default-export
9+
export default {
10+
rootDir: __dirname,
11+
displayName: pkg.name,
12+
testMatch: [join(__dirname, "src/**/*.test.{js,ts,tsx}")],
13+
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
14+
moduleNameMapper: {
15+
"\\.(css|less|sass|scss)$": "<rootDir>/src/__mocks__/styleMock.js",
16+
"^@shared(.*)$": "<rootDir>/shared$1",
17+
},
18+
coveragePathIgnorePatterns: ["node_modules", "__mocks__", "stories"],
19+
clearMocks: true,
20+
};

jest.setup.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const {
2+
matcherHint,
3+
printReceived,
4+
printExpected,
5+
} = require("jest-matcher-utils");
6+
const { toHaveNoViolations: axeMatchers } = require("jest-axe");
7+
const matchers = require("@testing-library/jest-dom/matchers");
8+
9+
// Consider [aria-activedescendant="${id}"] #${id} as the focused element.
10+
function toHaveFocus(element) {
11+
const result = matchers.toHaveFocus.call(this, element);
12+
const { activeElement } = element.ownerDocument;
13+
const activeId =
14+
activeElement && activeElement.getAttribute("aria-activedescendant");
15+
return {
16+
...result,
17+
pass: result.pass || activeId === element.id,
18+
message: () => {
19+
if (activeId) {
20+
return [
21+
matcherHint(`${this.isNot ? ".not" : ""}.toHaveFocus`, "element", ""),
22+
"",
23+
"Expected:",
24+
` ${printExpected(element)}`,
25+
"Received:",
26+
` ${printReceived(element.ownerDocument.getElementById(activeId))}`,
27+
].join("\n");
28+
}
29+
return result.message();
30+
},
31+
};
32+
}
33+
34+
expect.extend({ ...matchers, ...axeMatchers, toHaveFocus });

package.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"postrelease": "concurrently yarn:release:*",
3737
"release:github": "conventional-github-releaser -p angular",
3838
"release:tags": "git push --follow-tags origin main",
39-
"storybook": "start-storybook -p 6006"
39+
"storybook": "start-storybook -p 6006",
40+
"test": "jest --config ./jest.config.ts --no-cache"
4041
},
4142
"browserslist": {
4243
"production": [
@@ -65,9 +66,17 @@
6566
"@storybook/addon-essentials": "^6.1.10",
6667
"@storybook/addon-links": "^6.1.10",
6768
"@storybook/react": "^6.1.10",
69+
"@testing-library/dom": "^7.28.1",
70+
"@testing-library/jest-dom": "^5.11.6",
71+
"@testing-library/react": "^11.2.2",
72+
"@testing-library/react-hooks": "^3.5.0",
73+
"@testing-library/user-event": "^12.5.0",
74+
"@types/jest": "^26.0.16",
75+
"@types/jest-axe": "^3.5.1",
6876
"@types/node": "^14.14.10",
6977
"@types/react": "^17.0.0",
7078
"@types/react-dom": "^17.0.0",
79+
"@types/testing-library__jest-dom": "^5.9.5",
7180
"@typescript-eslint/eslint-plugin": "^4.9.0",
7281
"@typescript-eslint/parser": "^4.9.0",
7382
"babel-eslint": "^10.1.0",
@@ -89,13 +98,16 @@
8998
"eslint-plugin-testing-library": "^3.10.1",
9099
"gacp": "^2.10.2",
91100
"husky": "^4.3.5",
101+
"jest": "^26.6.3",
102+
"jest-axe": "^4.1.0",
92103
"lint-staged": "^10.5.3",
93104
"prettier": "^2.2.1",
94105
"react": "^17.0.1",
95106
"react-dom": "^17.0.1",
96107
"rimraf": "^3.0.2",
97108
"sort-package-json": "^1.48.0",
98109
"standard-version": "^9.0.0",
110+
"ts-node": "^9.1.0",
99111
"typescript": "^4.1.2"
100112
},
101113
"peer-dependencies": {

src/__mocks__/styleMock.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = {};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import * as React from "react";
2+
import { Button } from "../Button";
3+
4+
import { configureAxe } from "jest-axe";
5+
import { render, screen } from "@testing-library/react";
6+
7+
const axe = configureAxe({
8+
rules: {
9+
// disabled landmark rules when testing isolated components.
10+
region: { enabled: false },
11+
},
12+
});
13+
14+
describe("Testing Button", () => {
15+
it("should render properly", () => {
16+
render(<Button label="Hello world" />);
17+
18+
expect(screen.getByRole("button")).toHaveTextContent(/hello world/i);
19+
});
20+
21+
it("should not have axe violations", async () => {
22+
const { container } = render(<Button label="ally" />);
23+
const results = await axe(container);
24+
25+
expect(results).toHaveNoViolations();
26+
});
27+
});
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from "react";
33
import { Story, Meta } from "@storybook/react/types-6-0";
44

55
import "./button.css";
6-
import { Button, ButtonProps } from "../index";
6+
import { Button, ButtonProps } from "../../index";
77

88
export default {
99
title: "Button",

0 commit comments

Comments
 (0)