Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test Slate JS behavior in Cypress

How can I insert text in a Slate editor with Cypress? The Slate onChange handler doesn't seem to be called while typing with cy.type() or cy.clear().

like image 709
reydelo Avatar asked Apr 22 '20 08:04

reydelo


People also ask

How do you write test cases in Cypress?

Next steps Learn more about the Cypress UI. Start testing your app. Set up intelligent code completion for Cypress commands and assertions. Record your test results to the Dashboard for advanced features like parallelization, flake detection, and more.

How do you use after each in Cypress?

'AFTER EACH' step is executed after every test case and is present in each Cypress Test Case. It executes the steps mentioned under the "afterEach()" block. Apart from these, we can see the tests specified using the "it" and "specify" blocks that execute in the order as mentioned in the file.


1 Answers

The Cypress input commands (e.g. cy.type() and cy.clear()) work by dispatching input and change events - in the case of cy.type(), one per character. This mimics the behavior of a real browser as a user types on their keyboard and is enough to trigger the behavior of most application JavaScript.

However, Slate relies almost exclusively on the beforeinput event (see here https://docs.slatejs.org/concepts/xx-migrating#beforeinput) which is a new browser technology and an event which the Cypress input commands don’t simulate. Hopefully the Cypress team will update their input commands to dispatch the beforeinput event, but until they do I’ve created a couple of simple custom commands which will trigger Slate’s input event listeners and make it respond.

// 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');

If you need to support other inputTypes, all of the inputTypes supported by Slate are listed in the source code for editable.tsx

like image 54
reydelo Avatar answered Sep 30 '22 04:09

reydelo