reactTestingLibrary.spec.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import {useRef} from 'react';
  2. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  3. import Link from 'sentry/components/links/link';
  4. import {useLocation} from 'sentry/utils/useLocation';
  5. import {useNavigate} from 'sentry/utils/useNavigate';
  6. describe('rerender', () => {
  7. // Taken from https://testing-library.com/docs/example-update-props/
  8. let idCounter = 1;
  9. function NumberDisplay({number}: {number: number}) {
  10. const id = useRef(idCounter++); // to ensure we don't remount a different instance
  11. return (
  12. <div>
  13. <span data-test-id="number-display">{number}</span>
  14. <span data-test-id="instance-id">{id.current}</span>
  15. </div>
  16. );
  17. }
  18. test('calling render with the same component on the same container does not remount', () => {
  19. const {rerender} = render(<NumberDisplay number={1} />);
  20. expect(screen.getByTestId('number-display')).toHaveTextContent('1');
  21. // re-render the same component with different props
  22. rerender(<NumberDisplay number={2} />);
  23. expect(screen.getByTestId('number-display')).toHaveTextContent('2');
  24. expect(screen.getByTestId('instance-id')).toHaveTextContent('1');
  25. });
  26. });
  27. describe('disableRouterMocks', () => {
  28. it('starts with the correct initial location', () => {
  29. const {router} = render(<div />, {
  30. disableRouterMocks: true,
  31. initialRouterConfig: {location: '/foo/'},
  32. });
  33. expect(router.location.pathname).toBe('/foo/');
  34. });
  35. it('should react to clicking a Link', async () => {
  36. function TestComp() {
  37. const location = useLocation();
  38. return (
  39. <div>
  40. <Link to="/foo/bar/">Click me</Link>
  41. <div>You are at: {location.pathname}</div>
  42. </div>
  43. );
  44. }
  45. const {router} = render(<TestComp />, {
  46. disableRouterMocks: true,
  47. });
  48. const link = screen.getByText('Click me');
  49. await userEvent.click(link);
  50. expect(await screen.findByText('You are at: /foo/bar/')).toBeInTheDocument();
  51. expect(router.location.pathname).toBe('/foo/bar/');
  52. });
  53. it('should react to useNavigate()', async () => {
  54. function TestComp() {
  55. const location = useLocation();
  56. const navigate = useNavigate();
  57. return (
  58. <div>
  59. <button onClick={() => navigate('/foo/bar/')}>Click me</button>
  60. <div>You are at: {location.pathname}</div>
  61. </div>
  62. );
  63. }
  64. const {router} = render(<TestComp />, {
  65. disableRouterMocks: true,
  66. });
  67. const button = screen.getByText('Click me');
  68. await userEvent.click(button);
  69. expect(await screen.findByText('You are at: /foo/bar/')).toBeInTheDocument();
  70. expect(router.location.pathname).toBe('/foo/bar/');
  71. });
  72. it('can navigate in the test', async () => {
  73. function TestComp() {
  74. const location = useLocation();
  75. return <div>{location.pathname}</div>;
  76. }
  77. const {router} = render(<TestComp />, {disableRouterMocks: true});
  78. expect(screen.getByText('/mock-pathname/')).toBeInTheDocument();
  79. // Navigate to a new path
  80. router.navigate('/foo/bar/');
  81. await waitFor(() => {
  82. expect(router.location.pathname).toBe('/foo/bar/');
  83. });
  84. expect(screen.getByText('/foo/bar/')).toBeInTheDocument();
  85. // Navigate back to the previous path
  86. router.navigate(-1);
  87. await waitFor(() => {
  88. expect(router.location.pathname).toBe('/mock-pathname/');
  89. });
  90. expect(screen.getByText('/mock-pathname/')).toBeInTheDocument();
  91. });
  92. });