@depup/testing-library__user-event 14.6.3-depup.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 (309) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +25 -0
  3. package/changes.json +5 -0
  4. package/dist/cjs/clipboard/copy.js +22 -0
  5. package/dist/cjs/clipboard/cut.js +22 -0
  6. package/dist/cjs/clipboard/index.js +11 -0
  7. package/dist/cjs/clipboard/paste.js +24 -0
  8. package/dist/cjs/convenience/click.js +35 -0
  9. package/dist/cjs/convenience/hover.js +19 -0
  10. package/dist/cjs/convenience/index.js +14 -0
  11. package/dist/cjs/convenience/tab.js +7 -0
  12. package/dist/cjs/document/UI.js +90 -0
  13. package/dist/cjs/document/copySelection.js +29 -0
  14. package/dist/cjs/document/getValueOrTextContent.js +18 -0
  15. package/dist/cjs/document/index.js +17 -0
  16. package/dist/cjs/document/interceptor.js +104 -0
  17. package/dist/cjs/document/patchFocus.js +106 -0
  18. package/dist/cjs/document/prepareDocument.js +58 -0
  19. package/dist/cjs/document/trackValue.js +57 -0
  20. package/dist/cjs/event/behavior/click.js +32 -0
  21. package/dist/cjs/event/behavior/cut.js +14 -0
  22. package/dist/cjs/event/behavior/index.js +13 -0
  23. package/dist/cjs/event/behavior/keydown.js +128 -0
  24. package/dist/cjs/event/behavior/keypress.js +51 -0
  25. package/dist/cjs/event/behavior/keyup.js +17 -0
  26. package/dist/cjs/event/behavior/paste.js +18 -0
  27. package/dist/cjs/event/behavior/registry.js +5 -0
  28. package/dist/cjs/event/createEvent.js +193 -0
  29. package/dist/cjs/event/dispatchEvent.js +54 -0
  30. package/dist/cjs/event/eventMap.js +281 -0
  31. package/dist/cjs/event/focus.js +34 -0
  32. package/dist/cjs/event/index.js +22 -0
  33. package/dist/cjs/event/input.js +158 -0
  34. package/dist/cjs/event/radio.js +27 -0
  35. package/dist/cjs/event/selection/getInputRange.js +18 -0
  36. package/dist/cjs/event/selection/getTargetTypeAndSelection.js +31 -0
  37. package/dist/cjs/event/selection/index.js +24 -0
  38. package/dist/cjs/event/selection/modifySelection.js +21 -0
  39. package/dist/cjs/event/selection/modifySelectionPerMouse.js +40 -0
  40. package/dist/cjs/event/selection/moveSelection.js +38 -0
  41. package/dist/cjs/event/selection/resolveCaretPosition.js +60 -0
  42. package/dist/cjs/event/selection/selectAll.js +38 -0
  43. package/dist/cjs/event/selection/setSelection.js +21 -0
  44. package/dist/cjs/event/selection/setSelectionPerMouse.js +79 -0
  45. package/dist/cjs/event/selection/setSelectionRange.js +31 -0
  46. package/dist/cjs/event/selection/updateSelectionOnFocus.js +40 -0
  47. package/dist/cjs/event/types.js +2 -0
  48. package/dist/cjs/event/wrapEvent.js +10 -0
  49. package/dist/cjs/index.js +12 -0
  50. package/dist/cjs/keyboard/index.js +40 -0
  51. package/dist/cjs/keyboard/keyMap.js +178 -0
  52. package/dist/cjs/keyboard/parseKeyDef.js +45 -0
  53. package/dist/cjs/options.js +14 -0
  54. package/dist/cjs/package.json +3 -0
  55. package/dist/cjs/pointer/index.js +74 -0
  56. package/dist/cjs/pointer/keyMap.js +33 -0
  57. package/dist/cjs/pointer/parseKeyDef.js +23 -0
  58. package/dist/cjs/setup/api.js +35 -0
  59. package/dist/cjs/setup/directApi.js +75 -0
  60. package/dist/cjs/setup/index.js +11 -0
  61. package/dist/cjs/setup/setup.js +125 -0
  62. package/dist/cjs/setup/wrapAsync.js +11 -0
  63. package/dist/cjs/system/index.js +42 -0
  64. package/dist/cjs/system/keyboard.js +165 -0
  65. package/dist/cjs/system/pointer/buttons.js +80 -0
  66. package/dist/cjs/system/pointer/device.js +32 -0
  67. package/dist/cjs/system/pointer/index.js +156 -0
  68. package/dist/cjs/system/pointer/mouse.js +204 -0
  69. package/dist/cjs/system/pointer/pointer.js +129 -0
  70. package/dist/cjs/system/pointer/shared.js +8 -0
  71. package/dist/cjs/utility/clear.js +32 -0
  72. package/dist/cjs/utility/index.js +14 -0
  73. package/dist/cjs/utility/selectOptions.js +114 -0
  74. package/dist/cjs/utility/type.js +23 -0
  75. package/dist/cjs/utility/upload.js +62 -0
  76. package/dist/cjs/utils/click/isClickableInput.js +20 -0
  77. package/dist/cjs/utils/dataTransfer/Blob.js +16 -0
  78. package/dist/cjs/utils/dataTransfer/Clipboard.js +174 -0
  79. package/dist/cjs/utils/dataTransfer/DataTransfer.js +134 -0
  80. package/dist/cjs/utils/dataTransfer/FileList.js +24 -0
  81. package/dist/cjs/utils/edit/isContentEditable.js +18 -0
  82. package/dist/cjs/utils/edit/isEditable.js +29 -0
  83. package/dist/cjs/utils/edit/maxLength.js +26 -0
  84. package/dist/cjs/utils/edit/setFiles.js +58 -0
  85. package/dist/cjs/utils/edit/timeValue.js +40 -0
  86. package/dist/cjs/utils/focus/cursor.js +126 -0
  87. package/dist/cjs/utils/focus/getActiveElement.js +25 -0
  88. package/dist/cjs/utils/focus/getTabDestination.js +80 -0
  89. package/dist/cjs/utils/focus/isFocusable.js +9 -0
  90. package/dist/cjs/utils/focus/selection.js +20 -0
  91. package/dist/cjs/utils/focus/selector.js +15 -0
  92. package/dist/cjs/utils/index.js +78 -0
  93. package/dist/cjs/utils/keyDef/readNextDescriptor.js +91 -0
  94. package/dist/cjs/utils/misc/cloneEvent.js +7 -0
  95. package/dist/cjs/utils/misc/findClosest.js +14 -0
  96. package/dist/cjs/utils/misc/getDocumentFromNode.js +10 -0
  97. package/dist/cjs/utils/misc/getTreeDiff.js +25 -0
  98. package/dist/cjs/utils/misc/getWindow.js +19 -0
  99. package/dist/cjs/utils/misc/isDescendantOrSelf.js +14 -0
  100. package/dist/cjs/utils/misc/isDisabled.js +33 -0
  101. package/dist/cjs/utils/misc/isElementType.js +20 -0
  102. package/dist/cjs/utils/misc/isVisible.js +19 -0
  103. package/dist/cjs/utils/misc/level.js +17 -0
  104. package/dist/cjs/utils/misc/wait.js +14 -0
  105. package/dist/cjs/utils/pointer/cssPointerEvents.js +102 -0
  106. package/dist/esm/clipboard/copy.js +20 -0
  107. package/dist/esm/clipboard/cut.js +20 -0
  108. package/dist/esm/clipboard/index.js +3 -0
  109. package/dist/esm/clipboard/paste.js +22 -0
  110. package/dist/esm/convenience/click.js +31 -0
  111. package/dist/esm/convenience/hover.js +16 -0
  112. package/dist/esm/convenience/index.js +3 -0
  113. package/dist/esm/convenience/tab.js +5 -0
  114. package/dist/esm/document/UI.js +77 -0
  115. package/dist/esm/document/copySelection.js +27 -0
  116. package/dist/esm/document/getValueOrTextContent.js +16 -0
  117. package/dist/esm/document/index.js +4 -0
  118. package/dist/esm/document/interceptor.js +99 -0
  119. package/dist/esm/document/patchFocus.js +103 -0
  120. package/dist/esm/document/prepareDocument.js +56 -0
  121. package/dist/esm/document/trackValue.js +53 -0
  122. package/dist/esm/event/behavior/click.js +30 -0
  123. package/dist/esm/event/behavior/cut.js +12 -0
  124. package/dist/esm/event/behavior/index.js +7 -0
  125. package/dist/esm/event/behavior/keydown.js +126 -0
  126. package/dist/esm/event/behavior/keypress.js +49 -0
  127. package/dist/esm/event/behavior/keyup.js +15 -0
  128. package/dist/esm/event/behavior/paste.js +16 -0
  129. package/dist/esm/event/behavior/registry.js +3 -0
  130. package/dist/esm/event/createEvent.js +191 -0
  131. package/dist/esm/event/dispatchEvent.js +50 -0
  132. package/dist/esm/event/eventMap.js +277 -0
  133. package/dist/esm/event/focus.js +31 -0
  134. package/dist/esm/event/index.js +7 -0
  135. package/dist/esm/event/input.js +156 -0
  136. package/dist/esm/event/radio.js +25 -0
  137. package/dist/esm/event/selection/getInputRange.js +16 -0
  138. package/dist/esm/event/selection/getTargetTypeAndSelection.js +29 -0
  139. package/dist/esm/event/selection/index.js +9 -0
  140. package/dist/esm/event/selection/modifySelection.js +19 -0
  141. package/dist/esm/event/selection/modifySelectionPerMouse.js +38 -0
  142. package/dist/esm/event/selection/moveSelection.js +36 -0
  143. package/dist/esm/event/selection/resolveCaretPosition.js +58 -0
  144. package/dist/esm/event/selection/selectAll.js +35 -0
  145. package/dist/esm/event/selection/setSelection.js +19 -0
  146. package/dist/esm/event/selection/setSelectionPerMouse.js +77 -0
  147. package/dist/esm/event/selection/setSelectionRange.js +29 -0
  148. package/dist/esm/event/selection/updateSelectionOnFocus.js +38 -0
  149. package/dist/esm/event/types.js +1 -0
  150. package/dist/esm/event/wrapEvent.js +8 -0
  151. package/dist/esm/index.js +2 -0
  152. package/dist/esm/keyboard/index.js +37 -0
  153. package/dist/esm/keyboard/keyMap.js +176 -0
  154. package/dist/esm/keyboard/parseKeyDef.js +43 -0
  155. package/dist/esm/options.js +12 -0
  156. package/dist/esm/package.json +3 -0
  157. package/dist/esm/pointer/index.js +72 -0
  158. package/dist/esm/pointer/keyMap.js +31 -0
  159. package/dist/esm/pointer/parseKeyDef.js +21 -0
  160. package/dist/esm/setup/api.js +33 -0
  161. package/dist/esm/setup/directApi.js +58 -0
  162. package/dist/esm/setup/index.js +9 -0
  163. package/dist/esm/setup/setup.js +119 -0
  164. package/dist/esm/setup/wrapAsync.js +9 -0
  165. package/dist/esm/system/index.js +40 -0
  166. package/dist/esm/system/keyboard.js +162 -0
  167. package/dist/esm/system/pointer/buttons.js +74 -0
  168. package/dist/esm/system/pointer/device.js +30 -0
  169. package/dist/esm/system/pointer/index.js +154 -0
  170. package/dist/esm/system/pointer/mouse.js +202 -0
  171. package/dist/esm/system/pointer/pointer.js +127 -0
  172. package/dist/esm/system/pointer/shared.js +6 -0
  173. package/dist/esm/utility/clear.js +30 -0
  174. package/dist/esm/utility/index.js +4 -0
  175. package/dist/esm/utility/selectOptions.js +111 -0
  176. package/dist/esm/utility/type.js +21 -0
  177. package/dist/esm/utility/upload.js +60 -0
  178. package/dist/esm/utils/click/isClickableInput.js +18 -0
  179. package/dist/esm/utils/dataTransfer/Blob.js +14 -0
  180. package/dist/esm/utils/dataTransfer/Clipboard.js +167 -0
  181. package/dist/esm/utils/dataTransfer/DataTransfer.js +131 -0
  182. package/dist/esm/utils/dataTransfer/FileList.js +22 -0
  183. package/dist/esm/utils/edit/isContentEditable.js +15 -0
  184. package/dist/esm/utils/edit/isEditable.js +26 -0
  185. package/dist/esm/utils/edit/maxLength.js +23 -0
  186. package/dist/esm/utils/edit/setFiles.js +56 -0
  187. package/dist/esm/utils/edit/timeValue.js +37 -0
  188. package/dist/esm/utils/focus/cursor.js +124 -0
  189. package/dist/esm/utils/focus/getActiveElement.js +22 -0
  190. package/dist/esm/utils/focus/getTabDestination.js +78 -0
  191. package/dist/esm/utils/focus/isFocusable.js +7 -0
  192. package/dist/esm/utils/focus/selection.js +17 -0
  193. package/dist/esm/utils/focus/selector.js +13 -0
  194. package/dist/esm/utils/index.js +29 -0
  195. package/dist/esm/utils/keyDef/readNextDescriptor.js +89 -0
  196. package/dist/esm/utils/misc/cloneEvent.js +5 -0
  197. package/dist/esm/utils/misc/findClosest.js +12 -0
  198. package/dist/esm/utils/misc/getDocumentFromNode.js +8 -0
  199. package/dist/esm/utils/misc/getTreeDiff.js +23 -0
  200. package/dist/esm/utils/misc/getWindow.js +17 -0
  201. package/dist/esm/utils/misc/isDescendantOrSelf.js +12 -0
  202. package/dist/esm/utils/misc/isDisabled.js +31 -0
  203. package/dist/esm/utils/misc/isElementType.js +18 -0
  204. package/dist/esm/utils/misc/isVisible.js +17 -0
  205. package/dist/esm/utils/misc/level.js +13 -0
  206. package/dist/esm/utils/misc/wait.js +12 -0
  207. package/dist/esm/utils/pointer/cssPointerEvents.js +99 -0
  208. package/dist/types/clipboard/copy.d.ts +2 -0
  209. package/dist/types/clipboard/cut.d.ts +2 -0
  210. package/dist/types/clipboard/index.d.ts +3 -0
  211. package/dist/types/clipboard/paste.d.ts +2 -0
  212. package/dist/types/convenience/click.d.ts +4 -0
  213. package/dist/types/convenience/hover.d.ts +3 -0
  214. package/dist/types/convenience/index.d.ts +3 -0
  215. package/dist/types/convenience/tab.d.ts +4 -0
  216. package/dist/types/document/UI.d.ts +42 -0
  217. package/dist/types/document/copySelection.d.ts +1 -0
  218. package/dist/types/document/getValueOrTextContent.d.ts +1 -0
  219. package/dist/types/document/index.d.ts +5 -0
  220. package/dist/types/document/interceptor.d.ts +19 -0
  221. package/dist/types/document/patchFocus.d.ts +9 -0
  222. package/dist/types/document/prepareDocument.d.ts +8 -0
  223. package/dist/types/document/trackValue.d.ts +17 -0
  224. package/dist/types/event/behavior/click.d.ts +1 -0
  225. package/dist/types/event/behavior/cut.d.ts +1 -0
  226. package/dist/types/event/behavior/index.d.ts +8 -0
  227. package/dist/types/event/behavior/keydown.d.ts +1 -0
  228. package/dist/types/event/behavior/keypress.d.ts +1 -0
  229. package/dist/types/event/behavior/keyup.d.ts +1 -0
  230. package/dist/types/event/behavior/paste.d.ts +1 -0
  231. package/dist/types/event/behavior/registry.d.ts +8 -0
  232. package/dist/types/event/createEvent.d.ts +2 -0
  233. package/dist/types/event/dispatchEvent.d.ts +5 -0
  234. package/dist/types/event/eventMap.d.ts +265 -0
  235. package/dist/types/event/focus.d.ts +5 -0
  236. package/dist/types/event/index.d.ts +7 -0
  237. package/dist/types/event/input.d.ts +2 -0
  238. package/dist/types/event/radio.d.ts +4 -0
  239. package/dist/types/event/selection/getInputRange.d.ts +5 -0
  240. package/dist/types/event/selection/getTargetTypeAndSelection.d.ts +10 -0
  241. package/dist/types/event/selection/index.d.ts +15 -0
  242. package/dist/types/event/selection/modifySelection.d.ts +8 -0
  243. package/dist/types/event/selection/modifySelectionPerMouse.d.ts +7 -0
  244. package/dist/types/event/selection/moveSelection.d.ts +4 -0
  245. package/dist/types/event/selection/resolveCaretPosition.d.ts +8 -0
  246. package/dist/types/event/selection/selectAll.d.ts +5 -0
  247. package/dist/types/event/selection/setSelection.d.ts +10 -0
  248. package/dist/types/event/selection/setSelectionPerMouse.d.ts +8 -0
  249. package/dist/types/event/selection/setSelectionRange.d.ts +6 -0
  250. package/dist/types/event/selection/updateSelectionOnFocus.d.ts +5 -0
  251. package/dist/types/event/types.d.ts +20 -0
  252. package/dist/types/event/wrapEvent.d.ts +1 -0
  253. package/dist/types/index.d.ts +6 -0
  254. package/dist/types/keyboard/index.d.ts +3 -0
  255. package/dist/types/keyboard/keyMap.d.ts +5 -0
  256. package/dist/types/keyboard/parseKeyDef.d.ts +17 -0
  257. package/dist/types/options.d.ts +115 -0
  258. package/dist/types/pointer/index.d.ts +28 -0
  259. package/dist/types/pointer/keyMap.d.ts +2 -0
  260. package/dist/types/pointer/parseKeyDef.d.ts +6 -0
  261. package/dist/types/setup/api.d.ts +23 -0
  262. package/dist/types/setup/directApi.d.ts +24 -0
  263. package/dist/types/setup/index.d.ts +22 -0
  264. package/dist/types/setup/setup.d.ts +44 -0
  265. package/dist/types/setup/wrapAsync.d.ts +4 -0
  266. package/dist/types/system/index.d.ts +10 -0
  267. package/dist/types/system/keyboard.d.ts +50 -0
  268. package/dist/types/system/pointer/buttons.d.ts +23 -0
  269. package/dist/types/system/pointer/device.d.ts +8 -0
  270. package/dist/types/system/pointer/index.d.ts +21 -0
  271. package/dist/types/system/pointer/mouse.d.ts +31 -0
  272. package/dist/types/system/pointer/pointer.d.ts +32 -0
  273. package/dist/types/system/pointer/shared.d.ts +20 -0
  274. package/dist/types/utility/clear.d.ts +2 -0
  275. package/dist/types/utility/index.d.ts +4 -0
  276. package/dist/types/utility/selectOptions.d.ts +3 -0
  277. package/dist/types/utility/type.d.ts +9 -0
  278. package/dist/types/utility/upload.d.ts +5 -0
  279. package/dist/types/utils/click/isClickableInput.d.ts +15 -0
  280. package/dist/types/utils/dataTransfer/Blob.d.ts +3 -0
  281. package/dist/types/utils/dataTransfer/Clipboard.d.ts +11 -0
  282. package/dist/types/utils/dataTransfer/DataTransfer.d.ts +2 -0
  283. package/dist/types/utils/dataTransfer/FileList.d.ts +1 -0
  284. package/dist/types/utils/edit/isContentEditable.d.ts +7 -0
  285. package/dist/types/utils/edit/isEditable.d.ts +24 -0
  286. package/dist/types/utils/edit/maxLength.d.ts +14 -0
  287. package/dist/types/utils/edit/setFiles.d.ts +12 -0
  288. package/dist/types/utils/edit/timeValue.d.ts +4 -0
  289. package/dist/types/utils/focus/cursor.d.ts +9 -0
  290. package/dist/types/utils/focus/getActiveElement.d.ts +2 -0
  291. package/dist/types/utils/focus/getTabDestination.d.ts +1 -0
  292. package/dist/types/utils/focus/isFocusable.d.ts +1 -0
  293. package/dist/types/utils/focus/selection.d.ts +8 -0
  294. package/dist/types/utils/focus/selector.d.ts +1 -0
  295. package/dist/types/utils/index.d.ts +29 -0
  296. package/dist/types/utils/keyDef/readNextDescriptor.d.ts +21 -0
  297. package/dist/types/utils/misc/cloneEvent.d.ts +1 -0
  298. package/dist/types/utils/misc/findClosest.d.ts +1 -0
  299. package/dist/types/utils/misc/getDocumentFromNode.d.ts +1 -0
  300. package/dist/types/utils/misc/getTreeDiff.d.ts +1 -0
  301. package/dist/types/utils/misc/getWindow.d.ts +1 -0
  302. package/dist/types/utils/misc/isDescendantOrSelf.d.ts +1 -0
  303. package/dist/types/utils/misc/isDisabled.d.ts +1 -0
  304. package/dist/types/utils/misc/isElementType.d.ts +5 -0
  305. package/dist/types/utils/misc/isVisible.d.ts +1 -0
  306. package/dist/types/utils/misc/level.d.ts +8 -0
  307. package/dist/types/utils/misc/wait.d.ts +2 -0
  308. package/dist/types/utils/pointer/cssPointerEvents.d.ts +19 -0
  309. package/package.json +131 -0
@@ -0,0 +1,114 @@
1
+ 'use strict';
2
+
3
+ var dom = require('@testing-library/dom');
4
+ var isElementType = require('../utils/misc/isElementType.js');
5
+ require('../utils/dataTransfer/Clipboard.js');
6
+ var isDisabled = require('../utils/misc/isDisabled.js');
7
+ var wait = require('../utils/misc/wait.js');
8
+ var cssPointerEvents = require('../utils/pointer/cssPointerEvents.js');
9
+ require('../event/behavior/click.js');
10
+ require('../event/behavior/cut.js');
11
+ require('../event/behavior/keydown.js');
12
+ require('../event/behavior/keypress.js');
13
+ require('../event/behavior/keyup.js');
14
+ require('../event/behavior/paste.js');
15
+ var focus = require('../event/focus.js');
16
+
17
+ async function selectOptions(select, values) {
18
+ return selectOptionsBase.call(this, true, select, values);
19
+ }
20
+ async function deselectOptions(select, values) {
21
+ return selectOptionsBase.call(this, false, select, values);
22
+ }
23
+ async function selectOptionsBase(newValue, select, values) {
24
+ if (!newValue && !select.multiple) {
25
+ throw dom.getConfig().getElementError(`Unable to deselect an option in a non-multiple select. Use selectOptions to change the selection instead.`, select);
26
+ }
27
+ const valArray = Array.isArray(values) ? values : [
28
+ values
29
+ ];
30
+ const allOptions = Array.from(select.querySelectorAll('option, [role="option"]'));
31
+ const selectedOptions = valArray.map((val)=>{
32
+ if (typeof val !== 'string' && allOptions.includes(val)) {
33
+ return val;
34
+ } else {
35
+ const matchingOption = allOptions.find((o)=>o.value === val || o.innerHTML === val);
36
+ if (matchingOption) {
37
+ return matchingOption;
38
+ } else {
39
+ throw dom.getConfig().getElementError(`Value "${String(val)}" not found in options`, select);
40
+ }
41
+ }
42
+ }).filter((option)=>!isDisabled.isDisabled(option));
43
+ if (isDisabled.isDisabled(select) || !selectedOptions.length) return;
44
+ const selectOption = (option)=>{
45
+ option.selected = newValue;
46
+ this.dispatchUIEvent(select, 'input', {
47
+ bubbles: true,
48
+ cancelable: false,
49
+ composed: true
50
+ });
51
+ this.dispatchUIEvent(select, 'change');
52
+ };
53
+ if (isElementType.isElementType(select, 'select')) {
54
+ if (select.multiple) {
55
+ for (const option of selectedOptions){
56
+ const withPointerEvents = this.config.pointerEventsCheck === 0 ? true : cssPointerEvents.hasPointerEvents(this, option);
57
+ // events fired for multiple select are weird. Can't use hover...
58
+ if (withPointerEvents) {
59
+ this.dispatchUIEvent(option, 'pointerover');
60
+ this.dispatchUIEvent(select, 'pointerenter');
61
+ this.dispatchUIEvent(option, 'mouseover');
62
+ this.dispatchUIEvent(select, 'mouseenter');
63
+ this.dispatchUIEvent(option, 'pointermove');
64
+ this.dispatchUIEvent(option, 'mousemove');
65
+ this.dispatchUIEvent(option, 'pointerdown');
66
+ this.dispatchUIEvent(option, 'mousedown');
67
+ }
68
+ focus.focusElement(select);
69
+ if (withPointerEvents) {
70
+ this.dispatchUIEvent(option, 'pointerup');
71
+ this.dispatchUIEvent(option, 'mouseup');
72
+ }
73
+ selectOption(option);
74
+ if (withPointerEvents) {
75
+ this.dispatchUIEvent(option, 'click');
76
+ }
77
+ await wait.wait(this.config);
78
+ }
79
+ } else if (selectedOptions.length === 1) {
80
+ const withPointerEvents = this.config.pointerEventsCheck === 0 ? true : cssPointerEvents.hasPointerEvents(this, select);
81
+ // the click to open the select options
82
+ if (withPointerEvents) {
83
+ await this.click(select);
84
+ } else {
85
+ focus.focusElement(select);
86
+ }
87
+ selectOption(selectedOptions[0]);
88
+ if (withPointerEvents) {
89
+ // the browser triggers another click event on the select for the click on the option
90
+ // this second click has no 'down' phase
91
+ this.dispatchUIEvent(select, 'pointerover');
92
+ this.dispatchUIEvent(select, 'pointerenter');
93
+ this.dispatchUIEvent(select, 'mouseover');
94
+ this.dispatchUIEvent(select, 'mouseenter');
95
+ this.dispatchUIEvent(select, 'pointerup');
96
+ this.dispatchUIEvent(select, 'mouseup');
97
+ this.dispatchUIEvent(select, 'click');
98
+ }
99
+ await wait.wait(this.config);
100
+ } else {
101
+ throw dom.getConfig().getElementError(`Cannot select multiple options on a non-multiple select`, select);
102
+ }
103
+ } else if (select.getAttribute('role') === 'listbox') {
104
+ for (const option of selectedOptions){
105
+ await this.click(option);
106
+ await this.unhover(option);
107
+ }
108
+ } else {
109
+ throw dom.getConfig().getElementError(`Cannot select options on elements that are neither select nor listbox elements`, select);
110
+ }
111
+ }
112
+
113
+ exports.deselectOptions = deselectOptions;
114
+ exports.selectOptions = selectOptions;
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ var index = require('../keyboard/index.js');
4
+ require('../utils/dataTransfer/Clipboard.js');
5
+ var setSelectionRange = require('../event/selection/setSelectionRange.js');
6
+
7
+ async function type(element, text, { skipClick = this.config.skipClick, skipAutoClose = this.config.skipAutoClose, initialSelectionStart, initialSelectionEnd } = {}) {
8
+ // TODO: properly type guard
9
+ // we use this workaround for now to prevent changing behavior
10
+ if (element.disabled) return;
11
+ if (!skipClick) {
12
+ await this.click(element);
13
+ }
14
+ if (initialSelectionStart !== undefined) {
15
+ setSelectionRange.setSelectionRange(element, initialSelectionStart, initialSelectionEnd !== null && initialSelectionEnd !== void 0 ? initialSelectionEnd : initialSelectionStart);
16
+ }
17
+ await this.keyboard(text);
18
+ if (!skipAutoClose) {
19
+ await index.releaseAllKeys(this);
20
+ }
21
+ }
22
+
23
+ exports.type = type;
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ var isElementType = require('../utils/misc/isElementType.js');
4
+ var FileList = require('../utils/dataTransfer/FileList.js');
5
+ require('../utils/dataTransfer/Clipboard.js');
6
+ var setFiles = require('../utils/edit/setFiles.js');
7
+ var isDisabled = require('../utils/misc/isDisabled.js');
8
+ var getWindow = require('../utils/misc/getWindow.js');
9
+
10
+ async function upload(element, fileOrFiles) {
11
+ const input = isElementType.isElementType(element, 'label') ? element.control : element;
12
+ if (!input || !isElementType.isElementType(input, 'input', {
13
+ type: 'file'
14
+ })) {
15
+ throw new TypeError(`The ${input === element ? 'given' : 'associated'} ${input === null || input === void 0 ? void 0 : input.tagName} element does not accept file uploads`);
16
+ }
17
+ if (isDisabled.isDisabled(element)) return;
18
+ const files = (Array.isArray(fileOrFiles) ? fileOrFiles : [
19
+ fileOrFiles
20
+ ]).filter((file)=>!this.config.applyAccept || isAcceptableFile(file, input.accept)).slice(0, input.multiple ? undefined : 1);
21
+ const fileDialog = ()=>{
22
+ var _input_files;
23
+ // do not fire an input event if the file selection does not change
24
+ if (files.length === ((_input_files = input.files) === null || _input_files === void 0 ? void 0 : _input_files.length) && files.every((f, i)=>{
25
+ var _input_files;
26
+ return f === ((_input_files = input.files) === null || _input_files === void 0 ? void 0 : _input_files.item(i));
27
+ })) {
28
+ return;
29
+ }
30
+ setFiles.setFiles(input, FileList.createFileList(getWindow.getWindow(element), files));
31
+ this.dispatchUIEvent(input, 'input');
32
+ this.dispatchUIEvent(input, 'change');
33
+ };
34
+ input.addEventListener('fileDialog', fileDialog);
35
+ await this.click(element);
36
+ input.removeEventListener('fileDialog', fileDialog);
37
+ }
38
+ // When matching files, browsers ignore case and consider jpeg/jpg interchangeable.
39
+ function normalize(nameOrType) {
40
+ return nameOrType.toLowerCase().replace(/(\.|\/)jpg\b/g, '$1jpeg');
41
+ }
42
+ function isAcceptableFile(file, accept) {
43
+ if (!accept) {
44
+ return true;
45
+ }
46
+ const wildcards = [
47
+ 'audio/*',
48
+ 'image/*',
49
+ 'video/*'
50
+ ];
51
+ return normalize(accept).trim().split(/\s*,\s*/).some((acceptToken)=>{
52
+ // tokens starting with a dot represent a file extension
53
+ if (acceptToken.startsWith('.')) {
54
+ return normalize(file.name).endsWith(acceptToken);
55
+ } else if (wildcards.includes(acceptToken)) {
56
+ return normalize(file.type).startsWith(acceptToken.replace('*', ''));
57
+ }
58
+ return normalize(file.type) === acceptToken;
59
+ });
60
+ }
61
+
62
+ exports.upload = upload;
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var isElementType = require('../misc/isElementType.js');
4
+
5
+ var clickableInputTypes = /*#__PURE__*/ function(clickableInputTypes) {
6
+ clickableInputTypes["button"] = "button";
7
+ clickableInputTypes["color"] = "color";
8
+ clickableInputTypes["file"] = "file";
9
+ clickableInputTypes["image"] = "image";
10
+ clickableInputTypes["reset"] = "reset";
11
+ clickableInputTypes["submit"] = "submit";
12
+ clickableInputTypes["checkbox"] = "checkbox";
13
+ clickableInputTypes["radio"] = "radio";
14
+ return clickableInputTypes;
15
+ }(clickableInputTypes || {});
16
+ function isClickableInput(element) {
17
+ return isElementType.isElementType(element, 'button') || isElementType.isElementType(element, 'input') && element.type in clickableInputTypes;
18
+ }
19
+
20
+ exports.isClickableInput = isClickableInput;
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ // jsdom does not implement Blob.text()
4
+ function readBlobText(blob, FileReader) {
5
+ return new Promise((res, rej)=>{
6
+ const fr = new FileReader();
7
+ fr.onerror = rej;
8
+ fr.onabort = rej;
9
+ fr.onload = ()=>{
10
+ res(String(fr.result));
11
+ };
12
+ fr.readAsText(blob);
13
+ });
14
+ }
15
+
16
+ exports.readBlobText = readBlobText;
@@ -0,0 +1,174 @@
1
+ 'use strict';
2
+
3
+ var getWindow = require('../misc/getWindow.js');
4
+ var Blob = require('./Blob.js');
5
+ var DataTransfer = require('./DataTransfer.js');
6
+
7
+ function _define_property(obj, key, value) {
8
+ if (key in obj) {
9
+ Object.defineProperty(obj, key, {
10
+ value: value,
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true
14
+ });
15
+ } else obj[key] = value;
16
+ return obj;
17
+ }
18
+ // MDN lists string|Blob|Promise<Blob|string> as possible types in ClipboardItemData
19
+ // lib.dom.d.ts lists only Promise<Blob|string>
20
+ // https://developer.mozilla.org/en-US/docs/Web/API/ClipboardItem/ClipboardItem#syntax
21
+ function createClipboardItem(window, ...blobs) {
22
+ const dataMap = Object.fromEntries(blobs.map((b)=>[
23
+ typeof b === 'string' ? 'text/plain' : b.type,
24
+ Promise.resolve(b)
25
+ ]));
26
+ // use real ClipboardItem if available
27
+ /* istanbul ignore if */ if (typeof window.ClipboardItem !== 'undefined') {
28
+ return new window.ClipboardItem(dataMap);
29
+ }
30
+ return new class ClipboardItem {
31
+ get types() {
32
+ return Array.from(Object.keys(this.data));
33
+ }
34
+ async getType(type) {
35
+ const value = await this.data[type];
36
+ if (!value) {
37
+ throw new Error(`${type} is not one of the available MIME types on this item.`);
38
+ }
39
+ return value instanceof window.Blob ? value : new window.Blob([
40
+ value
41
+ ], {
42
+ type
43
+ });
44
+ }
45
+ constructor(d){
46
+ _define_property(this, "data", void 0);
47
+ this.data = d;
48
+ }
49
+ }(dataMap);
50
+ }
51
+ const ClipboardStubControl = Symbol('Manage ClipboardSub');
52
+ function createClipboardStub(window, control) {
53
+ return Object.assign(new class Clipboard extends window.EventTarget {
54
+ async read() {
55
+ return Array.from(this.items);
56
+ }
57
+ async readText() {
58
+ let text = '';
59
+ for (const item of this.items){
60
+ const type = item.types.includes('text/plain') ? 'text/plain' : item.types.find((t)=>t.startsWith('text/'));
61
+ if (type) {
62
+ text += await item.getType(type).then((b)=>Blob.readBlobText(b, window.FileReader));
63
+ }
64
+ }
65
+ return text;
66
+ }
67
+ async write(data) {
68
+ this.items = data;
69
+ }
70
+ async writeText(text) {
71
+ this.items = [
72
+ createClipboardItem(window, text)
73
+ ];
74
+ }
75
+ constructor(...args){
76
+ super(...args), _define_property(this, "items", []);
77
+ }
78
+ }(), {
79
+ [ClipboardStubControl]: control
80
+ });
81
+ }
82
+ function isClipboardStub(clipboard) {
83
+ return !!(clipboard === null || clipboard === void 0 ? void 0 : clipboard[ClipboardStubControl]);
84
+ }
85
+ function attachClipboardStubToView(window) {
86
+ if (isClipboardStub(window.navigator.clipboard)) {
87
+ return window.navigator.clipboard[ClipboardStubControl];
88
+ }
89
+ const realClipboard = Object.getOwnPropertyDescriptor(window.navigator, 'clipboard');
90
+ let stub;
91
+ const control = {
92
+ resetClipboardStub: ()=>{
93
+ stub = createClipboardStub(window, control);
94
+ },
95
+ detachClipboardStub: ()=>{
96
+ /* istanbul ignore if */ if (realClipboard) {
97
+ Object.defineProperty(window.navigator, 'clipboard', realClipboard);
98
+ } else {
99
+ Object.defineProperty(window.navigator, 'clipboard', {
100
+ value: undefined,
101
+ configurable: true
102
+ });
103
+ }
104
+ }
105
+ };
106
+ stub = createClipboardStub(window, control);
107
+ Object.defineProperty(window.navigator, 'clipboard', {
108
+ get: ()=>stub,
109
+ configurable: true
110
+ });
111
+ return stub[ClipboardStubControl];
112
+ }
113
+ function resetClipboardStubOnView(window) {
114
+ if (isClipboardStub(window.navigator.clipboard)) {
115
+ window.navigator.clipboard[ClipboardStubControl].resetClipboardStub();
116
+ }
117
+ }
118
+ function detachClipboardStubFromView(window) {
119
+ if (isClipboardStub(window.navigator.clipboard)) {
120
+ window.navigator.clipboard[ClipboardStubControl].detachClipboardStub();
121
+ }
122
+ }
123
+ async function readDataTransferFromClipboard(document) {
124
+ const window = document.defaultView;
125
+ const clipboard = window === null || window === void 0 ? void 0 : window.navigator.clipboard;
126
+ const items = clipboard && await clipboard.read();
127
+ if (!items) {
128
+ throw new Error('The Clipboard API is unavailable.');
129
+ }
130
+ const dt = DataTransfer.createDataTransfer(window);
131
+ for (const item of items){
132
+ for (const type of item.types){
133
+ dt.setData(type, await item.getType(type).then((b)=>Blob.readBlobText(b, window.FileReader)));
134
+ }
135
+ }
136
+ return dt;
137
+ }
138
+ async function writeDataTransferToClipboard(document, clipboardData) {
139
+ const window = getWindow.getWindow(document);
140
+ const clipboard = window.navigator.clipboard;
141
+ const items = [];
142
+ for(let i = 0; i < clipboardData.items.length; i++){
143
+ const dtItem = clipboardData.items[i];
144
+ const blob = await DataTransfer.getBlobFromDataTransferItem(window, dtItem);
145
+ items.push(createClipboardItem(window, blob));
146
+ }
147
+ const written = clipboard && await clipboard.write(items).then(()=>true, // Can happen with other implementations that e.g. require permissions
148
+ /* istanbul ignore next */ ()=>false);
149
+ if (!written) {
150
+ throw new Error('The Clipboard API is unavailable.');
151
+ }
152
+ }
153
+ const g = globalThis;
154
+ /* istanbul ignore else */ if (typeof g.afterEach === 'function') {
155
+ g.afterEach(()=>{
156
+ if (typeof globalThis.window !== 'undefined') {
157
+ resetClipboardStubOnView(globalThis.window);
158
+ }
159
+ });
160
+ }
161
+ /* istanbul ignore else */ if (typeof g.afterAll === 'function') {
162
+ g.afterAll(()=>{
163
+ if (typeof globalThis.window !== 'undefined') {
164
+ detachClipboardStubFromView(globalThis.window);
165
+ }
166
+ });
167
+ }
168
+
169
+ exports.attachClipboardStubToView = attachClipboardStubToView;
170
+ exports.createClipboardItem = createClipboardItem;
171
+ exports.detachClipboardStubFromView = detachClipboardStubFromView;
172
+ exports.readDataTransferFromClipboard = readDataTransferFromClipboard;
173
+ exports.resetClipboardStubOnView = resetClipboardStubOnView;
174
+ exports.writeDataTransferToClipboard = writeDataTransferToClipboard;
@@ -0,0 +1,134 @@
1
+ 'use strict';
2
+
3
+ var FileList = require('./FileList.js');
4
+
5
+ function _define_property(obj, key, value) {
6
+ if (key in obj) {
7
+ Object.defineProperty(obj, key, {
8
+ value: value,
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true
12
+ });
13
+ } else obj[key] = value;
14
+ return obj;
15
+ }
16
+ // DataTransfer is not implemented in jsdom.
17
+ // DataTransfer with FileList is being created by the browser on certain events.
18
+ class DataTransferItemStub {
19
+ getAsFile() {
20
+ return this.file;
21
+ }
22
+ getAsString(callback) {
23
+ if (typeof this.data === 'string') {
24
+ callback(this.data);
25
+ }
26
+ }
27
+ /* istanbul ignore next */ webkitGetAsEntry() {
28
+ throw new Error('not implemented');
29
+ }
30
+ constructor(dataOrFile, type){
31
+ _define_property(this, "kind", void 0);
32
+ _define_property(this, "type", void 0);
33
+ _define_property(this, "file", null);
34
+ _define_property(this, "data", undefined);
35
+ if (typeof dataOrFile === 'string') {
36
+ this.kind = 'string';
37
+ this.type = String(type);
38
+ this.data = dataOrFile;
39
+ } else {
40
+ this.kind = 'file';
41
+ this.type = dataOrFile.type;
42
+ this.file = dataOrFile;
43
+ }
44
+ }
45
+ }
46
+ class DataTransferItemListStub extends Array {
47
+ add(...args) {
48
+ const item = new DataTransferItemStub(args[0], args[1]);
49
+ this.push(item);
50
+ return item;
51
+ }
52
+ clear() {
53
+ this.splice(0, this.length);
54
+ }
55
+ remove(index) {
56
+ this.splice(index, 1);
57
+ }
58
+ }
59
+ function getTypeMatcher(type, exact) {
60
+ const [group, sub] = type.split('/');
61
+ const isGroup = !sub || sub === '*';
62
+ return (item)=>{
63
+ return exact ? item.type === (isGroup ? group : type) : isGroup ? item.type.startsWith(`${group}/`) : item.type === group;
64
+ };
65
+ }
66
+ function createDataTransferStub(window) {
67
+ return new class DataTransferStub {
68
+ getData(format) {
69
+ var _this_items_find;
70
+ const match = (_this_items_find = this.items.find(getTypeMatcher(format, true))) !== null && _this_items_find !== void 0 ? _this_items_find : this.items.find(getTypeMatcher(format, false));
71
+ let text = '';
72
+ match === null || match === void 0 ? void 0 : match.getAsString((t)=>{
73
+ text = t;
74
+ });
75
+ return text;
76
+ }
77
+ setData(format, data) {
78
+ const matchIndex = this.items.findIndex(getTypeMatcher(format, true));
79
+ const item = new DataTransferItemStub(data, format);
80
+ if (matchIndex >= 0) {
81
+ this.items.splice(matchIndex, 1, item);
82
+ } else {
83
+ this.items.push(item);
84
+ }
85
+ }
86
+ clearData(format) {
87
+ if (format) {
88
+ const matchIndex = this.items.findIndex(getTypeMatcher(format, true));
89
+ if (matchIndex >= 0) {
90
+ this.items.remove(matchIndex);
91
+ }
92
+ } else {
93
+ this.items.clear();
94
+ }
95
+ }
96
+ get types() {
97
+ const t = [];
98
+ if (this.files.length) {
99
+ t.push('Files');
100
+ }
101
+ this.items.forEach((i)=>t.push(i.type));
102
+ Object.freeze(t);
103
+ return t;
104
+ }
105
+ /* istanbul ignore next */ setDragImage() {}
106
+ constructor(){
107
+ _define_property(this, "dropEffect", 'none');
108
+ _define_property(this, "effectAllowed", 'uninitialized');
109
+ _define_property(this, "items", new DataTransferItemListStub());
110
+ _define_property(this, "files", FileList.createFileList(window, []));
111
+ }
112
+ }();
113
+ }
114
+ function createDataTransfer(window, files = []) {
115
+ // Use real DataTransfer if available
116
+ const dt = typeof window.DataTransfer === 'undefined' ? createDataTransferStub(window) : /* istanbul ignore next */ new window.DataTransfer();
117
+ Object.defineProperty(dt, 'files', {
118
+ get: ()=>FileList.createFileList(window, files)
119
+ });
120
+ return dt;
121
+ }
122
+ async function getBlobFromDataTransferItem(window, item) {
123
+ if (item.kind === 'file') {
124
+ return item.getAsFile();
125
+ }
126
+ return new window.Blob([
127
+ await new Promise((r)=>item.getAsString(r))
128
+ ], {
129
+ type: item.type
130
+ });
131
+ }
132
+
133
+ exports.createDataTransfer = createDataTransfer;
134
+ exports.getBlobFromDataTransferItem = getBlobFromDataTransferItem;
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ // FileList can not be created per constructor.
4
+ function createFileList(window, files) {
5
+ const list = {
6
+ ...files,
7
+ length: files.length,
8
+ item: (index)=>list[index],
9
+ [Symbol.iterator]: function* nextFile() {
10
+ for(let i = 0; i < list.length; i++){
11
+ yield list[i];
12
+ }
13
+ }
14
+ };
15
+ list.constructor = window.FileList;
16
+ // guard for environments without FileList
17
+ /* istanbul ignore else */ if (window.FileList) {
18
+ Object.setPrototypeOf(list, window.FileList.prototype);
19
+ }
20
+ Object.freeze(list);
21
+ return list;
22
+ }
23
+
24
+ exports.createFileList = createFileList;
@@ -0,0 +1,18 @@
1
+ 'use strict';
2
+
3
+ // jsdom is not supporting isContentEditable
4
+ function isContentEditable(element) {
5
+ return element.hasAttribute('contenteditable') && (element.getAttribute('contenteditable') == 'true' || element.getAttribute('contenteditable') == '');
6
+ }
7
+ /**
8
+ * If a node is a contenteditable or inside one, return that element.
9
+ */ function getContentEditable(node) {
10
+ const element = getElement(node);
11
+ return element && (element.closest('[contenteditable=""]') || element.closest('[contenteditable="true"]'));
12
+ }
13
+ function getElement(node) {
14
+ return node.nodeType === 1 ? node : node.parentElement;
15
+ }
16
+
17
+ exports.getContentEditable = getContentEditable;
18
+ exports.isContentEditable = isContentEditable;
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ var isElementType = require('../misc/isElementType.js');
4
+ var isContentEditable = require('./isContentEditable.js');
5
+
6
+ function isEditable(element) {
7
+ return isEditableInputOrTextArea(element) && !element.readOnly || isContentEditable.isContentEditable(element);
8
+ }
9
+ var editableInputTypes = /*#__PURE__*/ function(editableInputTypes) {
10
+ editableInputTypes["text"] = "text";
11
+ editableInputTypes["date"] = "date";
12
+ editableInputTypes["datetime-local"] = "datetime-local";
13
+ editableInputTypes["email"] = "email";
14
+ editableInputTypes["month"] = "month";
15
+ editableInputTypes["number"] = "number";
16
+ editableInputTypes["password"] = "password";
17
+ editableInputTypes["search"] = "search";
18
+ editableInputTypes["tel"] = "tel";
19
+ editableInputTypes["time"] = "time";
20
+ editableInputTypes["url"] = "url";
21
+ editableInputTypes["week"] = "week";
22
+ return editableInputTypes;
23
+ }(editableInputTypes || {});
24
+ function isEditableInputOrTextArea(element) {
25
+ return isElementType.isElementType(element, 'textarea') || isElementType.isElementType(element, 'input') && element.type in editableInputTypes;
26
+ }
27
+
28
+ exports.isEditable = isEditable;
29
+ exports.isEditableInputOrTextArea = isEditableInputOrTextArea;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var isElementType = require('../misc/isElementType.js');
4
+
5
+ var maxLengthSupportedTypes = /*#__PURE__*/ function(maxLengthSupportedTypes) {
6
+ maxLengthSupportedTypes["email"] = "email";
7
+ maxLengthSupportedTypes["password"] = "password";
8
+ maxLengthSupportedTypes["search"] = "search";
9
+ maxLengthSupportedTypes["telephone"] = "telephone";
10
+ maxLengthSupportedTypes["text"] = "text";
11
+ maxLengthSupportedTypes["url"] = "url";
12
+ return maxLengthSupportedTypes;
13
+ }(maxLengthSupportedTypes || {});
14
+ // can't use .maxLength property because of a jsdom bug:
15
+ // https://github.com/jsdom/jsdom/issues/2927
16
+ function getMaxLength(element) {
17
+ var _element_getAttribute;
18
+ const attr = (_element_getAttribute = element.getAttribute('maxlength')) !== null && _element_getAttribute !== void 0 ? _element_getAttribute : '';
19
+ return /^\d+$/.test(attr) && Number(attr) >= 0 ? Number(attr) : undefined;
20
+ }
21
+ function supportsMaxLength(element) {
22
+ return isElementType.isElementType(element, 'textarea') || isElementType.isElementType(element, 'input') && element.type in maxLengthSupportedTypes;
23
+ }
24
+
25
+ exports.getMaxLength = getMaxLength;
26
+ exports.supportsMaxLength = supportsMaxLength;