-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Place the caret at the start/end (all text elements) or clicked point (contenteditable only) #8529
Conversation
Thanks for taking the time to open a PR!
|
780a35c
to
312ddda
Compare
Flaky failures. |
// caretPositionFromPoint doesn't work on headless mode on Firefox. | ||
if (Cypress.isBrowser('chrome')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should try to fix this not working in headless firefox. This could be really confusing to users whose tests fail in runMode but pass in openMode.
If we were going to ship this we would need to print a warning in headless firefox if the option is supplied.
We also would need to write some tests to cover the behavior in headed firefox
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cause of the problem is caretPositionFromPoint
function. It simply returns 0 in headless mode. I fixed this test by adding Cypress.config('isInteractive') === true
.
I added error message about skipping this test.
@@ -2393,6 +2393,13 @@ declare namespace Cypress { | |||
* @default false | |||
*/ | |||
cmdKey: boolean | |||
/** | |||
* Where the caret should be placed when <input>, <textarea>, [contenteditable] elements are clicked. | |||
* 'point' option can be only used with [contenteditable]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should add some logic to throw an error if caretPosition: 'point' is given to a non [contenteditable] element
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added an error message.
} else if (caretPosition === 'point') { | ||
const { x, y } = getMouseCoords(state) | ||
|
||
$selection.moveSelectionToPoint(state('window'), x, y) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similarly needs onlyIfEmptySelection: true
to fulfill the browser default action if selection is changed during the prev event
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that it's impossible. To use onlyIfEmptySelection
, We need element. But in this case, we don't use element. We just use clientX
and clientY
.
312ddda
to
b35736c
Compare
What happened to the tests :( |
@sainthkh I'm not sure what's happened to the tests in here - seems specific to this PR. |
I'll check it out tomorrow. |
@jennifer-shehane The bug happened because of a circular reference in files. I'm finding ways to solve that problem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
considering this proposed solution does not work in firefox headless, I think there's a better solution here.
Right now we grab the host contenteditable
if the subject is inside a contenteditable. Users want the ability to target specific elements inside, not necessarily where the click hits.
So we could change behavior when targeting contenteditables to select the provided subject instead of the host contenteditable. so if the user does cy.get('div[contenteditable] > div > p')
we put the cursor at the end of <p>
instead of div[contenteditable]
. This could use the simple selection.selectNodeContents api to achieve that. Do you think that would meet users' needs @sainthkh? It would be a breaking change
@bkucera It's yes and no.
I think #5721 isn't an invalid request because there are cases like putting the caret at a precise position is necessary to test WYSIWYG editors. (Example scenario: Click a position in the middle of a sentence. Ctrl + b to turn on bold mode. Type a word. Check if the new word is shown in bold.) And I'm also afraid that breaking My answer for your suggestion is this: Add The problem is #5721. For some developers, current I believe there are 3 options for now:
What do you think? |
@sainthkh this would not affect cy.get, only what element cy.type and cy.click target, so it wouldn't be that big of a breaking change. cy.type already has logic around contenteditable subjects as for #5721 I dont believe this PR fixes the issue. That issue is asking for an option like |
@bkucera I agree with you. I'll close this PR and open a new one. |
User facing changelog
Users can choose to place the caret at the start or end of the text elements(
<input>
,<textarea>
)When a contentdeditable element is clicked, the caret can be placed at the clicked point.
Additional details
caretPositionFromPoint
andcaretRangeFromPoint
. Because of that, it only works with[contenteditable]
.How has the user experience changed?
N/A
PR Tasks
cypress-documentation
? => coming soon...type definitions
?cypress.schema.json
?