Skip to content
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

feature: userEvent clear() #1440

Merged
merged 8 commits into from
Aug 10, 2023
Merged

feature: userEvent clear() #1440

merged 8 commits into from
Aug 10, 2023

Conversation

mdjastrzebski
Copy link
Member

Summary

Method for clearing the content of TextInput element. This method is useful as type() helper, following OG User Event implementation, is appending text and not replacing it. Hence, users need a way to clear it in some cases. Currently they have to resort to fireEvent.changeText(element, '') workaround.

Test plan

Added tests based on subset type() tests.

@codecov
Copy link

codecov bot commented Aug 7, 2023

Codecov Report

Patch coverage: 100.00% and project coverage change: +0.01% 🎉

Comparison is base (dace5cb) 97.56% compared to head (e0c15ea) 97.57%.
Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1440      +/-   ##
==========================================
+ Coverage   97.56%   97.57%   +0.01%     
==========================================
  Files          72       74       +2     
  Lines        4266     4338      +72     
  Branches      631      636       +5     
==========================================
+ Hits         4162     4233      +71     
- Misses        104      105       +1     
Files Changed Coverage Δ
src/user-event/utils/text-range.ts 100.00% <ø> (ø)
src/user-event/clear.ts 100.00% <100.00%> (ø)
src/user-event/index.ts 100.00% <100.00%> (ø)
src/user-event/press/press.ts 100.00% <100.00%> (ø)
src/user-event/setup/setup.ts 100.00% <100.00%> (ø)
src/user-event/type/type.ts 100.00% <100.00%> (ø)
src/user-event/utils/host-components.ts 100.00% <100.00%> (ø)
src/user-event/utils/index.ts 83.33% <100.00%> (-16.67%) ⬇️

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

}

// Skip events if the element is disabled
if (element.props.editable === false || !isPointerEventEnabled(element)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we want to log or throw to inform the user the action is not possible? because I think if he did it, he did not realize his component is not editable and it would be nice to notify him of it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good idea to throw a helpful error in such case.

There seems to be some discrepancy in OG User Event on that front:

  • clear() and click()/pointer() seem to throw if element is not enabled
  • type() seems to silently ignore the fact.

I think we should have consistent semantics in such case, i.e. always throw a helpful error.

One thing to note, this would be again the Fire Event API which silently ignores such events.

@MattAgn @pierrezimmermannbam @AugustinLF @thymikee any thoughts on that more general subject?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i agree, we should always throw errors and document it well so people are not too surprised it's different with FireEvent. And maybe we could also think if we want to change the behavior of fireEvent in the future

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added throwing error here in case element is not editable nor pressable (pointer events prop).

For other types of elements, I'll open an issue for discussion.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW fireEvent was already throwing errors in the past when no enable event handler was found but that has been removed. Here are refs to OG issue: #469, and PR #470

const previousText = element.props.value ?? element.props.defaultValue ?? '';
const selectionRange = {
start: 0,
end: previousText.length,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since it starts at 0, shoud not the end be previousText.length -1 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this is actually fine, 0 is before first character, 1 is after first character, so n would be after n characters.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh yes understood


// 3. Press backspace
const finalText = '';
await emitTypingEvents(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's funny that with the backspace event, we still have to precise the finalText where the action itself of deleting should be enough to determine the final text

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emitTypingEvents is primitive function that just emits events and does not calculate changes. It expects to receive all of following: key pressed, text after change, text before change.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh alright, i did not go check the implementation behind it

@@ -79,14 +78,16 @@ export async function type(
dispatchEvent(element, 'blur', EventBuilder.Common.blur());
}

async function emitTypingEvents(
export async function emitTypingEvents(
config: UserEventConfig,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] i often see config options passed as the last argument (usually because they're optional), which makes me wonder if we always want these options? could we want a default config ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an internal function (export is not added to user-event/index.ts), we need the current config in order to invoke wait, etc

Copy link
Collaborator

@pierrezimmermannbam pierrezimmermannbam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice addition! It's nice to see userEvent API coming together!
The only thing I'm not sure is whether it should throw or not for disabled elements but we can have that discussion on the dedicated issue. However I don't really like the idea of a release where clear would throw but not type and press so APIs should be aligned before next release imo and because I'm not convinced yet that we should throw maybe the easiest for now is to keep that for another PR?

@mdjastrzebski
Copy link
Member Author

I've removed throwing error on disabled/not focusable element.

@mdjastrzebski mdjastrzebski merged commit 62a9b57 into main Aug 10, 2023
9 checks passed
@mdjastrzebski mdjastrzebski deleted the feature/user-event-clear branch August 10, 2023 20:35
@mdjastrzebski
Copy link
Member Author

This PR has been released in v12.2.1 🚡

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants