text: 'use strict';
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
  
  var _extends = _interopDefault(require('@babel/runtime/helpers/extends'));
  var prettyFormat = _interopDefault(require('pretty-format'));
  var domAccessibilityApi = require('dom-accessibility-api');
  var ariaQuery = require('aria-query');
  var _regeneratorRuntime = _interopDefault(require('@babel/runtime/regenerator'));
  var _asyncToGenerator = _interopDefault(require('@babel/runtime/helpers/asyncToGenerator'));
  var _objectWithoutPropertiesLoose = _interopDefault(require('@babel/runtime/helpers/objectWithoutPropertiesLoose'));
  
  var globalObj = typeof window === 'undefined' ? global : window; // Currently this fn only supports jest timers, but it could support other test runners in the future.
  
  function runWithRealTimers(callback) {
    var fakeTimersType = getJestFakeTimersType();
  
    if (fakeTimersType) {
      jest.useRealTimers();
    }
  
    var callbackReturnValue = callback();
  
    if (fakeTimersType) {
      jest.useFakeTimers(fakeTimersType);
    }
  
    return callbackReturnValue;
  }
  
  function getJestFakeTimersType() {
    // istanbul ignore if
    if (typeof jest === 'undefined' || typeof globalObj.setTimeout === 'undefined') {
      return null;
    }
  
    if (typeof globalObj.setTimeout._isMockFunction !== 'undefined' && globalObj.setTimeout._isMockFunction) {
      return 'legacy';
    }
  
    if (typeof globalObj.setTimeout.clock !== 'undefined' && typeof jest.getRealSystemTime !== 'undefined') {
      try {
        // jest.getRealSystemTime is only supported for Jest's `modern` fake timers and otherwise throws
        jest.getRealSystemTime();
        return 'modern';
      } catch (_unused) {// not using Jest's modern fake timers
      }
    }
  
    return null;
  }
  
  var jestFakeTimersAreEnabled = function () {
    return Boolean(getJestFakeTimersType());
  }; // we only run our tests in node, and setImmediate is supported in node.
  // istanbul ignore next
  
  
  function setImmediatePolyfill(fn) {
    return globalObj.setTimeout(fn, 0);
  }
  
  function getTimeFunctions() {
    // istanbul ignore next
    return {
      clearTimeoutFn: globalObj.clearTimeout,
      setImmediateFn: globalObj.setImmediate || setImmediatePolyfill,
      setTimeoutFn: globalObj.setTimeout
    };
  }
  
  var _runWithRealTimers = runWithRealTimers(getTimeFunctions),
      clearTimeoutFn = _runWithRealTimers.clearTimeoutFn,
      setImmediateFn = _runWithRealTimers.setImmediateFn,
      setTimeoutFn = _runWithRealTimers.setTimeoutFn;
  
  function getDocument() {
    /* istanbul ignore if */
    if (typeof window === 'undefined') {
      throw new Error('Could not find default container');
    }
  
    return window.document;
  }
  
  function getWindowFromNode(node) {
    if (node.defaultView) {
      // node is document
      return node.defaultView;
    } else if (node.ownerDocument && node.ownerDocument.defaultView) {
      // node is a DOM node
      return node.ownerDocument.defaultView;
    } else if (node.window) {
      // node is window
      return node.window;
    } else if (node.then instanceof Function) {
      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...`?");
    } else {
      // The user passed something unusual to a calling function
      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");
    }
  }
  
  function checkContainerType(container) {
    if (!container || !(typeof container.querySelector === 'function') || !(typeof container.querySelectorAll === 'function')) {
      throw new TypeError("Expected container to be an Element, a Document or a DocumentFragment but got " + getTypeName(container) + ".");
    }
  
    function getTypeName(object) {
      if (typeof object === 'object') {
        return object === null ? 'null' : object.constructor.name;
      }
  
      return typeof object;
    }
  }
  
  function inCypress(dom) {
    var window = dom.ownerDocument && dom.ownerDocument.defaultView || undefined;
    return typeof global !== 'undefined' && global.Cypress || typeof window !== 'undefined' && window.Cypress;
  }
  
  var inNode = function () {
    return typeof process !== 'undefined' && process.versions !== undefined && process.versions.node !== undefined;
  };
  
  var getMaxLength = function (dom) {
    return inCypress(dom) ? 0 : typeof process !== 'undefined' && process.env.DEBUG_PRINT_LIMIT || 7000;
  };
  
  var _prettyFormat$plugins = prettyFormat.plugins,
      DOMElement = _prettyFormat$plugins.DOMElement,
      DOMCollection = _prettyFormat$plugins.DOMCollection;
  
  function prettyDOM(dom, maxLength, options) {
    if (!dom) {
      dom = getDocument().body;
    }
  
    if (typeof maxLength !== 'number') {
      maxLength = getMaxLength(dom);
    }
  
    if (maxLength === 0) {
      return '';
    }
  
    if (dom.documentElement) {
      dom = dom.documentElement;
    }
  
    var domTypeName = typeof dom;
  
    if (domTypeName === 'object') {
      domTypeName = dom.constructor.name;
    } else {
      // To don't fall with `in` operator
      dom = {};
    }
  
    if (!('outerHTML' in dom)) {
      throw new TypeError("Expected an element or document but got " + domTypeName);
    }
  
    var debugContent = prettyFormat(dom, _extends({
      plugins: [DOMElement, DOMCollection],
      printFunctionName: false,
      highlight: inNode()
    }, options));
    return maxLength !== undefined && dom.outerHTML.length > maxLength ? debugContent.slice(0, maxLength) + "..." : debugContent;
  }
  
  var logDOM = function () {
    return console.log(prettyDOM.apply(void 0, arguments));
  };
  
  // other parts of the code assume that all exports from
  // './queries' are query functions.
  
  var config = {
    testIdAttribute: 'data-testid',
    asyncUtilTimeout: 1000,
    // this is to support React's async `act` function.
    // forcing react-testing-library to wrap all async functions would've been
    // a total nightmare (consider wrapping every findBy* query and then also
    // updating `within` so those would be wrapped too. Total nightmare).
    // so we have this config option that's really only intended for
    // react-testing-library to use. For that reason, this feature will remain
    // undocumented.
    asyncWrapper: function asyncWrapper(cb) {
      return cb();
    },
    eventWrapper: function eventWrapper(cb) {
      return cb();
    },
    // default value for the `hidden` option in `ByRole` queries
    defaultHidden: false,
    // showOriginalStackTrace flag to show the full error stack traces for async errors
    showOriginalStackTrace: false,
    // throw errors w/ suggestions for better queries. Opt in so off by default.
    throwSuggestions: false,
    // called when getBy* queries fail. (message, container) => Error
    getElementError: function getElementError(message, container) {
      var error = new Error([message, prettyDOM(container)].filter(Boolean).join('\n\n'));
      error.name = 'TestingLibraryElementError';
      return error;
    },
    _disableExpensiveErrorDiagnostics: false,
    computedStyleSupportsPseudoElements: false
  };
  var DEFAULT_IGNORE_TAGS = 'script, style';
  function runWithExpensiveErrorDiagnosticsDisabled(callback) {
    try {
      config._disableExpensiveErrorDiagnostics = true;
      return callback();
    } finally {
      config._disableExpensiveErrorDiagnostics = false;
    }
  }
  function configure(newConfig) {
    if (typeof newConfig === 'function') {
      // Pass the existing config out to the provided function
      // and accept a delta in return
      newConfig = newConfig(config);
    } // Merge the incoming config delta
  
  
    config = _extends({}, config, newConfig);
  }
  function getConfig() {
    return config;
  }
  
  function assertNotNullOrUndefined(matcher) {
    if (matcher == null) {
      throw new Error("It looks like " + matcher + " was passed instead of a matcher. Did you do something like getByText(" + matcher + ")?");
    }
  }
  
  function fuzzyMatches(textToMatch, node, matcher, normalizer) {
    if (typeof textToMatch !== 'string') {
      return false;
    }
  
    assertNotNullOrUndefined(matcher);
    var normalizedText = normalizer(textToMatch);
  
    if (typeof matcher === 'string') {
      return normalizedText.toLowerCase().includes(matcher.toLowerCase());
    } else if (typeof matcher === 'function') {
      return matcher(normalizedText, node);
    } else {
      return matcher.test(normalizedText);
    }
  }
  
  function matches(textToMatch, node, matcher, normalizer) {
    if (typeof textToMatch !== 'string') {
      return false;
    }
  
    assertNotNullOrUndefined(matcher);
    var normalizedText = normalizer(textToMatch);
  
    if (typeof matcher === 'string') {
      return normalizedText === matcher;
    } else if (typeof matcher === 'function') {
      return matcher(normalizedText, node);
    } else {
      return matcher.test(normalizedText);
    }
  }
  
  function getDefaultNormalizer(_temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$trim = _ref.trim,
        trim = _ref$trim === void 0 ? true : _ref$trim,
        _ref$collapseWhitespa = _ref.collapseWhitespace,
        collapseWhitespace = _ref$collapseWhitespa === void 0 ? true : _ref$collapseWhitespa;
  
    return function (text) {
      var normalizedText = text;
      normalizedText = trim ? normalizedText.trim() : normalizedText;
      normalizedText = collapseWhitespace ? normalizedText.replace(/\s+/g, ' ') : normalizedText;
      return normalizedText;
    };
  }
  /**
   * Constructs a normalizer to pass to functions in matches.js
   * @param {boolean|undefined} trim The user-specified value for `trim`, without
   * any defaulting having been applied
   * @param {boolean|undefined} collapseWhitespace The user-specified value for
   * `collapseWhitespace`, without any defaulting having been applied
   * @param {Function|undefined} normalizer The user-specified normalizer
   * @returns {Function} A normalizer
   */
  
  
  function makeNormalizer(_ref2) {
    var trim = _ref2.trim,
        collapseWhitespace = _ref2.collapseWhitespace,
        normalizer = _ref2.normalizer;
  
    if (normalizer) {
      // User has specified a custom normalizer
      if (typeof trim !== 'undefined' || typeof collapseWhitespace !== 'undefined') {
        // They've also specified a value for trim or collapseWhitespace
        throw new Error('trim and collapseWhitespace are not supported with a normalizer. ' + 'If you want to use the default trim and collapseWhitespace logic in your normalizer, ' + 'use "getDefaultNormalizer({trim, collapseWhitespace})" and compose that into your normalizer');
      }
  
      return normalizer;
    } else {
      // No custom normalizer specified. Just use default.
      return getDefaultNormalizer({
        trim: trim,
        collapseWhitespace: collapseWhitespace
      });
    }
  }
  
  // Constant node.nodeType for text nodes, see:
  // https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType#Node_type_constants
  var TEXT_NODE = 3;
  
  function getNodeText(node) {
    if (node.matches('input[type=submit], input[type=button]')) {
      return node.value;
    }
  
    return Array.from(node.childNodes).filter(function (child) {
      return child.nodeType === TEXT_NODE && Boolean(child.textContent);
    }).map(function (c) {
      return c.textContent;
    }).join('');
  }
  
  function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } it = o[Symbol.iterator](); return it.next.bind(it); }
  
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
  
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
  var elementRoleList = buildElementRoleList(ariaQuery.elementRoles);
  /**
   * @param {Element} element -
   * @returns {boolean} - `true` if `element` and its subtree are inaccessible
   */
  
  function isSubtreeInaccessible(element) {
    if (element.hidden === true) {
      return true;
    }
  
    if (element.getAttribute('aria-hidden') === 'true') {
      return true;
    }
  
    var window = element.ownerDocument.defaultView;
  
    if (window.getComputedStyle(element).display === 'none') {
      return true;
    }
  
    return false;
  }
  /**
   * Partial implementation https://www.w3.org/TR/wai-aria-1.2/#tree_exclusion
   * which should only be used for elements with a non-presentational role i.e.
   * `role="none"` and `role="presentation"` will not be excluded.
   *
   * Implements aria-hidden semantics (i.e. parent overrides child)
   * Ignores "Child Presentational: True" characteristics
   *
   * @param {Element} element -
   * @param {object} [options] -
   * @param {function (element: Element): boolean} options.isSubtreeInaccessible -
   * can be used to return cached results from previous isSubtreeInaccessible calls
   * @returns {boolean} true if excluded, otherwise false
   */
  
  
  function isInaccessible(element, options) {
    if (options === void 0) {
      options = {};
    }
  
    var _options = options,
        _options$isSubtreeIna = _options.isSubtreeInaccessible,
        isSubtreeInaccessibleImpl = _options$isSubtreeIna === void 0 ? isSubtreeInaccessible : _options$isSubtreeIna;
    var window = element.ownerDocument.defaultView; // since visibility is inherited we can exit early
  
    if (window.getComputedStyle(element).visibility === 'hidden') {
      return true;
    }
  
    var currentElement = element;
  
    while (currentElement) {
      if (isSubtreeInaccessibleImpl(currentElement)) {
        return true;
      }
  
      currentElement = currentElement.parentElement;
    }
  
    return false;
  }
  
  function getImplicitAriaRoles(currentNode) {
    // eslint bug here:
    // eslint-disable-next-line no-unused-vars
    for (var _iterator = _createForOfIteratorHelperLoose(elementRoleList), _step; !(_step = _iterator()).done;) {
      var _step$value = _step.value,
          selector = _step$value.selector,
          roles = _step$value.roles;
  
      if (currentNode.matches(selector)) {
        return [].concat(roles);
      }
    }
  
    return [];
  }
  
  function buildElementRoleList(elementRolesMap) {
    function makeElementSelector(_ref) {
      var name = _ref.name,
          _ref$attributes = _ref.attributes,
          attributes = _ref$attributes === void 0 ? [] : _ref$attributes;
      return "" + name + attributes.map(function (_ref2) {
        var attributeName = _ref2.name,
            value = _ref2.value,
            _ref2$constraints = _ref2.constraints,
            constraints = _ref2$constraints === void 0 ? [] : _ref2$constraints;
        var shouldNotExist = constraints.indexOf('undefined') !== -1;
  
        if (shouldNotExist) {
          return ":not([" + attributeName + "])";
        } else if (value) {
          return "[" + attributeName + "=\"" + value + "\"]";
        } else {
          return "[" + attributeName + "]";
        }
      }).join('');
    }
  
    function getSelectorSpecificity(_ref3) {
      var _ref3$attributes = _ref3.attributes,
          attributes = _ref3$attributes === void 0 ? [] : _ref3$attributes;
      return attributes.length;
    }
  
    var result = []; // eslint bug here:
    // eslint-disable-next-line no-unused-vars
  
    for (var _iterator2 = _createForOfIteratorHelperLoose(elementRolesMap.entries()), _step2; !(_step2 = _iterator2()).done;) {
      var _step2$value = _step2.value,
          element = _step2$value[0],
          roles = _step2$value[1];
      result = [].concat(result, [{
        selector: makeElementSelector(element),
        roles: Array.from(roles),
        specificity: getSelectorSpecificity(element)
      }]);
    }
  
    return result.sort(function (_ref4, _ref5) {
      var leftSpecificity = _ref4.specificity;
      var rightSpecificity = _ref5.specificity;
      return rightSpecificity - leftSpecificity;
    });
  }
  
  function getRoles(container, _temp) {
    var _ref6 = _temp === void 0 ? {} : _temp,
        _ref6$hidden = _ref6.hidden,
        hidden = _ref6$hidden === void 0 ? false : _ref6$hidden;
  
    function flattenDOM(node) {
      return [node].concat(Array.from(node.children).reduce(function (acc, child) {
        return [].concat(acc, flattenDOM(child));
      }, []));
    }
  
    return flattenDOM(container).filter(function (element) {
      return hidden === false ? isInaccessible(element) === false : true;
    }).reduce(function (acc, node) {
      var roles = []; // TODO: This violates html-aria which does not allow any role on every element
  
      if (node.hasAttribute('role')) {
        roles = node.getAttribute('role').split(' ').slice(0, 1);
      } else {
        roles = getImplicitAriaRoles(node);
      }
  
      return roles.reduce(function (rolesAcc, role) {
        var _extends2, _extends3;
  
        return Array.isArray(rolesAcc[role]) ? _extends({}, rolesAcc, (_extends2 = {}, _extends2[role] = [].concat(rolesAcc[role], [node]), _extends2)) : _extends({}, rolesAcc, (_extends3 = {}, _extends3[role] = [node], _extends3));
      }, acc);
    }, {});
  }
  
  function prettyRoles(dom, _ref7) {
    var hidden = _ref7.hidden;
    var roles = getRoles(dom, {
      hidden: hidden
    }); // We prefer to skip generic role, we don't recommend it
  
    return Object.entries(roles).filter(function (_ref8) {
      var role = _ref8[0];
      return role !== 'generic';
    }).map(function (_ref9) {
      var role = _ref9[0],
          elements = _ref9[1];
      var delimiterBar = '-'.repeat(50);
      var elementsString = elements.map(function (el) {
        var nameString = "Name \"" + domAccessibilityApi.computeAccessibleName(el, {
          computedStyleSupportsPseudoElements: getConfig().computedStyleSupportsPseudoElements
        }) + "\":\n";
        var domString = prettyDOM(el.cloneNode(false));
        return "" + nameString + domString;
      }).join('\n\n');
      return role + ":\n\n" + elementsString + "\n\n" + delimiterBar;
    }).join('\n');
  }
  
  var logRoles = function (dom, _temp2) {
    var _ref10 = _temp2 === void 0 ? {} : _temp2,
        _ref10$hidden = _ref10.hidden,
        hidden = _ref10$hidden === void 0 ? false : _ref10$hidden;
  
    return console.log(prettyRoles(dom, {
      hidden: hidden
    }));
  };
  /**
   * @param {Element} element -
   * @returns {boolean | undefined} - false/true if (not)selected, undefined if not selectable
   */
  
  
  function computeAriaSelected(element) {
    // implicit value from html-aam mappings: https://www.w3.org/TR/html-aam-1.0/#html-attribute-state-and-property-mappings
    // https://www.w3.org/TR/html-aam-1.0/#details-id-97
    if (element.tagName === 'OPTION') {
      return element.selected;
    } // explicit value
  
  
    return checkBooleanAttribute(element, 'aria-selected');
  }
  /**
   * @param {Element} element -
   * @returns {boolean | undefined} - false/true if (not)checked, undefined if not checked-able
   */
  
  
  function computeAriaChecked(element) {
    // implicit value from html-aam mappings: https://www.w3.org/TR/html-aam-1.0/#html-attribute-state-and-property-mappings
    // https://www.w3.org/TR/html-aam-1.0/#details-id-56
    // https://www.w3.org/TR/html-aam-1.0/#details-id-67
    if ('indeterminate' in element && element.indeterminate) {
      return undefined;
    }
  
    if ('checked' in element) {
      return element.checked;
    } // explicit value
  
  
    return checkBooleanAttribute(element, 'aria-checked');
  }
  /**
   * @param {Element} element -
   * @returns {boolean | undefined} - false/true if (not)pressed, undefined if not press-able
   */
  
  
  function computeAriaPressed(element) {
    // https://www.w3.org/TR/wai-aria-1.1/#aria-pressed
    return checkBooleanAttribute(element, 'aria-pressed');
  }
  
  function checkBooleanAttribute(element, attribute) {
    var attributeValue = element.getAttribute(attribute);
  
    if (attributeValue === 'true') {
      return true;
    }
  
    if (attributeValue === 'false') {
      return false;
    }
  
    return undefined;
  }
  /**
   * @param {Element} element -
   * @returns {number | undefined} - number if implicit heading or aria-level present, otherwise undefined
   */
  
  
  function computeHeadingLevel(element) {
    // https://w3c.github.io/html-aam/#el-h1-h6
    // https://w3c.github.io/html-aam/#el-h1-h6
    // explicit aria-level value
    // https://www.w3.org/TR/wai-aria-1.2/#aria-level
    var ariaLevelAttribute = element.getAttribute('aria-level') && Number(element.getAttribute('aria-level'));
    return ariaLevelAttribute || {
      H1: 1,
      H2: 2,
      H3: 3,
      H4: 4,
      H5: 5,
      H6: 6
    }[element.tagName];
  }
  
  var normalize = getDefaultNormalizer();
  
  function getLabelTextFor(element) {
    var label = element.labels && Array.from(element.labels).find(function (el) {
      return Boolean(normalize(el.textContent));
    }); // non form elements that are using aria-labelledby won't be included in `element.labels`
  
    if (!label) {
      var ariaLabelledBy = element.getAttribute('aria-labelledby');
  
      if (ariaLabelledBy) {
        // this is only a temporary fix. The problem is that at the moment @testing-library/dom
        // not support label concatenation
        // see https://github.com/testing-library/dom-testing-library/issues/545
        var firstId = ariaLabelledBy.split(' ')[0]; // we're using this notation because with the # selector we would have to escape special characters e.g. user.name
        // see https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector#Escaping_special_characters
  
        label = document.querySelector("[id=\"" + firstId + "\"]");
      }
    }
  
    if (label) {
      return label.textContent;
    }
  
    return undefined;
  }
  
  function escapeRegExp(string) {
    return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
  }
  
  function getRegExpMatcher(string) {
    return new RegExp(escapeRegExp(string.toLowerCase()), 'i');
  }
  
  function makeSuggestion(queryName, element, content, _ref) {
    var variant = _ref.variant,
        name = _ref.name;
    var warning = '';
    var queryOptions = {};
    var queryArgs = [queryName === 'Role' || queryName === 'TestId' ? content : getRegExpMatcher(content)];
  
    if (name) {
      queryOptions.name = getRegExpMatcher(name);
    }
  
    if (queryName === 'Role' && isInaccessible(element)) {
      queryOptions.hidden = true;
      warning = "Element is inaccessible. This means that the element and all its children are invisible to screen readers.\n    If you are using the aria-hidden prop, make sure this is the right choice for your case.\n    ";
      console.warn(warning);
    }
  
    if (Object.keys(queryOptions).length > 0) {
      queryArgs.push(queryOptions);
    }
  
    var queryMethod = variant + "By" + queryName;
    return {
      queryName: queryName,
      queryMethod: queryMethod,
      queryArgs: queryArgs,
      variant: variant,
      warning: warning,
      toString: function toString() {
        var text = queryArgs[0],
            options = queryArgs[1];
        text = typeof text === 'string' ? "'" + text + "'" : text;
        options = options ? ", { " + Object.entries(options).map(function (_ref2) {
          var k = _ref2[0],
              v = _ref2[1];
          return k + ": " + v;
        }).join(', ') + " }" : '';
        return queryMethod + "(" + text + options + ")";
      }
    };
  }
  
  function canSuggest(currentMethod, requestedMethod, data) {
    return data && (!requestedMethod || requestedMethod.toLowerCase() === currentMethod.toLowerCase());
  }
  
  function getSuggestedQuery(element, variant, method) {
    var _element$getAttribute, _getImplicitAriaRoles;
  
    if (variant === void 0) {
      variant = 'get';
    }
  
    // don't create suggestions for script and style elements
    if (element.matches(DEFAULT_IGNORE_TAGS)) {
      return undefined;
    } //We prefer to suggest something else if the role is generic
  
  
    var role = (_element$getAttribute = element.getAttribute('role')) != null ? _element$getAttribute : (_getImplicitAriaRoles = getImplicitAriaRoles(element)) == null ? void 0 : _getImplicitAriaRoles[0];
  
    if (role !== 'generic' && canSuggest('Role', method, role)) {
      return makeSuggestion('Role', element, role, {
        variant: variant,
        name: domAccessibilityApi.computeAccessibleName(element, {
          computedStyleSupportsPseudoElements: getConfig().computedStyleSupportsPseudoElements
        })
      });
    }
  
    var labelText = getLabelTextFor(element);
  
    if (canSuggest('LabelText', method, labelText)) {
      return makeSuggestion('LabelText', element, labelText, {
        variant: variant
      });
    }
  
    var placeholderText = element.getAttribute('placeholder');
  
    if (canSuggest('PlaceholderText', method, placeholderText)) {
      return makeSuggestion('PlaceholderText', element, placeholderText, {
        variant: variant
      });
    }
  
    var textContent = normalize(getNodeText(element));
  
    if (canSuggest('Text', method, textContent)) {
      return makeSuggestion('Text', element, textContent, {
        variant: variant
      });
    }
  
    if (canSuggest('DisplayValue', method, element.value)) {
      return makeSuggestion('DisplayValue', element, normalize(element.value), {
        variant: variant
      });
    }
  
    var alt = element.getAttribute('alt');
  
    if (canSuggest('AltText', method, alt)) {
      return makeSuggestion('AltText', element, alt, {
        variant: variant
      });
    }
  
    var title = element.getAttribute('title');
  
    if (canSuggest('Title', method, title)) {
      return makeSuggestion('Title', element, title, {
        variant: variant
      });
    }
  
    var testId = element.getAttribute(getConfig().testIdAttribute);
  
    if (canSuggest('TestId', method, testId)) {
      return makeSuggestion('TestId', element, testId, {
        variant: variant
      });
    }
  
    return undefined;
  }
  
  // closer to their code (because async stack traces are hard to follow).
  
  function copyStackTrace(target, source) {
    target.stack = source.stack.replace(source.message, target.message);
  }
  
  function waitFor(callback, _ref) {
    var _ref$container = _ref.container,
        container = _ref$container === void 0 ? getDocument() : _ref$container,
        _ref$timeout = _ref.timeout,
        timeout = _ref$timeout === void 0 ? getConfig().asyncUtilTimeout : _ref$timeout,
        _ref$showOriginalStac = _ref.showOriginalStackTrace,
        showOriginalStackTrace = _ref$showOriginalStac === void 0 ? getConfig().showOriginalStackTrace : _ref$showOriginalStac,
        stackTraceError = _ref.stackTraceError,
        _ref$interval = _ref.interval,
        interval = _ref$interval === void 0 ? 50 : _ref$interval,
        _ref$onTimeout = _ref.onTimeout,
        onTimeout = _ref$onTimeout === void 0 ? function (error) {
      error.message = error.message + "\n\n" + prettyDOM(container);
      return error;
    } : _ref$onTimeout,
        _ref$mutationObserver = _ref.mutationObserverOptions,
        mutationObserverOptions = _ref$mutationObserver === void 0 ? {
      subtree: true,
      childList: true,
      attributes: true,
      characterData: true
    } : _ref$mutationObserver;
  
    if (typeof callback !== 'function') {
      throw new TypeError('Received `callback` arg must be a function');
    }
  
    return new Promise( /*#__PURE__*/function () {
      var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(resolve, reject) {
        var lastError, intervalId, observer, finished, overallTimeoutTimer, usingFakeTimers, _getWindowFromNode, MutationObserver, onDone, checkCallback, handleTimeout;
  
        return _regeneratorRuntime.wrap(function (_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                handleTimeout = function () {
                  var error;
  
                  if (lastError) {
                    error = lastError;
  
                    if (!showOriginalStackTrace && error.name === 'TestingLibraryElementError') {
                      copyStackTrace(error, stackTraceError);
                    }
                  } else {
                    error = new Error('Timed out in waitFor.');
  
                    if (!showOriginalStackTrace) {
                      copyStackTrace(error, stackTraceError);
                    }
                  }
  
                  onDone(onTimeout(error), null);
                };
  
                checkCallback = function () {
                  try {
                    onDone(null, runWithExpensiveErrorDiagnosticsDisabled(callback)); // If `callback` throws, wait for the next mutation, interval, or timeout.
                  } catch (error) {
                    // Save the most recent callback error to reject the promise with it in the event of a timeout
                    lastError = error;
                  }
                };
  
                onDone = function (error, result) {
                  finished = true;
                  clearTimeoutFn(overallTimeoutTimer);
  
                  if (!usingFakeTimers) {
                    clearInterval(intervalId);
                    setImmediateFn(function () {
                      return observer.disconnect();
                    });
                  }
  
                  if (error) {
                    reject(error);
                  } else {
                    resolve(result);
                  }
                };
  
                finished = false;
                overallTimeoutTimer = setTimeoutFn(handleTimeout, timeout);
                usingFakeTimers = jestFakeTimersAreEnabled();
  
                if (!usingFakeTimers) {
                  _context.next = 17;
                  break;
                }
  
                checkCallback(); // this is a dangerous rule to disable because it could lead to an
                // infinite loop. However, eslint isn't smart enough to know that we're
                // setting finished inside `onDone` which will be called when we're done
                // waiting or when we've timed out.
                // eslint-disable-next-line no-unmodified-loop-condition
  
              case 8:
                if (finished) {
                  _context.next = 15;
                  break;
                }
  
                // we *could* (maybe should?) use `advanceTimersToNextTimer` but it's
                // possible that could make this loop go on forever if someone is using
                // third party code that's setting up recursive timers so rapidly that
                // the user's timer's don't get a chance to resolve. So we'll advance
                // by an interval instead. (We have a test for this case).
                jest.advanceTimersByTime(interval); // It's really important that checkCallback is run *before* we flush
                // in-flight promises. To be honest, I'm not sure why, and I can't quite
                // think of a way to reproduce the problem in a test, but I spent
                // an entire day banging my head against a wall on this.
  
                checkCallback(); // In this rare case, we *need* to wait for in-flight promises
                // to resolve before continuing. We don't need to take advantage
                // of parallelization so we're fine.
                // https://stackoverflow.com/a/59243586/971592
                // eslint-disable-next-line no-await-in-loop
  
                _context.next = 13;
                return new Promise(function (r) {
                  return setImmediateFn(r);
                });
  
              case 13:
                _context.next = 8;
                break;
  
              case 15:
                _context.next = 22;
                break;
  
              case 17:
                intervalId = setInterval(checkCallback, interval);
                _getWindowFromNode = getWindowFromNode(container), MutationObserver = _getWindowFromNode.MutationObserver;
                observer = new MutationObserver(checkCallback);
                observer.observe(container, mutationObserverOptions);
                checkCallback();
  
              case 22:
              case "end":
                return _context.stop();
            }
          }
        }, _callee);
      }));
  
      return function () {
        return _ref2.apply(this, arguments);
      };
    }());
  }
  
  function waitForWrapper(callback, options) {
    // create the error here so its stack trace is as close to the
    // calling code as possible
    var stackTraceError = new Error('STACK_TRACE_MESSAGE');
    return getConfig().asyncWrapper(function () {
      return waitFor(callback, _extends({
        stackTraceError: stackTraceError
      }, options));
    });
  }
  
  var hasWarned = false; // deprecated... TODO: remove this method. We renamed this to `waitFor` so the
  // code people write reads more clearly.
  
  function wait() {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
  
    // istanbul ignore next
    var _args$ = args[0],
        first = _args$ === void 0 ? function () {} : _args$,
        rest = args.slice(1);
  
    if (!hasWarned) {
      hasWarned = true;
      console.warn("`wait` has been deprecated and replaced by `waitFor` instead. In most cases you should be able to find/replace `wait` with `waitFor`. Learn more: https://testing-library.com/docs/dom-testing-library/api-async#waitfor.");
    }
  
    return waitForWrapper.apply(void 0, [first].concat(rest));
  }
  
  function getElementError(message, container) {
    return getConfig().getElementError(message, container);
  }
  
  function getMultipleElementsFoundError(message, container) {
    return getElementError(message + "\n\n(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)).", container);
  }
  
  function queryAllByAttribute(attribute, container, text, _temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$exact = _ref.exact,
        exact = _ref$exact === void 0 ? true : _ref$exact,
        collapseWhitespace = _ref.collapseWhitespace,
        trim = _ref.trim,
        normalizer = _ref.normalizer;
  
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
    return Array.from(container.querySelectorAll("[" + attribute + "]")).filter(function (node) {
      return matcher(node.getAttribute(attribute), node, text, matchNormalizer);
    });
  }
  
  function queryByAttribute(attribute, container, text) {
    for (var _len = arguments.length, args = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) {
      args[_key - 3] = arguments[_key];
    }
  
    var els = queryAllByAttribute.apply(void 0, [attribute, container, text].concat(args));
  
    if (els.length > 1) {
      throw getMultipleElementsFoundError("Found multiple elements by [" + attribute + "=" + text + "]", container);
    }
  
    return els[0] || null;
  } // this accepts a query function and returns a function which throws an error
  // if more than one elements is returned, otherwise it returns the first
  // element or null
  
  
  function makeSingleQuery(allQuery, getMultipleError) {
    return function (container) {
      for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
        args[_key2 - 1] = arguments[_key2];
      }
  
      var els = allQuery.apply(void 0, [container].concat(args));
  
      if (els.length > 1) {
        var elementStrings = els.map(function (element) {
          return prettyDOM(element);
        }).join('\n\n');
        throw getMultipleElementsFoundError(getMultipleError.apply(void 0, [container].concat(args)) + "\n\nHere are the matching elements:\n\n" + elementStrings, container);
      }
  
      return els[0] || null;
    };
  }
  
  function getSuggestionError(suggestion, container) {
    return getConfig().getElementError("A better query is available, try this:\n" + suggestion.toString() + "\n", container);
  } // this accepts a query function and returns a function which throws an error
  // if an empty list of elements is returned
  
  
  function makeGetAllQuery(allQuery, getMissingError) {
    return function (container) {
      for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
        args[_key3 - 1] = arguments[_key3];
      }
  
      var els = allQuery.apply(void 0, [container].concat(args));
  
      if (!els.length) {
        throw getConfig().getElementError(getMissingError.apply(void 0, [container].concat(args)), container);
      }
  
      return els;
    };
  } // this accepts a getter query function and returns a function which calls
  // waitFor and passing a function which invokes the getter.
  
  
  function makeFindQuery(getter) {
    return function (container, text, options, waitForOptions) {
      return waitForWrapper(function () {
        return getter(container, text, options);
      }, waitForOptions);
    };
  }
  
  var wrapSingleQueryWithSuggestion = function (query, queryAllByName, variant) {
    return function (container) {
      for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
        args[_key4 - 1] = arguments[_key4];
      }
  
      var element = query.apply(void 0, [container].concat(args));
  
      var _args$slice = args.slice(-1),
          _args$slice$ = _args$slice[0];
  
      _args$slice$ = _args$slice$ === void 0 ? {} : _args$slice$;
      var _args$slice$$suggest = _args$slice$.suggest,
          suggest = _args$slice$$suggest === void 0 ? getConfig().throwSuggestions : _args$slice$$suggest;
  
      if (element && suggest) {
        var suggestion = getSuggestedQuery(element, variant);
  
        if (suggestion && !queryAllByName.endsWith(suggestion.queryName)) {
          throw getSuggestionError(suggestion.toString(), container);
        }
      }
  
      return element;
    };
  };
  
  var wrapAllByQueryWithSuggestion = function (query, queryAllByName, variant) {
    return function (container) {
      for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
        args[_key5 - 1] = arguments[_key5];
      }
  
      var els = query.apply(void 0, [container].concat(args));
  
      var _args$slice2 = args.slice(-1),
          _args$slice2$ = _args$slice2[0];
  
      _args$slice2$ = _args$slice2$ === void 0 ? {} : _args$slice2$;
      var _args$slice2$$suggest = _args$slice2$.suggest,
          suggest = _args$slice2$$suggest === void 0 ? getConfig().throwSuggestions : _args$slice2$$suggest;
  
      if (els.length && suggest) {
        // get a unique list of all suggestion messages.  We are only going to make a suggestion if
        // all the suggestions are the same
        var uniqueSuggestionMessages = [].concat(new Set(els.map(function (element) {
          var _getSuggestedQuery;
  
          return (_getSuggestedQuery = getSuggestedQuery(element, variant)) == null ? void 0 : _getSuggestedQuery.toString();
        })));
  
        if ( // only want to suggest if all the els have the same suggestion.
        uniqueSuggestionMessages.length === 1 && !queryAllByName.endsWith(getSuggestedQuery(els[0], variant).queryName)) {
          throw getSuggestionError(uniqueSuggestionMessages[0], container);
        }
      }
  
      return els;
    };
  };
  
  function buildQueries(queryAllBy, getMultipleError, getMissingError) {
    var queryBy = wrapSingleQueryWithSuggestion(makeSingleQuery(queryAllBy, getMultipleError), queryAllBy.name, 'query');
    var getAllBy = makeGetAllQuery(queryAllBy, getMissingError);
    var getBy = makeSingleQuery(getAllBy, getMultipleError);
    var getByWithSuggestions = wrapSingleQueryWithSuggestion(getBy, queryAllBy.name, 'get');
    var getAllWithSuggestions = wrapAllByQueryWithSuggestion(getAllBy, queryAllBy.name.replace('query', 'get'), 'getAll');
    var findAllBy = makeFindQuery(wrapAllByQueryWithSuggestion(getAllBy, queryAllBy.name, 'findAll'));
    var findBy = makeFindQuery(wrapSingleQueryWithSuggestion(getBy, queryAllBy.name, 'find'));
    return [queryBy, getAllWithSuggestions, getByWithSuggestions, findAllBy, findBy];
  }
  
  var queryHelpers = /*#__PURE__*/Object.freeze({
    __proto__: null,
    getElementError: getElementError,
    wrapAllByQueryWithSuggestion: wrapAllByQueryWithSuggestion,
    wrapSingleQueryWithSuggestion: wrapSingleQueryWithSuggestion,
    getMultipleElementsFoundError: getMultipleElementsFoundError,
    queryAllByAttribute: queryAllByAttribute,
    queryByAttribute: queryByAttribute,
    makeSingleQuery: makeSingleQuery,
    makeGetAllQuery: makeGetAllQuery,
    makeFindQuery: makeFindQuery,
    buildQueries: buildQueries
  });
  
  function queryAllLabels(container) {
    return Array.from(container.querySelectorAll('label,input')).map(function (node) {
      var textToMatch = node.tagName.toLowerCase() === 'label' ? node.textContent : node.value || null; // The children of a textarea are part of `textContent` as well. We
      // need to remove them from the string so we can match it afterwards.
  
      Array.from(node.querySelectorAll('textarea')).forEach(function (textarea) {
        textToMatch = textToMatch.replace(textarea.value, '');
      }); // The children of a select are also part of `textContent`, so we
      // need also to remove their text.
  
      Array.from(node.querySelectorAll('select')).forEach(function (select) {
        textToMatch = textToMatch.replace(select.textContent, '');
      });
      return {
        node: node,
        textToMatch: textToMatch
      };
    }).filter(function (_ref) {
      var textToMatch = _ref.textToMatch;
      return textToMatch !== null;
    });
  }
  
  function queryAllLabelsByText(container, text, _temp) {
    var _ref2 = _temp === void 0 ? {} : _temp,
        _ref2$exact = _ref2.exact,
        exact = _ref2$exact === void 0 ? true : _ref2$exact,
        trim = _ref2.trim,
        collapseWhitespace = _ref2.collapseWhitespace,
        normalizer = _ref2.normalizer;
  
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
    var textToMatchByLabels = queryAllLabels(container);
    return textToMatchByLabels.filter(function (_ref3) {
      var node = _ref3.node,
          textToMatch = _ref3.textToMatch;
      return matcher(textToMatch, node, text, matchNormalizer);
    }).map(function (_ref4) {
      var node = _ref4.node;
      return node;
    });
  }
  
  function getLabelContent(label) {
    var labelContent = label.getAttribute('value') || label.textContent;
    Array.from(label.querySelectorAll('textarea')).forEach(function (textarea) {
      labelContent = labelContent.replace(textarea.value, '');
    });
    Array.from(label.querySelectorAll('select')).forEach(function (select) {
      labelContent = labelContent.replace(select.textContent, '');
    });
    return labelContent;
  }
  
  function queryAllByLabelText(container, text, _temp2) {
    var _ref5 = _temp2 === void 0 ? {} : _temp2,
        _ref5$selector = _ref5.selector,
        selector = _ref5$selector === void 0 ? '*' : _ref5$selector,
        _ref5$exact = _ref5.exact,
        exact = _ref5$exact === void 0 ? true : _ref5$exact,
        collapseWhitespace = _ref5.collapseWhitespace,
        trim = _ref5.trim,
        normalizer = _ref5.normalizer;
  
    checkContainerType(container);
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
    var matchingLabelledElements = Array.from(container.querySelectorAll('*')).filter(function (element) {
      return getLabels(element) || element.hasAttribute('aria-labelledby');
    }).reduce(function (labelledElements, labelledElement) {
      var labelsId = labelledElement.getAttribute('aria-labelledby') ? labelledElement.getAttribute('aria-labelledby').split(' ') : [];
      var labelsValue = labelsId.length ? labelsId.map(function (labelId) {
        var labellingElement = container.querySelector("[id=\"" + labelId + "\"]");
        return labellingElement ? getLabelContent(labellingElement) : '';
      }) : Array.from(getLabels(labelledElement)).map(function (label) {
        var textToMatch = getLabelContent(label);
        var labelledFormControl = Array.from(label.querySelectorAll('button, input, meter, output, progress, select, textarea')).filter(function (element) {
          return element.matches(selector);
        })[0];
  
        if (labelledFormControl) {
          if (matcher(textToMatch, labelledFormControl, text, matchNormalizer)) labelledElements.push(labelledFormControl);
        }
  
        return textToMatch;
      });
      labelsValue = labelsValue.filter(Boolean);
      if (matcher(labelsValue.join(' '), labelledElement, text, matchNormalizer)) labelledElements.push(labelledElement);
  
      if (labelsValue.length > 1) {
        labelsValue.forEach(function (labelValue, index) {
          if (matcher(labelValue, labelledElement, text, matchNormalizer)) labelledElements.push(labelledElement);
          var labelsFiltered = [].concat(labelsValue);
          labelsFiltered.splice(index, 1);
  
          if (labelsFiltered.length > 1) {
            if (matcher(labelsFiltered.join(' '), labelledElement, text, matchNormalizer)) labelledElements.push(labelledElement);
          }
        });
      }
  
      return labelledElements;
    }, []).concat(queryAllByAttribute('aria-label', container, text, {
      exact: exact
    }));
    return Array.from(new Set(matchingLabelledElements)).filter(function (element) {
      return element.matches(selector);
    });
  } // the getAll* query would normally look like this:
  // const getAllByLabelText = makeGetAllQuery(
  //   queryAllByLabelText,
  //   (c, text) => `Unable to find a label with the text of: ${text}`,
  // )
  // however, we can give a more helpful error message than the generic one,
  // so we're writing this one out by hand.
  
  
  var getAllByLabelText = function (container, text) {
    for (var _len = arguments.length, rest = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
      rest[_key - 2] = arguments[_key];
    }
  
    var els = queryAllByLabelText.apply(void 0, [container, text].concat(rest));
  
    if (!els.length) {
      var labels = queryAllLabelsByText.apply(void 0, [container, text].concat(rest));
  
      if (labels.length) {
        var tagNames = labels.map(function (label) {
          return getTagNameOfElementAssociatedWithLabelViaFor(container, label);
        }).filter(function (tagName) {
          return !!tagName;
        });
  
        if (tagNames.length) {
          throw getConfig().getElementError(tagNames.map(function (tagName) {
            return "Found a label with the text of: " + text + ", however the element associated with this label (<" + tagName + " />) is non-labellable [https://html.spec.whatwg.org/multipage/forms.html#category-label]. If you really need to label a <" + tagName + " />, you can use aria-label or aria-labelledby instead.";
          }).join('\n\n'), container);
        } else {
          throw getConfig().getElementError("Found a label with the text of: " + text + ", however no form control was found associated to that label. Make sure you're using the \"for\" attribute or \"aria-labelledby\" attribute correctly.", container);
        }
      } else {
        throw getConfig().getElementError("Unable to find a label with the text of: " + text, container);
      }
    }
  
    return els;
  };
  
  function getTagNameOfElementAssociatedWithLabelViaFor(container, label) {
    var htmlFor = label.getAttribute('for');
  
    if (!htmlFor) {
      return null;
    }
  
    var element = container.querySelector("[id=\"" + htmlFor + "\"]");
    return element ? element.tagName.toLowerCase() : null;
  } // the reason mentioned above is the same reason we're not using buildQueries
  
  
  var getMultipleError = function (c, text) {
    return "Found multiple elements with the text of: " + text;
  };
  
  var queryByLabelText = wrapSingleQueryWithSuggestion(makeSingleQuery(queryAllByLabelText, getMultipleError), queryAllByLabelText.name, 'query');
  var getByLabelText = makeSingleQuery(getAllByLabelText, getMultipleError);
  var findAllByLabelText = makeFindQuery(wrapAllByQueryWithSuggestion(getAllByLabelText, getAllByLabelText.name, 'findAll'));
  var findByLabelText = makeFindQuery(wrapSingleQueryWithSuggestion(getByLabelText, getByLabelText.name, 'find'));
  var getAllByLabelTextWithSuggestions = wrapAllByQueryWithSuggestion(getAllByLabelText, getAllByLabelText.name, 'getAll');
  var getByLabelTextWithSuggestions = wrapSingleQueryWithSuggestion(getByLabelText, getAllByLabelText.name, 'get');
  var queryAllByLabelTextWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByLabelText, queryAllByLabelText.name, 'queryAll');
  
  function getLabels(element) {
    if (element.labels !== undefined) return element.labels;
    if (!isLabelable(element)) return null;
    var labels = element.ownerDocument.querySelectorAll('label');
    return Array.from(labels).filter(function (label) {
      return label.control === element;
    });
  }
  
  function isLabelable(element) {
    return element.tagName.match(/BUTTON|METER|OUTPUT|PROGRESS|SELECT|TEXTAREA/) || element.tagName === 'INPUT' && element.getAttribute('type') !== 'hidden';
  }
  
  function queryAllByPlaceholderText() {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
  
    checkContainerType.apply(void 0, args);
    return queryAllByAttribute.apply(void 0, ['placeholder'].concat(args));
  }
  
  var getMultipleError$1 = function (c, text) {
    return "Found multiple elements with the placeholder text of: " + text;
  };
  
  var getMissingError = function (c, text) {
    return "Unable to find an element with the placeholder text of: " + text;
  };
  
  var queryAllByPlaceholderTextWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByPlaceholderText, queryAllByPlaceholderText.name, 'queryAll');
  
  var _buildQueries = buildQueries(queryAllByPlaceholderText, getMultipleError$1, getMissingError),
      queryByPlaceholderText = _buildQueries[0],
      getAllByPlaceholderText = _buildQueries[1],
      getByPlaceholderText = _buildQueries[2],
      findAllByPlaceholderText = _buildQueries[3],
      findByPlaceholderText = _buildQueries[4];
  
  function queryAllByText(container, text, _temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$selector = _ref.selector,
        selector = _ref$selector === void 0 ? '*' : _ref$selector,
        _ref$exact = _ref.exact,
        exact = _ref$exact === void 0 ? true : _ref$exact,
        collapseWhitespace = _ref.collapseWhitespace,
        trim = _ref.trim,
        _ref$ignore = _ref.ignore,
        ignore = _ref$ignore === void 0 ? DEFAULT_IGNORE_TAGS : _ref$ignore,
        normalizer = _ref.normalizer;
  
    checkContainerType(container);
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
    var baseArray = [];
  
    if (typeof container.matches === 'function' && container.matches(selector)) {
      baseArray = [container];
    }
  
    return [].concat(baseArray, Array.from(container.querySelectorAll(selector))).filter(function (node) {
      return !ignore || !node.matches(ignore);
    }).filter(function (node) {
      return matcher(getNodeText(node), node, text, matchNormalizer);
    });
  }
  
  var getMultipleError$2 = function (c, text) {
    return "Found multiple elements with the text: " + text;
  };
  
  var getMissingError$1 = function (c, text) {
    return "Unable to find an element with the text: " + text + ". This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.";
  };
  
  var queryAllByTextWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByText, queryAllByText.name, 'queryAll');
  
  var _buildQueries$1 = buildQueries(queryAllByText, getMultipleError$2, getMissingError$1),
      queryByText = _buildQueries$1[0],
      getAllByText = _buildQueries$1[1],
      getByText = _buildQueries$1[2],
      findAllByText = _buildQueries$1[3],
      findByText = _buildQueries$1[4];
  
  function queryAllByDisplayValue(container, value, _temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$exact = _ref.exact,
        exact = _ref$exact === void 0 ? true : _ref$exact,
        collapseWhitespace = _ref.collapseWhitespace,
        trim = _ref.trim,
        normalizer = _ref.normalizer;
  
    checkContainerType(container);
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
    return Array.from(container.querySelectorAll("input,textarea,select")).filter(function (node) {
      if (node.tagName === 'SELECT') {
        var selectedOptions = Array.from(node.options).filter(function (option) {
          return option.selected;
        });
        return selectedOptions.some(function (optionNode) {
          return matcher(getNodeText(optionNode), optionNode, value, matchNormalizer);
        });
      } else {
        return matcher(node.value, node, value, matchNormalizer);
      }
    });
  }
  
  var getMultipleError$3 = function (c, value) {
    return "Found multiple elements with the display value: " + value + ".";
  };
  
  var getMissingError$2 = function (c, value) {
    return "Unable to find an element with the display value: " + value + ".";
  };
  
  var queryAllByDisplayValueWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByDisplayValue, queryAllByDisplayValue.name, 'queryAll');
  
  var _buildQueries$2 = buildQueries(queryAllByDisplayValue, getMultipleError$3, getMissingError$2),
      queryByDisplayValue = _buildQueries$2[0],
      getAllByDisplayValue = _buildQueries$2[1],
      getByDisplayValue = _buildQueries$2[2],
      findAllByDisplayValue = _buildQueries$2[3],
      findByDisplayValue = _buildQueries$2[4];
  
  function queryAllByAltText(container, alt, _temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$exact = _ref.exact,
        exact = _ref$exact === void 0 ? true : _ref$exact,
        collapseWhitespace = _ref.collapseWhitespace,
        trim = _ref.trim,
        normalizer = _ref.normalizer;
  
    checkContainerType(container);
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
    return Array.from(container.querySelectorAll('img,input,area')).filter(function (node) {
      return matcher(node.getAttribute('alt'), node, alt, matchNormalizer);
    });
  }
  
  var getMultipleError$4 = function (c, alt) {
    return "Found multiple elements with the alt text: " + alt;
  };
  
  var getMissingError$3 = function (c, alt) {
    return "Unable to find an element with the alt text: " + alt;
  };
  
  var queryAllByAltTextWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByAltText, queryAllByAltText.name, 'queryAll');
  
  var _buildQueries$3 = buildQueries(queryAllByAltText, getMultipleError$4, getMissingError$3),
      queryByAltText = _buildQueries$3[0],
      getAllByAltText = _buildQueries$3[1],
      getByAltText = _buildQueries$3[2],
      findAllByAltText = _buildQueries$3[3],
      findByAltText = _buildQueries$3[4];
  
  var isSvgTitle = function (node) {
    var _node$parentElement;
  
    return node.tagName.toLowerCase() === 'title' && ((_node$parentElement = node.parentElement) == null ? void 0 : _node$parentElement.tagName.toLowerCase()) === 'svg';
  };
  
  function queryAllByTitle(container, text, _temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$exact = _ref.exact,
        exact = _ref$exact === void 0 ? true : _ref$exact,
        collapseWhitespace = _ref.collapseWhitespace,
        trim = _ref.trim,
        normalizer = _ref.normalizer;
  
    checkContainerType(container);
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
    return Array.from(container.querySelectorAll('[title], svg > title')).filter(function (node) {
      return matcher(node.getAttribute('title'), node, text, matchNormalizer) || isSvgTitle(node) && matcher(getNodeText(node), node, text, matchNormalizer);
    });
  }
  
  var getMultipleError$5 = function (c, title) {
    return "Found multiple elements with the title: " + title + ".";
  };
  
  var getMissingError$4 = function (c, title) {
    return "Unable to find an element with the title: " + title + ".";
  };
  
  var queryAllByTitleWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByTitle, queryAllByTitle.name, 'queryAll');
  
  var _buildQueries$4 = buildQueries(queryAllByTitle, getMultipleError$5, getMissingError$4),
      queryByTitle = _buildQueries$4[0],
      getAllByTitle = _buildQueries$4[1],
      getByTitle = _buildQueries$4[2],
      findAllByTitle = _buildQueries$4[3],
      findByTitle = _buildQueries$4[4];
  
  function queryAllByRole(container, role, _temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$exact = _ref.exact,
        exact = _ref$exact === void 0 ? true : _ref$exact,
        collapseWhitespace = _ref.collapseWhitespace,
        _ref$hidden = _ref.hidden,
        hidden = _ref$hidden === void 0 ? getConfig().defaultHidden : _ref$hidden,
        name = _ref.name,
        trim = _ref.trim,
        normalizer = _ref.normalizer,
        _ref$queryFallbacks = _ref.queryFallbacks,
        queryFallbacks = _ref$queryFallbacks === void 0 ? false : _ref$queryFallbacks,
        selected = _ref.selected,
        checked = _ref.checked,
        pressed = _ref.pressed,
        level = _ref.level;
  
    checkContainerType(container);
    var matcher = exact ? matches : fuzzyMatches;
    var matchNormalizer = makeNormalizer({
      collapseWhitespace: collapseWhitespace,
      trim: trim,
      normalizer: normalizer
    });
  
    if (selected !== undefined) {
      var _allRoles$get;
  
      // guard against unknown roles
      if (((_allRoles$get = ariaQuery.roles.get(role)) == null ? void 0 : _allRoles$get.props['aria-selected']) === undefined) {
        throw new Error("\"aria-selected\" is not supported on role \"" + role + "\".");
      }
    }
  
    if (checked !== undefined) {
      var _allRoles$get2;
  
      // guard against unknown roles
      if (((_allRoles$get2 = ariaQuery.roles.get(role)) == null ? void 0 : _allRoles$get2.props['aria-checked']) === undefined) {
        throw new Error("\"aria-checked\" is not supported on role \"" + role + "\".");
      }
    }
  
    if (pressed !== undefined) {
      var _allRoles$get3;
  
      // guard against unknown roles
      if (((_allRoles$get3 = ariaQuery.roles.get(role)) == null ? void 0 : _allRoles$get3.props['aria-pressed']) === undefined) {
        throw new Error("\"aria-pressed\" is not supported on role \"" + role + "\".");
      }
    }
  
    if (level !== undefined) {
      // guard against using `level` option with any role other than `heading`
      if (role !== 'heading') {
        throw new Error("Role \"" + role + "\" cannot have \"level\" property.");
      }
    }
  
    var subtreeIsInaccessibleCache = new WeakMap();
  
    function cachedIsSubtreeInaccessible(element) {
      if (!subtreeIsInaccessibleCache.has(element)) {
        subtreeIsInaccessibleCache.set(element, isSubtreeInaccessible(element));
      }
  
      return subtreeIsInaccessibleCache.get(element);
    }
  
    return Array.from(container.querySelectorAll('*')).filter(function (node) {
      var isRoleSpecifiedExplicitly = node.hasAttribute('role');
  
      if (isRoleSpecifiedExplicitly) {
        var roleValue = node.getAttribute('role');
  
        if (queryFallbacks) {
          return roleValue.split(' ').filter(Boolean).some(function (text) {
            return matcher(text, node, role, matchNormalizer);
          });
        } // if a custom normalizer is passed then let normalizer handle the role value
  
  
        if (normalizer) {
          return matcher(roleValue, node, role, matchNormalizer);
        } // other wise only send the first word to match
  
  
        var _roleValue$split = roleValue.split(' '),
            firstWord = _roleValue$split[0];
  
        return matcher(firstWord, node, role, matchNormalizer);
      }
  
      var implicitRoles = getImplicitAriaRoles(node);
      return implicitRoles.some(function (implicitRole) {
        return matcher(implicitRole, node, role, matchNormalizer);
      });
    }).filter(function (element) {
      if (selected !== undefined) {
        return selected === computeAriaSelected(element);
      }
  
      if (checked !== undefined) {
        return checked === computeAriaChecked(element);
      }
  
      if (pressed !== undefined) {
        return pressed === computeAriaPressed(element);
      }
  
      if (level !== undefined) {
        return level === computeHeadingLevel(element);
      } // don't care if aria attributes are unspecified
  
  
      return true;
    }).filter(function (element) {
      return hidden === false ? isInaccessible(element, {
        isSubtreeInaccessible: cachedIsSubtreeInaccessible
      }) === false : true;
    }).filter(function (element) {
      if (name === undefined) {
        // Don't care
        return true;
      }
  
      return matches(domAccessibilityApi.computeAccessibleName(element, {
        computedStyleSupportsPseudoElements: getConfig().computedStyleSupportsPseudoElements
      }), element, name, function (text) {
        return text;
      });
    });
  }
  
  var getMultipleError$6 = function (c, role, _temp2) {
    var _ref2 = _temp2 === void 0 ? {} : _temp2,
        name = _ref2.name;
  
    var nameHint = '';
  
    if (name === undefined) {
      nameHint = '';
    } else if (typeof name === 'string') {
      nameHint = " and name \"" + name + "\"";
    } else {
      nameHint = " and name `" + name + "`";
    }
  
    return "Found multiple elements with the role \"" + role + "\"" + nameHint;
  };
  
  var getMissingError$5 = function (container, role, _temp3) {
    var _ref3 = _temp3 === void 0 ? {} : _temp3,
        _ref3$hidden = _ref3.hidden,
        hidden = _ref3$hidden === void 0 ? getConfig().defaultHidden : _ref3$hidden,
        name = _ref3.name;
  
    if (getConfig()._disableExpensiveErrorDiagnostics) {
      return "Unable to find role=\"" + role + "\"";
    }
  
    var roles = '';
    Array.from(container.children).forEach(function (childElement) {
      roles += prettyRoles(childElement, {
        hidden: hidden,
        includeName: name !== undefined
      });
    });
    var roleMessage;
  
    if (roles.length === 0) {
      if (hidden === false) {
        roleMessage = 'There are no accessible roles. But there might be some inaccessible roles. ' + 'If you wish to access them, then set the `hidden` option to `true`. ' + 'Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole';
      } else {
        roleMessage = 'There are no available roles.';
      }
    } else {
      roleMessage = ("\nHere are the " + (hidden === false ? 'accessible' : 'available') + " roles:\n\n  " + roles.replace(/\n/g, '\n  ').replace(/\n\s\s\n/g, '\n\n') + "\n").trim();
    }
  
    var nameHint = '';
  
    if (name === undefined) {
      nameHint = '';
    } else if (typeof name === 'string') {
      nameHint = " and name \"" + name + "\"";
    } else {
      nameHint = " and name `" + name + "`";
    }
  
    return ("\nUnable to find an " + (hidden === false ? 'accessible ' : '') + "element with the role \"" + role + "\"" + nameHint + "\n\n" + roleMessage).trim();
  };
  
  var queryAllByRoleWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByRole, queryAllByRole.name, 'queryAll');
  
  var _buildQueries$5 = buildQueries(queryAllByRole, getMultipleError$6, getMissingError$5),
      queryByRole = _buildQueries$5[0],
      getAllByRole = _buildQueries$5[1],
      getByRole = _buildQueries$5[2],
      findAllByRole = _buildQueries$5[3],
      findByRole = _buildQueries$5[4];
  
  var getTestIdAttribute = function () {
    return getConfig().testIdAttribute;
  };
  
  function queryAllByTestId() {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
  
    checkContainerType.apply(void 0, args);
    return queryAllByAttribute.apply(void 0, [getTestIdAttribute()].concat(args));
  }
  
  var getMultipleError$7 = function (c, id) {
    return "Found multiple elements by: [" + getTestIdAttribute() + "=\"" + id + "\"]";
  };
  
  var getMissingError$6 = function (c, id) {
    return "Unable to find an element by: [" + getTestIdAttribute() + "=\"" + id + "\"]";
  };
  
  var queryAllByTestIdWithSuggestions = wrapAllByQueryWithSuggestion(queryAllByTestId, queryAllByTestId.name, 'queryAll');
  
  var _buildQueries$6 = buildQueries(queryAllByTestId, getMultipleError$7, getMissingError$6),
      queryByTestId = _buildQueries$6[0],
      getAllByTestId = _buildQueries$6[1],
      getByTestId = _buildQueries$6[2],
      findAllByTestId = _buildQueries$6[3],
      findByTestId = _buildQueries$6[4];
  
  var queries = /*#__PURE__*/Object.freeze({
    __proto__: null,
    queryAllByLabelText: queryAllByLabelTextWithSuggestions,
    queryByLabelText: queryByLabelText,
    getAllByLabelText: getAllByLabelTextWithSuggestions,
    getByLabelText: getByLabelTextWithSuggestions,
    findAllByLabelText: findAllByLabelText,
    findByLabelText: findByLabelText,
    queryByPlaceholderText: queryByPlaceholderText,
    queryAllByPlaceholderText: queryAllByPlaceholderTextWithSuggestions,
    getByPlaceholderText: getByPlaceholderText,
    getAllByPlaceholderText: getAllByPlaceholderText,
    findAllByPlaceholderText: findAllByPlaceholderText,
    findByPlaceholderText: findByPlaceholderText,
    queryByText: queryByText,
    queryAllByText: queryAllByTextWithSuggestions,
    getByText: getByText,
    getAllByText: getAllByText,
    findAllByText: findAllByText,
    findByText: findByText,
    queryByDisplayValue: queryByDisplayValue,
    queryAllByDisplayValue: queryAllByDisplayValueWithSuggestions,
    getByDisplayValue: getByDisplayValue,
    getAllByDisplayValue: getAllByDisplayValue,
    findAllByDisplayValue: findAllByDisplayValue,
    findByDisplayValue: findByDisplayValue,
    queryByAltText: queryByAltText,
    queryAllByAltText: queryAllByAltTextWithSuggestions,
    getByAltText: getByAltText,
    getAllByAltText: getAllByAltText,
    findAllByAltText: findAllByAltText,
    findByAltText: findByAltText,
    queryByTitle: queryByTitle,
    queryAllByTitle: queryAllByTitleWithSuggestions,
    getByTitle: getByTitle,
    getAllByTitle: getAllByTitle,
    findAllByTitle: findAllByTitle,
    findByTitle: findByTitle,
    queryByRole: queryByRole,
    queryAllByRole: queryAllByRoleWithSuggestions,
    getAllByRole: getAllByRole,
    getByRole: getByRole,
    findAllByRole: findAllByRole,
    findByRole: findByRole,
    queryByTestId: queryByTestId,
    queryAllByTestId: queryAllByTestIdWithSuggestions,
    getByTestId: getByTestId,
    getAllByTestId: getAllByTestId,
    findAllByTestId: findAllByTestId,
    findByTestId: findByTestId
  });
  
  /**
   * @typedef {{[key: string]: Function}} FuncMap
   */
  
  /**
   * @param {HTMLElement} element container
   * @param {FuncMap} queries object of functions
   * @param {Object} initialValue for reducer
   * @returns {FuncMap} returns object of functions bound to container
   */
  
  function getQueriesForElement(element, queries$1, initialValue) {
    if (queries$1 === void 0) {
      queries$1 = queries;
    }
  
    if (initialValue === void 0) {
      initialValue = {};
    }
  
    return Object.keys(queries$1).reduce(function (helpers, key) {
      var fn = queries$1[key];
      helpers[key] = fn.bind(null, element);
      return helpers;
    }, initialValue);
  }
  
  var hasWarned$1 = false; // deprecated... TODO: remove this method. People should use a find* query or
  // wait instead the reasoning is that this doesn't really do anything useful
  // that you can't get from using find* or wait.
  
  function waitForElement() {
    return _waitForElement.apply(this, arguments);
  }
  
  function _waitForElement() {
    _waitForElement = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(callback, options) {
      return _regeneratorRuntime.wrap(function (_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (!hasWarned$1) {
                hasWarned$1 = true;
                console.warn("`waitForElement` has been deprecated. Use a `find*` query (preferred: https://testing-library.com/docs/dom-testing-library/api-queries#findby) or use `waitFor` instead: https://testing-library.com/docs/dom-testing-library/api-async#waitfor");
              }
  
              if (callback) {
                _context.next = 3;
                break;
              }
  
              throw new Error('waitForElement requires a callback as the first parameter');
  
            case 3:
              return _context.abrupt("return", waitForWrapper(function () {
                var result = callback();
  
                if (!result) {
                  throw new Error('Timed out in waitForElement.');
                }
  
                return result;
              }, options));
  
            case 4:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));
    return _waitForElement.apply(this, arguments);
  }
  /*
  eslint
    require-await: "off"
  */
  
  var isRemoved = function (result) {
    return !result || Array.isArray(result) && !result.length;
  }; // Check if the element is not present.
  // As the name implies, waitForElementToBeRemoved should check `present` --> `removed`
  
  
  function initialCheck(elements) {
    if (isRemoved(elements)) {
      throw new Error('The element(s) given to waitForElementToBeRemoved are already removed. waitForElementToBeRemoved requires that the element(s) exist(s) before waiting for removal.');
    }
  }
  
  function waitForElementToBeRemoved() {
    return _waitForElementToBeRemoved.apply(this, arguments);
  }
  
  function _waitForElementToBeRemoved() {
    _waitForElementToBeRemoved = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(callback, options) {
      var timeoutError, elements, getRemainingElements;
      return _regeneratorRuntime.wrap(function (_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              // created here so we get a nice stacktrace
              timeoutError = new Error('Timed out in waitForElementToBeRemoved.');
  
              if (typeof callback !== 'function') {
                initialCheck(callback);
                elements = Array.isArray(callback) ? callback : [callback];
                getRemainingElements = elements.map(function (element) {
                  var parent = element.parentElement;
  
                  while (parent.parentElement) {
                    parent = parent.parentElement;
                  }
  
                  return function () {
                    return parent.contains(element) ? element : null;
                  };
                });
  
                callback = function () {
                  return getRemainingElements.map(function (c) {
                    return c();
                  }).filter(Boolean);
                };
              }
  
              initialCheck(callback());
              return _context.abrupt("return", waitForWrapper(function () {
                var result;
  
                try {
                  result = callback();
                } catch (error) {
                  if (error.name === 'TestingLibraryElementError') {
                    return undefined;
                  }
  
                  throw error;
                }
  
                if (!isRemoved(result)) {
                  throw timeoutError;
                }
  
                return undefined;
              }, options));
  
            case 4:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));
    return _waitForElementToBeRemoved.apply(this, arguments);
  }
  /*
  eslint
    require-await: "off"
  */
  
  var hasWarned$2 = false; // deprecated... TODO: remove this method. People should use wait instead
  // the reasoning is that waiting for just any DOM change is an implementation
  // detail. People should be waiting for a specific thing to change.
  
  function waitForDomChange(_temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$container = _ref.container,
        container = _ref$container === void 0 ? getDocument() : _ref$container,
        _ref$timeout = _ref.timeout,
        timeout = _ref$timeout === void 0 ? getConfig().asyncUtilTimeout : _ref$timeout,
        _ref$mutationObserver = _ref.mutationObserverOptions,
        mutationObserverOptions = _ref$mutationObserver === void 0 ? {
      subtree: true,
      childList: true,
      attributes: true,
      characterData: true
    } : _ref$mutationObserver;
  
    if (!hasWarned$2) {
      hasWarned$2 = true;
      console.warn("`waitForDomChange` has been deprecated. Use `waitFor` instead: https://testing-library.com/docs/dom-testing-library/api-async#waitfor.");
    }
  
    return new Promise(function (resolve, reject) {
      var timer = setTimeoutFn(function () {
        onDone(new Error('Timed out in waitForDomChange.'), null);
      }, timeout);
  
      var _getWindowFromNode = getWindowFromNode(container),
          MutationObserver = _getWindowFromNode.MutationObserver;
  
      var observer = new MutationObserver(function (mutationsList) {
        onDone(null, mutationsList);
      });
      runWithRealTimers(function () {
        return observer.observe(container, mutationObserverOptions);
      });
  
      function onDone(error, result) {
        clearTimeoutFn(timer);
        setImmediateFn(function () {
          return observer.disconnect();
        });
  
        if (error) {
          reject(error);
        } else {
          resolve(result);
        }
      }
    });
  }
  
  function waitForDomChangeWrapper() {
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
  
    return getConfig().asyncWrapper(function () {
      return waitForDomChange.apply(void 0, args);
    });
  }
  
  var eventMap = {
    // Clipboard Events
    copy: {
      EventType: 'ClipboardEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    cut: {
      EventType: 'ClipboardEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    paste: {
      EventType: 'ClipboardEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    // Composition Events
    compositionEnd: {
      EventType: 'CompositionEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    compositionStart: {
      EventType: 'CompositionEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    compositionUpdate: {
      EventType: 'CompositionEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    // Keyboard Events
    keyDown: {
      EventType: 'KeyboardEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        charCode: 0,
        composed: true
      }
    },
    keyPress: {
      EventType: 'KeyboardEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        charCode: 0,
        composed: true
      }
    },
    keyUp: {
      EventType: 'KeyboardEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        charCode: 0,
        composed: true
      }
    },
    // Focus Events
    focus: {
      EventType: 'FocusEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false,
        composed: true
      }
    },
    blur: {
      EventType: 'FocusEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false,
        composed: true
      }
    },
    focusIn: {
      EventType: 'FocusEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    focusOut: {
      EventType: 'FocusEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    // Form Events
    change: {
      EventType: 'Event',
      defaultInit: {
        bubbles: true,
        cancelable: false
      }
    },
    input: {
      EventType: 'InputEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    invalid: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: true
      }
    },
    submit: {
      EventType: 'Event',
      defaultInit: {
        bubbles: true,
        cancelable: true
      }
    },
    reset: {
      EventType: 'Event',
      defaultInit: {
        bubbles: true,
        cancelable: true
      }
    },
    // Mouse Events
    click: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        button: 0,
        composed: true
      }
    },
    contextMenu: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    dblClick: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    drag: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    dragEnd: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    dragEnter: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    dragExit: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    dragLeave: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    dragOver: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    dragStart: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    drop: {
      EventType: 'DragEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    mouseDown: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    mouseEnter: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false,
        composed: true
      }
    },
    mouseLeave: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false,
        composed: true
      }
    },
    mouseMove: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    mouseOut: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    mouseOver: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    mouseUp: {
      EventType: 'MouseEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    // Selection Events
    select: {
      EventType: 'Event',
      defaultInit: {
        bubbles: true,
        cancelable: false
      }
    },
    // Touch Events
    touchCancel: {
      EventType: 'TouchEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    touchEnd: {
      EventType: 'TouchEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    touchMove: {
      EventType: 'TouchEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    touchStart: {
      EventType: 'TouchEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    // UI Events
    scroll: {
      EventType: 'UIEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    // Wheel Events
    wheel: {
      EventType: 'WheelEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    // Media Events
    abort: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    canPlay: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    canPlayThrough: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    durationChange: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    emptied: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    encrypted: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    ended: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    loadedData: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    loadedMetadata: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    loadStart: {
      EventType: 'ProgressEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    pause: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    play: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    playing: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    progress: {
      EventType: 'ProgressEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    rateChange: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    seeked: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    seeking: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    stalled: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    suspend: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    timeUpdate: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    volumeChange: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    waiting: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    // Image Events
    load: {
      EventType: 'UIEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    error: {
      EventType: 'Event',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    // Animation Events
    animationStart: {
      EventType: 'AnimationEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false
      }
    },
    animationEnd: {
      EventType: 'AnimationEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false
      }
    },
    animationIteration: {
      EventType: 'AnimationEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false
      }
    },
    // Transition Events
    transitionEnd: {
      EventType: 'TransitionEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true
      }
    },
    // pointer events
    pointerOver: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    pointerEnter: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    pointerDown: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    pointerMove: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    pointerUp: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    pointerCancel: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false,
        composed: true
      }
    },
    pointerOut: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: true,
        cancelable: true,
        composed: true
      }
    },
    pointerLeave: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false
      }
    },
    gotPointerCapture: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false,
        composed: true
      }
    },
    lostPointerCapture: {
      EventType: 'PointerEvent',
      defaultInit: {
        bubbles: false,
        cancelable: false,
        composed: true
      }
    },
    // history events
    popState: {
      EventType: 'PopStateEvent',
      defaultInit: {
        bubbles: true,
        cancelable: false
      }
    }
  };
  var eventAliasMap = {
    doubleClick: 'dblClick'
  };
  
  function fireEvent(element, event) {
    return getConfig().eventWrapper(function () {
      if (!event) {
        throw new Error("Unable to fire an event - please provide an event object.");
      }
  
      if (!element) {
        throw new Error("Unable to fire a \"" + event.type + "\" event - please provide a DOM element.");
      }
  
      return element.dispatchEvent(event);
    });
  }
  
  function createEvent(eventName, node, init, _temp) {
    var _ref = _temp === void 0 ? {} : _temp,
        _ref$EventType = _ref.EventType,
        EventType = _ref$EventType === void 0 ? 'Event' : _ref$EventType,
        _ref$defaultInit = _ref.defaultInit,
        defaultInit = _ref$defaultInit === void 0 ? {} : _ref$defaultInit;
  
    if (!node) {
      throw new Error("Unable to fire a \"" + eventName + "\" event - please provide a DOM element.");
    }
  
    var eventInit = _extends({}, defaultInit, init);
  
    var _eventInit$target = eventInit.target;
    _eventInit$target = _eventInit$target === void 0 ? {} : _eventInit$target;
  
    var value = _eventInit$target.value,
        files = _eventInit$target.files,
        targetProperties = _objectWithoutPropertiesLoose(_eventInit$target, ["value", "files"]);
  
    if (value !== undefined) {
      setNativeValue(node, value);
    }
  
    if (files !== undefined) {
      // input.files is a read-only property so this is not allowed:
      // input.files = [file]
      // so we have to use this workaround to set the property
      Object.defineProperty(node, 'files', {
        configurable: true,
        enumerable: true,
        writable: true,
        value: files
      });
    }
  
    Object.assign(node, targetProperties);
    var window = getWindowFromNode(node);
    var EventConstructor = window[EventType] || window.Event;
    var event;
    /* istanbul ignore else  */
  
    if (typeof EventConstructor === 'function') {
      event = new EventConstructor(eventName, eventInit);
    } else {
      // IE11 polyfill from https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
      event = window.document.createEvent(EventType);
  
      var bubbles = eventInit.bubbles,
          cancelable = eventInit.cancelable,
          detail = eventInit.detail,
          otherInit = _objectWithoutPropertiesLoose(eventInit, ["bubbles", "cancelable", "detail"]);
  
      event.initEvent(eventName, bubbles, cancelable, detail);
      Object.keys(otherInit).forEach(function (eventKey) {
        event[eventKey] = otherInit[eventKey];
      });
    } // DataTransfer is not supported in jsdom: https://github.com/jsdom/jsdom/issues/1568
  
  
    ['dataTransfer', 'clipboardData'].forEach(function (dataTransferKey) {
      var dataTransferValue = eventInit[dataTransferKey];
  
      if (typeof dataTransferValue === 'object') {
        /* istanbul ignore if  */
        if (typeof window.DataTransfer === 'function') {
          Object.defineProperty(event, dataTransferKey, {
            value: Object.getOwnPropertyNames(dataTransferValue).reduce(function (acc, propName) {
              Object.defineProperty(acc, propName, {
                value: dataTransferValue[propName]
              });
              return acc;
            }, new window.DataTransfer())
          });
        } else {
          Object.defineProperty(event, dataTransferKey, {
            value: dataTransferValue
          });
        }
      }
    });
    return event;
  }
  
  Object.keys(eventMap).forEach(function (key) {
    var _eventMap$key = eventMap[key],
        EventType = _eventMap$key.EventType,
        defaultInit = _eventMap$key.defaultInit;
    var eventName = key.toLowerCase();
  
    createEvent[key] = function (node, init) {
      return createEvent(eventName, node, init, {
        EventType: EventType,
        defaultInit: defaultInit
      });
    };
  
    fireEvent[key] = function (node, init) {
      return fireEvent(node, createEvent[key](node, init));
    };
  }); // function written after some investigation here:
  // https://github.com/facebook/react/issues/10135#issuecomment-401496776
  
  function setNativeValue(element, value) {
    var _ref2 = Object.getOwnPropertyDescriptor(element, 'value') || {},
        valueSetter = _ref2.set;
  
    var prototype = Object.getPrototypeOf(element);
  
    var _ref3 = Object.getOwnPropertyDescriptor(prototype, 'value') || {},
        prototypeValueSetter = _ref3.set;
  
    if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
      prototypeValueSetter.call(element, value);
    }
    /* istanbul ignore next (I don't want to bother) */
    else if (valueSetter) {
        valueSetter.call(element, value);
      } else {
        throw new Error('The given element does not have a value setter');
      }
  }
  
  Object.keys(eventAliasMap).forEach(function (aliasKey) {
    var key = eventAliasMap[aliasKey];
  
    fireEvent[aliasKey] = function () {
      return fireEvent[key].apply(fireEvent, arguments);
    };
  });
  /* eslint complexity:["error", 9] */
  
  var debug = function (element, maxLength, options) {
    return Array.isArray(element) ? element.forEach(function (el) {
      return logDOM(el, maxLength, options);
    }) : logDOM(element, maxLength, options);
  };
  
  var screen = typeof document !== 'undefined' && document.body ? getQueriesForElement(document.body, queries, {
    debug: debug
  }) : Object.keys(queries).reduce(function (helpers, key) {
    helpers[key] = function () {
      throw new TypeError('For queries bound to document.body a global document has to be available... Learn more: https://testing-library.com/s/screen-global-error');
    };
  
    return helpers;
  }, {
    debug: debug
  });
  
  exports.buildQueries = buildQueries;
  exports.configure = configure;
  exports.createEvent = createEvent;
  exports.findAllByAltText = findAllByAltText;
  exports.findAllByDisplayValue = findAllByDisplayValue;
  exports.findAllByLabelText = findAllByLabelText;
  exports.findAllByPlaceholderText = findAllByPlaceholderText;
  exports.findAllByRole = findAllByRole;
  exports.findAllByTestId = findAllByTestId;
  exports.findAllByText = findAllByText;
  exports.findAllByTitle = findAllByTitle;
  exports.findByAltText = findByAltText;
  exports.findByDisplayValue = findByDisplayValue;
  exports.findByLabelText = findByLabelText;
  exports.findByPlaceholderText = findByPlaceholderText;
  exports.findByRole = findByRole;
  exports.findByTestId = findByTestId;
  exports.findByText = findByText;
  exports.findByTitle = findByTitle;
  exports.fireEvent = fireEvent;
  exports.getAllByAltText = getAllByAltText;
  exports.getAllByDisplayValue = getAllByDisplayValue;
  exports.getAllByLabelText = getAllByLabelTextWithSuggestions;
  exports.getAllByPlaceholderText = getAllByPlaceholderText;
  exports.getAllByRole = getAllByRole;
  exports.getAllByTestId = getAllByTestId;
  exports.getAllByText = getAllByText;
  exports.getAllByTitle = getAllByTitle;
  exports.getByAltText = getByAltText;
  exports.getByDisplayValue = getByDisplayValue;
  exports.getByLabelText = getByLabelTextWithSuggestions;
  exports.getByPlaceholderText = getByPlaceholderText;
  exports.getByRole = getByRole;
  exports.getByTestId = getByTestId;
  exports.getByText = getByText;
  exports.getByTitle = getByTitle;
  exports.getConfig = getConfig;
  exports.getDefaultNormalizer = getDefaultNormalizer;
  exports.getElementError = getElementError;
  exports.getMultipleElementsFoundError = getMultipleElementsFoundError;
  exports.getNodeText = getNodeText;
  exports.getQueriesForElement = getQueriesForElement;
  exports.getRoles = getRoles;
  exports.getSuggestedQuery = getSuggestedQuery;
  exports.isInaccessible = isInaccessible;
  exports.logDOM = logDOM;
  exports.logRoles = logRoles;
  exports.makeFindQuery = makeFindQuery;
  exports.makeGetAllQuery = makeGetAllQuery;
  exports.makeSingleQuery = makeSingleQuery;
  exports.prettyDOM = prettyDOM;
  exports.queries = queries;
  exports.queryAllByAltText = queryAllByAltTextWithSuggestions;
  exports.queryAllByAttribute = queryAllByAttribute;
  exports.queryAllByDisplayValue = queryAllByDisplayValueWithSuggestions;
  exports.queryAllByLabelText = queryAllByLabelTextWithSuggestions;
  exports.queryAllByPlaceholderText = queryAllByPlaceholderTextWithSuggestions;
  exports.queryAllByRole = queryAllByRoleWithSuggestions;
  exports.queryAllByTestId = queryAllByTestIdWithSuggestions;
  exports.queryAllByText = queryAllByTextWithSuggestions;
  exports.queryAllByTitle = queryAllByTitleWithSuggestions;
  exports.queryByAltText = queryByAltText;
  exports.queryByAttribute = queryByAttribute;
  exports.queryByDisplayValue = queryByDisplayValue;
  exports.queryByLabelText = queryByLabelText;
  exports.queryByPlaceholderText = queryByPlaceholderText;
  exports.queryByRole = queryByRole;
  exports.queryByTestId = queryByTestId;
  exports.queryByText = queryByText;
  exports.queryByTitle = queryByTitle;
  exports.queryHelpers = queryHelpers;
  exports.screen = screen;
  exports.wait = wait;
  exports.waitFor = waitForWrapper;
  exports.waitForDomChange = waitForDomChangeWrapper;
  exports.waitForElement = waitForElement;
  exports.waitForElementToBeRemoved = waitForElementToBeRemoved;
  exports.within = getQueriesForElement;
  exports.wrapAllByQueryWithSuggestion = wrapAllByQueryWithSuggestion;
  exports.wrapSingleQueryWithSuggestion = wrapSingleQueryWithSuggestion;
  