bug
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):

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

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
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.
Update: looks like the type command is inserting the text into an unexpected element i.e. the element that accompanies the placeholder and contains zero width character:

Not sure if this is a Slate issue or a Cypress issue at this point.
@achou11 do you by any chance have a small test-case of this issue?
There is an ongoing thread of users finding their appropriate hacks to get it working. Some may lead to a solution of how to support it natively.
https://slate-js.slack.com/archives/C1RH7AXSS/p1579110773288500
Slate is relying more heavily on the beforeInput event to deal with user interaction.
I havent had the time to dive into this problem, but reading the documentation on cypress I noticed:
https://docs.cypress.io/api/commands/type.html#Events-that-fire
beforeinput is not fired even though it is in the spec because no browser has adopted it.
And this is probably because firefox still does not declare they support beforeInput
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/beforeinput_event
Firefox has released a preview version that _does_ have beforeinput support so that might work out soon
https://bugzilla.mozilla.org/show_bug.cgi?id=970802
Cypress does not yet have an issue for this on their backlog as far as I could tell.
https://github.com/cypress-io/cypress
I'm uncertain I have enough information to make a report.
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鈥檛 simulate. Hopefully the Cypress team will update their input commands to dispatch the beforeinput event, but until they do I鈥檝e created a couple of simple custom commands which will trigger Slate鈥檚 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
@reydelo Tried that approach but it didn't work.
@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.
Closing this since, as noted above, it really is a Cypress issue with Cypress not firing beforeinput and there are listed workarounds above for folks that need to test using Cypress.
Someone was able to test the editor with CyPress without the autoFocus property?
Is someone knows how to simulate the enter button click in the slate input? For example, the comment input field which posts a comment after click Enter
Most helpful comment
@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
Editablecomponent hasautoFocuson it. I'm using Storybook and had tocy.wait(200)on render for mine to work. To test your setup you can try running cypress against the Slate example.Here's a snippet from the examples on usage.