You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Cypress选择文本?求medium-draft编辑器文本选择测试方法

在Cypress中选中富文本编辑器(如medium-draft)的特定文本范围

我之前测试富文本编辑器的时候也踩过这个坑,Cypress确实没有直接提供选中文本的内置命令,但我们可以借助原生JS API或者模拟用户操作来实现,针对你提到的类似medium-draft的编辑器,这里有几个实用方案:

方案1:使用原生Range和Selection API(最通用稳定)

这是适配大多数富文本编辑器的通用方法,利用浏览器原生的Range和Selection对象来精确选中指定范围的文本。

举个针对medium-draft的示例代码:

// 先定位到medium-draft的编辑器容器
cy.get('.DraftEditor-editorContainer')
  .then($editor => {
    // 获取编辑器内的文本节点(根据实际DOM结构调整,medium-draft的文本通常在public-DraftStyleDefault-block下)
    const textBlock = $editor.find('.public-DraftStyleDefault-block')[0];
    const textNode = textBlock.firstChild; // 假设文本直接在block的第一个子节点中

    // 创建Range对象,设置选中范围(从第2个字符到第8个字符)
    const range = document.createRange();
    range.setStart(textNode, 2);
    range.setEnd(textNode, 8);

    // 将Range添加到当前选中区域
    const selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
  });

注意:你需要根据编辑器实际的DOM结构调整文本节点的获取方式,如果文本分散在多个子元素中,可能需要遍历找到对应的textNode。

方案2:模拟鼠标拖拽选中文本(贴近真实用户行为)

如果你想模拟用户用鼠标拖拽选中文本的操作,可以用Cypress的trigger方法模拟鼠标事件:

// 先定位到包含目标文本的block
cy.get('.public-DraftStyleDefault-block')
  .contains('需要选中的目标文本片段')
  .then($el => {
    const rect = $el[0].getBoundingClientRect();
    // 鼠标按下在文本起始位置附近
    cy.wrap($el).trigger('mousedown', { clientX: rect.left + 5, clientY: rect.top + 5, force: true });
    // 鼠标拖拽到文本结束位置附近
    cy.wrap($el).trigger('mousemove', { clientX: rect.right - 5, clientY: rect.top + 5, force: true });
    // 松开鼠标完成选中
    cy.wrap($el).trigger('mouseup', { force: true });
  });

这个方法的优势是完全模拟用户操作,但如果文本存在换行、多格式混合的情况,可能需要微调坐标参数来保证选中的准确性。

方案3:针对Draft.js(medium-draft基于它)的直接状态操作

如果你的项目有权限访问编辑器的内部状态(比如应用中暴露了Draft.js的EditorState),可以直接通过修改编辑器状态来选中文本,这种方式最精准:

cy.window().then(win => {
  // 假设你的应用全局暴露了editorState和updateEditorState方法
  const { editorState, updateEditorState } = win;
  const Draft = win.Draft; // 确保Draft.js对象可访问

  // 获取当前内容的第一个block(可根据实际需求调整block)
  const contentState = editorState.getCurrentContent();
  const firstBlockKey = contentState.getFirstBlock().getKey();

  // 创建选中状态:从第2个字符到第8个字符
  const selectionState = Draft.SelectionState.createEmpty(firstBlockKey)
    .merge({
      anchorOffset: 2,
      focusOffset: 8,
      hasFocus: true
    });

  // 更新编辑器状态,完成选中
  const newEditorState = Draft.EditorState.acceptSelection(editorState, selectionState);
  updateEditorState(newEditorState);
});

额外提示

  • 测试前务必确保编辑器已完全加载、文本已渲染完成,可以用cy.contains('目标文本').should('be.visible')等待元素就绪
  • 如果编辑器嵌入在iframe中,需要先进入iframe上下文:cy.iframe('#editor-iframe').then(...)
  • 不同浏览器的Selection API可能有细微差异,建议在目标测试浏览器上验证效果

内容的提问来源于stack exchange,提问作者yamadapc

火山引擎 最新活动