dropdownMenu.tsx 2.6 KB

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