anu-verzum 1.21.7 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +34 -6
  2. package/dist/core/components/AnulyticsProvider.d.ts +3 -0
  3. package/dist/core/components/AnulyticsProvider.js +10 -2
  4. package/dist/core/components/History.d.ts +3 -0
  5. package/dist/core/components/History.js +10 -2
  6. package/dist/core/components/Intl.d.ts +3 -0
  7. package/dist/core/components/Intl.js +13 -2
  8. package/dist/core/elements.d.ts +1 -1
  9. package/dist/core/reconciler.d.ts +5 -0
  10. package/dist/core/reconciler.js +41 -2
  11. package/dist/testing/__tests__/smoke.test.d.ts +1 -0
  12. package/dist/testing/__tests__/smoke.test.js +180 -0
  13. package/dist/testing/act.d.ts +4 -0
  14. package/dist/testing/act.js +42 -0
  15. package/dist/testing/cleanup.d.ts +3 -0
  16. package/dist/testing/cleanup.js +32 -0
  17. package/dist/testing/events/fireEvent.d.ts +17 -0
  18. package/dist/testing/events/fireEvent.js +45 -0
  19. package/dist/testing/events/userEvent.d.ts +12 -0
  20. package/dist/testing/events/userEvent.js +67 -0
  21. package/dist/testing/globals.d.js +1 -0
  22. package/dist/testing/index.d.ts +9 -0
  23. package/dist/testing/index.js +109 -0
  24. package/dist/testing/queries/byAltText.d.ts +2 -0
  25. package/dist/testing/queries/byAltText.js +15 -0
  26. package/dist/testing/queries/byLabelText.d.ts +2 -0
  27. package/dist/testing/queries/byLabelText.js +47 -0
  28. package/dist/testing/queries/byPlaceholderText.d.ts +2 -0
  29. package/dist/testing/queries/byPlaceholderText.js +15 -0
  30. package/dist/testing/queries/byRole.d.ts +2 -0
  31. package/dist/testing/queries/byRole.js +73 -0
  32. package/dist/testing/queries/byTestId.d.ts +2 -0
  33. package/dist/testing/queries/byTestId.js +11 -0
  34. package/dist/testing/queries/byText.d.ts +2 -0
  35. package/dist/testing/queries/byText.js +27 -0
  36. package/dist/testing/queries/byTitle.d.ts +2 -0
  37. package/dist/testing/queries/byTitle.js +15 -0
  38. package/dist/testing/queries/index.d.ts +2 -0
  39. package/dist/testing/queries/index.js +43 -0
  40. package/dist/testing/queries/queryBuilder.d.ts +2 -0
  41. package/dist/testing/queries/queryBuilder.js +36 -0
  42. package/dist/testing/render.d.ts +3 -0
  43. package/dist/testing/render.js +46 -0
  44. package/dist/testing/types.d.ts +59 -0
  45. package/dist/testing/types.js +5 -0
  46. package/dist/testing/waitFor.d.ts +3 -0
  47. package/dist/testing/waitFor.js +41 -0
  48. package/dist/testing/wrappers.d.ts +17 -0
  49. package/dist/testing/wrappers.js +46 -0
  50. package/package.json +12 -2
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  <h3>@author: <strong>Anubis-programmer</strong></h3>
6
6
  <h3>@license: <strong>MIT</strong></h3>
7
- <h3>@version: <strong>1.21.7</strong></h3>
7
+ <h3>@version: <strong>1.22.0</strong></h3>
8
8
 
9
9
  <br>
10
10
 
@@ -17,6 +17,7 @@ A lightweight React-inspired UI library for building component-based web applica
17
17
  - Client-side routing over the History API
18
18
  - Context API, i18n (Intl), feature flags, and built-in event analytics (Anulytics)
19
19
  - Ships with TypeScript declaration files — no `@types` package needed
20
+ - Built-in testing companion — **Anu Testing Library (ATL)** shipped as `anu-verzum/testing`
20
21
 
21
22
  <br>
22
23
  <hr>
@@ -188,16 +189,43 @@ The following types are exported from `anu-verzum` for use in consumer projects:
188
189
  #### Library development scripts
189
190
 
190
191
  ```bash
191
- npm run clean # Delete dist/ entirely
192
- npm run build # Clean, compile TypeScript sources to dist/, and emit .d.ts files
193
- npm run typecheck # Type-check without emitting any output
194
- npm run lint # Run ESLint on all source files
195
- npm run format # Format all source files with Prettier
192
+ npm run clean # Delete dist/ entirely
193
+ npm run build # Clean, compile TypeScript sources to dist/, and emit .d.ts files
194
+ npm run typecheck # Type-check without emitting any output
195
+ npm run lint # Run ESLint on all source files
196
+ npm run format # Format all source files with Prettier
197
+ npm test # Run the Anu Testing Library test suite with Jest
198
+ npm run test:watch # Run Jest in interactive watch mode
199
+ npm run test:coverage # Run Jest and generate a coverage report
196
200
  ```
197
201
 
198
202
  <br>
199
203
  <hr>
200
204
 
205
+ <h2 id="testing">Testing</h2>
206
+
207
+ ANUVerzum ships a built-in testing library — **Anu Testing Library (ATL)** — importable as `anu-verzum/testing`. It mirrors the philosophy of Testing Library: query the DOM the way a user would (by role, text, label), fire events, and assert on real output — no component internals, no custom matchers.
208
+
209
+ ```typescript
210
+ import Anu from 'anu-verzum';
211
+ import { render, fireEvent } from 'anu-verzum/testing';
212
+
213
+ const { getByText, getByRole } = render(<Counter />);
214
+ fireEvent.click(getByRole('button'));
215
+ expect(getByText('Count: 1')).toBeDefined();
216
+ ```
217
+
218
+ If TypeScript reports that `describe`, `test`, or `expect` are not found, your `tsconfig.json` likely has an explicit `"types"` list. Add `"jest"` to it — and `"node"` if tests reference `process.env`:
219
+
220
+ ```json
221
+ { "compilerOptions": { "types": ["node", "jest"] } }
222
+ ```
223
+
224
+ See **[USERS_MANUAL.md — Testing](./documentation/USERS_MANUAL.md#testing)** for the full API reference and usage guide.
225
+
226
+ <br>
227
+ <hr>
228
+
201
229
  <h2>Documentation</h2>
202
230
 
203
231
  Full usage documentation, API reference, and code examples:
@@ -29,3 +29,6 @@ declare class AnulyticsProvider extends Component<AnulyticsProviderProps> {
29
29
  render(): AnuElement | AnuElement[] | null;
30
30
  }
31
31
  export default AnulyticsProvider;
32
+ export declare const __testing: {
33
+ reset(): void;
34
+ };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.trackStateChange = exports.trackRouteChange = exports.trackEvent = exports.default = void 0;
6
+ exports.trackStateChange = exports.trackRouteChange = exports.trackEvent = exports.default = exports.__testing = void 0;
7
7
  var _Component = require("./Component");
8
8
  var _serverApi = _interopRequireDefault(require("../../server-api/server-api"));
9
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -218,4 +218,12 @@ class AnulyticsProvider extends _Component.Component {
218
218
  }
219
219
  }
220
220
  }
221
- var _default = exports.default = AnulyticsProvider;
221
+ var _default = exports.default = AnulyticsProvider;
222
+ const __testing = exports.__testing = {
223
+ reset() {
224
+ if (process.env.NODE_ENV !== 'test') {
225
+ return;
226
+ }
227
+ AnulyticsState.setAnulyticsInstanceExist(false);
228
+ }
229
+ };
@@ -47,3 +47,6 @@ declare const History: {
47
47
  getAllUrlParamNames: () => string[];
48
48
  };
49
49
  export default History;
50
+ export declare const __testing: {
51
+ reset(): void;
52
+ };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.goTo = exports.default = void 0;
6
+ exports.goTo = exports.default = exports.__testing = void 0;
7
7
  var _elements = require("../elements");
8
8
  var _Component = require("./Component");
9
9
  var _AnulyticsProvider = require("./AnulyticsProvider");
@@ -210,4 +210,12 @@ const History = {
210
210
  getUrlParams,
211
211
  getAllUrlParamNames
212
212
  };
213
- var _default = exports.default = History;
213
+ var _default = exports.default = History;
214
+ const __testing = exports.__testing = {
215
+ reset() {
216
+ if (process.env.NODE_ENV !== 'test') {
217
+ return;
218
+ }
219
+ instances.length = 0;
220
+ }
221
+ };
@@ -21,3 +21,6 @@ declare const Intl: {
21
21
  Provider: ({ locale, messages, defaultLocale, children }: IntlProviderProps) => AnuElement | null;
22
22
  };
23
23
  export default Intl;
24
+ export declare const __testing: {
25
+ reset(): void;
26
+ };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = void 0;
6
+ exports.default = exports.__testing = void 0;
7
7
  var _elements = require("../elements");
8
8
  var _Context = require("./Context");
9
9
  const _Intl = (0, _Context.createContext)({});
@@ -168,4 +168,15 @@ const Intl = {
168
168
  formatMessage,
169
169
  Provider: IntlProvider
170
170
  };
171
- var _default = exports.default = Intl;
171
+ var _default = exports.default = Intl;
172
+ const __testing = exports.__testing = {
173
+ reset() {
174
+ if (process.env.NODE_ENV !== 'test') {
175
+ return;
176
+ }
177
+ __messagesContext = {
178
+ locale: undefined,
179
+ messages: {}
180
+ };
181
+ }
182
+ };
@@ -12,7 +12,7 @@ export type Ref<T> = {
12
12
  };
13
13
  export type FunctionComponent<P extends Props = Props> = (props: P) => AnuElement<any, any> | AnuElement<any, any>[] | string | number | boolean | null | undefined;
14
14
  export type ComponentConstructor<P extends Props = Props> = new (props: P, context?: Record<string, any>) => any;
15
- export type ElementType = string | FunctionComponent | ComponentConstructor;
15
+ export type ElementType = string | FunctionComponent<any> | ComponentConstructor<any>;
16
16
  export type AnuElement<P = Props, T extends ElementType = ElementType> = {
17
17
  type: T;
18
18
  props: P;
@@ -2,3 +2,8 @@ import { AnuElement, Ref } from './elements';
2
2
  export declare const createRef: <T = any>() => Ref<T>;
3
3
  export declare const scheduleUpdate: (instance: any, partialState: Record<string, any>, partialStateCallback?: (prevState: any, prevProps: any) => any) => void;
4
4
  export declare const render: (elements: AnuElement | AnuElement[], containerDom: Element) => void;
5
+ export declare const unmountComponentAtNode: (containerDom: Element) => void;
6
+ export declare const __testing: {
7
+ flushSync(): void;
8
+ resetGlobals(): void;
9
+ };
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.scheduleUpdate = exports.render = exports.createRef = void 0;
6
+ exports.unmountComponentAtNode = exports.scheduleUpdate = exports.render = exports.createRef = exports.__testing = void 0;
7
7
  var _domUtils = require("./domUtils");
8
8
  const HOST_COMPONENT = 'host';
9
9
  const CLASS_COMPONENT = 'class';
@@ -446,4 +446,43 @@ const render = (elements, containerDom) => {
446
446
  });
447
447
  requestIdleCallback(performWork);
448
448
  };
449
- exports.render = render;
449
+ exports.render = render;
450
+ const unmountComponentAtNode = containerDom => {
451
+ if (!containerDom._rootContainerFiber) {
452
+ return;
453
+ }
454
+ updateQueue.push({
455
+ from: HOST_ROOT,
456
+ dom: containerDom,
457
+ newProps: {
458
+ children: []
459
+ }
460
+ });
461
+ requestIdleCallback(performWork);
462
+ };
463
+ exports.unmountComponentAtNode = unmountComponentAtNode;
464
+ const __testing = exports.__testing = {
465
+ flushSync() {
466
+ if (process.env.NODE_ENV !== 'test') {
467
+ return;
468
+ }
469
+ const syncDeadline = {
470
+ didTimeout: false,
471
+ timeRemaining: () => 999
472
+ };
473
+ while (updateQueue.length > 0 || nextUnitOfWork != null) {
474
+ workLoop(syncDeadline);
475
+ }
476
+ nextUnitOfWork = null;
477
+ pendingCommit = null;
478
+ },
479
+ resetGlobals() {
480
+ if (process.env.NODE_ENV !== 'test') {
481
+ return;
482
+ }
483
+ updateQueue.length = 0;
484
+ componentLifecyclesQueue.length = 0;
485
+ nextUnitOfWork = null;
486
+ pendingCommit = null;
487
+ }
488
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+
3
+ var _index = _interopRequireWildcard(require("../../index"));
4
+ var _index2 = require("../index");
5
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
6
+ class Counter extends _index.Component {
7
+ state = {
8
+ count: 0
9
+ };
10
+ render() {
11
+ return _index.default.createElement('div', {}, _index.default.createElement('p', {}, `Count: ${this.state.count}`), _index.default.createElement('button', {
12
+ onClick: () => this.setState({
13
+ count: this.state.count + 1
14
+ })
15
+ }, 'Increment'));
16
+ }
17
+ }
18
+ const Greeting = ({
19
+ name
20
+ }) => _index.default.createElement('h1', {}, `Hello, ${name}!`);
21
+ describe('render', () => {
22
+ test('renders a function component', () => {
23
+ const {
24
+ getByText
25
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
26
+ name: 'World'
27
+ }));
28
+ expect(getByText('Hello, World!')).toBeDefined();
29
+ });
30
+ test('renders a class component', () => {
31
+ const {
32
+ getByText
33
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
34
+ expect(getByText('Count: 0')).toBeDefined();
35
+ });
36
+ test('returns a container attached to document.body', () => {
37
+ const {
38
+ container
39
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
40
+ name: 'test'
41
+ }));
42
+ expect(document.body.contains(container)).toBe(true);
43
+ });
44
+ });
45
+ describe('queries', () => {
46
+ test('getByRole finds button', () => {
47
+ const {
48
+ getByRole
49
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
50
+ const btn = getByRole('button');
51
+ expect(btn).toBeDefined();
52
+ expect(btn.textContent).toBe('Increment');
53
+ });
54
+ test('getByRole with name option', () => {
55
+ const {
56
+ getByRole
57
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
58
+ const btn = getByRole('button', {
59
+ name: 'Increment'
60
+ });
61
+ expect(btn).toBeDefined();
62
+ });
63
+ test('queryByText returns null when not found', () => {
64
+ const {
65
+ queryByText
66
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
67
+ name: 'test'
68
+ }));
69
+ expect(queryByText('Not here')).toBeNull();
70
+ });
71
+ test('getByText throws when not found', () => {
72
+ const {
73
+ getByText
74
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
75
+ name: 'test'
76
+ }));
77
+ expect(() => getByText('Not here')).toThrow();
78
+ });
79
+ test('findByText resolves asynchronously', async () => {
80
+ const {
81
+ findByText
82
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
83
+ name: 'World'
84
+ }));
85
+ const el = await findByText('Hello, World!');
86
+ expect(el).toBeDefined();
87
+ });
88
+ });
89
+ describe('fireEvent', () => {
90
+ test('click triggers onClick and re-renders', () => {
91
+ const {
92
+ getByText,
93
+ getByRole
94
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
95
+ expect(getByText('Count: 0')).toBeDefined();
96
+ _index2.fireEvent.click(getByRole('button'));
97
+ expect(getByText('Count: 1')).toBeDefined();
98
+ });
99
+ test('multiple clicks accumulate', () => {
100
+ const {
101
+ getByText,
102
+ getByRole
103
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
104
+ _index2.fireEvent.click(getByRole('button'));
105
+ _index2.fireEvent.click(getByRole('button'));
106
+ _index2.fireEvent.click(getByRole('button'));
107
+ expect(getByText('Count: 3')).toBeDefined();
108
+ });
109
+ });
110
+ describe('userEvent', () => {
111
+ test('click fires full mouse event sequence', () => {
112
+ const {
113
+ getByText,
114
+ getByRole
115
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
116
+ _index2.userEvent.click(getByRole('button'));
117
+ expect(getByText('Count: 1')).toBeDefined();
118
+ });
119
+ });
120
+ describe('rerender', () => {
121
+ test('updates the component with new props', () => {
122
+ const {
123
+ getByText,
124
+ rerender
125
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
126
+ name: 'Alice'
127
+ }));
128
+ expect(getByText('Hello, Alice!')).toBeDefined();
129
+ rerender(_index.default.createElement(Greeting, {
130
+ name: 'Bob'
131
+ }));
132
+ expect(getByText('Hello, Bob!')).toBeDefined();
133
+ });
134
+ });
135
+ describe('waitFor', () => {
136
+ test('polls until assertion passes', async () => {
137
+ const {
138
+ getByText
139
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
140
+ name: 'World'
141
+ }));
142
+ await (0, _index2.waitFor)(() => {
143
+ expect(getByText('Hello, World!')).toBeDefined();
144
+ });
145
+ });
146
+ test('rejects when assertion never passes', async () => {
147
+ const {
148
+ queryByText
149
+ } = (0, _index2.render)(_index.default.createElement(Greeting, {
150
+ name: 'World'
151
+ }));
152
+ await expect((0, _index2.waitFor)(() => {
153
+ expect(queryByText('MISSING')).not.toBeNull();
154
+ }, {
155
+ timeout: 100,
156
+ interval: 20
157
+ })).rejects.toThrow();
158
+ });
159
+ });
160
+ describe('act', () => {
161
+ test('flushes state updates synchronously', () => {
162
+ const {
163
+ getByText,
164
+ getByRole
165
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
166
+ (0, _index2.act)(() => {
167
+ _index2.fireEvent.click(getByRole('button'));
168
+ });
169
+ expect(getByText('Count: 1')).toBeDefined();
170
+ });
171
+ test('wraps async callbacks', async () => {
172
+ const {
173
+ getByText
174
+ } = (0, _index2.render)(_index.default.createElement(Counter, {}));
175
+ await (0, _index2.act)(async () => {
176
+ await Promise.resolve();
177
+ });
178
+ expect(getByText('Count: 0')).toBeDefined();
179
+ });
180
+ });
@@ -0,0 +1,4 @@
1
+ export declare const installSyncScheduler: () => void;
2
+ export declare const uninstallSyncScheduler: () => void;
3
+ export declare const flushEffects: () => void;
4
+ export declare const act: (callback: () => void | Promise<void>) => void | Promise<void>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.uninstallSyncScheduler = exports.installSyncScheduler = exports.flushEffects = exports.act = void 0;
7
+ var _reconciler = require("../core/reconciler");
8
+ const FAKE_DEADLINE = {
9
+ didTimeout: false,
10
+ timeRemaining: () => 999
11
+ };
12
+ let _installed = false;
13
+ const installSyncScheduler = () => {
14
+ if (_installed) {
15
+ return;
16
+ }
17
+ _installed = true;
18
+ window.requestIdleCallback = cb => {
19
+ cb(FAKE_DEADLINE);
20
+ return 0;
21
+ };
22
+ window.cancelIdleCallback = () => {};
23
+ };
24
+ exports.installSyncScheduler = installSyncScheduler;
25
+ const uninstallSyncScheduler = () => {
26
+ _installed = false;
27
+ };
28
+ exports.uninstallSyncScheduler = uninstallSyncScheduler;
29
+ const flushEffects = () => {
30
+ _reconciler.__testing.flushSync();
31
+ };
32
+ exports.flushEffects = flushEffects;
33
+ const act = callback => {
34
+ const result = callback();
35
+ if (result && typeof result.then === 'function') {
36
+ return result.then(() => {
37
+ _reconciler.__testing.flushSync();
38
+ });
39
+ }
40
+ _reconciler.__testing.flushSync();
41
+ };
42
+ exports.act = act;
@@ -0,0 +1,3 @@
1
+ export declare const registerContainer: (container: Element) => void;
2
+ export declare const cleanup: () => void;
3
+ export declare const setupAutoCleanup: () => void;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.setupAutoCleanup = exports.registerContainer = exports.cleanup = void 0;
7
+ var _reconciler = require("../core/reconciler");
8
+ var _History = require("../core/components/History");
9
+ var _Intl = require("../core/components/Intl");
10
+ var _AnulyticsProvider = require("../core/components/AnulyticsProvider");
11
+ const mountedContainers = new Set();
12
+ const registerContainer = container => {
13
+ mountedContainers.add(container);
14
+ };
15
+ exports.registerContainer = registerContainer;
16
+ const cleanup = () => {
17
+ mountedContainers.forEach(container => {
18
+ container.parentNode?.removeChild(container);
19
+ });
20
+ mountedContainers.clear();
21
+ _reconciler.__testing.resetGlobals();
22
+ _History.__testing.reset();
23
+ _Intl.__testing.reset();
24
+ _AnulyticsProvider.__testing.reset();
25
+ };
26
+ exports.cleanup = cleanup;
27
+ const setupAutoCleanup = () => {
28
+ if (typeof afterEach === 'function') {
29
+ afterEach(cleanup);
30
+ }
31
+ };
32
+ exports.setupAutoCleanup = setupAutoCleanup;
@@ -0,0 +1,17 @@
1
+ type EventInit = globalThis.EventInit & Record<string, any>;
2
+ export declare const fireEvent: {
3
+ (element: Element, eventName: string, init?: EventInit): boolean;
4
+ click(el: Element, init?: MouseEventInit): boolean;
5
+ dblclick(el: Element, init?: MouseEventInit): boolean;
6
+ change(el: Element, init?: globalThis.EventInit): boolean;
7
+ input(el: Element, init?: globalThis.EventInit): boolean;
8
+ focus(el: Element, init?: FocusEventInit): boolean;
9
+ blur(el: Element, init?: FocusEventInit): boolean;
10
+ keyDown(el: Element, init?: KeyboardEventInit): boolean;
11
+ keyUp(el: Element, init?: KeyboardEventInit): boolean;
12
+ keyPress(el: Element, init?: KeyboardEventInit): boolean;
13
+ submit(el: Element, init?: globalThis.EventInit): boolean;
14
+ mouseDown(el: Element, init?: MouseEventInit): boolean;
15
+ mouseUp(el: Element, init?: MouseEventInit): boolean;
16
+ };
17
+ export {};
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.fireEvent = void 0;
7
+ var _act = require("../act");
8
+ const buildEvent = (eventName, init) => {
9
+ const opts = {
10
+ bubbles: true,
11
+ cancelable: true,
12
+ ...init
13
+ };
14
+ if (/^(click|mouse|contextmenu|dblclick)/i.test(eventName)) {
15
+ return new MouseEvent(eventName, opts);
16
+ }
17
+ if (/^key/i.test(eventName)) {
18
+ return new KeyboardEvent(eventName, opts);
19
+ }
20
+ if (/^(focus|blur)/i.test(eventName)) {
21
+ return new FocusEvent(eventName, opts);
22
+ }
23
+ if (/^pointer/i.test(eventName)) {
24
+ return new PointerEvent(eventName, opts);
25
+ }
26
+ return new Event(eventName, opts);
27
+ };
28
+ const fireEvent = (element, eventName, init) => {
29
+ const dispatched = element.dispatchEvent(buildEvent(eventName, init));
30
+ (0, _act.flushEffects)();
31
+ return dispatched;
32
+ };
33
+ exports.fireEvent = fireEvent;
34
+ fireEvent.click = (el, init) => fireEvent(el, 'click', init);
35
+ fireEvent.dblclick = (el, init) => fireEvent(el, 'dblclick', init);
36
+ fireEvent.change = (el, init) => fireEvent(el, 'change', init);
37
+ fireEvent.input = (el, init) => fireEvent(el, 'input', init);
38
+ fireEvent.focus = (el, init) => fireEvent(el, 'focus', init);
39
+ fireEvent.blur = (el, init) => fireEvent(el, 'blur', init);
40
+ fireEvent.keyDown = (el, init) => fireEvent(el, 'keydown', init);
41
+ fireEvent.keyUp = (el, init) => fireEvent(el, 'keyup', init);
42
+ fireEvent.keyPress = (el, init) => fireEvent(el, 'keypress', init);
43
+ fireEvent.submit = (el, init) => fireEvent(el, 'submit', init);
44
+ fireEvent.mouseDown = (el, init) => fireEvent(el, 'mousedown', init);
45
+ fireEvent.mouseUp = (el, init) => fireEvent(el, 'mouseup', init);
@@ -0,0 +1,12 @@
1
+ export declare const userEvent: {
2
+ click: (element: Element) => void;
3
+ dblclick: (element: Element) => void;
4
+ type: (element: HTMLInputElement | HTMLTextAreaElement, text: string) => void;
5
+ clear: (element: HTMLInputElement | HTMLTextAreaElement) => void;
6
+ change: (element: HTMLInputElement | HTMLSelectElement, value: string) => void;
7
+ submit: (form: HTMLFormElement) => void;
8
+ selectOption: (select: HTMLSelectElement, value: string) => void;
9
+ tab: (options?: {
10
+ shift?: boolean;
11
+ }) => void;
12
+ };
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.userEvent = void 0;
7
+ var _fireEvent = require("./fireEvent");
8
+ const userEvent = exports.userEvent = {
9
+ click: element => {
10
+ (0, _fireEvent.fireEvent)(element, 'mousedown');
11
+ (0, _fireEvent.fireEvent)(element, 'mouseup');
12
+ (0, _fireEvent.fireEvent)(element, 'click');
13
+ },
14
+ dblclick: element => {
15
+ (0, _fireEvent.fireEvent)(element, 'mousedown');
16
+ (0, _fireEvent.fireEvent)(element, 'mouseup');
17
+ (0, _fireEvent.fireEvent)(element, 'click');
18
+ (0, _fireEvent.fireEvent)(element, 'mousedown');
19
+ (0, _fireEvent.fireEvent)(element, 'mouseup');
20
+ (0, _fireEvent.fireEvent)(element, 'click');
21
+ (0, _fireEvent.fireEvent)(element, 'dblclick');
22
+ },
23
+ type: (element, text) => {
24
+ (0, _fireEvent.fireEvent)(element, 'focus');
25
+ for (const char of text) {
26
+ (0, _fireEvent.fireEvent)(element, 'keydown', {
27
+ key: char
28
+ });
29
+ (0, _fireEvent.fireEvent)(element, 'keypress', {
30
+ key: char
31
+ });
32
+ element.value += char;
33
+ (0, _fireEvent.fireEvent)(element, 'input');
34
+ (0, _fireEvent.fireEvent)(element, 'keyup', {
35
+ key: char
36
+ });
37
+ }
38
+ (0, _fireEvent.fireEvent)(element, 'change');
39
+ },
40
+ clear: element => {
41
+ (0, _fireEvent.fireEvent)(element, 'focus');
42
+ element.value = '';
43
+ (0, _fireEvent.fireEvent)(element, 'input');
44
+ (0, _fireEvent.fireEvent)(element, 'change');
45
+ },
46
+ change: (element, value) => {
47
+ element.value = value;
48
+ (0, _fireEvent.fireEvent)(element, 'input');
49
+ (0, _fireEvent.fireEvent)(element, 'change');
50
+ },
51
+ submit: form => {
52
+ (0, _fireEvent.fireEvent)(form, 'submit');
53
+ },
54
+ selectOption: (select, value) => {
55
+ select.value = value;
56
+ (0, _fireEvent.fireEvent)(select, 'change');
57
+ },
58
+ tab: (options = {}) => {
59
+ const focused = document.activeElement;
60
+ if (focused) {
61
+ (0, _fireEvent.fireEvent)(focused, 'keydown', {
62
+ key: 'Tab',
63
+ shiftKey: options.shift ?? false
64
+ });
65
+ }
66
+ }
67
+ };
@@ -0,0 +1 @@
1
+ "use strict";
@@ -0,0 +1,9 @@
1
+ export { render } from './render';
2
+ export { act, flushEffects, installSyncScheduler, uninstallSyncScheduler } from './act';
3
+ export { cleanup, setupAutoCleanup } from './cleanup';
4
+ export { waitFor, waitForElementToBeRemoved } from './waitFor';
5
+ export { fireEvent } from './events/fireEvent';
6
+ export { userEvent } from './events/userEvent';
7
+ export { renderWithStore, renderWithRouter, renderWithIntl, renderWithContext } from './wrappers';
8
+ export { buildQueries } from './queries/index';
9
+ export type { RenderOptions, RenderResult, BoundQueries, BoundQuery, ByRoleOptions, TextMatch, WaitForOptions, } from './types';