I'm having a hard time creating a text selection. Things I've tried:
document.createRange()
and window.getSelection()
cy.trigger
to simulate a cursor drag over the paragraph.dblclick
on the paragraph.Test highlighting text.
I can provide sample code for the approaches I tried, but I'll hold off for now in case there's a completely different known way of doing this.
Cypress 3.1.1, Chrome 70.0.3538.102
What are you trying to test with highlighting text? It'll be easier to determine a fix if we understand what you're trying to do.
My application keeps a record of highlighted text. I'm trying to test that that works correctly.
We've gotten this question several times. We don't have a specific API implemented to handle highlighting text. We do have a generic cy.trigger()
where you can trigger any event, so it is theoretically possible to test many of what you'd need, but would require intimate knowledge of how your application works and what events it triggers.
I will update this issue to reflect request for this feature. This issue should now track:
This feature also requires work that's already in progress for our Native Events issue: https://github.com/cypress-io/cypress/issues/311
Related comment from @tnrich on wanting ability to highlight text with cy.type('{meta}a')
:
I would specifically like a way to trigger the exact same thing as a user-invoked "meta+a" on any element. That might happen to select text in some instances, or select everything in the page if not inside an input/textarea, or it might do something totally different if there are hotkeys listening to that specific keypress.
@Bkucera Would this situation be covered in the Native Events work currently?
This would have to be a new command entirely, and isn't planned for the native events release. However we do plan to support text selection in the future
In the meantime, you can try this:
cy.get('p.mytext')
.trigger('mousedown')
.then(($el) => {
const el = $el[0]
const document = el.ownerDocument
const range = document.createRange()
range.selectNodeContents(el)
document.getSelection().removeAllRanges(range)
document.getSelection().addRange(range)
})
.trigger('mouseup')
cy.document().trigger('selectionchange')
@Bkucera why this line cy.document().trigger('selectionchange')
is needed? Btw, great solution!
Here are a couple of commands that are working for my team, using Cypress to test a Slate based editor:
https://gist.github.com/erquhart/37bf2d938ab594058e0572ed17d3837a
Includes the ability to naively select based on text matching:
cy.get('p').setSelection('foo')
Or set both the start and end points of the selection:
cy.get('p').setSelection('foo', 'baz')
Also setCursorBefore/After
with the same text matching interface, plus some other lower level commands.
@vctormb it's what the browser fires if you were to select text manually, but it won't make a difference if your app code doesn't listen for it
FYI, I couldn't get the gist above working with input
or textarea
's and it looks like its due to lack of support: https://developer.mozilla.org/en-US/docs/Web/API/Window/getSelection#Related_objects (it also wasn't working in Chrome 80 for me), so I created a fork of the gist with a different path for those elements:
https://gist.github.com/samtsai/5cf901ba61fd8d44c8dd7eaa728cac49
@erquhart Thanks you so much !!! The highlighting works !!!
I feel maybe this can be made into an official way of highlighting text instead of just being labelled as a workaround !!! hehe
Yeah I used this Gist successfully on a selection-heavy project test suite and encountered no real issue, I'd be fine if this was the code used for official support despite its potential limitations, it's still better than no support
Glad it worked for you! It's super naive, Eg., duplicates of the targeted string can trip it up easily. We've avoided this by not using duplicate strings in our tests (they're generally short strings anyway). Probably not a viable candidate for a first class solution, but a good stopgap.
For anyone running into issues w/ the gist, our implementation has evolved a bit and may work better. You'll just have to dig a bit in the source file to find the relevant code. Here's the source as of today: https://github.com/netlify/netlify-cms/blob/a4b7481a99f58b9abe85ab5712d27593cde20096/cypress/support/commands.js#L180
@erquhart Thanks a lot! You saved us hours of work.
I really recommend you to create a separate package with all selection related commands so people can just install it via npm in the future and use it directly. I'd be the first one to star it!
For future readers: if @erquhart solution is not working for you, try to trigger a 'selectstart' after the triggered 'mousedown' in the 'selection' command. That seems to fake better a real mouse interaction.
In my case i had a popup that is triggered when text was selected.
Most helpful comment
Here are a couple of commands that are working for my team, using Cypress to test a Slate based editor:
https://gist.github.com/erquhart/37bf2d938ab594058e0572ed17d3837a
Includes the ability to naively select based on text matching:
Or set both the start and end points of the selection:
Also
setCursorBefore/After
with the same text matching interface, plus some other lower level commands.