使用Selenium或Cypress测试时如何在slate.js上触发更改事件

时间:2018-12-03 17:03:41

标签: selenium cypress slate.js

我正在尝试在进行E2E测试(使用硒或柏树)和slate.js时模拟“更改”事件的方法

在用户界面中,当用户单击一个单词时,我们会弹出一个模态(与该单词相关)。我无法做到这一点,因为我无法触发change事件来触发

3 个答案:

答案 0 :(得分:1)

赛普拉斯的输入命令(例如cy.type()cy.clear())通过调度inputchange事件来工作-对于cy.type(),每个字符一个。这模仿了用户在其键盘上键入时真实浏览器的行为,并且足以触发大多数应用程序JavaScript的行为。

但是,Slate几乎完全依赖于beforeinput事件(请参见此处https://docs.slatejs.org/concepts/xx-migrating#beforeinput),该事件是一种新的浏览器技术,是赛普拉斯输入命令不模拟的事件。希望赛普拉斯团队会更新他们的输入命令以调度beforeinput事件,但是直到他们完成之前,我已经创建了几个简单的自定义命令,这些命令将触发Slate的输入事件监听器并使其响应。

    // commands.js
    Cypress.Commands.add('getEditor', (selector) => {
      return cy.get(selector)
        .click();
    });

    Cypress.Commands.add('typeInSlate', { prevSubject: true }, (subject, text) => {
      return cy.wrap(subject)
        .then(subject => {
          subject[0].dispatchEvent(new InputEvent('beforeinput', { inputType: 'insertText', data: text }));
          return subject;
        })
    });

    Cypress.Commands.add('clearInSlate', { prevSubject: true }, (subject) => {
      return cy.wrap(subject)
        .then(subject => {
          subject[0].dispatchEvent(new InputEvent('beforeinput', { inputType: 'deleteHardLineBackward' }))
          return subject;
        })
    });

    // slateEditor.spec.js
    cy.getEditor('[data-testid=slateEditor1] [contenteditable]')
        .typeInSlate('Some input text ');

    cy.getEditor('[data-testid=slateEditor2] [contenteditable]')
        .clearInSlate()
        .typeInSlate('http://httpbin.org/status/409');

如果您需要支持其他inputType,则会列出in the source code for editable.tsx

列出Slate支持的所有inputType。

答案 1 :(得分:0)

Cypress可以显式触发事件:https://docs.cypress.io/api/commands/trigger.html#Syntax

这可能对您有用:

cy.get(#element).trigger("change")

答案 2 :(得分:0)

找到了解决方案:

1)将引用添加到编辑器

 <Editor
   ref={this.editor}
 />

2)为自定义事件添加文档监听器

componentDidMount() {
    document.addEventListener("Test_SelectWord", this.onTestSelectWord)
}

componentWillUnmount() {
    document.removeEventListener("Test_SelectWord", this.onTestSelectWord)
}

3)创建一个创建自定义选择事件的处理程序

onTestSelectWord(val: any) {
    let slateEditor = val.detail.parentElement.parentElement.parentElement.parentElement

    // Events are special, can't use spread or Object.keys
    let selectEvent: any = {}
    for (let key in val) { 
        if (key === 'currentTarget') {
            selectEvent['currentTarget'] = slateEditor
        }
        else if (key === 'type') {
            selectEvent['type'] = "select"
        }
        else {
            selectEvent[key] = val[key] 
        }
    }

    // Make selection
    let selection = window.getSelection();        
    let range = document.createRange();
    range.selectNodeContents(val.detail);
    selection.removeAllRanges();
    selection.addRange(range)

    // Fire select event
    this.editor.current.onEvent("onSelect", selectEvent)
}

4)在测试代码中使用以下内容:

arr = Array.from(document.querySelectorAll(".cl-token-node"))
text = arr.filter(element => element.children[0].innerText === "*WORD_YOU_ARE_SELECTING*")[0].children[0].children[0]
var event = new CustomEvent("Test_SelectWord", {detail: text})
document.dispatchEvent(event, text)