Playwright 测试

学习如何编写与 Plate 集成的 Playwright 测试。

Playwright 支持在无头浏览器中进行端到端测试。本指南介绍如何使用 @platejs/playwright 将 Playwright 与 Plate 集成。

设置

安装依赖

按照 Playwright 指南 在您的应用中安装 Playwright,并确保您可以编写基本的端到端测试。

pnpm add @platejs/playwright playwright

添加 PlaywrightPlugin

为了让您的 Playwright 测试能够访问和操作编辑器,您需要在编辑器中添加 PlaywrightPlugin

const editor = createPlateEditor({
  plugins: [
    // 其他插件...
    PlaywrightPlugin.configure({ enabled: process.env.NODE_ENV !== 'production' }),
  ]
})

这会在 window.platePlaywrightAdapter 上暴露各种工具函数。

获取编辑器句柄

什么是编辑器句柄?

大多数 Playwright 测试代码在非浏览器环境中运行。与 Plate 编辑器交互需要使用 Playwright 的 evaluateevaluateHandle API 在浏览器上下文中运行 JavaScript。

句柄 引用浏览器中的 JavaScript 对象。编辑器句柄指的是您的 Plate 编辑器的 editor 实例(JSHandle<PlateEditor>)。

在您的 Playwright 测试中,在与 Plate 交互之前获取编辑器句柄:

const editorHandle = await getEditorHandle(page);

对于多个编辑器,指定可编辑元素:

const editable = getEditable(page.getByTestId('my-editor-container'));
const editorHandle = await getEditorHandle(page, editable);

定位器必须精确匹配一个 [data-slate-editor] 元素。

开始编写测试

有了 editorHandle,您现在可以开始为编辑器编写 Playwright 测试了。

示例

通过路径获取节点句柄

使用 getNodeByPath 获取引用特定路径节点的句柄。要断言节点的值,使用 .jsonValue() 将其转换为 JSON。

const nodeHandle = await getNodeByPath(page, editorHandle, [0]);
 
expect(await nodeHandle.jsonValue()).toBe({
  type: 'p',
  children: [{ text: '我的段落' }],
});

获取节点的类型

const firstNodeType = await getTypeAtPath(page, editorHandle, [0]);
expect(firstNodeType).toBe('h1');

获取节点的 DOM 节点

在 Playwright 中,您经常需要引用特定的 DOM 元素以断言其状态或执行涉及它的操作。

getDOMNodeByPath 返回与给定路径的 Plate 节点对应的 DOM 节点的 ElementHandle

const firstNodeEl = await getDOMNodeByPath(page, elementHandle, [0]);
await firstNodeEl.hover();

点击节点

await clickAtPath(page, elementHandle, [0]);

获取选区

const selection = await getSelection(page, editorHandle);
 
expect(selection).toBe({
  anchor: { path: [0, 0], offset: 0 },
  focus: { path: [0, 0], offset: 7 },
});

选择点或范围

要在编辑器中的特定位置输入,您需要使用 setSelection 选择该点。

如果您选择单个点(由 pathoffset 组成),光标将放置在该点。如果您选择一个范围(由 anchorfocus 组成),将选中该范围。如果您选择一个路径,将选中该路径处的整个节点。

在设置选区之前,请确保聚焦编辑器。在 WebKit 中,使用 editable.focus() 聚焦编辑器可能无法正常工作,因此最好的方法是使用 clickAtPath

// 点击第一个段落以聚焦编辑器
await clickAtPath(page, editorHandle, [0]);
 
await setSelection(page, editorHandle, {
  path: [0, 0],
  offset: 2,
});
 
await page.keyboard.type('你好,世界!');

导入的查询和转换

您可能想要将查询或转换(如 getBlockAboveinsertNodes)导入到 Playwright 测试中使用。

不幸的是,这是不可能的。您只能在浏览器上下文中直接与 editor 实例交互(使用 evaluateevaluateHandle),并且无法将导入的函数从 Playwright 的作用域传递到浏览器中。这是因为 editor 对象和 JavaScript 函数都无法充分序列化。

最好的解决方案是以用户相同的方式与编辑器交互,而不使用任何导入的查询或转换。这将使您的 Playwright 测试更有可能捕获应用程序中的错误。

如果这不可行,您可以在 evaluateevaluateHandle 中调用 editor 对象的方法。(如果需要从浏览器返回对 DOM 节点或 JavaScript 对象的引用,请使用 evaluateHandle。如果需要返回 JavaScript 对象的序列化副本,或者不需要返回任何值,请使用 evaluate。)

请注意,虽然这些查询和转换不能直接在 Playwright 测试中使用,但在应用程序代码中使用编辑器实例时它们是可用的。有关如何在应用程序中使用这些方法的更多信息,请参阅编辑器方法文档。

有关 evaluateevaluateHandle 的更多信息,请参阅 Playwright 文档

await editorHandle.evaluate((editor) => {
  editor.tf.insertNodes(/* ... */);
});

有关 evaluateevaluateHandle 的更多信息,请参阅 Playwright 文档

API

getEditorHandle

获取 Plate 编辑器实例的句柄。

Parameters

  • page Page

    Playwright 页面对象。

  • editable optional Locator

    可编辑元素的定位器。默认为第一个 [data-slate-editor]。

ReturnsEditorHandle

    Plate 编辑器实例的句柄。

getNodeByPath

获取指定路径的节点。

Parameters

Collapse all
  • page Page

    Playwright 页面对象。

  • editorHandle EditorHandle

    编辑器实例的句柄。

  • path Path

    节点的路径。

ReturnsJSHandle<TNode>

    路径处节点的句柄。

getDOMNodeByPath

获取给定路径的 Plate 节点对应的 DOM 节点。

Parameters

Collapse all
  • page Page

    Playwright 页面对象。

  • editorHandle EditorHandle

    编辑器实例的句柄。

  • path Path

    节点的路径。

ReturnsElementHandle

    对应 DOM 节点的 ElementHandle。

clickAtPath

模拟点击指定路径的节点。

Parameters

Collapse all
  • page Page

    Playwright 页面对象。

  • editorHandle EditorHandle

    编辑器实例的句柄。

  • path Path

    要点击的节点的路径。

getSelection

获取当前编辑器选区。

Parameters

Collapse all
  • page Page

    Playwright 页面对象。

  • editorHandle EditorHandle

    编辑器实例的句柄。

ReturnsSelection

    当前编辑器选区。

setSelection

将编辑器选区设置为指定范围。

Parameters

Collapse all
  • page Page

    Playwright 页面对象。

  • editorHandle EditorHandle

    编辑器实例的句柄。

  • at Location

    要设置选区的位置。

getTypeAtPath

获取指定路径处节点的类型。

Parameters

Collapse all
  • page Page

    Playwright 页面对象。

  • editorHandle EditorHandle

    编辑器实例的句柄。

  • path Path

    节点的路径。

Returnsstring

    路径处节点的类型。