React 测试库用户事件抛出错误`TypeError:root.elementFromPoint 不是函数`

问题描述 投票:0回答:1

我正在尝试编写一个测试,在编辑器中写入 / 并观察出现的菜单。 为此,我尝试使用 userEvent.type() 方法来模拟真实的键盘键入事件。但是,我收到错误

 Error: Uncaught [TypeError: root.elementFromPoint is not a function]
(请参阅底部的完整错误)

我尝试了一些方法,并且在下面包含了(不起作用)测试:

  • userEvent.hover() 不会抛出任何错误,但也不会导致 dom 树发生预期的变化
  • userEvent.click() 给出与 userEvent.type() 相同的错误
  • 如果我稍等一下,树似乎会发生变化,但是更改后的树也不包含预期的 html 元素
  • 我使用“文本框”而不是“编辑器”作为咏叹调角色,但我仍然遇到问题

RichTextRenderer 是一个 React 组件,它使用 TipTap(基于 Prosemirror)来创建可编辑文本块。问题是,我理解 type() 不起作用,可能是因为它是一个内容可编辑的 div。但是, click() 也不起作用,这完全没有意义。当我谷歌 elementFromPoint 它是一个函数时,所以错误也很奇怪。如何让 userEvent.type() 工作并实际更改具有“编辑器”角色的段落内容?

我编写了以下测试:

test("Typing slash opens the slash menu", async () => {
  render(
    <DndProvider backend={HTML5Backend}>
      <RichTextRenderer/>
    </DndProvider>
  );
  const block = screen.getByRole("editor");
  screen.debug();
  expect(block).toBeInTheDocument();
  userEvent.type(block, "/");
}, 10000);

并且 screen.debug() 打印以下树:

    <body>
      <div>
        <div>
          <div>
            <div
              aria-expanded="false"
              class="ProseMirror editor"
              contenteditable="true"
              tabindex="0"
            >
              <p
                class="is-empty is-editor-empty"
                data-placeholder=""
                role="editor"
              >
                <br />
              </p>
            </div>
          </div>
        </div>
      </div>
    </body>

给出的完整错误是:

 console.error
    Error: Uncaught [TypeError: root.elementFromPoint is not a function]
        at reportException (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
        at innerInvokeEventListeners (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:341:9)
        at invokeEventListeners (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
        at HTMLParagraphElementImpl._dispatch (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
        at HTMLParagraphElementImpl.dispatchEvent (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
        at HTMLParagraphElement.dispatchEvent (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
        at /home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/dom/dist/events.js:25:20
        at /home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/react/dist/pure.js:66:16
        at batchedUpdates$1 (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/react-dom/cjs/react-dom.development.js:22380:12)
        at act (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14) TypeError: root.elementFromPoint is not a function
        at posAtCoords (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/prosemirror-view/src/domcoords.js:245:18)
        at EditorView.posAtCoords$1 [as posAtCoords] (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/prosemirror-view/src/index.js:275:12)
        at Object.<anonymous>.handlers.mousedown (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/prosemirror-view/src/input.js:266:18)
        at HTMLDivElement.view.dom.addEventListener.view.eventHandlers.<computed> (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/prosemirror-view/src/input.js:46:9)
        at HTMLDivElement.callTheUserObjectsOperation (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
        at innerInvokeEventListeners (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:338:25)
        at invokeEventListeners (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
        at HTMLParagraphElementImpl._dispatch (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
        at HTMLParagraphElementImpl.dispatchEvent (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
        at HTMLParagraphElement.dispatchEvent (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
        at /home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/dom/dist/events.js:25:20
        at /home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/react/dist/pure.js:66:16
        at batchedUpdates$1 (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/react-dom/cjs/react-dom.development.js:22380:12)
        at act (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14)
        at Object.eventWrapper (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/react/dist/pure.js:65:28)
        at fireEvent (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/dom/dist/events.js:16:35)
        at Function.fireEvent.<computed> [as mouseDown] (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/dom/dist/events.js:125:36)
        at clickElement (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/user-event/dist/click.js:72:52)
        at click (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/user-event/dist/click.js:136:7)
        at typeImpl (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/user-event/dist/type.js:172:36)
        at Object.type (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/@testing-library/user-event/dist/type.js:155:14)
        at Object.<anonymous> (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/src/documentRenderers/richtext/test/slashMenu.test.tsx:39:13)
        at _callCircusTest (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-circus/build/run.js:212:5)
        at _runTest (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-circus/build/run.js:149:3)
        at _runTestsForDescribeBlock (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-circus/build/run.js:63:9)
        at run (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-circus/build/run.js:25:3)
        at runAndTransformResultsToJestFormat (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:176:21)
        at jestAdapter (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:109:19)
        at runTestInternal (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-runner/build/runTest.js:380:16)
        at runTest (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-runner/build/runTest.js:472:34)
        at Object.worker (/home/nikko/Folders/Uni/SoftwareProject/typecell-next/node_modules/jest-runner/build/testWorker.js:133:12)

      at VirtualConsole.<anonymous> (node_modules/jsdom/lib/jsdom/virtual-console.js:29:45)
      at reportException (node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:70:28)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:341:9)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
      at HTMLParagraphElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
      at HTMLParagraphElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
reactjs integration-testing user-input react-testing-library
1个回答
0
投票

测试库很可能基于

jsdom
,它不实现布局。同时,Prosemirror(以及 TipTap)使用布局信息。

对于 my 测试,存根布局函数就足够了。

function getBoundingClientRect(): DOMRect {
  const rec = {
    x: 0,
    y: 0,
    bottom: 0,
    height: 0,
    left: 0,
    right: 0,
    top: 0,
    width: 0,
  };
  return { ...rec, toJSON: () => rec };
}

class FakeDOMRectList extends Array<DOMRect> implements DOMRectList {
  item(index: number): DOMRect | null {
    return this[index];
  }
}

document.elementFromPoint = (): null => null;
HTMLElement.prototype.getBoundingClientRect = getBoundingClientRect;
HTMLElement.prototype.getClientRects = (): DOMRectList =>
  new FakeDOMRectList();
Range.prototype.getBoundingClientRect = getBoundingClientRect;
Range.prototype.getClientRects = (): DOMRectList =>
  new FakeDOMRectList();
© www.soinside.com 2019 - 2024. All rights reserved.