我正在使用 TypeScript 构建一个 React JS 应用程序。在我的应用程序中,我在表单中使用 TinyMCE 编辑器。我还在 TypeScript 中使用 Cypress 编写集成测试。我现在无法使用 TypeScript 在 Cypress 中设置 TinyMCE 编辑器值。我正在使用这个库来操作 Cypress 中的 TinyMCE 编辑器,https://github.com/ForeachOS/cypress-tinymce.
这是我的 React JS TinyMCE 编辑器代码。
import React, { FC } from 'react'
import { Editor } from '@tinymce/tinymce-react'
interface RichEditorFieldProps {
id: string
name?: string
value?: string
onChange: (fieldName: string, value: string) => void
}
const RichEditorField: FC<RichEditorFieldProps> = (
props: RichEditorFieldProps
) => {
const getFieldName = () => {
return props.name ? props.name : props.id
}
return (
<div cy-data-id={props.id} className={'rich-editor-field-container'}>
<Editor
id={props.id}
apiKey={'zjf0nctg4gmjj0a5u5uxm7pcrs0ka4hwcuxzskhxh5hauugf'}
value={props.value ?? ''}
onEditorChange={(content) => {
props.onChange(getFieldName(), content)
}}
/>
</div>
)
}
我正在渲染该组件如下:
<FormRichEditorField
value={formik.values.specification}
label={'Specification'}
error={
formik.touched.specification &&
formik.errors.specification
}
id={'specification'}
onChange={formik.setFieldValue}
/>
我要强调的是小编的id是
specification
.
为了在 Cypress 中为此编写测试,我安装了我提到的包,https://github.com/ForeachOS/cypress-tinymce.
安装包并导入到support/index.ts文件后,我不能像下面这样调用函数:
cy.setTinyMceContent('specification', 'This is the new content');
我必须添加以下代码以使其与 TypeScript 兼容:
declare namespace Cypress {
interface Chainable<Subject = any> {
setTinyMceContent(tinyMceId: string, content: any): void
}
}
然后我在我的 Cypress 测试中设置 TinyMCE 编辑器字段的值如下:
cy.setTinyMceContent('specification', 'This is testing')
当我运行测试时,出现以下错误:
Cannot read properties of undefined (reading 'specification')
我的代码有什么问题,我该如何解决?
包装
cypress-tinymce
看起来已经过时了。最新版本 6 tinyMCE 上没有editors
属性。
以下是我迄今为止最好的。有几个地方需要等待编辑器启动。
第二个等待当前的文本内容,这不太好,因为它太具体了。我还没有找到更好的方法来做到这一点。
更新自@WaiYanHein评论
/// <reference types="cypress" />
Cypress.Commands.add('setTinyMceContent', (tinyMceId: string, content: any) => {
cy.window().should('have.property', 'tinymce') // wait for tinyMCE
cy.wait(1000).then(() => { // wait for editor to be ready
const win = cy.state('window')
const editor = win.tinymce.EditorManager.get()
.filter((editor: any) => editor.id === fieldId)[0]
editor2.setContent(content, { format: 'text' });
})
})
it('adds some text to tinyMCE', () => {
cy.visit('http://localhost:3001')
cy.setTinyMceContent('specification', 'This is the new content')
cy.window().then(win => {
cy.wrap(win.tinymce.activeEditor.getContent({ format: 'text'}))
.should('eq', 'This is the new content') // ✅ passes
})
});
React 应用程序正在控制内容,您可能会看到文本更改为“这是新内容”然后恢复为“一些文本”。
我认为这是由
onChange()
事件触发引起的,它重新渲染组件并将其设置回应用程序的文本。
正因为如此,通过应用程序操作来控制 React 应用程序可能比直接访问 tinyMCE API 更好。取决于您的测试目标。
Cypress.Commands.add(
"setTinyMceContent",
(tinyMceId = "tiny-mce", content = "") => {
cy.window().should("have.property", "tinymce"); // wait for tinyMCE
cy.wait(500);
cy.window().then((win) => {
const editor = win.tinymce.EditorManager.get().find(
(edtr) => edtr.id === tinyMceId
);
editor.setContent(content, { format: "text" });
cy.wait(250);
cy.wrap(editor.getContent({ format: "text" })).should("eq", content);
});
}
);
这对我适用于 v6