helpers.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.getWindowFromNode = getWindowFromNode;
  6. exports.getDocument = getDocument;
  7. exports.runWithRealTimers = runWithRealTimers;
  8. exports.checkContainerType = checkContainerType;
  9. exports.jestFakeTimersAreEnabled = jestFakeTimersAreEnabled;
  10. exports.TEXT_NODE = exports.setTimeout = exports.setImmediate = exports.clearTimeout = void 0;
  11. const globalObj = typeof window === 'undefined' ? global : window; // Constant node.nodeType for text nodes, see:
  12. // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType#Node_type_constants
  13. const TEXT_NODE = 3; // Currently this fn only supports jest timers, but it could support other test runners in the future.
  14. exports.TEXT_NODE = TEXT_NODE;
  15. function runWithRealTimers(callback) {
  16. return hasJestTimers() ? runWithJestRealTimers(callback).callbackReturnValue : // istanbul ignore next
  17. callback();
  18. }
  19. function hasJestTimers() {
  20. return typeof jest !== 'undefined' && jest !== null && typeof jest.useRealTimers === 'function';
  21. }
  22. function runWithJestRealTimers(callback) {
  23. const timerAPI = {
  24. clearInterval,
  25. clearTimeout,
  26. setInterval,
  27. setTimeout
  28. }; // For more on why we have the check here,
  29. // checkout https://github.com/testing-library/dom-testing-library/issues/914
  30. if (typeof setImmediate === 'function') {
  31. timerAPI.setImmediate = setImmediate;
  32. }
  33. if (typeof clearImmediate === 'function') {
  34. timerAPI.clearImmediate = clearImmediate;
  35. }
  36. jest.useRealTimers();
  37. const callbackReturnValue = callback();
  38. const usedFakeTimers = Object.entries(timerAPI).some(([name, func]) => func !== globalObj[name]);
  39. if (usedFakeTimers) {
  40. var _timerAPI$setTimeout;
  41. jest.useFakeTimers((_timerAPI$setTimeout = timerAPI.setTimeout) != null && _timerAPI$setTimeout.clock ? 'modern' : 'legacy');
  42. }
  43. return {
  44. callbackReturnValue,
  45. usedFakeTimers
  46. };
  47. }
  48. function jestFakeTimersAreEnabled() {
  49. return hasJestTimers() ? runWithJestRealTimers(() => {}).usedFakeTimers : // istanbul ignore next
  50. false;
  51. } // we only run our tests in node, and setImmediate is supported in node.
  52. // istanbul ignore next
  53. function setImmediatePolyfill(fn) {
  54. return globalObj.setTimeout(fn, 0);
  55. }
  56. function getTimeFunctions() {
  57. // istanbul ignore next
  58. return {
  59. clearTimeoutFn: globalObj.clearTimeout,
  60. setImmediateFn: globalObj.setImmediate || setImmediatePolyfill,
  61. setTimeoutFn: globalObj.setTimeout
  62. };
  63. }
  64. const {
  65. clearTimeoutFn,
  66. setImmediateFn,
  67. setTimeoutFn
  68. } = runWithRealTimers(getTimeFunctions);
  69. exports.setTimeout = setTimeoutFn;
  70. exports.setImmediate = setImmediateFn;
  71. exports.clearTimeout = clearTimeoutFn;
  72. function getDocument() {
  73. /* istanbul ignore if */
  74. if (typeof window === 'undefined') {
  75. throw new Error('Could not find default container');
  76. }
  77. return window.document;
  78. }
  79. function getWindowFromNode(node) {
  80. if (node.defaultView) {
  81. // node is document
  82. return node.defaultView;
  83. } else if (node.ownerDocument && node.ownerDocument.defaultView) {
  84. // node is a DOM node
  85. return node.ownerDocument.defaultView;
  86. } else if (node.window) {
  87. // node is window
  88. return node.window;
  89. } else if (node.then instanceof Function) {
  90. throw new Error(`It looks like you passed a Promise object instead of a DOM node. Did you do something like \`fireEvent.click(screen.findBy...\` when you meant to use a \`getBy\` query \`fireEvent.click(screen.getBy...\`, or await the findBy query \`fireEvent.click(await screen.findBy...\`?`);
  91. } else if (Array.isArray(node)) {
  92. throw new Error(`It looks like you passed an Array instead of a DOM node. Did you do something like \`fireEvent.click(screen.getAllBy...\` when you meant to use a \`getBy\` query \`fireEvent.click(screen.getBy...\`?`);
  93. } else if (typeof node.debug === 'function' && typeof node.logTestingPlaygroundURL === 'function') {
  94. throw new Error(`It looks like you passed a \`screen\` object. Did you do something like \`fireEvent.click(screen, ...\` when you meant to use a query, e.g. \`fireEvent.click(screen.getBy..., \`?`);
  95. } else {
  96. // The user passed something unusual to a calling function
  97. throw new Error(`Unable to find the "window" object for the given node. Please file an issue with the code that's causing you to see this error: https://github.com/testing-library/dom-testing-library/issues/new`);
  98. }
  99. }
  100. function checkContainerType(container) {
  101. if (!container || !(typeof container.querySelector === 'function') || !(typeof container.querySelectorAll === 'function')) {
  102. throw new TypeError(`Expected container to be an Element, a Document or a DocumentFragment but got ${getTypeName(container)}.`);
  103. }
  104. function getTypeName(object) {
  105. if (typeof object === 'object') {
  106. return object === null ? 'null' : object.constructor.name;
  107. }
  108. return typeof object;
  109. }
  110. }