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 交互之前获取编辑器句柄:
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
选择该点。
如果您选择单个点(由 path
和 offset
组成),光标将放置在该点。如果您选择一个范围(由 anchor
和 focus
组成),将选中该范围。如果您选择一个路径,将选中该路径处的整个节点。
在设置选区之前,请确保聚焦编辑器。在 WebKit 中,使用 editable.focus()
聚焦编辑器可能无法正常工作,因此最好的方法是使用 clickAtPath
。
// 点击第一个段落以聚焦编辑器
await clickAtPath(page, editorHandle, [0]);
await setSelection(page, editorHandle, {
path: [0, 0],
offset: 2,
});
await page.keyboard.type('你好,世界!');
导入的查询和转换
您可能想要将查询或转换(如 getBlockAbove
或 insertNodes
)导入到 Playwright 测试中使用。
不幸的是,这是不可能的。您只能在浏览器上下文中直接与 editor
实例交互(使用 evaluate
或 evaluateHandle
),并且无法将导入的函数从 Playwright 的作用域传递到浏览器中。这是因为 editor
对象和 JavaScript 函数都无法充分序列化。
最好的解决方案是以用户相同的方式与编辑器交互,而不使用任何导入的查询或转换。这将使您的 Playwright 测试更有可能捕获应用程序中的错误。
如果这不可行,您可以在 evaluate
或 evaluateHandle
中调用 editor
对象的方法。(如果需要从浏览器返回对 DOM 节点或 JavaScript 对象的引用,请使用 evaluateHandle
。如果需要返回 JavaScript 对象的序列化副本,或者不需要返回任何值,请使用 evaluate
。)
请注意,虽然这些查询和转换不能直接在 Playwright 测试中使用,但在应用程序代码中使用编辑器实例时它们是可用的。有关如何在应用程序中使用这些方法的更多信息,请参阅编辑器方法文档。
有关 evaluate
和 evaluateHandle
的更多信息,请参阅 Playwright 文档。
await editorHandle.evaluate((editor) => {
editor.tf.insertNodes(/* ... */);
});
有关 evaluate
和 evaluateHandle
的更多信息,请参阅 Playwright 文档。
API
getEditorHandle
获取 Plate 编辑器实例的句柄。
getNodeByPath
获取指定路径的节点。
getDOMNodeByPath
获取给定路径的 Plate 节点对应的 DOM 节点。
clickAtPath
模拟点击指定路径的节点。
getSelection
获取当前编辑器选区。
setSelection
将编辑器选区设置为指定范围。
getTypeAtPath
获取指定路径处节点的类型。