setup.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { patchFocus } from '../document/patchFocus.js';
  2. import { prepareDocument } from '../document/prepareDocument.js';
  3. import { dispatchEvent, dispatchUIEvent } from '../event/dispatchEvent.js';
  4. import { attachClipboardStubToView } from '../utils/dataTransfer/Clipboard.js';
  5. import { getWindow } from '../utils/misc/getWindow.js';
  6. import { getDocumentFromNode } from '../utils/misc/getDocumentFromNode.js';
  7. import { setLevelRef, ApiLevel } from '../utils/misc/level.js';
  8. import { wait } from '../utils/misc/wait.js';
  9. import { PointerEventsCheckLevel } from '../options.js';
  10. import '@testing-library/dom';
  11. import { defaultKeyMap } from '../keyboard/keyMap.js';
  12. import { defaultKeyMap as defaultKeyMap$1 } from '../pointer/keyMap.js';
  13. import { System } from '../system/index.js';
  14. import { userEventApi } from './api.js';
  15. import { wrapAsync } from './wrapAsync.js';
  16. /**
  17. * Default options applied when API is called per `userEvent.anyApi()`
  18. */ const defaultOptionsDirect = {
  19. applyAccept: true,
  20. autoModify: true,
  21. delay: 0,
  22. document: globalThis.document,
  23. keyboardMap: defaultKeyMap,
  24. pointerMap: defaultKeyMap$1,
  25. pointerEventsCheck: PointerEventsCheckLevel.EachApiCall,
  26. skipAutoClose: false,
  27. skipClick: false,
  28. skipHover: false,
  29. writeToClipboard: false,
  30. advanceTimers: ()=>Promise.resolve()
  31. };
  32. /**
  33. * Default options applied when API is called per `userEvent().anyApi()`
  34. */ const defaultOptionsSetup = {
  35. ...defaultOptionsDirect,
  36. writeToClipboard: true
  37. };
  38. function createConfig(options = {}, defaults = defaultOptionsSetup, node) {
  39. const document = getDocument(options, node, defaults);
  40. return {
  41. ...defaults,
  42. ...options,
  43. document
  44. };
  45. }
  46. /**
  47. * Start a "session" with userEvent.
  48. * All APIs returned by this function share an input device state and a default configuration.
  49. */ function setupMain(options = {}) {
  50. const config = createConfig(options);
  51. prepareDocument(config.document);
  52. patchFocus(getWindow(config.document).HTMLElement);
  53. var _config_document_defaultView;
  54. const view = (_config_document_defaultView = config.document.defaultView) !== null && _config_document_defaultView !== undefined ? _config_document_defaultView : /* istanbul ignore next */ globalThis.window;
  55. attachClipboardStubToView(view);
  56. return createInstance(config).api;
  57. }
  58. /**
  59. * Setup in direct call per `userEvent.anyApi()`
  60. */ function setupDirect({ keyboardState, pointerState, ...options } = {}, node) {
  61. const config = createConfig(options, defaultOptionsDirect, node);
  62. prepareDocument(config.document);
  63. patchFocus(getWindow(config.document).HTMLElement);
  64. var _ref;
  65. const system = (_ref = pointerState !== null && pointerState !== undefined ? pointerState : keyboardState) !== null && _ref !== undefined ? _ref : new System();
  66. return {
  67. api: createInstance(config, system).api,
  68. system
  69. };
  70. }
  71. /**
  72. * Create a set of callbacks with different default settings but the same state.
  73. */ function setupSub(options) {
  74. return createInstance({
  75. ...this.config,
  76. ...options
  77. }, this.system).api;
  78. }
  79. function wrapAndBindImpl(instance, impl) {
  80. function method(...args) {
  81. setLevelRef(instance, ApiLevel.Call);
  82. return wrapAsync(()=>impl.apply(instance, args).then(async (ret)=>{
  83. await wait(instance.config);
  84. return ret;
  85. }));
  86. }
  87. Object.defineProperty(method, 'name', {
  88. get: ()=>impl.name
  89. });
  90. return method;
  91. }
  92. function createInstance(config, system = new System()) {
  93. const instance = {};
  94. Object.assign(instance, {
  95. config,
  96. dispatchEvent: dispatchEvent.bind(instance),
  97. dispatchUIEvent: dispatchUIEvent.bind(instance),
  98. system,
  99. levelRefs: {},
  100. ...userEventApi
  101. });
  102. return {
  103. instance,
  104. api: {
  105. ...Object.fromEntries(Object.entries(userEventApi).map(([name, api])=>[
  106. name,
  107. wrapAndBindImpl(instance, api)
  108. ])),
  109. setup: setupSub.bind(instance)
  110. }
  111. };
  112. }
  113. function getDocument(options, node, defaults) {
  114. var _options_document, _ref;
  115. return (_ref = (_options_document = options.document) !== null && _options_document !== undefined ? _options_document : node && getDocumentFromNode(node)) !== null && _ref !== undefined ? _ref : defaults.document;
  116. }
  117. export { createConfig, createInstance, setupDirect, setupMain, setupSub };