Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

test-utils.ts 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import "pepjs";
  2. import {
  3. render,
  4. queries,
  5. RenderResult,
  6. RenderOptions,
  7. waitFor,
  8. } from "@testing-library/react";
  9. import * as toolQueries from "./queries/toolQueries";
  10. import { ImportedDataState } from "../data/types";
  11. import { STORAGE_KEYS } from "../excalidraw-app/data/localStorage";
  12. import { SceneData } from "../types";
  13. const customQueries = {
  14. ...queries,
  15. ...toolQueries,
  16. };
  17. type TestRenderFn = (
  18. ui: React.ReactElement,
  19. options?: Omit<
  20. RenderOptions & { localStorageData?: ImportedDataState },
  21. "queries"
  22. >,
  23. ) => Promise<RenderResult<typeof customQueries>>;
  24. const renderApp: TestRenderFn = async (ui, options) => {
  25. if (options?.localStorageData) {
  26. initLocalStorage(options.localStorageData);
  27. delete options.localStorageData;
  28. }
  29. const renderResult = render(ui, {
  30. queries: customQueries,
  31. ...options,
  32. });
  33. GlobalTestState.renderResult = renderResult;
  34. Object.defineProperty(GlobalTestState, "canvas", {
  35. // must be a getter because at the time of ExcalidrawApp render the
  36. // child App component isn't likely mounted yet (and thus canvas not
  37. // present in DOM)
  38. get() {
  39. return renderResult.container.querySelector("canvas")!;
  40. },
  41. });
  42. await waitFor(() => {
  43. const canvas = renderResult.container.querySelector("canvas");
  44. if (!canvas) {
  45. throw new Error("not initialized yet");
  46. }
  47. });
  48. return renderResult;
  49. };
  50. // re-export everything
  51. export * from "@testing-library/react";
  52. // override render method
  53. export { renderApp as render };
  54. /**
  55. * For state-sharing across test helpers.
  56. * NOTE: there shouldn't be concurrency issues as each test is running in its
  57. * own process and thus gets its own instance of this module when running
  58. * tests in parallel.
  59. */
  60. export class GlobalTestState {
  61. /**
  62. * automatically updated on each call to render()
  63. */
  64. static renderResult: RenderResult<typeof customQueries> = null!;
  65. /**
  66. * retrieves canvas for currently rendered app instance
  67. */
  68. static get canvas(): HTMLCanvasElement {
  69. return null!;
  70. }
  71. }
  72. const initLocalStorage = (data: ImportedDataState) => {
  73. if (data.elements) {
  74. localStorage.setItem(
  75. STORAGE_KEYS.LOCAL_STORAGE_ELEMENTS,
  76. JSON.stringify(data.elements),
  77. );
  78. }
  79. if (data.appState) {
  80. localStorage.setItem(
  81. STORAGE_KEYS.LOCAL_STORAGE_APP_STATE,
  82. JSON.stringify(data.appState),
  83. );
  84. }
  85. };
  86. export const updateSceneData = (data: SceneData) => {
  87. (window.collab as any).excalidrawAPI.updateScene(data);
  88. };
  89. const originalGetBoundingClientRect =
  90. global.window.HTMLDivElement.prototype.getBoundingClientRect;
  91. export const mockBoundingClientRect = () => {
  92. // override getBoundingClientRect as by default it will always return all values as 0 even if customized in html
  93. global.window.HTMLDivElement.prototype.getBoundingClientRect = () => ({
  94. top: 10,
  95. left: 20,
  96. bottom: 10,
  97. right: 10,
  98. width: 200,
  99. x: 10,
  100. y: 20,
  101. height: 100,
  102. toJSON: () => {},
  103. });
  104. };
  105. export const restoreOriginalGetBoundingClientRect = () => {
  106. global.window.HTMLDivElement.prototype.getBoundingClientRect = originalGetBoundingClientRect;
  107. };