question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`onChange` is not called when using Cypress's `type` command

See original GitHub issue

Do you want to request a feature or report a bug?

bug

What’s the current behavior?

Using Cypress’s type command to insert some text in a Slate editor. The Slate onChange handler doesn’t seem to be called while typing (note how the placeholder is never removed):

cypress-slate-issue

Here’s some console output for the onChange handler for the duration of this interaction:

onchange-console-slate-issue

This was only logged once (presumably when the editor mounted). Instead, this should’ve been logged several times and the leaf should’ve ended up with a text value equivalent to what was typed.

Slate: 0.57.1 Browser: Chrome (in a Cypress environment) OS: Mac

What’s the expected behavior?

onChange should be called as the value changes when typing. There’s some documentation about how events are handled for Cypress’s type command here.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:10 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
mwood23commented, Apr 26, 2020

@alexmonteirocastro I couldn’t get it to work for me either and chased it down into the source. The solution posted works and goes through all the code paths you’d want as long as your Editable component has autoFocus on it. I’m using Storybook and had to cy.wait(200) on render for mine to work. To test your setup you can try running cypress against the Slate example.

// Spec file to be ran in Cypress
describe('Test that setup works', () => {
  beforeEach(function() {
    cy.visit('https://www.slatejs.org/examples/richtext')
  })

  it('Can type in Slate using helper commands', function() {
    cy.getEditor('[contenteditable=true]').typeInSlate('Some text here')
  })
})

Here’s a snippet from the examples on usage.

4reactions
reydelocommented, Apr 22, 2020

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 here

Read more comments on GitHub >

github_iconTop Results From Across the Web

type
Type into a non-input or non-textarea element with tabindex ... Cypress respects not firing subsequent events if previous ones were canceled.
Read more >
How to trigger a click on a select with Cypress?
Use cy.select() command instead to change the value. In my case, clicking on a select triggers an api call to populate the select...
Read more >
How to handle Click Events in Cypress
click() is used to trigger the click event. Example: Click on the button with id #mybutton using the below command. cy.get( ...
Read more >
Testing Synthetic Events in Cypress - ryanfiller.com
Synthetic events are, by definition, events that do not belong ... A jquery event is also called with a generic Object , albeit...
Read more >
user-event v13
We take the same stance as Cypress in that we do not simulate the behavior that happens with modifier key combinations as different...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found