├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .fatherrc.ts
├── .gitignore
├── .husky
└── pre-commit
├── .prettierignore
├── .prettierrc.js
├── README.md
├── jest.config.js
├── package.json
├── src
├── autoComplete
│ ├── __tests__
│ │ └── autoComplete.test.tsx
│ └── index.ts
├── button
│ ├── __tests__
│ │ └── button.test.tsx
│ └── index.ts
├── cascader
│ ├── __tests__
│ │ └── cascader.test.tsx
│ └── index.ts
├── checkbox
│ ├── __tests__
│ │ └── checkbox.test.tsx
│ └── index.ts
├── collapse
│ ├── __tests__
│ │ └── collapse.test.tsx
│ └── index.ts
├── datePicker
│ ├── __tests__
│ │ └── datePicker.test.tsx
│ └── index.ts
├── drawer
│ ├── __tests__
│ │ └── drawer.test.tsx
│ └── index.ts
├── dropdown
│ └── index.ts
├── form
│ ├── __tests__
│ │ └── form.test.tsx
│ └── index.ts
├── index.ts
├── input
│ ├── __tests__
│ │ ├── input.test.tsx
│ │ └── textarea.test.tsx
│ ├── index.ts
│ └── textarea.ts
├── inputNumber
│ └── index.ts
├── interface.ts
├── message
│ ├── __tests__
│ │ └── message.test.tsx
│ └── index.ts
├── modal
│ ├── __tests__
│ │ ├── confirm.test.tsx
│ │ └── modal.test.tsx
│ ├── confirm.ts
│ └── index.ts
├── pagination
│ ├── __tests__
│ │ └── pagination.test.tsx
│ └── index.ts
├── popconfirm
│ ├── __tests__
│ │ └── popconfirm.test.tsx
│ └── index.ts
├── provider
│ └── index.ts
├── radio
│ ├── __tests__
│ │ └── radio.test.tsx
│ └── index.ts
├── select
│ ├── __tests__
│ │ └── select.test.tsx
│ └── index.ts
├── switch
│ ├── __tests__
│ │ └── switch.test.tsx
│ └── index.ts
├── table
│ ├── __tests__
│ │ └── table.test.tsx
│ └── index.tsx
├── tabs
│ ├── __tests__
│ │ └── tabs.test.tsx
│ └── index.ts
├── timePicker
│ ├── __tests__
│ │ └── timePicker.test.tsx
│ └── index.ts
├── tooltip
│ ├── __tests__
│ │ └── tooltip.test.tsx
│ └── index.ts
├── transfer
│ ├── __tests__
│ │ └── transfer.test.tsx
│ └── index.ts
├── tree
│ ├── __tests__
│ │ └── tree.test.tsx
│ └── index.ts
├── treeSelect
│ ├── __tests__
│ │ └── treeSelect.test.tsx
│ └── index.ts
├── upload
│ ├── __tests__
│ │ └── upload.test.tsx
│ └── index.ts
└── utils
│ ├── __tests__
│ └── utils.test.tsx
│ └── index.ts
├── tests
└── setupTests.ts
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | # 🎨 editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | end_of_line = lf
8 | indent_style = space
9 | indent_size = 4
10 | trim_trailing_whitespace = true
11 | insert_final_newline = true
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Please Checkout And Make Sure Patterns Isn't Exist In .gitignore File First
2 | coverage
3 | dist
4 | *.yaml
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [require.resolve('ko-lint-config/.eslintrc')],
3 | rules: {
4 | '@typescript-eslint/no-non-null-assertion': 2,
5 | },
6 | overrides: [
7 | {
8 | files: ['**/__tests__/*.tsx'],
9 | rules: {
10 | '@typescript-eslint/no-non-null-assertion': 0,
11 | '@typescript-eslint/ban-ts-comment': 0,
12 | },
13 | },
14 | ],
15 | };
16 |
--------------------------------------------------------------------------------
/.fatherrc.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'father';
2 |
3 | export default defineConfig({
4 | platform: 'node',
5 | cjs: {},
6 | prebundle: {
7 | deps: {}
8 | },
9 | });
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /dist
3 | .DS_Store
4 | coverage
5 | pnpm-lock.yaml
6 | *.lock
7 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | pnpm exec lint-staged
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Please Checkout And Make Sure Patterns Isn't Exist In .gitignore File First
2 | coverage
3 | dist
4 | *.yaml
5 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | ...require('ko-lint-config/.prettierrc'),
3 | printWidth: 120,
4 | };
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
ant-design-testing
2 |
3 | _Easier testing for ant-design-based UI library_
4 |
5 | ## Usage
6 |
7 | ```shell
8 | $ pnpm install ant-design-testing -D
9 | ```
10 |
11 | then, modify the prefixCls if you need it
12 |
13 | ```tsx
14 | // setupTests.ts
15 | import { provider } from 'ant-design-testing';
16 |
17 | provider({ prefixCls: 'ant' });
18 | ```
19 |
20 | ```tsx
21 | // yourInput.test.tsx
22 | import { input } from 'ant-design-testing';
23 |
24 | describe("Test input's fire functions", () => {
25 | test('fireChange', () => {
26 | const fn = jest.fn();
27 | const { container } = render();
28 | input.fireChange(container, 'test');
29 | expect(fn).toBeCalled();
30 | });
31 | });
32 | ```
33 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | setupFilesAfterEnv: ['./tests/setupTests.ts'],
3 | testEnvironment: 'jsdom',
4 | transform: {
5 | '^.+\\.(t|j)sx?$': ['@swc/jest'],
6 | },
7 | testPathIgnorePatterns: ['/node_modules/'],
8 | testMatch: ['**/__tests__/**/(*.)+(spec|test).[jt]s?(x)'],
9 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
10 | };
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ant-design-testing",
3 | "version": "0.1.0-beta.4",
4 | "description": "Easier testing for ant-design-based UI library",
5 | "main": "dist/cjs/index.js",
6 | "types": "dist/cjs/index.d.ts",
7 | "scripts": {
8 | "dev": "father dev",
9 | "build": "father build",
10 | "build:deps": "father prebundle",
11 | "prepublishOnly": "father doctor && npm run build",
12 | "test": "jest",
13 | "release": "bumpp --commit --push --tag && npm publish",
14 | "prepare": "husky install"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/mortalYoung/ant-design-testing"
19 | },
20 | "keywords": [
21 | "Ant Design",
22 | "UI library"
23 | ],
24 | "authors": [
25 | "mortalYoung "
26 | ],
27 | "license": "MIT",
28 | "files": [
29 | "dist",
30 | "compiled"
31 | ],
32 | "publishConfig": {
33 | "access": "public",
34 | "registry": "https://registry.npmjs.org/"
35 | },
36 | "peerDependencies": {
37 | "@testing-library/react": "*",
38 | "antd": "4",
39 | "rc-resize-observer": "*"
40 | },
41 | "peerDependenciesMeta": {
42 | "rc-resize-observer": {
43 | "optional": true
44 | }
45 | },
46 | "devDependencies": {
47 | "@swc/core": "^1.3.58",
48 | "@swc/jest": "^0.2.26",
49 | "@testing-library/react": "^13.0.0",
50 | "@types/jest": "^29.5.1",
51 | "antd": "4",
52 | "bumpp": "^9.1.0",
53 | "father": "^4.2.0",
54 | "husky": "^8.0.3",
55 | "jest": "^29.5.0",
56 | "jest-environment-jsdom": "^29.5.0",
57 | "ko-lint-config": "^2.2.20",
58 | "lint-staged": "^13.2.2",
59 | "moment": "^2.29.4",
60 | "prettier": "^2.8.8",
61 | "rc-resize-observer": "*",
62 | "react": "^18.2.0",
63 | "react-dom": "^18.2.0",
64 | "typescript": "^4.8.0"
65 | },
66 | "lint-staged": {
67 | "*.{ts,js,tsx}": [
68 | "eslint --fix",
69 | "prettier --write"
70 | ]
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/autoComplete/__tests__/autoComplete.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { AutoComplete } from 'antd';
4 |
5 | import * as autoComplete from '..';
6 |
7 | describe('Test Select fire functions', () => {
8 | beforeEach(() => {
9 | jest.useFakeTimers();
10 | cleanup();
11 | });
12 |
13 | afterEach(() => {
14 | jest.useRealTimers();
15 | });
16 |
17 | it('query', () => {
18 | const { container, getByTestId } = render(
19 | <>
20 |
21 |
22 | >
23 | );
24 | expect(autoComplete.query(container)).toBe(getByTestId('autoComplete1'));
25 | expect(autoComplete.query(container, 1)).toBe(getByTestId('autoComplete2'));
26 | });
27 |
28 | it('querySelector', () => {
29 | const { container } = render(
30 | <>
31 |
32 |
33 | >
34 | );
35 | expect(autoComplete.querySelector(container)).not.toBe(autoComplete.querySelector(container, 1));
36 | });
37 |
38 | it('queryOption', () => {
39 | const { container } = render(
40 | node.parentNode}
42 | options={[
43 | { label: 'a', value: 'a' },
44 | { label: 'b', value: 'b' },
45 | ]}
46 | />
47 | );
48 | autoComplete.fireOpen(container);
49 | expect(autoComplete.queryOption(container)?.textContent).toBe('a');
50 | expect(autoComplete.queryOption(container, 1)?.textContent).toBe('b');
51 | });
52 |
53 | it('queryOption', () => {
54 | const fn1 = jest.fn();
55 | const fn2 = jest.fn();
56 | const { container } = render(
57 | <>
58 |
59 |
60 | >
61 | );
62 | autoComplete.fireClear(autoComplete.queryClear(container)!);
63 | expect(fn1).toBeCalledTimes(1);
64 | expect(fn2).not.toBeCalled();
65 | autoComplete.fireClear(autoComplete.queryClear(container, 1)!);
66 | expect(fn2).toBeCalledTimes(1);
67 | });
68 |
69 | it('queryInput', () => {
70 | const { container, getByTestId } = render(
71 | <>
72 |
73 |
74 | >
75 | );
76 | expect(autoComplete.queryInput(container)).toBe(getByTestId('autoComplete1').querySelector('input'));
77 | expect(autoComplete.queryInput(container, 1)).toBe(getByTestId('autoComplete2').querySelector('input'));
78 | });
79 |
80 | it('fireOpen', () => {
81 | const fn = jest.fn();
82 | const { container } = render(
83 |
84 | );
85 | autoComplete.fireOpen(container);
86 | expect(fn).toBeCalledWith(true);
87 | });
88 |
89 | it('fireSelect', () => {
90 | const fn = jest.fn();
91 | const { container } = render(
92 | node.parentNode}
95 | options={[{ label: 'a', value: 'a' }]}
96 | />
97 | );
98 | autoComplete.fireOpen(container);
99 | autoComplete.fireSelect(container, 0);
100 | expect(fn).toBeCalled();
101 | });
102 |
103 | it('fireSearch', () => {
104 | const fn = jest.fn();
105 | const { container } = render();
106 | autoComplete.fireSearch(container, 'test');
107 | expect(fn).toBeCalled();
108 | });
109 |
110 | it('fireFocus', () => {
111 | const fn = jest.fn();
112 | const { container } = render();
113 | autoComplete.fireFocus(container);
114 | expect(fn).toBeCalled();
115 | });
116 |
117 | it('fireBlur', () => {
118 | const fn = jest.fn();
119 | const { container } = render();
120 | autoComplete.fireFocus(container);
121 | autoComplete.fireBlur(container);
122 | expect(fn).toBeCalled();
123 | });
124 |
125 | it('fireClear', () => {
126 | const fn = jest.fn();
127 | const { container } = render(
128 |
129 | );
130 | autoComplete.fireClear(container);
131 | expect(fn).toBeCalled();
132 | });
133 | });
134 |
--------------------------------------------------------------------------------
/src/autoComplete/index.ts:
--------------------------------------------------------------------------------
1 | import type { IContainer } from '../interface';
2 | import { getProvider } from '../provider';
3 | import * as select from '../select';
4 | import { queryViaSelector } from '../utils';
5 |
6 | /**
7 | * Fires onSearch function
8 | */
9 | export function fireSearch(container: IContainer, value: any) {
10 | select.fireSearch(container, value);
11 | }
12 |
13 | /**
14 | * Fires onDropdownVisibleChange function.
15 | * Meanwhile, open Dropdown
16 | * @prerequisite call `jest.useFakeTimers()`
17 | */
18 | export function fireOpen(container: IContainer) {
19 | select.fireOpen(container);
20 | }
21 |
22 | /**
23 | * Fires onSelect function
24 | */
25 | export function fireSelect(container: IContainer, index: number) {
26 | select.fireSelect(container, index);
27 | }
28 |
29 | /**
30 | * Fires onFocus function
31 | */
32 | export function fireFocus(container: IContainer) {
33 | select.fireFocus(container);
34 | }
35 |
36 | /**
37 | * Fires onBlur function
38 | */
39 | export function fireBlur(container: IContainer) {
40 | select.fireBlur(container);
41 | }
42 |
43 | /**
44 | * Fires onClear function
45 | */
46 | export function fireClear(container: IContainer) {
47 | select.fireClear(container);
48 | }
49 |
50 | /**
51 | * Returns the `index` container of AutoComplete
52 | * @param index default is `0`
53 | */
54 | export function query(container: IContainer, index = 0) {
55 | const selector = `.${getProvider('prefixCls')}-select-auto-complete`;
56 | const ele = queryViaSelector(container, selector, index);
57 | return ele;
58 | }
59 |
60 | /**
61 | * Returns input element of AutoComplete
62 | */
63 | export function queryInput(container: IContainer, index = 0) {
64 | return select.queryInput(container, index);
65 | }
66 |
67 | /**
68 | * Returns selector element of AutoComplete
69 | */
70 | export function querySelector(container: IContainer, index = 0) {
71 | return select.querySelector(container, index);
72 | }
73 |
74 | /**
75 | * Returns option element of AutoComplete
76 | */
77 | export function queryOption(container: IContainer, index = 0) {
78 | return select.queryOption(container, index);
79 | }
80 |
81 | /**
82 | * Returns clear icon element of AutoComplete
83 | */
84 | export function queryClear(container: IContainer, index = 0) {
85 | return select.queryClear(container, index);
86 | }
87 |
--------------------------------------------------------------------------------
/src/button/__tests__/button.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import { Button } from 'antd';
4 |
5 | import * as button from '..';
6 |
7 | describe("Test Button's fire functions", () => {
8 | test('query', () => {
9 | const { container, getByTestId } = render(
10 | <>
11 |
12 |
13 | >
14 | );
15 | expect(button.query(container)).toBe(getByTestId('button1'));
16 | expect(button.query(container, 1)).toBe(getByTestId('button2'));
17 | });
18 | test('test fireClick', () => {
19 | const fn = jest.fn();
20 | const { container } = render();
21 | button.fireClick(container);
22 | expect(fn).toBeCalled();
23 | });
24 |
25 | test('fireClick support dom self', () => {
26 | const fn = jest.fn();
27 | const { container } = render();
28 | button.fireClick(button.query(container)!);
29 | expect(fn).toBeCalled();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/src/button/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onClick function for Button
9 | */
10 | export const fireClick = (container: IContainer) => {
11 | const selector = `.${getProvider('prefixCls')}-btn`;
12 | const ele = query(container);
13 | if (!ele) throw failedQuerySelector(selector);
14 | fireEvent.click(ele);
15 | };
16 |
17 | /**
18 | * Returns the `index` button that is a descendant of node.
19 | * @param {number} index default is `0`
20 | */
21 | export const query = (container: IContainer, index = 0) => {
22 | const selector = `.${getProvider('prefixCls')}-btn`;
23 | const ele = queryViaSelector(container, selector, index);
24 | return ele;
25 | };
26 |
--------------------------------------------------------------------------------
/src/cascader/__tests__/cascader.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, fireEvent, render } from '@testing-library/react';
3 | import { Cascader } from 'antd';
4 |
5 | import * as cascader from '..';
6 |
7 | const options = [
8 | {
9 | label: '1',
10 | value: '1',
11 | children: [
12 | {
13 | label: '1-1',
14 | value: '1-1',
15 | children: [
16 | {
17 | label: '1-1-1',
18 | value: '1-1-1',
19 | },
20 | ],
21 | },
22 | ],
23 | },
24 | ];
25 |
26 | describe("Test Cascader's fire functions", () => {
27 | beforeEach(() => {
28 | cleanup();
29 | jest.useFakeTimers();
30 | });
31 | afterEach(() => {
32 | jest.useRealTimers();
33 | });
34 |
35 | test('query', () => {
36 | const { container, getByTestId } = render(
37 |
38 |
39 |
40 |
41 | );
42 | expect(cascader.query(container)).toBe(getByTestId('cascader1'));
43 | expect(cascader.query(container, 1)).toBe(getByTestId('cascader2'));
44 | });
45 |
46 | test('querySelect', () => {
47 | const fn = jest.fn();
48 | const { container } = render(
49 |
50 |
51 |
52 |
53 | );
54 | cascader.fireOpen(cascader.querySelect(container)!);
55 | expect(fn).toBeCalledTimes(1);
56 | cascader.fireOpen(cascader.querySelect(container, 1)!);
57 | // The second time is called because of hidden the first one
58 | expect(fn).toBeCalledTimes(3);
59 | });
60 |
61 | test('queryInput', () => {
62 | const fn = jest.fn();
63 | const { container, getByTestId } = render(
64 |
65 |
66 |
67 |
68 | );
69 |
70 | expect(cascader.queryInput(container)).toBe(getByTestId('cascader1').querySelector('input'));
71 | expect(cascader.queryInput(container, 1)).toBe(getByTestId('cascader2').querySelector('input'));
72 | });
73 |
74 | test('queryDropdown', () => {
75 | render();
76 | expect(cascader.queryDropdown(document)).not.toBeNull();
77 | });
78 |
79 | test('queryMenu', () => {
80 | const fn = jest.fn();
81 | render();
82 | cascader.fireChange(cascader.queryMenu(document)!, 0);
83 | expect(fn).toBeCalled();
84 | });
85 |
86 | test('queryMenuItem', () => {
87 | const fn = jest.fn();
88 | render();
89 | fireEvent.click(cascader.queryMenuItem(document)!);
90 | expect(fn).toBeCalled();
91 | });
92 |
93 | test('fireOpen', () => {
94 | const fn = jest.fn();
95 | const { container } = render();
96 | cascader.fireOpen(container);
97 | expect(fn).toBeCalledTimes(1);
98 | });
99 |
100 | test('fireChange', () => {
101 | const fn = jest.fn();
102 | const { container } = render(
103 | node.parentNode} options={options} />
104 | );
105 | cascader.fireOpen(container);
106 | cascader.fireChange(container, 0, 0, 0);
107 | expect(fn).toBeCalled();
108 | });
109 |
110 | test('fireChange with hover trigger', () => {
111 | const fn = jest.fn();
112 | const { container } = render(
113 | node.parentNode}
117 | options={options}
118 | />
119 | );
120 | cascader.fireOpen(container);
121 | cascader.fireChange(container, 'hover', 0, 0, 0);
122 | expect(fn).toBeCalled();
123 | });
124 |
125 | test('fireSearch', () => {
126 | const fn = jest.fn();
127 | const { container } = render(
128 |
131 | path.some(
132 | (option) => (option.label as string).toLowerCase().indexOf(inputValue.toLowerCase()) > -1
133 | ),
134 | }}
135 | onSearch={fn}
136 | />
137 | );
138 | cascader.fireSearch(container, 'test');
139 | expect(fn).toBeCalled();
140 | });
141 |
142 | test('fireClear', () => {
143 | const fn = jest.fn();
144 | const { container } = render(
145 |
146 | );
147 | cascader.fireClear(container);
148 | expect(fn).toBeCalled();
149 | });
150 |
151 | test('fireChange with multiple', () => {
152 | const fn1 = jest.fn();
153 | const fn2 = jest.fn();
154 | const { container } = render(
155 | <>
156 | node.parentNode} options={options} />
157 | node.parentNode} options={options} />
158 | >
159 | );
160 | cascader.fireOpen(container);
161 | cascader.fireChange(container, 0, 0, 0);
162 | expect(fn1).toBeCalledTimes(1);
163 | expect(fn2).toBeCalledTimes(0);
164 |
165 | cascader.fireOpen(cascader.query(container, 1)!);
166 | cascader.fireChange(cascader.queryDropdown(container, 1)!, 0, 0, 0);
167 | expect(fn1).toBeCalledTimes(1);
168 | expect(fn2).toBeCalledTimes(1);
169 | });
170 | });
171 |
--------------------------------------------------------------------------------
/src/cascader/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 | import type { CascaderProps } from 'antd';
3 |
4 | import type { IContainer } from '../interface';
5 | import { getProvider } from '../provider';
6 | import { fireClear as selectFireClear, fireOpen as selectFireOpen } from '../select';
7 | import { failedQuerySelector, queryViaSelector, queryViaSelectors } from '../utils';
8 |
9 | /**
10 | * Fires onDropdownVisibleChange for Cascader, and open drowdown
11 | */
12 | export function fireOpen(container: IContainer) {
13 | selectFireOpen(container);
14 | }
15 |
16 | /**
17 | * Fires onChange for Cascader
18 | * @param indexes each panel's index
19 | */
20 | export function fireChange(container: IContainer, ...indexes: number[]): void;
21 | /**
22 | * Fires onChange for Cascader by click or hover
23 | * @param type as same as Cascader's expandTrigger
24 | * @param indexes each panel's index
25 | */
26 | export function fireChange(container: IContainer, type: CascaderProps['expandTrigger'], ...indexes: number[]): void;
27 | export function fireChange(
28 | container: IContainer,
29 | typeOrIndex: CascaderProps['expandTrigger'] | number,
30 | ...rest: number[]
31 | ) {
32 | const type = typeof typeOrIndex === 'string' ? typeOrIndex : 'click';
33 | const indexes = typeof typeOrIndex === 'number' ? [typeOrIndex].concat(rest) : rest;
34 | const triggerEvent = {
35 | click: 'click',
36 | hover: 'mouseEnter',
37 | } as const;
38 | for (let i = 0; i < indexes.length; i++) {
39 | const index = indexes[i];
40 | const selectors = [
41 | `ul.${getProvider('prefixCls')}-cascader-menu`,
42 | `li.${getProvider('prefixCls')}-cascader-menu-item`,
43 | ];
44 | const ele = queryViaSelectors(container, selectors, [i, index]);
45 | if (!ele) throw failedQuerySelector(selectors.join(' '));
46 |
47 | const last = i === indexes.length - 1;
48 | fireEvent[last ? 'click' : triggerEvent[type]]?.(ele);
49 | }
50 | }
51 |
52 | /**
53 | * Fires onSearch for Cascader
54 | */
55 | export function fireSearch(container: IContainer, value: string) {
56 | const selector = 'input';
57 | const ele = queryInput(container);
58 | if (!ele) throw failedQuerySelector(selector);
59 | fireEvent.change(ele, { target: { value } });
60 | }
61 |
62 | /**
63 | * Fires onClear for Cascader
64 | * @notice clear button **ONLY** accessible for non-empty value
65 | */
66 | export function fireClear(container: IContainer) {
67 | selectFireClear(container);
68 | }
69 |
70 | /**
71 | * Returns the `index` element of Cascader's container
72 | * @param index the order of Cascader's container, default is `0`
73 | */
74 | export function query(container: IContainer, index = 0) {
75 | const selector = `.${getProvider('prefixCls')}-cascader`;
76 | const ele = queryViaSelector(container, selector, index);
77 | return ele;
78 | }
79 |
80 | /**
81 | * Returns the `index` element of Cascader's Select
82 | * @param index the order of Cascader's Select, default is `0`
83 | */
84 | export function querySelect(container: IContainer, index = 0) {
85 | const selector = `.${getProvider('prefixCls')}-select-selector`;
86 | const ele = queryViaSelector(container, selector, index);
87 | return ele;
88 | }
89 |
90 | /**
91 | * Returns the `index` element of Cascader's Input
92 | * @param index the order of Cascader's Input, default is `0`
93 | */
94 | export function queryInput(container: IContainer, index = 0) {
95 | const selector = 'input';
96 | const ele = queryViaSelector(container, selector, index);
97 | return ele;
98 | }
99 |
100 | /**
101 | * Returns the `index` element of Cascader's Dropdown
102 | * @notice Be aware of the different parentElement affected by getPopupContainer
103 | * @param index the order of Cascader's Dropdown, default is `0`
104 | */
105 | export function queryDropdown(container: IContainer, index = 0) {
106 | const selector = `.${getProvider('prefixCls')}-cascader-dropdown`;
107 | const ele = queryViaSelector(container, selector, index);
108 | return ele;
109 | }
110 |
111 | /**
112 | * Returns the `index` element of Menu inside Cascader's Dropdown
113 | * @param index the order of Menu, default is `0`
114 | */
115 | export function queryMenu(container: IContainer, index = 0) {
116 | const selector = `ul.${getProvider('prefixCls')}-cascader-menu`;
117 | const ele = queryViaSelector(container, selector, index);
118 | return ele;
119 | }
120 |
121 | /**
122 | * Returns the `index` element of MenuItem inside Cascader's Dropdown
123 | * @param index the order of MenuItem, default is `0`
124 | */
125 | export function queryMenuItem(container: IContainer, index = 0) {
126 | const selector = `li.${getProvider('prefixCls')}-cascader-menu-item`;
127 | const ele = queryViaSelector(container, selector, index);
128 | return ele;
129 | }
130 |
--------------------------------------------------------------------------------
/src/checkbox/__tests__/checkbox.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Checkbox } from 'antd';
4 |
5 | import * as checkbox from '..';
6 |
7 | describe('Test checkbox', () => {
8 | beforeEach(cleanup);
9 |
10 | test('query', () => {
11 | const { container, getByTestId } = render(
12 | <>
13 | Checkbox
14 | Checkbox
15 | >
16 | );
17 | expect(checkbox.query(container)?.querySelector('input')).toBe(getByTestId('Checkbox1'));
18 | expect(checkbox.query(container, 1)?.querySelector('input')).toBe(getByTestId('Checkbox2'));
19 | });
20 |
21 | test('queryGroup', () => {
22 | const { container, getByTestId } = render(
23 | <>
24 |
25 |
26 | >
27 | );
28 | expect(checkbox.queryGroup(container)).toBe(getByTestId('Checkbox1'));
29 | expect(checkbox.queryGroup(container, 1)).toBe(getByTestId('Checkbox2'));
30 | });
31 |
32 | test('queryInput', () => {
33 | const fn = jest.fn();
34 | const { container } = render();
35 | checkbox.fireChange(checkbox.queryInput(container)!, 0);
36 | expect(fn).toBeCalledWith(['Apple']);
37 | });
38 |
39 | test('fireChange', () => {
40 | const fn = jest.fn();
41 | const { container } = render();
42 | checkbox.fireChange(container, 0);
43 | expect(fn).toBeCalledWith(['Apple']);
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/src/checkbox/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onChange function
9 | */
10 | export function fireChange(container: IContainer, index: number) {
11 | const selector = `.${getProvider('prefixCls')}-checkbox-input`;
12 | const ele = queryInput(container, index);
13 | if (!ele) throw failedQuerySelector(selector);
14 | fireEvent.click(ele);
15 | }
16 |
17 | /**
18 | * Returns the `index` container
19 | * @param index default is `0`
20 | */
21 | export function query(container: IContainer, index = 0) {
22 | const selector = `.${getProvider('prefixCls')}-checkbox-wrapper`;
23 | const ele = queryViaSelector(container, selector, index);
24 | return ele;
25 | }
26 |
27 | /**
28 | * Returns the `index` container for checkbox's group
29 | * @param index default is `0`
30 | */
31 | export function queryGroup(container: IContainer, index = 0) {
32 | const selector = `.${getProvider('prefixCls')}-checkbox-group`;
33 | const ele = queryViaSelector(container, selector, index);
34 | return ele;
35 | }
36 |
37 | /**
38 | * Returns the `index` input inside Checkbox
39 | * @param index default is `0`
40 | */
41 | export function queryInput(container: IContainer, index = 0) {
42 | const selector = `.${getProvider('prefixCls')}-checkbox-input`;
43 | const ele = queryViaSelector(container, selector, index);
44 | return ele;
45 | }
46 |
--------------------------------------------------------------------------------
/src/collapse/__tests__/collapse.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Collapse } from 'antd';
4 |
5 | import * as collapse from '..';
6 |
7 | describe("Test Collapse's fire functions", () => {
8 | beforeEach(cleanup);
9 |
10 | test('query', () => {
11 | const fn1 = jest.fn();
12 | const fn2 = jest.fn();
13 | const { container } = render(
14 | <>
15 |
16 |
17 | 1
18 |
19 |
20 |
21 |
22 | 1
23 |
24 |
25 | >
26 | );
27 | collapse.fireChange(collapse.query(container, 1)!, 0);
28 | expect(fn1).not.toBeCalled();
29 | expect(fn2).toBeCalled();
30 | });
31 |
32 | test('fireChange', () => {
33 | const fn = jest.fn();
34 | const { container } = render(
35 |
36 |
37 | 1
38 |
39 |
40 | 2
41 |
42 |
43 | );
44 |
45 | collapse.fireChange(container, 0);
46 | expect(fn).toBeCalled();
47 | });
48 | });
49 |
--------------------------------------------------------------------------------
/src/collapse/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onChange function
9 | */
10 | export function fireChange(container: IContainer, index: number) {
11 | const selector = `.${getProvider('prefixCls')}-collapse-header`;
12 | const ele = queryViaSelector(container, selector, index);
13 | if (!ele) throw failedQuerySelector(selector);
14 | fireEvent.click(ele);
15 | }
16 |
17 | /**
18 | * Returns the `index` container of Collapse
19 | */
20 | export function query(container: IContainer, index = 0) {
21 | const selector = `.${getProvider('prefixCls')}-collapse`;
22 | const ele = queryViaSelector(container, selector, index);
23 | return ele;
24 | }
25 |
--------------------------------------------------------------------------------
/src/datePicker/__tests__/datePicker.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { DatePicker } from 'antd';
4 | import moment from 'moment';
5 |
6 | import * as datePicker from '..';
7 |
8 | const dateAdaptor = moment;
9 |
10 | describe("Test DatePicker's fire functions", () => {
11 | beforeEach(cleanup);
12 |
13 | test('query', () => {
14 | const { container, getByTestId } = render(
15 | <>
16 |
17 |
18 | >
19 | );
20 | expect(datePicker.query(container)?.querySelector('input')).toBe(getByTestId('datePicker1'));
21 | expect(datePicker.query(container, 1)?.querySelector('input')).toBe(getByTestId('datePicker2'));
22 | });
23 |
24 | test('queryInput', () => {
25 | const { container, getByTestId } = render(
26 | <>
27 |
28 |
29 | >
30 | );
31 | expect(datePicker.queryInput(container)).toBe(getByTestId('datePicker1'));
32 | expect(datePicker.queryInput(container, 1)).toBe(getByTestId('datePicker2'));
33 | });
34 |
35 | test('queryDropdown', () => {
36 | const fn = jest.fn();
37 | const { container } = render(
38 | node.parentElement!}
42 | />
43 | );
44 | datePicker.fireOpen(container);
45 | datePicker.fireChange(datePicker.queryDropdown(container)!, '24');
46 | expect(
47 | (fn.mock.calls[0][0] as ReturnType).isSame(dateAdaptor('2018-04-24 19:18'))
48 | ).toBeTruthy();
49 | expect(fn.mock.calls[0][1]).toBe(dateAdaptor('2018-04-24 19:18').format('YYYY-MM-DD'));
50 | });
51 |
52 | test('querySuperPrevButton', () => {
53 | const { container } = render(
54 | node.parentElement!} />
55 | );
56 | datePicker.fireOpen(container);
57 | expect(datePicker.querySuperPrevButton(container)?.nodeName).toBe('BUTTON');
58 | });
59 |
60 | test('fireOpen', () => {
61 | const fn = jest.fn();
62 | const { container } = render();
63 | datePicker.fireOpen(container);
64 | expect(fn).toBeCalledTimes(1);
65 | });
66 |
67 | test('fireClose', () => {
68 | const fn = jest.fn();
69 | const { container } = render();
70 | datePicker.fireClose(container);
71 | expect(fn).toBeCalledTimes(1);
72 | });
73 |
74 | test('firePanelChange', () => {
75 | const fn = jest.fn();
76 | const { container } = render(
77 | node.parentElement!}
81 | />
82 | );
83 | datePicker.fireOpen(container);
84 | datePicker.firePanelChange(container);
85 | expect(fn).lastCalledWith(dateAdaptor('2018-04-13 19:18').subtract(1, 'year'), 'date');
86 | });
87 |
88 | test('firePanelChange with certain button', () => {
89 | const fn = jest.fn();
90 | const { container } = render(
91 | node.parentElement!}
95 | />
96 | );
97 | datePicker.fireOpen(container);
98 | datePicker.firePanelChange(datePicker.queryPrevButton(container)!);
99 | expect(fn).lastCalledWith(dateAdaptor('2018-04-13 19:18').subtract(1, 'month'), 'date');
100 |
101 | datePicker.firePanelChange(datePicker.queryNextButton(container)!);
102 | expect(fn).lastCalledWith(dateAdaptor('2018-04-13 19:18'), 'date');
103 |
104 | datePicker.firePanelChange(datePicker.querySuperNextButton(container)!);
105 | expect(fn).lastCalledWith(dateAdaptor('2018-04-13 19:18').add(1, 'year'), 'date');
106 |
107 | datePicker.firePanelChange(datePicker.queryMonthButton(container)!);
108 | expect(fn).lastCalledWith(dateAdaptor('2018-04-13 19:18').add(1, 'year'), 'month');
109 |
110 | datePicker.firePanelChange(datePicker.queryYearButton(container)!);
111 | expect(fn).lastCalledWith(dateAdaptor('2018-04-13 19:18').add(1, 'year'), 'year');
112 |
113 | datePicker.firePanelChange(datePicker.queryDecadeButton(container)!);
114 | expect(fn).lastCalledWith(dateAdaptor('2018-04-13 19:18').add(1, 'year'), 'decade');
115 | });
116 |
117 | test('fireChange', () => {
118 | const fn = jest.fn();
119 | const { container } = render(
120 | node.parentElement!}
124 | />
125 | );
126 | datePicker.fireOpen(container);
127 | datePicker.fireChange(container, '24');
128 | expect(
129 | (fn.mock.calls[0][0] as ReturnType).isSame(dateAdaptor('2018-04-24 19:18'))
130 | ).toBeTruthy();
131 | expect(fn.mock.calls[0][1]).toBe(dateAdaptor('2018-04-24 19:18').format('YYYY-MM-DD'));
132 | });
133 |
134 | test('fireCalendarChange', () => {
135 | const fn = jest.fn();
136 | const { container } = render(
137 | node.parentElement!}
141 | />
142 | );
143 | datePicker.fireOpen(container);
144 | datePicker.fireChange(container, '15');
145 |
146 | expect(fn).toBeCalled();
147 | });
148 |
149 | test('fireOk', () => {
150 | const fn = jest.fn();
151 | const { container } = render(
152 | node.parentElement!}
157 | />
158 | );
159 |
160 | datePicker.fireOpen(container);
161 | datePicker.fireOk(container);
162 | expect(fn).toBeCalledTimes(1);
163 | });
164 | });
165 |
--------------------------------------------------------------------------------
/src/datePicker/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, failedTriggerElement, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onOpenChange function.
9 | * Meanwhile, open Dropdown
10 | */
11 | export function fireOpen(container: IContainer) {
12 | const selector = 'input';
13 | const ele = queryInput(container);
14 | if (!ele) throw failedQuerySelector(selector);
15 | fireEvent.mouseDown(ele);
16 | fireEvent.focus(ele);
17 | }
18 |
19 | /**
20 | * Fires onOpenChange function.
21 | * Meanwhile, close dropdown
22 | */
23 | export function fireClose(container: IContainer) {
24 | const selector = 'input';
25 | const ele = queryInput(container);
26 | if (!ele) throw failedQuerySelector(selector);
27 | fireEvent.blur(ele);
28 | }
29 |
30 | /**
31 | * Fires onPanelChange function
32 | * @notice there are majority ways to call onPanelChange depends on current panel's status
33 | *
34 | * The sequence of calling onPanelChange is like
35 | * `[super prev] -> [prev] -> [next] -> [super next] -> [month] -> [year] -> [decade]`
36 | *
37 | * _If you intent to call specific button, call firePanelChange with queryXXX_
38 | *
39 | * @param mode defualt is `date`
40 | */
41 | export function firePanelChange(container: IContainer) {
42 | const ele =
43 | querySuperPrevButton(container) ||
44 | queryPrevButton(container) ||
45 | queryNextButton(container) ||
46 | querySuperNextButton(container) ||
47 | queryMonthButton(container) ||
48 | queryYearButton(container) ||
49 | queryDecadeButton(container);
50 | if (!ele) throw failedTriggerElement();
51 | fireEvent.click(ele);
52 | }
53 |
54 | /**
55 | * Fires onChange function or onCalendarChange function for DatePicker.RangePicker
56 | * @notice May **NOT** call onChange certainly, it depends on whether called firePanelChange before
57 | * @param text current text on Panel
58 | */
59 | export function fireChange(container: IContainer, text: string) {
60 | const eles = container.querySelectorAll('table td');
61 | const selector = '-in-view';
62 | const cell = Array.from(eles).find((td) => {
63 | return td.textContent === String(text) && td.className.includes(selector);
64 | });
65 | if (!cell) throw failedQuerySelector(`end with ${selector}`);
66 | fireEvent.click(cell);
67 | }
68 |
69 | /**
70 | * Fires onOk function
71 | */
72 | export function fireOk(container: IContainer) {
73 | const selector = `.${getProvider('prefixCls')}-picker-ok > *`;
74 | const ele = queryViaSelector(container, selector);
75 | if (!ele) throw failedQuerySelector(selector);
76 | fireEvent.click(ele);
77 | }
78 |
79 | /**
80 | * Returns the `index` container of DatePicker
81 | * @param index defualt is `0`
82 | */
83 | export function query(container: IContainer, index = 0) {
84 | const selector = `.${getProvider('prefixCls')}-picker`;
85 | const ele = queryViaSelector(container, selector, index);
86 | return ele;
87 | }
88 |
89 | /**
90 | * Returns the `index` input element in DatePicker
91 | * @param index default is `0`
92 | */
93 | export function queryInput(container: IContainer, index = 0) {
94 | const selector = `input`;
95 | const ele = queryViaSelector(container, selector, index);
96 | return ele;
97 | }
98 |
99 | /**
100 | * Returns the `index` dropdown's container about DatePicker
101 | * @param index default is `0`
102 | * @returns
103 | */
104 | export function queryDropdown(container: IContainer, index = 0) {
105 | const selector = `.${getProvider('prefixCls')}-picker-dropdown`;
106 | const ele = queryViaSelector(container, selector, index);
107 | return ele;
108 | }
109 |
110 | /**
111 | * Returns the `index` super prev button
112 | * @param index defualt is `0`
113 | */
114 | export function querySuperPrevButton(container: IContainer, index = 0) {
115 | const selector = `.${getProvider('prefixCls')}-picker-header-super-prev-btn`;
116 | const ele = queryViaSelector(container, selector, index);
117 | return ele;
118 | }
119 |
120 | /**
121 | * Returns the `index` prev button
122 | * @param index defualt is `0`
123 | */
124 | export function queryPrevButton(container: IContainer, index = 0) {
125 | const selector = `.${getProvider('prefixCls')}-picker-header-prev-btn`;
126 | const ele = queryViaSelector(container, selector, index);
127 | return ele;
128 | }
129 |
130 | /**
131 | * Returns the `index` super next button
132 | * @param index defualt is `0`
133 | */
134 | export function querySuperNextButton(container: IContainer, index = 0) {
135 | const selector = `.${getProvider('prefixCls')}-picker-header-super-next-btn`;
136 | const ele = queryViaSelector(container, selector, index);
137 | return ele;
138 | }
139 |
140 | /**
141 | * Returns the `index` next button
142 | * @param index defualt is `0`
143 | */
144 | export function queryNextButton(container: IContainer, index = 0) {
145 | const selector = `.${getProvider('prefixCls')}-picker-header-next-btn`;
146 | const ele = queryViaSelector(container, selector, index);
147 | return ele;
148 | }
149 |
150 | /**
151 | * Returns the `index` decade button
152 | * @param index default is `0`
153 | */
154 | export function queryDecadeButton(container: IContainer, index = 0) {
155 | const selector = `.${getProvider('prefixCls')}-picker-decade-btn`;
156 | const ele = queryViaSelector(container, selector, index);
157 | return ele;
158 | }
159 |
160 | /**
161 | * Returns the `index` year button
162 | * @param index default is `0`
163 | */
164 | export function queryYearButton(container: IContainer, index = 0) {
165 | const selector = `.${getProvider('prefixCls')}-picker-year-btn`;
166 | const ele = queryViaSelector(container, selector, index);
167 | return ele;
168 | }
169 |
170 | /**
171 | * Returns the `index` month button
172 | * @param index default is `0`
173 | */
174 | export function queryMonthButton(container: IContainer, index = 0) {
175 | const selector = `.${getProvider('prefixCls')}-picker-month-btn`;
176 | const ele = queryViaSelector(container, selector, index);
177 | return ele;
178 | }
179 |
--------------------------------------------------------------------------------
/src/drawer/__tests__/drawer.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Drawer } from 'antd';
4 |
5 | import * as drawer from '..';
6 |
7 | describe("Test Drawer fire's functions", () => {
8 | beforeEach(cleanup);
9 |
10 | test('fireClose', () => {
11 | const fn = jest.fn();
12 | const { container } = render();
13 | drawer.fireClose(container);
14 | expect(fn).toBeCalled();
15 | });
16 |
17 | test('fireClose by icon', () => {
18 | const fn = jest.fn();
19 | const { container } = render();
20 | drawer.fireClose(container, { closeByMask: true });
21 | expect(fn).toBeCalled();
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/src/drawer/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onClose function.
9 | *
10 | * Call onClose via close icon by default
11 | */
12 | export function fireClose(container: IContainer, opt: { closeByMask: boolean } = { closeByMask: true }) {
13 | const selector = opt.closeByMask
14 | ? `.${getProvider('prefixCls')}-drawer-mask`
15 | : `.${getProvider('prefixCls')}-drawer-close`;
16 | const ele = queryViaSelector(container, selector);
17 | if (!ele) throw failedQuerySelector(selector);
18 | fireEvent.click(ele);
19 | }
20 |
--------------------------------------------------------------------------------
/src/dropdown/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | export function fireCloseWithESC() {
4 | fireEvent.keyDown(window, { key: 'Esc', keyCode: 27 });
5 | }
6 |
--------------------------------------------------------------------------------
/src/form/__tests__/form.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render, waitFor } from '@testing-library/react';
3 | import { Button, Form, Input } from 'antd';
4 |
5 | import * as button from '../../button';
6 | import * as form from '../';
7 |
8 | describe("Test form's functions", () => {
9 | beforeEach(() => {
10 | cleanup();
11 | jest.useFakeTimers();
12 | });
13 | afterEach(() => {
14 | jest.useRealTimers();
15 | });
16 |
17 | test('query', () => {
18 | const { container } = render(
19 | <>
20 |
21 |
22 | >
23 | );
24 | expect(form.query(container)?.id).toBe('basic');
25 | expect(form.query(container, 1)?.id).toBe('advance');
26 | });
27 |
28 | test('queryFormItems', async () => {
29 | const fn = jest.fn();
30 | const { container } = render(
31 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | );
40 | button.fireClick(form.queryFormItems(container, 1)!);
41 | await waitFor(() => {
42 | expect(fn).toBeCalledTimes(1);
43 | });
44 | });
45 |
46 | test('queryFormItemControls', () => {
47 | const { container } = render(
48 |
50 |
51 |
52 |
53 | );
54 | expect(form.queryFormItemControls(container)?.querySelector('label')).toBeNull();
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/src/form/index.ts:
--------------------------------------------------------------------------------
1 | import { IContainer } from '../interface';
2 | import { getProvider } from '../provider';
3 | import { queryViaSelector } from '../utils';
4 |
5 | /**
6 | * Returns the `index` container of Form
7 | * @param index default is `0`
8 | */
9 | export function query(container: IContainer, index = 0) {
10 | const selector = `.${getProvider('prefixCls')}-form`;
11 | return queryViaSelector(container, selector, index);
12 | }
13 |
14 | /**
15 | * Returns the `index` form item's element
16 | * @param index default is `0`
17 | */
18 | export function queryFormItems(container: IContainer, index = 0) {
19 | const selector = `.${getProvider('prefixCls')}-form-item`;
20 | return queryViaSelector(container, selector, index);
21 | }
22 |
23 | /**
24 | * Returns the `index` form item's control's element
25 | * @param index default is `0`
26 | */
27 | export function queryFormItemControls(container: IContainer, index = 0) {
28 | const selector = `.${getProvider('prefixCls')}-form-item-control`;
29 | return queryViaSelector(container, selector, index);
30 | }
31 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * as autoComplete from './autoComplete';
2 | export * as button from './button';
3 | export * as cascader from './cascader';
4 | export * as checkbox from './checkbox';
5 | export * as collapse from './collapse';
6 | export * as datePicker from './datePicker';
7 | export * as drawer from './drawer';
8 | export * as dropdown from './dropdown';
9 | export * as form from './form';
10 | export * as input from './input';
11 | export * as inputNumber from './inputNumber';
12 | export * as message from './message';
13 | export * as modal from './modal';
14 | export * as pagination from './pagination';
15 | export * as popconfirm from './popconfirm';
16 | export { getProvider, getProviders, provider } from './provider';
17 | export * as radio from './radio';
18 | export * as select from './select';
19 | export * as switch from './switch';
20 | export * as table from './table';
21 | export * as tabs from './tabs';
22 | export * as timePicker from './timePicker';
23 | export * as tooltip from './tooltip';
24 | export * as transfer from './transfer';
25 | export * as tree from './tree';
26 | export * as treeSelect from './treeSelect';
27 | export * as upload from './upload';
28 |
--------------------------------------------------------------------------------
/src/input/__tests__/input.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import { Input } from 'antd';
4 |
5 | import * as input from '..';
6 |
7 | describe("Test input's fire functions", () => {
8 | test('query', () => {
9 | const { container, getByTestId } = render(
10 |
11 |
12 |
13 |
14 | );
15 | expect(input.query(container)).toBe(getByTestId('input1'));
16 | expect(input.query(container, 1)).toBe(getByTestId('input2'));
17 | });
18 |
19 | test('fireChange', () => {
20 | const fn = jest.fn();
21 | const { container } = render();
22 | input.fireChange(container, 'test');
23 |
24 | expect(fn).toBeCalled();
25 | });
26 |
27 | test('fireFocus', () => {
28 | const fn = jest.fn();
29 | const { container } = render();
30 | input.fireFocus(container);
31 |
32 | expect(fn).toBeCalled();
33 | });
34 |
35 | test('fireBlur', () => {
36 | const fn = jest.fn();
37 | const { container } = render();
38 | input.fireBlur(container);
39 |
40 | expect(fn).toBeCalled();
41 | });
42 |
43 | test('fireClear', () => {
44 | const fn = jest.fn();
45 | const { container } = render();
46 | input.fireClear(container);
47 | expect(fn).toBeCalled();
48 | });
49 |
50 | test('firePressEnter', () => {
51 | const fn = jest.fn();
52 | const { container } = render();
53 | input.firePressEnter(container);
54 |
55 | expect(fn).toBeCalled();
56 | });
57 | });
58 |
--------------------------------------------------------------------------------
/src/input/__tests__/textarea.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render, waitFor } from '@testing-library/react';
3 | import { Input } from 'antd';
4 |
5 | import * as textarea from '../textarea';
6 |
7 | describe("Test textarea's fire functions", () => {
8 | beforeEach(cleanup);
9 | test('query', () => {
10 | const { container, getByTestId } = render(
11 | <>
12 |
13 |
14 | >
15 | );
16 | expect(textarea.query(container)).toBe(getByTestId('textarea1'));
17 | expect(textarea.query(container, 1)).toBe(getByTestId('textarea2'));
18 | });
19 |
20 | test('fireChange', () => {
21 | const fn = jest.fn();
22 | const { container } = render();
23 | textarea.fireChange(container, 'test');
24 |
25 | expect(fn).toBeCalled();
26 | });
27 |
28 | test('fireFocus', () => {
29 | const fn = jest.fn();
30 | const { container } = render();
31 | textarea.fireFocus(container);
32 |
33 | expect(fn).toBeCalled();
34 | });
35 |
36 | test('fireBlur', () => {
37 | const fn = jest.fn();
38 | const { container } = render();
39 | textarea.fireBlur(container);
40 |
41 | expect(fn).toBeCalled();
42 | });
43 |
44 | test('fireClear', () => {
45 | const fn = jest.fn();
46 | const { container } = render();
47 | textarea.fireClear(container);
48 | expect(fn).toBeCalled();
49 | });
50 |
51 | test('firePressEnter', () => {
52 | const fn = jest.fn();
53 | const { container } = render();
54 | textarea.firePressEnter(container);
55 |
56 | expect(fn).toBeCalled();
57 | });
58 |
59 | test('fireResize', async () => {
60 | const fn = jest.fn();
61 | const { container } = render();
62 | textarea.fireResize(container, { width: 200, height: 300 } as DOMRect);
63 |
64 | await waitFor(() => {
65 | expect(fn).toBeCalled();
66 | });
67 | });
68 | });
69 |
--------------------------------------------------------------------------------
/src/input/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onFocus function
9 | */
10 | export function fireFocus(container: IContainer) {
11 | const selector = 'input';
12 | const inputEl = query(container);
13 | if (!inputEl) throw failedQuerySelector(selector);
14 | fireEvent.focus(inputEl);
15 | }
16 |
17 | /**
18 | * Fires onBlur function
19 | */
20 | export function fireBlur(container: IContainer) {
21 | const selector = 'input';
22 | const inputEl = query(container);
23 | if (!inputEl) throw failedQuerySelector(selector);
24 | fireEvent.blur(inputEl);
25 | }
26 |
27 | /**
28 | * Fires onChange function
29 | */
30 | export function fireChange(container: IContainer, value: any) {
31 | const selector = 'input';
32 | const inputEl = query(container);
33 | if (!inputEl) throw failedQuerySelector(selector);
34 | fireEvent.change(inputEl, { target: { value } });
35 | }
36 |
37 | /**
38 | * Fires onClear function
39 | */
40 | export function fireClear(container: IContainer) {
41 | const selector = `.${getProvider('prefixCls')}-input-clear-icon`;
42 | const ele =
43 | container instanceof HTMLInputElement
44 | ? query(container.parentElement as HTMLElement)
45 | : queryViaSelector(container, selector);
46 |
47 | if (!ele) throw failedQuerySelector(selector);
48 | fireEvent.click(ele);
49 | }
50 |
51 | /**
52 | * Fires onPressEnter function
53 | */
54 | export function firePressEnter(container: IContainer) {
55 | const selector = 'input';
56 | const inputEl = query(container);
57 | if (!inputEl) throw failedQuerySelector(selector);
58 | fireEvent.keyDown(inputEl, { key: 'Enter' });
59 | }
60 |
61 | /**
62 | * Returns the input element
63 | */
64 | export function query(container: IContainer, index = 0) {
65 | const selector = `input.${getProvider('prefixCls')}-input`;
66 | const ele = queryViaSelector(container, selector, index);
67 | return ele;
68 | }
69 |
70 | export * as textarea from './textarea';
71 |
--------------------------------------------------------------------------------
/src/input/textarea.ts:
--------------------------------------------------------------------------------
1 | import { act, fireEvent } from '@testing-library/react';
2 | import { _rs as onResize } from 'rc-resize-observer/lib/utils/observerUtil';
3 |
4 | import type { IContainer } from '../interface';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 | import { fireClear as inputFireClear } from '.';
7 |
8 | /**
9 | * Fires onFocus function
10 | */
11 | export function fireFocus(container: IContainer) {
12 | const selector = 'textarea';
13 | const textareaEl = query(container);
14 | if (!textareaEl) throw failedQuerySelector(selector);
15 | fireEvent.focus(textareaEl);
16 | }
17 |
18 | /**
19 | * Fires onBlur function
20 | */
21 | export function fireBlur(container: IContainer) {
22 | const selector = 'textarea';
23 | const textareaEl = query(container);
24 | if (!textareaEl) throw failedQuerySelector(selector);
25 | fireEvent.blur(textareaEl);
26 | }
27 |
28 | /**
29 | * Fires onChange functionƒ
30 | */
31 | export function fireChange(container: IContainer, value: any) {
32 | const selector = 'textarea';
33 | const textareaEl = query(container);
34 | if (!textareaEl) throw failedQuerySelector(selector);
35 | fireEvent.change(textareaEl, { target: { value } });
36 | }
37 |
38 | /**
39 | * Fires onClear function
40 | */
41 | export function fireClear(container: IContainer) {
42 | // directly call input's fireClear
43 | inputFireClear(container);
44 | }
45 |
46 | /**
47 | * Fires onClear function
48 | */
49 | export function firePressEnter(container: IContainer) {
50 | const selector = 'textarea';
51 | const textareaEl = query(container);
52 | if (!textareaEl) throw failedQuerySelector(selector);
53 | fireEvent.keyDown(textareaEl, { keyCode: 13 });
54 | }
55 |
56 | /**
57 | * Fires onResize function
58 | */
59 | export function fireResize(container: IContainer, rect: DOMRect) {
60 | const selector = 'textarea';
61 | const textareaEl = query(container);
62 | if (!textareaEl) throw failedQuerySelector(selector);
63 | const originGetBoundingClientRect = textareaEl.getBoundingClientRect;
64 | textareaEl.getBoundingClientRect = () => rect;
65 |
66 | act(() => {
67 | onResize([{ target: textareaEl } as unknown as ResizeObserverEntry]);
68 | });
69 |
70 | textareaEl.getBoundingClientRect = originGetBoundingClientRect;
71 | }
72 |
73 | /**
74 | * Returns the textarea element
75 | */
76 | export function query(container: IContainer, index = 0) {
77 | const selector = 'textarea';
78 | return queryViaSelector(container, selector, index);
79 | }
80 |
--------------------------------------------------------------------------------
/src/inputNumber/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onChange function
9 | */
10 | export function fireChange(container: IContainer, value: any) {
11 | const selector = `input.${getProvider('prefixCls')}-input-number-input`;
12 | const ele = queryInput(container);
13 | if (!ele) throw failedQuerySelector(selector);
14 | fireEvent.change(ele, { target: { value } });
15 | }
16 |
17 | /**
18 | * Fires onStepUp function
19 | */
20 | export function fireStepUp(container: IContainer) {
21 | const selector = `.${getProvider('prefixCls')}-input-number-handler-up`;
22 | const ele = queryViaSelector(container, selector);
23 | if (!ele) throw failedQuerySelector(selector);
24 | fireEvent.mouseDown(ele);
25 | }
26 |
27 | /**
28 | * Fires onStepDown function
29 | */
30 | export function fireStepDown(container: IContainer) {
31 | const selector = `.${getProvider('prefixCls')}-input-number-handler-down`;
32 | const ele = queryViaSelector(container, selector);
33 | if (!ele) throw failedQuerySelector(selector);
34 | fireEvent.mouseDown(ele);
35 | }
36 |
37 | /**
38 | * Fires onPressEnter function
39 | */
40 | export function firePressEnter(container: IContainer) {
41 | const selector = `input.${getProvider('prefixCls')}-input-number-input`;
42 | const inputEl = queryInput(container);
43 | if (!inputEl) throw failedQuerySelector(selector);
44 | fireEvent.keyDown(inputEl, { key: 'Enter' });
45 | }
46 |
47 | /**
48 | * Fires onFocus function
49 | */
50 | export function fireFocus(container: IContainer) {
51 | const selector = `input.${getProvider('prefixCls')}-input-number-input`;
52 | const inputEl = queryInput(container);
53 | if (!inputEl) throw failedQuerySelector(selector);
54 | fireEvent.focus(inputEl);
55 | }
56 |
57 | /**
58 | * Fires onBlur function
59 | */
60 | export function fireBlur(container: IContainer) {
61 | const selector = `input.${getProvider('prefixCls')}-input-number-input`;
62 | const inputEl = queryInput(container);
63 | if (!inputEl) throw failedQuerySelector(selector);
64 | fireEvent.blur(inputEl);
65 | }
66 |
67 | /**
68 | * Returns the container of InputNumber
69 | */
70 | export function query(container: IContainer, index = 0) {
71 | const selector = `.${getProvider('prefixCls')}-input-number`;
72 | const ele = queryViaSelector(container, selector, index);
73 | return ele;
74 | }
75 |
76 | /**
77 | * Returns the input element of InputNumber
78 | */
79 | export function queryInput(container: IContainer, index = 0) {
80 | const selector = `input.${getProvider('prefixCls')}-input-number-input`;
81 | const ele = queryViaSelector(container, selector, index);
82 | return ele;
83 | }
84 |
--------------------------------------------------------------------------------
/src/interface.ts:
--------------------------------------------------------------------------------
1 | export type IContainer = HTMLElement | Document;
2 |
--------------------------------------------------------------------------------
/src/message/__tests__/message.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Button, message as Message } from 'antd';
4 |
5 | import * as button from '../../button';
6 | import * as message from '../index';
7 |
8 | describe('Test Message', () => {
9 | beforeEach(() => {
10 | cleanup();
11 | document.body.innerHTML = '';
12 | jest.useFakeTimers();
13 | });
14 | afterEach(() => {
15 | jest.useRealTimers();
16 | Message.destroy();
17 | });
18 |
19 | it('query', () => {
20 | const { container } = render();
21 | button.fireClick(container);
22 | expect(message.query(document)).not.toBeNull();
23 | });
24 |
25 | it('fireClick', () => {
26 | const fn = jest.fn();
27 | const { container } = render(
28 |
38 | );
39 | button.fireClick(container);
40 | message.fireClick(document);
41 | expect(fn).toBeCalledTimes(1);
42 | });
43 |
44 | it('fireClose', async () => {
45 | const fn = jest.fn();
46 | const { container } = render(
47 |
58 | );
59 | button.fireClick(container);
60 | await message.fireClose(4000);
61 | expect(fn).toBeCalledTimes(1);
62 | });
63 | });
64 |
--------------------------------------------------------------------------------
/src/message/index.ts:
--------------------------------------------------------------------------------
1 | import { act, fireEvent } from '@testing-library/react';
2 |
3 | import { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onClick function
9 | */
10 | export function fireClick(container: IContainer) {
11 | const ele = queryContent(container);
12 | if (!ele) throw failedQuerySelector(`.${getProvider('prefixCls')}-notice-content`);
13 | fireEvent.click(ele);
14 | }
15 |
16 | /**
17 | * Fires onClose function by waiting duration
18 | * @param {number} duration ms
19 | */
20 | export async function fireClose(duration = 3000) {
21 | for (let i = 0; i < 10; i += 1) {
22 | // eslint-disable-next-line no-await-in-loop
23 | await Promise.resolve();
24 | }
25 |
26 | act(() => {
27 | jest.advanceTimersByTime(duration);
28 | });
29 | }
30 |
31 | /**
32 | * Returns the container element
33 | */
34 | export function query(container: IContainer, index = 0) {
35 | const selector = `.${getProvider('prefixCls')}-message`;
36 | const ele = queryViaSelector(container, selector, index);
37 | return ele;
38 | }
39 |
40 | /**
41 | * Returns the content element
42 | */
43 | export function queryContent(container: IContainer, index = 0) {
44 | const selector = `.${getProvider('prefixCls')}-message-notice-content`;
45 | const ele = queryViaSelector(container, selector, index);
46 | return ele;
47 | }
48 |
--------------------------------------------------------------------------------
/src/modal/__tests__/confirm.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Modal } from 'antd';
4 |
5 | import { getProvider } from '../../provider';
6 | import * as confirm from '../confirm';
7 |
8 | function Confirm({ onOk, onCancel }: any) {
9 | const handleConfirm = () => {
10 | Modal.confirm({
11 | title: 'Do you Want to delete these items?',
12 | onOk,
13 | onCancel,
14 | });
15 | };
16 |
17 | return (
18 |
21 | );
22 | }
23 |
24 | describe("Test confirm's fire functions", () => {
25 | beforeEach(() => {
26 | cleanup();
27 | jest.useFakeTimers();
28 | document.body.innerHTML = '';
29 | });
30 |
31 | afterEach(() => {
32 | jest.useRealTimers();
33 | });
34 |
35 | test('query', () => {
36 | const { getByTestId } = render();
37 | confirm.fireOpen(getByTestId('trigger'));
38 | expect(confirm.query(document)).not.toBeNull();
39 | });
40 |
41 | test('queryBtns', () => {
42 | const { getByTestId } = render();
43 | confirm.fireOpen(getByTestId('trigger'));
44 | expect(confirm.queryBtns(document)).not.toBeNull();
45 | });
46 |
47 | test('queryCancelButton', () => {
48 | const fn = jest.fn();
49 | const { getByTestId } = render();
50 | confirm.fireOpen(getByTestId('trigger'));
51 | confirm.fireCancel(confirm.queryCancelButton(document)!);
52 | expect(fn).toBeCalled();
53 | });
54 |
55 | test('queryOkButton', () => {
56 | const fn = jest.fn();
57 | const { getByTestId } = render();
58 | confirm.fireOpen(getByTestId('trigger'));
59 | confirm.fireOk(confirm.queryOkButton(document)!);
60 | expect(fn).toBeCalled();
61 | });
62 |
63 | test('fireOpen', () => {
64 | const fn = jest.fn();
65 | const { getByTestId } = render();
66 | confirm.fireOpen(getByTestId('trigger'));
67 |
68 | expect(document.querySelector(`.${getProvider('prefixCls')}-modal-root`)).not.toBeNull();
69 | });
70 |
71 | test('fireOk', () => {
72 | const fn = jest.fn();
73 | const { getByTestId } = render();
74 | confirm.fireOpen(getByTestId('trigger'));
75 | confirm.fireOk(document.body);
76 | expect(fn).toBeCalled();
77 | });
78 |
79 | test('fireCancel', () => {
80 | const fn = jest.fn();
81 | const { getByTestId } = render();
82 | confirm.fireOpen(getByTestId('trigger'));
83 | confirm.fireCancel(document.body);
84 | expect(fn).toBeCalled();
85 | });
86 | });
87 |
--------------------------------------------------------------------------------
/src/modal/__tests__/modal.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Modal } from 'antd';
4 |
5 | import * as modal from '..';
6 |
7 | describe("Test Modal fire's functions", () => {
8 | beforeEach(cleanup);
9 |
10 | test('queryModalFooter', () => {
11 | const { container } = render();
12 | expect(modal.queryModalFooter(container)).not.toBeNull();
13 | });
14 |
15 | test('queryCancelButton', () => {
16 | const fn = jest.fn();
17 | const { container } = render();
18 | modal.fireCancel(modal.queryCancelButton(container)!);
19 | expect(fn).toBeCalled();
20 | });
21 |
22 | test('queryOkButton', () => {
23 | const fn = jest.fn();
24 | const { container } = render();
25 | modal.fireOk(modal.queryOkButton(container)!);
26 | expect(fn).toBeCalled();
27 | });
28 |
29 | test('fireCancel', () => {
30 | const fn = jest.fn();
31 | const { container } = render();
32 | modal.fireCancel(container);
33 | expect(fn).toBeCalled();
34 | });
35 |
36 | test('fireCancel with queryMask', () => {
37 | const fn = jest.fn();
38 | const { container } = render();
39 | modal.fireCancel(modal.queryMask(container)!);
40 | expect(fn).toBeCalled();
41 | });
42 |
43 | test('fireOk', () => {
44 | const fn = jest.fn();
45 | const { container } = render();
46 | modal.fireOk(container);
47 | expect(fn).toBeCalled();
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/src/modal/confirm.ts:
--------------------------------------------------------------------------------
1 | import { act, fireEvent } from '@testing-library/react';
2 |
3 | import * as button from '../button';
4 | import type { IContainer } from '../interface';
5 | import { getProvider } from '../provider';
6 | import { failedTriggerElement, queryViaSelector } from '../utils';
7 | import * as modal from './';
8 |
9 | /**
10 | * Open confirm
11 | * @prerequisite call `jest.useFakeTimers()`
12 | */
13 | export function fireOpen(ele?: HTMLElement) {
14 | if (!ele) throw failedTriggerElement();
15 |
16 | act(() => {
17 | fireEvent.click(ele);
18 | jest.runAllTimers();
19 | });
20 | }
21 |
22 | /**
23 | * Fires onOk function
24 | */
25 | export function fireOk(container: IContainer) {
26 | const ele = queryOkButton(container);
27 | if (!ele) throw failedTriggerElement();
28 | fireEvent.click(ele);
29 | }
30 |
31 | /**
32 | * Fires onCancel function
33 | */
34 | export function fireCancel(container: IContainer) {
35 | const ele = queryCancelButton(container);
36 | if (!ele) throw failedTriggerElement();
37 | fireEvent.click(ele);
38 | }
39 |
40 | /**
41 | * Returns the container element
42 | */
43 | export function query(container: IContainer, index = 0) {
44 | return modal.query(container, index);
45 | }
46 |
47 | /**
48 | * Returns the btns area inside Modal.confirm
49 | */
50 | export function queryBtns(container: IContainer, index = 0) {
51 | const selector = `.${getProvider('prefixCls')}-modal-confirm-btns`;
52 | const ele = queryViaSelector(container, selector, index);
53 | return ele;
54 | }
55 |
56 | /**
57 | * Returns the cancel button
58 | */
59 | export function queryCancelButton(container: IContainer, index = 0) {
60 | if (container instanceof HTMLButtonElement) {
61 | return container;
62 | }
63 | const btns = queryBtns(container, index);
64 | if (!btns) return null;
65 | return button.query(btns, 0);
66 | }
67 |
68 | /**
69 | * Returns the Ok button
70 | */
71 | export function queryOkButton(container: IContainer, index = 0) {
72 | if (container instanceof HTMLButtonElement) {
73 | return container;
74 | }
75 | const btns = queryBtns(container, index);
76 | if (!btns) return null;
77 | return button.query(btns, 1);
78 | }
79 |
--------------------------------------------------------------------------------
/src/modal/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import * as button from '../button';
4 | import type { IContainer } from '../interface';
5 | import { getProvider } from '../provider';
6 | import { failedTriggerElement, queryViaSelector } from '../utils';
7 |
8 | /**
9 | * Fires onOk function
10 | */
11 | export function fireOk(container: IContainer) {
12 | const ele = queryOkButton(container);
13 | if (!ele) throw failedTriggerElement();
14 | fireEvent.click(ele);
15 | }
16 |
17 | /**
18 | * Fires onCancel function
19 | * @notice Since there are two ways to call onCancel, called via cancel button by default.
20 | * If you intent to call onCancel by mask clicked, please call fireCancel with queryMask
21 | */
22 | export function fireCancel(container: IContainer) {
23 | const ele = queryCancelButton(container) || queryMask(container);
24 | if (!ele) throw failedTriggerElement();
25 | fireEvent.click(ele);
26 | }
27 |
28 | /**
29 | * Returns the `index` container root element of Modal
30 | */
31 | export function query(container: IContainer, index = 0) {
32 | const selector = `.${getProvider('prefixCls')}-modal`;
33 | const ele = queryViaSelector(container, selector, index);
34 | return ele;
35 | }
36 |
37 | /**
38 | * Returns the `index` footer element
39 | */
40 | export function queryModalFooter(container: IContainer, index = 0) {
41 | const selector = `.${getProvider('prefixCls')}-modal-footer`;
42 | const ele = queryViaSelector(container, selector, index);
43 | return ele;
44 | }
45 |
46 | /**
47 | * Returns the cancel button
48 | */
49 | export function queryCancelButton(container: IContainer, index = 0) {
50 | if (container instanceof HTMLButtonElement) {
51 | return container;
52 | }
53 | const ele = queryModalFooter(container, index);
54 | if (!ele) return null;
55 | return button.query(ele, 0);
56 | }
57 |
58 | /**
59 | * Returns the ok button
60 | */
61 | export function queryOkButton(container: IContainer, index = 0) {
62 | if (container instanceof HTMLButtonElement) {
63 | return container;
64 | }
65 | const ele = queryModalFooter(container, index);
66 | if (!ele) return null;
67 | return button.query(ele, 1);
68 | }
69 |
70 | /**
71 | * Returns the mask element
72 | */
73 | export function queryMask(container: IContainer, index = 0) {
74 | const selector = `.${getProvider('prefixCls')}-modal-close`;
75 | const ele = queryViaSelector(container, selector, index);
76 | return ele;
77 | }
78 |
79 | export * as confirm from './confirm';
80 |
--------------------------------------------------------------------------------
/src/pagination/__tests__/pagination.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Pagination } from 'antd';
4 |
5 | import * as pagination from '../';
6 |
7 | describe('Test Pagination', () => {
8 | beforeEach(() => {
9 | cleanup();
10 | jest.useFakeTimers();
11 | });
12 |
13 | afterEach(() => {
14 | jest.useRealTimers();
15 | });
16 |
17 | it('query', () => {
18 | const { container } = render();
19 | expect(pagination.query(container)).not.toBeNull();
20 | });
21 |
22 | it('queryPrevButton', () => {
23 | const { container } = render();
24 | expect(pagination.queryPrevButton(container)).not.toBeNull();
25 | });
26 |
27 | it('queryNextButton', () => {
28 | const { container } = render();
29 | expect(pagination.queryNextButton(container)).not.toBeNull();
30 | });
31 |
32 | it('queryPaginationItem', () => {
33 | const { container } = render();
34 | expect(pagination.queryPaginationItem(container, 1)).not.toBeNull();
35 | });
36 |
37 | it('fireSizeChange', () => {
38 | const fn = jest.fn();
39 | const { container } = render();
40 | pagination.fireSizeOpen(container);
41 | pagination.fireSizeChange(container, 1);
42 | expect(fn).toBeCalledWith(6, 20);
43 | });
44 |
45 | it('fireChange', () => {
46 | const fn = jest.fn();
47 | const { container } = render();
48 | pagination.fireChange(container);
49 | expect(fn).toBeCalledWith(2, 10);
50 | });
51 |
52 | it('fireChange with queryPrevButton', () => {
53 | const fn = jest.fn();
54 | const { container } = render();
55 | pagination.fireChange(container);
56 | expect(fn).toBeCalledWith(2, 10);
57 | pagination.fireChange(pagination.queryPrevButton(container)!);
58 | expect(fn).toBeCalledWith(1, 10);
59 | });
60 |
61 | it('fireChange with specific item', () => {
62 | const fn = jest.fn();
63 | const { container } = render();
64 | pagination.fireChange(pagination.queryPaginationItem(container, 3)!);
65 | expect(fn).toBeCalledWith(3, 10);
66 | });
67 |
68 | it('fireChange with jump next', () => {
69 | const fn = jest.fn();
70 | const { container } = render();
71 | pagination.fireChange(pagination.queryJumpNext(container)!);
72 | expect(fn).toBeCalledWith(6, 10);
73 | });
74 |
75 | it('fireChange with jump prev', () => {
76 | const fn = jest.fn();
77 | const { container } = render();
78 | pagination.fireChange(pagination.queryJumpPrev(container)!);
79 | expect(fn).toBeCalledWith(1, 10);
80 | });
81 |
82 | it('fireChange with quick jump', () => {
83 | const fn = jest.fn();
84 | const { container } = render();
85 | pagination.fireChange(pagination.queryQuickJump(container)!, 20);
86 | expect(fn).toBeCalledWith(20, 10);
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/src/pagination/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import * as select from '../select';
6 | import { failedTriggerElement, queryViaSelector, queryViaSelectors } from '../utils';
7 |
8 | /**
9 | * Fires pageSize's dropdown open
10 | */
11 | export function fireSizeOpen(container: IContainer) {
12 | select.fireOpen(container);
13 | }
14 | /**
15 | * Fires onShowSizeChange function
16 | */
17 | export function fireSizeChange(container: IContainer, index: number) {
18 | const dropdown = select.queryDropdown(container);
19 | if (!dropdown) throw failedTriggerElement();
20 | select.fireSelect(dropdown, index);
21 | }
22 | /**
23 | * Fires onChange function
24 | * @notice there are majority ways to call onChange
25 | *
26 | * The sequence of calling onChange is like
27 | * `[next button] -> [prev button] -> [container self]`
28 | *
29 | * _If you intent to call specific button, call fireChange with queryXXX_
30 | */
31 | export function fireChange(container: HTMLInputElement, value: number): void;
32 | export function fireChange(Container: IContainer): void;
33 | export function fireChange(container: IContainer, value?: number) {
34 | if (container instanceof HTMLInputElement) {
35 | if (!value) throw new Error('Call quick jump must pass through value');
36 | fireEvent.focus(container);
37 | fireEvent.change(container, { target: { value } });
38 | fireEvent.blur(container);
39 | } else {
40 | const ele = queryNextButton(container) || queryPrevButton(container) || container;
41 | if (!ele) throw failedTriggerElement();
42 | fireEvent.click(ele);
43 | }
44 | }
45 |
46 | /**
47 | * Returns the container
48 | */
49 | export function query(container: IContainer, index = 0) {
50 | const selector = `.${getProvider('prefixCls')}-pagination`;
51 | const ele = queryViaSelector(container, selector, index);
52 | return ele;
53 | }
54 |
55 | /**
56 | * Returns the prev button element
57 | */
58 | export function queryPrevButton(container: IContainer, index = 0) {
59 | const selectors = [
60 | `.${getProvider('prefixCls')}-pagination-prev`,
61 | `.${getProvider('prefixCls')}-pagination-item-link`,
62 | ];
63 | const ele = queryViaSelectors(container, selectors, [index]);
64 | return ele;
65 | }
66 |
67 | /**
68 | * Returns the next button element
69 | */
70 | export function queryNextButton(container: IContainer, index = 0) {
71 | const selectors = [
72 | `.${getProvider('prefixCls')}-pagination-next`,
73 | `.${getProvider('prefixCls')}-pagination-item-link`,
74 | ];
75 | const ele = queryViaSelectors(container, selectors, [index]);
76 | return ele;
77 | }
78 |
79 | /**
80 | * Returns the pagination item element
81 | * @index page number
82 | */
83 | export function queryPaginationItem(container: IContainer, index: number) {
84 | if (index === 0) {
85 | console.warn('Page number should not start from 0');
86 | return null;
87 | }
88 | const selector = `.${getProvider('prefixCls')}-pagination-item-${index}`;
89 | const ele = queryViaSelector(container, selector, 0);
90 | return ele;
91 | }
92 |
93 | /**
94 | * Returns the jump next element
95 | */
96 | export function queryJumpNext(container: IContainer, index = 0) {
97 | const selector = `.${getProvider('prefixCls')}-pagination-jump-next`;
98 | const ele = queryViaSelector(container, selector, index);
99 | return ele;
100 | }
101 |
102 | /**
103 | * Returns the jump prev element
104 | */
105 | export function queryJumpPrev(container: IContainer, index = 0) {
106 | const selector = `.${getProvider('prefixCls')}-pagination-jump-prev`;
107 | const ele = queryViaSelector(container, selector, index);
108 | return ele;
109 | }
110 |
111 | /**
112 | * Returns the quick jump input element
113 | */
114 | export function queryQuickJump(container: IContainer, index = 0) {
115 | const selectors = [`.${getProvider('prefixCls')}-pagination-options-quick-jumper`, 'input'];
116 | const ele = queryViaSelectors(container, selectors, [index]);
117 | return ele;
118 | }
119 |
--------------------------------------------------------------------------------
/src/popconfirm/__tests__/popconfirm.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Button, Popconfirm } from 'antd';
4 |
5 | import * as button from '../../button';
6 | import * as confirm from '..';
7 |
8 | describe("Test popconfirm fire's functions", () => {
9 | beforeEach(() => {
10 | cleanup();
11 | jest.useFakeTimers();
12 | });
13 |
14 | afterEach(() => {
15 | jest.useRealTimers();
16 | });
17 |
18 | test('query', () => {
19 | const { container } = render(
20 | node.parentElement!}>
21 |
22 |
23 | );
24 | confirm.fireOpen(button.query(container)!);
25 | expect(confirm.query(container)).not.toBeNull();
26 | });
27 |
28 | test('queryButtons', () => {
29 | const { container } = render(
30 | node.parentElement!}>
31 |
32 |
33 | );
34 | confirm.fireOpen(button.query(container)!);
35 | expect(confirm.queryButtons(container)).not.toBeNull();
36 | });
37 |
38 | test('queryCancelButton', () => {
39 | const fn = jest.fn();
40 | const { container } = render(
41 | node.parentElement!}>
42 |
43 |
44 | );
45 | confirm.fireOpen(button.query(container)!);
46 | confirm.fireCancel(confirm.queryCancelButton(container)!);
47 | expect(fn).toBeCalled();
48 | });
49 |
50 | test('queryConfirmButton', () => {
51 | const fn = jest.fn();
52 | const { container } = render(
53 | node.parentElement!}>
54 |
55 |
56 | );
57 | confirm.fireOpen(button.query(container)!);
58 | confirm.fireConfirm(confirm.queryConfirmButton(container)!);
59 | expect(fn).toBeCalled();
60 | });
61 |
62 | test('fireOpen', () => {
63 | const fn = jest.fn();
64 | const { container } = render(
65 | node.parentElement!}>
66 |
67 |
68 | );
69 | confirm.fireOpen(button.query(container)!);
70 | expect(fn).toBeCalledTimes(1);
71 | });
72 |
73 | test('fireCancel', () => {
74 | const fn = jest.fn();
75 | const { container } = render(
76 | node.parentElement!}>
77 |
78 |
79 | );
80 | confirm.fireOpen(button.query(container)!);
81 | confirm.fireCancel(container);
82 | expect(fn).toBeCalled();
83 | });
84 |
85 | test('fireConfirm', () => {
86 | const fn = jest.fn();
87 | const { container } = render(
88 | node.parentElement!}>
89 |
90 |
91 | );
92 | confirm.fireOpen(button.query(container)!);
93 | confirm.fireConfirm(container);
94 | expect(fn).toBeCalled();
95 | });
96 | });
97 |
--------------------------------------------------------------------------------
/src/popconfirm/index.ts:
--------------------------------------------------------------------------------
1 | import { act, fireEvent } from '@testing-library/react';
2 |
3 | import * as button from '../button';
4 | import type { IContainer } from '../interface';
5 | import { getProvider } from '../provider';
6 | import { failedQuerySelector, failedTriggerElement, queryViaSelector } from '../utils';
7 |
8 | /**
9 | * Open popconfirm
10 | */
11 | export function fireOpen(trigger: HTMLElement) {
12 | if (!trigger) throw failedTriggerElement();
13 | act(() => {
14 | jest.runAllTimers();
15 | fireEvent.click(trigger);
16 | });
17 | }
18 |
19 | /**
20 | * Fires onCancel function
21 | */
22 | export function fireCancel(container: IContainer) {
23 | const selector = `.${getProvider('prefixCls')}-popover-buttons .${getProvider('prefixCls')}-btn`;
24 | const ele = queryCancelButton(container);
25 | if (!ele) throw failedQuerySelector(selector);
26 | fireEvent.click(ele);
27 | }
28 |
29 | /**
30 | * Fires onConfirm function
31 | */
32 | export function fireConfirm(container: IContainer) {
33 | const selector = `.${getProvider('prefixCls')}-popover-buttons .${getProvider('prefixCls')}-btn`;
34 | const ele = queryConfirmButton(container);
35 | if (!ele) throw failedQuerySelector(selector);
36 | fireEvent.click(ele);
37 | }
38 |
39 | /**
40 | * Returns the container element
41 | */
42 | export function query(container: IContainer, index = 0) {
43 | const selector = `.${getProvider('prefixCls')}-popover`;
44 | const ele = queryViaSelector(container, selector, index);
45 | return ele;
46 | }
47 |
48 | /**
49 | * Returns the buttons element
50 | */
51 | export function queryButtons(container: IContainer, index = 0) {
52 | const selector = `.${getProvider('prefixCls')}-popover-buttons`;
53 | const ele = queryViaSelector(container, selector, index);
54 | return ele;
55 | }
56 |
57 | /**
58 | * Returns the cancel button inside buttons
59 | */
60 | export function queryCancelButton(container: IContainer, index = 0) {
61 | if (container instanceof HTMLButtonElement) {
62 | return container;
63 | }
64 | const ele = queryButtons(container, index);
65 | if (!ele) return null;
66 | return button.query(ele, 0);
67 | }
68 |
69 | /**
70 | * Returns the confirm button inside buttons
71 | */
72 | export function queryConfirmButton(container: IContainer, index = 0) {
73 | if (container instanceof HTMLButtonElement) {
74 | return container;
75 | }
76 | const ele = queryButtons(container, index);
77 | if (!ele) return null;
78 | return button.query(ele, 1);
79 | }
80 |
--------------------------------------------------------------------------------
/src/provider/index.ts:
--------------------------------------------------------------------------------
1 | const globalConfig = {
2 | prefixCls: 'rc',
3 | };
4 |
5 | export function getProviders() {
6 | return globalConfig;
7 | }
8 |
9 | export function getProvider(key: keyof typeof globalConfig) {
10 | return globalConfig[key];
11 | }
12 |
13 | export function provider(opt: Partial) {
14 | Object.assign(globalConfig, opt);
15 | }
16 |
--------------------------------------------------------------------------------
/src/radio/__tests__/radio.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Radio } from 'antd';
4 |
5 | import * as radio from '..';
6 |
7 | describe("Test Radio's fire functions", () => {
8 | beforeEach(cleanup);
9 |
10 | test('query', () => {
11 | const { container } = render(Radio);
12 | expect(radio.query(container)).not.toBeNull();
13 | });
14 |
15 | test('queryGroup', () => {
16 | const { container } = render();
17 | expect(radio.queryGroup(container)).not.toBeNull();
18 | });
19 |
20 | test('queryInput', () => {
21 | const { container } = render();
22 | expect(radio.queryInput(container)).not.toBeNull();
23 | });
24 |
25 | test('fireMouseEnter', () => {
26 | const fn = jest.fn();
27 | const { container } = render(Radio);
28 |
29 | radio.fireMouseEnter(container);
30 | expect(fn).toBeCalledTimes(1);
31 | });
32 |
33 | test('fireMouseEnter with group', () => {
34 | const fn = jest.fn();
35 | const { container } = render(
36 |
37 | A
38 |
39 | );
40 |
41 | radio.fireMouseEnter(container);
42 | expect(fn).toBeCalledTimes(1);
43 | });
44 |
45 | test('fireMouseLeave', () => {
46 | const fn = jest.fn();
47 | const { container } = render(Radio);
48 |
49 | radio.fireMouseLeave(container);
50 | expect(fn).toBeCalledTimes(1);
51 | });
52 |
53 | test('fireMouseLeave with group', () => {
54 | const fn = jest.fn();
55 | const { container } = render(
56 |
57 | A
58 |
59 | );
60 |
61 | radio.fireMouseLeave(container);
62 | expect(fn).toBeCalledTimes(1);
63 | });
64 |
65 | test('fireChange', () => {
66 | const fn = jest.fn();
67 | const { container } = render(
68 |
69 | A
70 | B
71 |
72 | );
73 |
74 | radio.fireChange(container, 1);
75 | expect(fn).toBeCalledTimes(1);
76 | });
77 | });
78 |
--------------------------------------------------------------------------------
/src/radio/index.ts:
--------------------------------------------------------------------------------
1 | import { fireEvent } from '@testing-library/react';
2 |
3 | import type { IContainer } from '../interface';
4 | import { getProvider } from '../provider';
5 | import { failedQuerySelector, queryViaSelector } from '../utils';
6 |
7 | /**
8 | * Fires onMouseEnter function
9 | */
10 | export function fireMouseEnter(container: IContainer) {
11 | const ele = queryGroup(container) || query(container);
12 | if (!ele) throw failedQuerySelector('radio');
13 | fireEvent.mouseEnter(ele);
14 | }
15 |
16 | /**
17 | * Fires onMouseLeave function
18 | */
19 | export function fireMouseLeave(container: IContainer) {
20 | const ele = queryGroup(container) || query(container);
21 | if (!ele) throw failedQuerySelector('radio');
22 | fireEvent.mouseLeave(ele);
23 | }
24 |
25 | /**
26 | * Fires onChange function
27 | */
28 | export function fireChange(container: IContainer, index: number) {
29 | const ele = queryInput(container, index);
30 | if (!ele) throw failedQuerySelector(`input.${getProvider('prefixCls')}-radio-input`);
31 | fireEvent.click(ele);
32 | }
33 |
34 | /**
35 | * Returns the wrapper element for each Radio
36 | */
37 | export function query(container: IContainer, index = 0) {
38 | const selector = `.${getProvider('prefixCls')}-radio-wrapper`;
39 | const ele = queryViaSelector(container, selector, index);
40 | return ele;
41 | }
42 |
43 | /**
44 | * Returns the group element
45 | */
46 | export function queryGroup(container: IContainer, index = 0) {
47 | const selector = `.${getProvider('prefixCls')}-radio-group`;
48 | const ele = queryViaSelector(container, selector, index);
49 | return ele;
50 | }
51 |
52 | /**
53 | * Returns the input element in Radio
54 | */
55 | export function queryInput(container: IContainer, index = 0) {
56 | const selector = `input.${getProvider('prefixCls')}-radio-input`;
57 | const ele = queryViaSelector(container, selector, index);
58 | return ele;
59 | }
60 |
--------------------------------------------------------------------------------
/src/select/__tests__/select.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { cleanup, render } from '@testing-library/react';
3 | import { Select } from 'antd';
4 |
5 | import * as select from '..';
6 |
7 | describe('Test Select fire functions', () => {
8 | beforeEach(() => {
9 | jest.useFakeTimers();
10 | document.body.innerHTML = '';
11 | cleanup();
12 | });
13 |
14 | afterEach(() => {
15 | jest.useRealTimers();
16 | });
17 |
18 | test('query', () => {
19 | const { container, getByTestId } = render(
20 | <>
21 |
22 |
23 | >
24 | );
25 | expect(select.query(container)).toBe(getByTestId('select1'));
26 | expect(select.query(container, 1)).toBe(getByTestId('select2'));
27 | });
28 |
29 | test('queryInput', () => {
30 | const fn1 = jest.fn();
31 | const fn2 = jest.fn();
32 | const { container } = render(
33 | <>
34 |
35 |
36 | >
37 | );
38 | select.fireSearch(select.queryInput(container)!, 'test1');
39 | select.fireSearch(select.queryInput(container, 1)!, 'test2');
40 | expect(fn1).toBeCalledWith('test1');
41 | expect(fn2).toBeCalledWith('test2');
42 | });
43 |
44 | test('querySelector', () => {
45 | const fn1 = jest.fn();
46 | const fn2 = jest.fn();
47 | const { container } = render(
48 | <>
49 |
50 |
51 | >
52 | );
53 | select.fireOpen(select.querySelector(container)!);
54 | expect(fn1).toBeCalledTimes(1);
55 | select.fireOpen(select.querySelector(container, 1)!);
56 | expect(fn2).toBeCalledTimes(1);
57 | });
58 |
59 | test('queryDropdown', () => {
60 | const fn1 = jest.fn();
61 | const fn2 = jest.fn();
62 | const { container } = render(
63 | <>
64 |
65 |
66 | >
67 | );
68 | select.fireOpen(select.querySelector(container)!);
69 | select.fireSelect(select.queryDropdown(document)!, 0);
70 | expect(fn1).toBeCalledWith(1, expect.objectContaining({ label: 1, value: 1 }));
71 | select.fireOpen(select.querySelector(container, 1)!);
72 | select.fireSelect(select.queryDropdown(document, 1)!, 0);
73 | expect(fn2).toBeCalledWith(2, expect.objectContaining({ label: 2, value: 2 }));
74 | });
75 |
76 | test('queryOption', () => {
77 | const fn = jest.fn();
78 | const { container } = render(
79 |