select-options.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.deselectOptions = exports.selectOptions = void 0;
  6. var _dom = require("@testing-library/dom");
  7. var _utils = require("./utils");
  8. var _click = require("./click");
  9. var _focus = require("./focus");
  10. var _hover = require("./hover");
  11. function selectOptionsBase(newValue, select, values, init) {
  12. if (!newValue && !select.multiple) {
  13. throw (0, _dom.getConfig)().getElementError(`Unable to deselect an option in a non-multiple select. Use selectOptions to change the selection instead.`, select);
  14. }
  15. const valArray = Array.isArray(values) ? values : [values];
  16. const allOptions = Array.from(select.querySelectorAll('option, [role="option"]'));
  17. const selectedOptions = valArray.map(val => {
  18. if (allOptions.includes(val)) {
  19. return val;
  20. } else {
  21. const matchingOption = allOptions.find(o => o.value === val || o.innerHTML === val);
  22. if (matchingOption) {
  23. return matchingOption;
  24. } else {
  25. throw (0, _dom.getConfig)().getElementError(`Value "${val}" not found in options`, select);
  26. }
  27. }
  28. }).filter(option => !option.disabled);
  29. if (select.disabled || !selectedOptions.length) return;
  30. if ((0, _utils.isInstanceOfElement)(select, 'HTMLSelectElement')) {
  31. if (select.multiple) {
  32. for (const option of selectedOptions) {
  33. // events fired for multiple select are weird. Can't use hover...
  34. _dom.fireEvent.pointerOver(option, init);
  35. _dom.fireEvent.pointerEnter(select, init);
  36. _dom.fireEvent.mouseOver(option);
  37. _dom.fireEvent.mouseEnter(select);
  38. _dom.fireEvent.pointerMove(option, init);
  39. _dom.fireEvent.mouseMove(option, init);
  40. _dom.fireEvent.pointerDown(option, init);
  41. _dom.fireEvent.mouseDown(option, init);
  42. (0, _focus.focus)(select, init);
  43. _dom.fireEvent.pointerUp(option, init);
  44. _dom.fireEvent.mouseUp(option, init);
  45. selectOption(option);
  46. _dom.fireEvent.click(option, init);
  47. }
  48. } else if (selectedOptions.length === 1) {
  49. // the click to open the select options
  50. (0, _click.click)(select, init);
  51. selectOption(selectedOptions[0]); // the browser triggers another click event on the select for the click on the option
  52. // this second click has no 'down' phase
  53. _dom.fireEvent.pointerOver(select, init);
  54. _dom.fireEvent.pointerEnter(select, init);
  55. _dom.fireEvent.mouseOver(select);
  56. _dom.fireEvent.mouseEnter(select);
  57. _dom.fireEvent.pointerUp(select, init);
  58. _dom.fireEvent.mouseUp(select, init);
  59. _dom.fireEvent.click(select, init);
  60. } else {
  61. throw (0, _dom.getConfig)().getElementError(`Cannot select multiple options on a non-multiple select`, select);
  62. }
  63. } else if (select.getAttribute('role') === 'listbox') {
  64. selectedOptions.forEach(option => {
  65. (0, _hover.hover)(option, init);
  66. (0, _click.click)(option, init);
  67. (0, _hover.unhover)(option, init);
  68. });
  69. } else {
  70. throw (0, _dom.getConfig)().getElementError(`Cannot select options on elements that are neither select nor listbox elements`, select);
  71. }
  72. function selectOption(option) {
  73. option.selected = newValue;
  74. (0, _dom.fireEvent)(select, (0, _dom.createEvent)('input', select, {
  75. bubbles: true,
  76. cancelable: false,
  77. composed: true,
  78. ...init
  79. }));
  80. _dom.fireEvent.change(select, init);
  81. }
  82. }
  83. const selectOptions = selectOptionsBase.bind(null, true);
  84. exports.selectOptions = selectOptions;
  85. const deselectOptions = selectOptionsBase.bind(null, false);
  86. exports.deselectOptions = deselectOptions;