dropdownMenu.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import {act} from 'react-dom/test-utils';
  2. import {ReactWrapper} from 'enzyme'; // eslint-disable-line no-restricted-imports
  3. import {triggerPress} from 'sentry-test/utils';
  4. import toArray from 'sentry/utils/toArray';
  5. type SelectDropdownItemProps = {
  6. /**
  7. * They key(s) of menu item(s) to select. If the item is nested inside a
  8. * sub-menu, then this must be an array containing the keys of ancestor
  9. * items, with the highest-level item first, and the last item to select
  10. * last.
  11. */
  12. itemKey: string | string[];
  13. /**
  14. * The root node wrapper, must be provided to run wrapper.update() after
  15. * each step.
  16. */
  17. wrapper: ReactWrapper;
  18. /**
  19. * Optional arguments to help the function better locate the dropdown
  20. * control. Useful if there are more than one control inside `wrapper`. If
  21. * provided, before each selection, the function will first call
  22. * wrapper.find([prefix])[.first()/.last()/.at([at])]
  23. */
  24. specifiers?: {
  25. prefix: string;
  26. at?: number;
  27. first?: boolean;
  28. last?: boolean;
  29. };
  30. /**
  31. * Selector for the dropdown's trigger button, useful for custom trigger
  32. * components whose display name is different from 'TriggerButton'.
  33. */
  34. triggerSelector?: string;
  35. };
  36. /**
  37. * @deprecated
  38. * (This function is only necessary for enzyme tests, which we are migrating
  39. * away from in favor if React Testing Library.)
  40. *
  41. * Selects a dropdown menu item. Works for both top-level and nested items.
  42. */
  43. export async function selectDropdownMenuItem({
  44. wrapper,
  45. itemKey,
  46. specifiers,
  47. triggerSelector = 'Button',
  48. }: SelectDropdownItemProps) {
  49. /**
  50. * Returns a ReactWrapper which we'll use to find the
  51. * dropdown menu control. If `specifiers` is not provided, returns the root
  52. * wrapper by default.
  53. */
  54. function getSpecifiedWrap(): ReactWrapper {
  55. if (!specifiers) {
  56. return wrapper;
  57. }
  58. const prefixedWrap = wrapper.find(specifiers.prefix);
  59. if (specifiers.first) {
  60. return prefixedWrap.first();
  61. }
  62. if (specifiers.last) {
  63. return prefixedWrap.last();
  64. }
  65. if (typeof specifiers.at === 'number') {
  66. return prefixedWrap.at(specifiers.at);
  67. }
  68. return prefixedWrap;
  69. }
  70. // Open the top-level dropdown menu
  71. await act(async () => {
  72. triggerPress(getSpecifiedWrap().find(triggerSelector));
  73. await tick();
  74. wrapper.update();
  75. });
  76. // Select menu item(s) via itemKey
  77. await act(async () => {
  78. const keys = toArray(itemKey);
  79. for (const key of keys) {
  80. triggerPress(
  81. getSpecifiedWrap().find(`MenuWrap MenuItemWrap[data-test-id="${key}"]`)
  82. );
  83. await tick();
  84. wrapper.update();
  85. }
  86. });
  87. }