@pie-lib/test-utils 1.1.0-next.3 → 1.1.0-next.4
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.
- package/lib/index.js +272 -0
- package/lib/index.js.map +1 -0
- package/lib/keyboard.js +173 -0
- package/lib/keyboard.js.map +1 -0
- package/lib/web-components.js +248 -0
- package/lib/web-components.js.map +1 -0
- package/package.json +2 -2
package/lib/index.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
var _exportNames = {
|
|
9
|
+
renderWithTheme: true,
|
|
10
|
+
renderWithProviders: true,
|
|
11
|
+
createTestTheme: true,
|
|
12
|
+
waitForRemoval: true,
|
|
13
|
+
userEvent: true,
|
|
14
|
+
Keys: true,
|
|
15
|
+
pressKey: true,
|
|
16
|
+
typeAndSubmit: true,
|
|
17
|
+
clearAndType: true,
|
|
18
|
+
navigateWithKeys: true,
|
|
19
|
+
waitForCustomElement: true,
|
|
20
|
+
renderWebComponent: true,
|
|
21
|
+
dispatchCustomEvent: true,
|
|
22
|
+
waitForEvent: true,
|
|
23
|
+
isCustomElementDefined: true,
|
|
24
|
+
createCustomElement: true
|
|
25
|
+
};
|
|
26
|
+
Object.defineProperty(exports, "Keys", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function get() {
|
|
29
|
+
return _keyboard.Keys;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports, "clearAndType", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function get() {
|
|
35
|
+
return _keyboard.clearAndType;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(exports, "createCustomElement", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
get: function get() {
|
|
41
|
+
return _webComponents.createCustomElement;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
exports.createTestTheme = createTestTheme;
|
|
45
|
+
Object.defineProperty(exports, "dispatchCustomEvent", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
get: function get() {
|
|
48
|
+
return _webComponents.dispatchCustomEvent;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
Object.defineProperty(exports, "isCustomElementDefined", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function get() {
|
|
54
|
+
return _webComponents.isCustomElementDefined;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
Object.defineProperty(exports, "navigateWithKeys", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
get: function get() {
|
|
60
|
+
return _keyboard.navigateWithKeys;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
Object.defineProperty(exports, "pressKey", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
get: function get() {
|
|
66
|
+
return _keyboard.pressKey;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
Object.defineProperty(exports, "renderWebComponent", {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
get: function get() {
|
|
72
|
+
return _webComponents.renderWebComponent;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
exports.renderWithProviders = renderWithProviders;
|
|
76
|
+
exports.renderWithTheme = renderWithTheme;
|
|
77
|
+
Object.defineProperty(exports, "typeAndSubmit", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: function get() {
|
|
80
|
+
return _keyboard.typeAndSubmit;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
Object.defineProperty(exports, "userEvent", {
|
|
84
|
+
enumerable: true,
|
|
85
|
+
get: function get() {
|
|
86
|
+
return _userEvent["default"];
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(exports, "waitForCustomElement", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
get: function get() {
|
|
92
|
+
return _webComponents.waitForCustomElement;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
Object.defineProperty(exports, "waitForEvent", {
|
|
96
|
+
enumerable: true,
|
|
97
|
+
get: function get() {
|
|
98
|
+
return _webComponents.waitForEvent;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(exports, "waitForRemoval", {
|
|
102
|
+
enumerable: true,
|
|
103
|
+
get: function get() {
|
|
104
|
+
return _react2.waitForElementToBeRemoved;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
108
|
+
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
109
|
+
var React = _interopRequireWildcard(require("react"));
|
|
110
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
111
|
+
var _react2 = require("@testing-library/react");
|
|
112
|
+
Object.keys(_react2).forEach(function (key) {
|
|
113
|
+
if (key === "default" || key === "__esModule") return;
|
|
114
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
115
|
+
if (key in exports && exports[key] === _react2[key]) return;
|
|
116
|
+
Object.defineProperty(exports, key, {
|
|
117
|
+
enumerable: true,
|
|
118
|
+
get: function get() {
|
|
119
|
+
return _react2[key];
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
var _styles = require("@mui/material/styles");
|
|
124
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
125
|
+
var _jestDom = require("@testing-library/jest-dom");
|
|
126
|
+
Object.keys(_jestDom).forEach(function (key) {
|
|
127
|
+
if (key === "default" || key === "__esModule") return;
|
|
128
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
129
|
+
if (key in exports && exports[key] === _jestDom[key]) return;
|
|
130
|
+
Object.defineProperty(exports, key, {
|
|
131
|
+
enumerable: true,
|
|
132
|
+
get: function get() {
|
|
133
|
+
return _jestDom[key];
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
var _keyboard = require("./keyboard");
|
|
138
|
+
var _webComponents = require("./web-components");
|
|
139
|
+
var _excluded = ["theme"],
|
|
140
|
+
_excluded2 = ["theme", "providers"];
|
|
141
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(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 (var _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); }
|
|
142
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
143
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
144
|
+
/**
|
|
145
|
+
* Default MUI theme for testing
|
|
146
|
+
*/
|
|
147
|
+
var defaultTheme = (0, _styles.createTheme)();
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Render a component with MUI ThemeProvider
|
|
151
|
+
*
|
|
152
|
+
* @param {React.ReactElement} ui - The component to render
|
|
153
|
+
* @param {Object} options - Render options
|
|
154
|
+
* @param {Object} options.theme - Custom MUI theme (optional)
|
|
155
|
+
* @param {Object} options.renderOptions - Additional options passed to RTL render
|
|
156
|
+
* @returns {Object} RTL render result
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* const { getByRole } = renderWithTheme(<Button>Click me</Button>);
|
|
160
|
+
* expect(getByRole('button')).toBeInTheDocument();
|
|
161
|
+
*/
|
|
162
|
+
function renderWithTheme(ui) {
|
|
163
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
164
|
+
var _options$theme = options.theme,
|
|
165
|
+
theme = _options$theme === void 0 ? defaultTheme : _options$theme,
|
|
166
|
+
renderOptions = (0, _objectWithoutProperties2["default"])(options, _excluded);
|
|
167
|
+
function Wrapper(_ref) {
|
|
168
|
+
var children = _ref.children;
|
|
169
|
+
return /*#__PURE__*/React.createElement(_styles.ThemeProvider, {
|
|
170
|
+
theme: theme
|
|
171
|
+
}, children);
|
|
172
|
+
}
|
|
173
|
+
Wrapper.propTypes = {
|
|
174
|
+
children: _propTypes["default"].node
|
|
175
|
+
};
|
|
176
|
+
return (0, _react2.render)(ui, _objectSpread({
|
|
177
|
+
wrapper: Wrapper
|
|
178
|
+
}, renderOptions));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Render a component with multiple providers (Theme, etc.)
|
|
183
|
+
* Useful when you need to wrap components with various context providers
|
|
184
|
+
*
|
|
185
|
+
* @param {React.ReactElement} ui - The component to render
|
|
186
|
+
* @param {Object} options - Render options
|
|
187
|
+
* @param {Object} options.theme - Custom MUI theme (optional)
|
|
188
|
+
* @param {Array<React.ComponentType>} options.providers - Additional providers to wrap
|
|
189
|
+
* @param {Object} options.renderOptions - Additional options passed to RTL render
|
|
190
|
+
* @returns {Object} RTL render result
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* const { getByText } = renderWithProviders(
|
|
194
|
+
* <MyComponent />,
|
|
195
|
+
* { providers: [ReduxProvider, RouterProvider] }
|
|
196
|
+
* );
|
|
197
|
+
*/
|
|
198
|
+
function renderWithProviders(ui) {
|
|
199
|
+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
200
|
+
var _options$theme2 = options.theme,
|
|
201
|
+
theme = _options$theme2 === void 0 ? defaultTheme : _options$theme2,
|
|
202
|
+
_options$providers = options.providers,
|
|
203
|
+
providers = _options$providers === void 0 ? [] : _options$providers,
|
|
204
|
+
renderOptions = (0, _objectWithoutProperties2["default"])(options, _excluded2);
|
|
205
|
+
function Wrapper(_ref2) {
|
|
206
|
+
var children = _ref2.children;
|
|
207
|
+
var wrapped = /*#__PURE__*/React.createElement(_styles.ThemeProvider, {
|
|
208
|
+
theme: theme
|
|
209
|
+
}, children);
|
|
210
|
+
|
|
211
|
+
// Wrap with additional providers (from innermost to outermost)
|
|
212
|
+
providers.forEach(function (Provider) {
|
|
213
|
+
wrapped = /*#__PURE__*/React.createElement(Provider, null, wrapped);
|
|
214
|
+
});
|
|
215
|
+
return wrapped;
|
|
216
|
+
}
|
|
217
|
+
Wrapper.propTypes = {
|
|
218
|
+
children: _propTypes["default"].node
|
|
219
|
+
};
|
|
220
|
+
return (0, _react2.render)(ui, _objectSpread({
|
|
221
|
+
wrapper: Wrapper
|
|
222
|
+
}, renderOptions));
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Create a custom theme for testing
|
|
227
|
+
* Useful for testing components with specific theme configurations
|
|
228
|
+
*
|
|
229
|
+
* @param {Object} themeOptions - MUI theme options
|
|
230
|
+
* @returns {Object} MUI theme
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* const darkTheme = createTestTheme({ palette: { mode: 'dark' } });
|
|
234
|
+
* renderWithTheme(<Component />, { theme: darkTheme });
|
|
235
|
+
*/
|
|
236
|
+
function createTestTheme() {
|
|
237
|
+
var themeOptions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
238
|
+
return (0, _styles.createTheme)(themeOptions);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Wait for an element to be removed from the DOM
|
|
243
|
+
* Wrapper around waitForElementToBeRemoved for convenience
|
|
244
|
+
*
|
|
245
|
+
* @example
|
|
246
|
+
* await waitForRemoval(() => screen.queryByText('Loading...'));
|
|
247
|
+
*/
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Re-export all of @testing-library/react for convenience
|
|
251
|
+
* This allows consumers to import everything from one place
|
|
252
|
+
*/
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Re-export userEvent as a named export for convenience
|
|
256
|
+
*/
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Re-export jest-dom matchers (they're automatically added in jest.setup.js,
|
|
260
|
+
* but we export them here for TypeScript support)
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Keyboard helpers for testing keyboard interactions
|
|
265
|
+
* Especially useful for components checking event.keyCode
|
|
266
|
+
*/
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Web component testing utilities
|
|
270
|
+
* For testing light DOM custom elements (no Shadow DOM)
|
|
271
|
+
*/
|
|
272
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["React","_interopRequireWildcard","require","_propTypes","_interopRequireDefault","_react2","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_styles","_userEvent","_jestDom","_keyboard","_webComponents","_excluded","_excluded2","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","_typeof","has","set","_t","getOwnPropertyDescriptor","ownKeys","getOwnPropertySymbols","filter","push","apply","_objectSpread","arguments","length","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defaultTheme","createTheme","renderWithTheme","ui","options","undefined","_options$theme","theme","renderOptions","_objectWithoutProperties2","Wrapper","_ref","children","createElement","ThemeProvider","propTypes","PropTypes","node","render","wrapper","renderWithProviders","_options$theme2","_options$providers","providers","_ref2","wrapped","Provider","createTestTheme","themeOptions"],"sources":["../src/index.js"],"sourcesContent":["import * as React from 'react';\nimport PropTypes from 'prop-types';\nimport { render } from '@testing-library/react';\nimport { ThemeProvider, createTheme } from '@mui/material/styles';\n\n/**\n * Default MUI theme for testing\n */\nconst defaultTheme = createTheme();\n\n/**\n * Render a component with MUI ThemeProvider\n *\n * @param {React.ReactElement} ui - The component to render\n * @param {Object} options - Render options\n * @param {Object} options.theme - Custom MUI theme (optional)\n * @param {Object} options.renderOptions - Additional options passed to RTL render\n * @returns {Object} RTL render result\n *\n * @example\n * const { getByRole } = renderWithTheme(<Button>Click me</Button>);\n * expect(getByRole('button')).toBeInTheDocument();\n */\nexport function renderWithTheme(ui, options = {}) {\n const { theme = defaultTheme, ...renderOptions } = options;\n\n function Wrapper({ children }) {\n return <ThemeProvider theme={theme}>{children}</ThemeProvider>;\n }\n Wrapper.propTypes = {\n children: PropTypes.node,\n };\n\n return render(ui, { wrapper: Wrapper, ...renderOptions });\n}\n\n/**\n * Render a component with multiple providers (Theme, etc.)\n * Useful when you need to wrap components with various context providers\n *\n * @param {React.ReactElement} ui - The component to render\n * @param {Object} options - Render options\n * @param {Object} options.theme - Custom MUI theme (optional)\n * @param {Array<React.ComponentType>} options.providers - Additional providers to wrap\n * @param {Object} options.renderOptions - Additional options passed to RTL render\n * @returns {Object} RTL render result\n *\n * @example\n * const { getByText } = renderWithProviders(\n * <MyComponent />,\n * { providers: [ReduxProvider, RouterProvider] }\n * );\n */\nexport function renderWithProviders(ui, options = {}) {\n const { theme = defaultTheme, providers = [], ...renderOptions } = options;\n\n function Wrapper({ children }) {\n let wrapped = <ThemeProvider theme={theme}>{children}</ThemeProvider>;\n\n // Wrap with additional providers (from innermost to outermost)\n providers.forEach((Provider) => {\n wrapped = <Provider>{wrapped}</Provider>;\n });\n\n return wrapped;\n }\n Wrapper.propTypes = {\n children: PropTypes.node,\n };\n\n return render(ui, { wrapper: Wrapper, ...renderOptions });\n}\n\n/**\n * Create a custom theme for testing\n * Useful for testing components with specific theme configurations\n *\n * @param {Object} themeOptions - MUI theme options\n * @returns {Object} MUI theme\n *\n * @example\n * const darkTheme = createTestTheme({ palette: { mode: 'dark' } });\n * renderWithTheme(<Component />, { theme: darkTheme });\n */\nexport function createTestTheme(themeOptions = {}) {\n return createTheme(themeOptions);\n}\n\n/**\n * Wait for an element to be removed from the DOM\n * Wrapper around waitForElementToBeRemoved for convenience\n *\n * @example\n * await waitForRemoval(() => screen.queryByText('Loading...'));\n */\nexport { waitForElementToBeRemoved as waitForRemoval } from '@testing-library/react';\n\n/**\n * Re-export all of @testing-library/react for convenience\n * This allows consumers to import everything from one place\n */\nexport * from '@testing-library/react';\n\n/**\n * Re-export userEvent as a named export for convenience\n */\nexport { default as userEvent } from '@testing-library/user-event';\n\n/**\n * Re-export jest-dom matchers (they're automatically added in jest.setup.js,\n * but we export them here for TypeScript support)\n */\nexport * from '@testing-library/jest-dom';\n\n/**\n * Keyboard helpers for testing keyboard interactions\n * Especially useful for components checking event.keyCode\n */\nexport {\n Keys,\n pressKey,\n typeAndSubmit,\n clearAndType,\n navigateWithKeys,\n} from './keyboard';\n\n/**\n * Web component testing utilities\n * For testing light DOM custom elements (no Shadow DOM)\n */\nexport {\n waitForCustomElement,\n renderWebComponent,\n dispatchCustomEvent,\n waitForEvent,\n isCustomElementDefined,\n createCustomElement,\n} from './web-components';\n\n"],"mappings":"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","ignoreList":[]}
|
package/lib/keyboard.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.Keys = void 0;
|
|
8
|
+
exports.clearAndType = clearAndType;
|
|
9
|
+
exports.navigateWithKeys = navigateWithKeys;
|
|
10
|
+
exports.pressKey = pressKey;
|
|
11
|
+
exports.typeAndSubmit = typeAndSubmit;
|
|
12
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
13
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
14
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
15
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
16
|
+
var _react = require("@testing-library/react");
|
|
17
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
|
+
/**
|
|
20
|
+
* Common keyboard key codes
|
|
21
|
+
* Useful for legacy components that check event.keyCode
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* pressKey(input, Keys.ENTER);
|
|
25
|
+
* pressKey(input, Keys.ESCAPE);
|
|
26
|
+
*/
|
|
27
|
+
var Keys = exports.Keys = {
|
|
28
|
+
ENTER: 13,
|
|
29
|
+
ESCAPE: 27,
|
|
30
|
+
SPACE: 32,
|
|
31
|
+
ARROW_LEFT: 37,
|
|
32
|
+
ARROW_UP: 38,
|
|
33
|
+
ARROW_RIGHT: 39,
|
|
34
|
+
ARROW_DOWN: 40,
|
|
35
|
+
TAB: 9,
|
|
36
|
+
BACKSPACE: 8,
|
|
37
|
+
DELETE: 46,
|
|
38
|
+
HOME: 36,
|
|
39
|
+
END: 35,
|
|
40
|
+
PAGE_UP: 33,
|
|
41
|
+
PAGE_DOWN: 34
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Simulate keyboard event with keyCode
|
|
46
|
+
* Useful for legacy components checking event.keyCode
|
|
47
|
+
*
|
|
48
|
+
* userEvent.type() with special keys like {Enter} doesn't work well with
|
|
49
|
+
* components that check event.keyCode. Use this helper instead.
|
|
50
|
+
*
|
|
51
|
+
* @param {HTMLElement} element - Target element
|
|
52
|
+
* @param {number} keyCode - Key code (use Keys.ENTER, Keys.ESCAPE, etc.)
|
|
53
|
+
* @param {string} type - Event type (keydown, keyup, keypress)
|
|
54
|
+
* @param {Object} options - Additional event properties
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* // Press Enter on an input
|
|
58
|
+
* const input = screen.getByRole('textbox');
|
|
59
|
+
* pressKey(input, Keys.ENTER);
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Press Escape with keyup event
|
|
63
|
+
* pressKey(dialog, Keys.ESCAPE, 'keyup');
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* // Press with additional properties
|
|
67
|
+
* pressKey(input, Keys.ENTER, 'keydown', { ctrlKey: true });
|
|
68
|
+
*/
|
|
69
|
+
function pressKey(element, keyCode) {
|
|
70
|
+
var type = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'keydown';
|
|
71
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
72
|
+
var event = new KeyboardEvent(type, _objectSpread({
|
|
73
|
+
keyCode: keyCode,
|
|
74
|
+
which: keyCode,
|
|
75
|
+
bubbles: true,
|
|
76
|
+
cancelable: true
|
|
77
|
+
}, options));
|
|
78
|
+
(0, _react.fireEvent)(element, event);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Type text and then press Enter
|
|
83
|
+
* Common pattern for form submissions
|
|
84
|
+
*
|
|
85
|
+
* @param {HTMLElement} element - Input element
|
|
86
|
+
* @param {string} text - Text to type
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* const input = screen.getByRole('textbox');
|
|
90
|
+
* await typeAndSubmit(input, 'hello world');
|
|
91
|
+
* expect(onSubmit).toHaveBeenCalledWith('hello world');
|
|
92
|
+
*/
|
|
93
|
+
function typeAndSubmit(_x, _x2) {
|
|
94
|
+
return _typeAndSubmit.apply(this, arguments);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Clear input and type new text
|
|
98
|
+
* Common pattern for updating form fields
|
|
99
|
+
*
|
|
100
|
+
* @param {HTMLElement} element - Input element
|
|
101
|
+
* @param {string} text - New text to type
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* const input = screen.getByRole('textbox');
|
|
105
|
+
* await clearAndType(input, 'new value');
|
|
106
|
+
*/
|
|
107
|
+
function _typeAndSubmit() {
|
|
108
|
+
_typeAndSubmit = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(element, text) {
|
|
109
|
+
var user;
|
|
110
|
+
return _regenerator["default"].wrap(function (_context) {
|
|
111
|
+
while (1) switch (_context.prev = _context.next) {
|
|
112
|
+
case 0:
|
|
113
|
+
user = _userEvent["default"].setup();
|
|
114
|
+
_context.next = 1;
|
|
115
|
+
return user.type(element, text);
|
|
116
|
+
case 1:
|
|
117
|
+
pressKey(element, Keys.ENTER);
|
|
118
|
+
case 2:
|
|
119
|
+
case "end":
|
|
120
|
+
return _context.stop();
|
|
121
|
+
}
|
|
122
|
+
}, _callee);
|
|
123
|
+
}));
|
|
124
|
+
return _typeAndSubmit.apply(this, arguments);
|
|
125
|
+
}
|
|
126
|
+
function clearAndType(_x3, _x4) {
|
|
127
|
+
return _clearAndType.apply(this, arguments);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Simulate keyboard navigation
|
|
131
|
+
* Press arrow keys to navigate through a list
|
|
132
|
+
*
|
|
133
|
+
* @param {HTMLElement} element - List or container element
|
|
134
|
+
* @param {number} steps - Number of steps to navigate (positive = down/right, negative = up/left)
|
|
135
|
+
* @param {string} direction - 'vertical' or 'horizontal'
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* // Navigate down 3 items in a list
|
|
139
|
+
* navigateWithKeys(listbox, 3, 'vertical');
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* // Navigate left 2 items
|
|
143
|
+
* navigateWithKeys(tabs, -2, 'horizontal');
|
|
144
|
+
*/
|
|
145
|
+
function _clearAndType() {
|
|
146
|
+
_clearAndType = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(element, text) {
|
|
147
|
+
var user;
|
|
148
|
+
return _regenerator["default"].wrap(function (_context2) {
|
|
149
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
150
|
+
case 0:
|
|
151
|
+
user = _userEvent["default"].setup();
|
|
152
|
+
_context2.next = 1;
|
|
153
|
+
return user.clear(element);
|
|
154
|
+
case 1:
|
|
155
|
+
_context2.next = 2;
|
|
156
|
+
return user.type(element, text);
|
|
157
|
+
case 2:
|
|
158
|
+
case "end":
|
|
159
|
+
return _context2.stop();
|
|
160
|
+
}
|
|
161
|
+
}, _callee2);
|
|
162
|
+
}));
|
|
163
|
+
return _clearAndType.apply(this, arguments);
|
|
164
|
+
}
|
|
165
|
+
function navigateWithKeys(element, steps) {
|
|
166
|
+
var direction = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'vertical';
|
|
167
|
+
var key = direction === 'vertical' ? steps > 0 ? Keys.ARROW_DOWN : Keys.ARROW_UP : steps > 0 ? Keys.ARROW_RIGHT : Keys.ARROW_LEFT;
|
|
168
|
+
var count = Math.abs(steps);
|
|
169
|
+
for (var i = 0; i < count; i++) {
|
|
170
|
+
pressKey(element, key);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=keyboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keyboard.js","names":["_userEvent","_interopRequireDefault","require","_react","ownKeys","e","r","t","Object","keys","getOwnPropertySymbols","o","filter","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","forEach","_defineProperty2","getOwnPropertyDescriptors","defineProperties","defineProperty","Keys","exports","ENTER","ESCAPE","SPACE","ARROW_LEFT","ARROW_UP","ARROW_RIGHT","ARROW_DOWN","TAB","BACKSPACE","DELETE","HOME","END","PAGE_UP","PAGE_DOWN","pressKey","element","keyCode","type","undefined","options","event","KeyboardEvent","which","bubbles","cancelable","fireEvent","typeAndSubmit","_x","_x2","_typeAndSubmit","_asyncToGenerator2","_regenerator","mark","_callee","text","user","wrap","_context","prev","next","userEvent","setup","stop","clearAndType","_x3","_x4","_clearAndType","_callee2","_context2","clear","navigateWithKeys","steps","direction","key","count","Math","abs","i"],"sources":["../src/keyboard.js"],"sourcesContent":["import userEvent from '@testing-library/user-event';\nimport { fireEvent } from '@testing-library/react';\n\n/**\n * Common keyboard key codes\n * Useful for legacy components that check event.keyCode\n *\n * @example\n * pressKey(input, Keys.ENTER);\n * pressKey(input, Keys.ESCAPE);\n */\nexport const Keys = {\n ENTER: 13,\n ESCAPE: 27,\n SPACE: 32,\n ARROW_LEFT: 37,\n ARROW_UP: 38,\n ARROW_RIGHT: 39,\n ARROW_DOWN: 40,\n TAB: 9,\n BACKSPACE: 8,\n DELETE: 46,\n HOME: 36,\n END: 35,\n PAGE_UP: 33,\n PAGE_DOWN: 34,\n};\n\n/**\n * Simulate keyboard event with keyCode\n * Useful for legacy components checking event.keyCode\n *\n * userEvent.type() with special keys like {Enter} doesn't work well with\n * components that check event.keyCode. Use this helper instead.\n *\n * @param {HTMLElement} element - Target element\n * @param {number} keyCode - Key code (use Keys.ENTER, Keys.ESCAPE, etc.)\n * @param {string} type - Event type (keydown, keyup, keypress)\n * @param {Object} options - Additional event properties\n *\n * @example\n * // Press Enter on an input\n * const input = screen.getByRole('textbox');\n * pressKey(input, Keys.ENTER);\n *\n * @example\n * // Press Escape with keyup event\n * pressKey(dialog, Keys.ESCAPE, 'keyup');\n *\n * @example\n * // Press with additional properties\n * pressKey(input, Keys.ENTER, 'keydown', { ctrlKey: true });\n */\nexport function pressKey(element, keyCode, type = 'keydown', options = {}) {\n const event = new KeyboardEvent(type, {\n keyCode,\n which: keyCode,\n bubbles: true,\n cancelable: true,\n ...options,\n });\n\n fireEvent(element, event);\n}\n\n/**\n * Type text and then press Enter\n * Common pattern for form submissions\n *\n * @param {HTMLElement} element - Input element\n * @param {string} text - Text to type\n *\n * @example\n * const input = screen.getByRole('textbox');\n * await typeAndSubmit(input, 'hello world');\n * expect(onSubmit).toHaveBeenCalledWith('hello world');\n */\nexport async function typeAndSubmit(element, text) {\n const user = userEvent.setup();\n await user.type(element, text);\n pressKey(element, Keys.ENTER);\n}\n\n/**\n * Clear input and type new text\n * Common pattern for updating form fields\n *\n * @param {HTMLElement} element - Input element\n * @param {string} text - New text to type\n *\n * @example\n * const input = screen.getByRole('textbox');\n * await clearAndType(input, 'new value');\n */\nexport async function clearAndType(element, text) {\n const user = userEvent.setup();\n await user.clear(element);\n await user.type(element, text);\n}\n\n/**\n * Simulate keyboard navigation\n * Press arrow keys to navigate through a list\n *\n * @param {HTMLElement} element - List or container element\n * @param {number} steps - Number of steps to navigate (positive = down/right, negative = up/left)\n * @param {string} direction - 'vertical' or 'horizontal'\n *\n * @example\n * // Navigate down 3 items in a list\n * navigateWithKeys(listbox, 3, 'vertical');\n *\n * @example\n * // Navigate left 2 items\n * navigateWithKeys(tabs, -2, 'horizontal');\n */\nexport function navigateWithKeys(element, steps, direction = 'vertical') {\n const key = direction === 'vertical'\n ? (steps > 0 ? Keys.ARROW_DOWN : Keys.ARROW_UP)\n : (steps > 0 ? Keys.ARROW_RIGHT : Keys.ARROW_LEFT);\n\n const count = Math.abs(steps);\n for (let i = 0; i < count; i++) {\n pressKey(element, key);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.createCustomElement = createCustomElement;
|
|
8
|
+
exports.dispatchCustomEvent = dispatchCustomEvent;
|
|
9
|
+
exports.isCustomElementDefined = isCustomElementDefined;
|
|
10
|
+
exports.renderWebComponent = renderWebComponent;
|
|
11
|
+
exports.waitForCustomElement = waitForCustomElement;
|
|
12
|
+
exports.waitForEvent = waitForEvent;
|
|
13
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
14
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
15
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
16
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
17
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
18
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
19
|
+
// Note: These helpers are for light DOM web components (no Shadow DOM)
|
|
20
|
+
// Standard React Testing Library queries work directly on these components
|
|
21
|
+
/**
|
|
22
|
+
* Wait for a custom element to be defined
|
|
23
|
+
* Custom elements are registered asynchronously
|
|
24
|
+
*
|
|
25
|
+
* @param {string} tagName - Custom element tag name (e.g., 'my-component')
|
|
26
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
27
|
+
* @returns {Promise<void>}
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* await waitForCustomElement('pie-chart');
|
|
31
|
+
* const chart = document.createElement('pie-chart');
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* await waitForCustomElement('my-component', 5000);
|
|
35
|
+
*/
|
|
36
|
+
function waitForCustomElement(_x) {
|
|
37
|
+
return _waitForCustomElement.apply(this, arguments);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Render a web component and wait for it to be ready
|
|
41
|
+
* Handles the full lifecycle: wait for definition, create, append, wait for render
|
|
42
|
+
*
|
|
43
|
+
* @param {string} tagName - Custom element tag name
|
|
44
|
+
* @param {Object} attributes - Attributes to set on the element
|
|
45
|
+
* @param {Object} properties - Properties to set on the element
|
|
46
|
+
* @param {HTMLElement} container - Container to append to (defaults to document.body)
|
|
47
|
+
* @returns {Promise<HTMLElement>} The custom element
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const chart = await renderWebComponent('pie-chart', {
|
|
51
|
+
* type: 'bar',
|
|
52
|
+
* 'data-testid': 'my-chart'
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* const button = await renderWebComponent('custom-button',
|
|
57
|
+
* { 'aria-label': 'Submit' },
|
|
58
|
+
* { onClick: jest.fn() }
|
|
59
|
+
* );
|
|
60
|
+
*/
|
|
61
|
+
function _waitForCustomElement() {
|
|
62
|
+
_waitForCustomElement = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(tagName) {
|
|
63
|
+
var timeout,
|
|
64
|
+
_args = arguments;
|
|
65
|
+
return _regenerator["default"].wrap(function (_context) {
|
|
66
|
+
while (1) switch (_context.prev = _context.next) {
|
|
67
|
+
case 0:
|
|
68
|
+
timeout = _args.length > 1 && _args[1] !== undefined ? _args[1] : 3000;
|
|
69
|
+
if (!customElements.get(tagName)) {
|
|
70
|
+
_context.next = 1;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
return _context.abrupt("return");
|
|
74
|
+
case 1:
|
|
75
|
+
return _context.abrupt("return", new Promise(function (resolve, reject) {
|
|
76
|
+
var timer = setTimeout(function () {
|
|
77
|
+
reject(new Error("Custom element '".concat(tagName, "' not defined within ").concat(timeout, "ms. ") + 'Make sure the element is registered with customElements.define().'));
|
|
78
|
+
}, timeout);
|
|
79
|
+
customElements.whenDefined(tagName).then(function () {
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
resolve();
|
|
82
|
+
});
|
|
83
|
+
}));
|
|
84
|
+
case 2:
|
|
85
|
+
case "end":
|
|
86
|
+
return _context.stop();
|
|
87
|
+
}
|
|
88
|
+
}, _callee);
|
|
89
|
+
}));
|
|
90
|
+
return _waitForCustomElement.apply(this, arguments);
|
|
91
|
+
}
|
|
92
|
+
function renderWebComponent(_x2) {
|
|
93
|
+
return _renderWebComponent.apply(this, arguments);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Dispatch a custom event on an element
|
|
97
|
+
* Web components often use custom events for communication
|
|
98
|
+
*
|
|
99
|
+
* @param {HTMLElement} element - Element to dispatch event from
|
|
100
|
+
* @param {string} eventName - Event name (e.g., 'change', 'custom-event')
|
|
101
|
+
* @param {*} detail - Event detail data
|
|
102
|
+
* @param {Object} options - Event options (bubbles, composed, etc.)
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* dispatchCustomEvent(chart, 'data-changed', { value: [1, 2, 3] });
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* dispatchCustomEvent(button, 'custom-click', null, { bubbles: false });
|
|
109
|
+
*/
|
|
110
|
+
function _renderWebComponent() {
|
|
111
|
+
_renderWebComponent = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(tagName) {
|
|
112
|
+
var attributes,
|
|
113
|
+
properties,
|
|
114
|
+
container,
|
|
115
|
+
element,
|
|
116
|
+
_args2 = arguments;
|
|
117
|
+
return _regenerator["default"].wrap(function (_context2) {
|
|
118
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
119
|
+
case 0:
|
|
120
|
+
attributes = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {};
|
|
121
|
+
properties = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : {};
|
|
122
|
+
container = _args2.length > 3 && _args2[3] !== undefined ? _args2[3] : document.body;
|
|
123
|
+
_context2.next = 1;
|
|
124
|
+
return waitForCustomElement(tagName);
|
|
125
|
+
case 1:
|
|
126
|
+
element = document.createElement(tagName); // Set attributes (strings)
|
|
127
|
+
Object.entries(attributes).forEach(function (_ref3) {
|
|
128
|
+
var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
|
|
129
|
+
key = _ref4[0],
|
|
130
|
+
value = _ref4[1];
|
|
131
|
+
element.setAttribute(key, value);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Set properties (objects, functions, etc.)
|
|
135
|
+
Object.entries(properties).forEach(function (_ref5) {
|
|
136
|
+
var _ref6 = (0, _slicedToArray2["default"])(_ref5, 2),
|
|
137
|
+
key = _ref6[0],
|
|
138
|
+
value = _ref6[1];
|
|
139
|
+
element[key] = value;
|
|
140
|
+
});
|
|
141
|
+
container.appendChild(element);
|
|
142
|
+
|
|
143
|
+
// Wait for component to render (custom elements may be async)
|
|
144
|
+
_context2.next = 2;
|
|
145
|
+
return new Promise(function (resolve) {
|
|
146
|
+
return setTimeout(resolve, 0);
|
|
147
|
+
});
|
|
148
|
+
case 2:
|
|
149
|
+
return _context2.abrupt("return", element);
|
|
150
|
+
case 3:
|
|
151
|
+
case "end":
|
|
152
|
+
return _context2.stop();
|
|
153
|
+
}
|
|
154
|
+
}, _callee2);
|
|
155
|
+
}));
|
|
156
|
+
return _renderWebComponent.apply(this, arguments);
|
|
157
|
+
}
|
|
158
|
+
function dispatchCustomEvent(element, eventName) {
|
|
159
|
+
var detail = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
160
|
+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
161
|
+
var event = new CustomEvent(eventName, _objectSpread({
|
|
162
|
+
detail: detail,
|
|
163
|
+
bubbles: true,
|
|
164
|
+
composed: true
|
|
165
|
+
}, options));
|
|
166
|
+
element.dispatchEvent(event);
|
|
167
|
+
return event;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Listen for a custom event and return a promise that resolves when fired
|
|
172
|
+
* Useful for testing event emissions
|
|
173
|
+
*
|
|
174
|
+
* @param {HTMLElement} element - Element to listen to
|
|
175
|
+
* @param {string} eventName - Event name to wait for
|
|
176
|
+
* @param {number} timeout - Timeout in milliseconds
|
|
177
|
+
* @returns {Promise<CustomEvent>} Promise that resolves with the event
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* const promise = waitForEvent(chart, 'data-loaded');
|
|
181
|
+
* chart.loadData();
|
|
182
|
+
* const event = await promise;
|
|
183
|
+
* expect(event.detail).toEqual({ loaded: true });
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* await waitForEvent(component, 'ready', 5000);
|
|
187
|
+
*/
|
|
188
|
+
function waitForEvent(element, eventName) {
|
|
189
|
+
var timeout = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3000;
|
|
190
|
+
return new Promise(function (resolve, reject) {
|
|
191
|
+
var timer = setTimeout(function () {
|
|
192
|
+
element.removeEventListener(eventName, _handler);
|
|
193
|
+
reject(new Error("Event '".concat(eventName, "' not fired within ").concat(timeout, "ms")));
|
|
194
|
+
}, timeout);
|
|
195
|
+
var _handler = function handler(event) {
|
|
196
|
+
clearTimeout(timer);
|
|
197
|
+
element.removeEventListener(eventName, _handler);
|
|
198
|
+
resolve(event);
|
|
199
|
+
};
|
|
200
|
+
element.addEventListener(eventName, _handler);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Check if a custom element is defined
|
|
206
|
+
* Useful for verifying element registration
|
|
207
|
+
*
|
|
208
|
+
* @param {string} tagName - Custom element tag name
|
|
209
|
+
* @returns {boolean} True if element is defined
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* if (isCustomElementDefined('pie-chart')) {
|
|
213
|
+
* // Element is ready to use
|
|
214
|
+
* }
|
|
215
|
+
*/
|
|
216
|
+
function isCustomElementDefined(tagName) {
|
|
217
|
+
return typeof customElements !== 'undefined' && customElements.get(tagName) !== undefined;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Helper to create and configure a custom element
|
|
222
|
+
* For light DOM web components that render React
|
|
223
|
+
*
|
|
224
|
+
* @param {string} tagName - Custom element tag name
|
|
225
|
+
* @param {Object} props - Props to pass to the element
|
|
226
|
+
* @returns {HTMLElement} The custom element
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* const chart = createCustomElement('pie-chart', {
|
|
230
|
+
* data: [1, 2, 3],
|
|
231
|
+
* type: 'bar'
|
|
232
|
+
* });
|
|
233
|
+
* document.body.appendChild(chart);
|
|
234
|
+
*/
|
|
235
|
+
function createCustomElement(tagName) {
|
|
236
|
+
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
237
|
+
var element = document.createElement(tagName);
|
|
238
|
+
|
|
239
|
+
// Set properties directly on the element
|
|
240
|
+
Object.entries(props).forEach(function (_ref) {
|
|
241
|
+
var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
|
|
242
|
+
key = _ref2[0],
|
|
243
|
+
value = _ref2[1];
|
|
244
|
+
element[key] = value;
|
|
245
|
+
});
|
|
246
|
+
return element;
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=web-components.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-components.js","names":["waitForCustomElement","_x","_waitForCustomElement","apply","arguments","_asyncToGenerator2","_regenerator","mark","_callee","tagName","timeout","_args","wrap","_context","prev","next","length","undefined","customElements","get","abrupt","Promise","resolve","reject","timer","setTimeout","Error","concat","whenDefined","then","clearTimeout","stop","renderWebComponent","_x2","_renderWebComponent","_callee2","attributes","properties","container","element","_args2","_context2","document","body","createElement","Object","entries","forEach","_ref3","_ref4","_slicedToArray2","key","value","setAttribute","_ref5","_ref6","appendChild","dispatchCustomEvent","eventName","detail","options","event","CustomEvent","_objectSpread","bubbles","composed","dispatchEvent","waitForEvent","removeEventListener","handler","addEventListener","isCustomElementDefined","createCustomElement","props","_ref","_ref2"],"sources":["../src/web-components.js"],"sourcesContent":["// Note: These helpers are for light DOM web components (no Shadow DOM)\n// Standard React Testing Library queries work directly on these components\n\n/**\n * Wait for a custom element to be defined\n * Custom elements are registered asynchronously\n *\n * @param {string} tagName - Custom element tag name (e.g., 'my-component')\n * @param {number} timeout - Timeout in milliseconds\n * @returns {Promise<void>}\n *\n * @example\n * await waitForCustomElement('pie-chart');\n * const chart = document.createElement('pie-chart');\n *\n * @example\n * await waitForCustomElement('my-component', 5000);\n */\nexport async function waitForCustomElement(tagName, timeout = 3000) {\n if (customElements.get(tagName)) {\n return;\n }\n\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(\n new Error(\n `Custom element '${tagName}' not defined within ${timeout}ms. ` +\n 'Make sure the element is registered with customElements.define().'\n )\n );\n }, timeout);\n\n customElements.whenDefined(tagName).then(() => {\n clearTimeout(timer);\n resolve();\n });\n });\n}\n\n/**\n * Render a web component and wait for it to be ready\n * Handles the full lifecycle: wait for definition, create, append, wait for render\n *\n * @param {string} tagName - Custom element tag name\n * @param {Object} attributes - Attributes to set on the element\n * @param {Object} properties - Properties to set on the element\n * @param {HTMLElement} container - Container to append to (defaults to document.body)\n * @returns {Promise<HTMLElement>} The custom element\n *\n * @example\n * const chart = await renderWebComponent('pie-chart', {\n * type: 'bar',\n * 'data-testid': 'my-chart'\n * });\n *\n * @example\n * const button = await renderWebComponent('custom-button',\n * { 'aria-label': 'Submit' },\n * { onClick: jest.fn() }\n * );\n */\nexport async function renderWebComponent(\n tagName,\n attributes = {},\n properties = {},\n container = document.body\n) {\n await waitForCustomElement(tagName);\n\n const element = document.createElement(tagName);\n\n // Set attributes (strings)\n Object.entries(attributes).forEach(([key, value]) => {\n element.setAttribute(key, value);\n });\n\n // Set properties (objects, functions, etc.)\n Object.entries(properties).forEach(([key, value]) => {\n element[key] = value;\n });\n\n container.appendChild(element);\n\n // Wait for component to render (custom elements may be async)\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n return element;\n}\n\n/**\n * Dispatch a custom event on an element\n * Web components often use custom events for communication\n *\n * @param {HTMLElement} element - Element to dispatch event from\n * @param {string} eventName - Event name (e.g., 'change', 'custom-event')\n * @param {*} detail - Event detail data\n * @param {Object} options - Event options (bubbles, composed, etc.)\n *\n * @example\n * dispatchCustomEvent(chart, 'data-changed', { value: [1, 2, 3] });\n *\n * @example\n * dispatchCustomEvent(button, 'custom-click', null, { bubbles: false });\n */\nexport function dispatchCustomEvent(\n element,\n eventName,\n detail = null,\n options = {}\n) {\n const event = new CustomEvent(eventName, {\n detail,\n bubbles: true,\n composed: true, // Allow event to cross shadow DOM boundary\n ...options,\n });\n\n element.dispatchEvent(event);\n return event;\n}\n\n/**\n * Listen for a custom event and return a promise that resolves when fired\n * Useful for testing event emissions\n *\n * @param {HTMLElement} element - Element to listen to\n * @param {string} eventName - Event name to wait for\n * @param {number} timeout - Timeout in milliseconds\n * @returns {Promise<CustomEvent>} Promise that resolves with the event\n *\n * @example\n * const promise = waitForEvent(chart, 'data-loaded');\n * chart.loadData();\n * const event = await promise;\n * expect(event.detail).toEqual({ loaded: true });\n *\n * @example\n * await waitForEvent(component, 'ready', 5000);\n */\nexport function waitForEvent(element, eventName, timeout = 3000) {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n element.removeEventListener(eventName, handler);\n reject(\n new Error(`Event '${eventName}' not fired within ${timeout}ms`)\n );\n }, timeout);\n\n const handler = (event) => {\n clearTimeout(timer);\n element.removeEventListener(eventName, handler);\n resolve(event);\n };\n\n element.addEventListener(eventName, handler);\n });\n}\n\n/**\n * Check if a custom element is defined\n * Useful for verifying element registration\n *\n * @param {string} tagName - Custom element tag name\n * @returns {boolean} True if element is defined\n *\n * @example\n * if (isCustomElementDefined('pie-chart')) {\n * // Element is ready to use\n * }\n */\nexport function isCustomElementDefined(tagName) {\n return typeof customElements !== 'undefined' && customElements.get(tagName) !== undefined;\n}\n\n/**\n * Helper to create and configure a custom element\n * For light DOM web components that render React\n *\n * @param {string} tagName - Custom element tag name\n * @param {Object} props - Props to pass to the element\n * @returns {HTMLElement} The custom element\n *\n * @example\n * const chart = createCustomElement('pie-chart', {\n * data: [1, 2, 3],\n * type: 'bar'\n * });\n * document.body.appendChild(chart);\n */\nexport function createCustomElement(tagName, props = {}) {\n const element = document.createElement(tagName);\n\n // Set properties directly on the element\n Object.entries(props).forEach(([key, value]) => {\n element[key] = value;\n });\n\n return element;\n}\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-lib/test-utils",
|
|
3
|
-
"version": "1.1.0-next.
|
|
3
|
+
"version": "1.1.0-next.4",
|
|
4
4
|
"description": "Testing utilities for pie-lib packages with React Testing Library and MUI support",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
"@testing-library/jest-dom": "^5.16.5",
|
|
22
22
|
"@testing-library/user-event": "^14.5.2"
|
|
23
23
|
},
|
|
24
|
-
"gitHead": "
|
|
24
|
+
"gitHead": "e51620791bab7434375dc0a101c39dc5926a457d",
|
|
25
25
|
"scripts": {}
|
|
26
26
|
}
|