-
Notifications
You must be signed in to change notification settings - Fork 249
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
Regression: Click event suddenly stopped working (Reactstrap / Popper.js 1.x) #639
Comments
We've added support for Could you check the computed |
pointer-events is |
This is strange. Could you collect the styles from the ancestors like: const computedStyles = []
for (
let el: Element | null = element;
el?.ownerDocument;
el = el.parentElement
) {
computedStyles.push(window.getComputedStyle(el).pointerEvents)
} Maybe we overlooked some edge case when implementing the helper. |
For me an issue triggers when I'm using DropDown menu from reactstrap; Tried to wrap my every |
My issue was solved by waiting for popper to rerender with the correct styles |
I am facing the same issue with v13.1.x. I am using react-popper v1.3.6
It returns As mentioned by @markivancho , react-popper adds Adding a waiting time of "0 ms" resolves this issue. But, it's not feasible to add this workaround for multiple failing tests. |
@abhinavpreetu Thanks for clearing this up. If an element is not clickable when you use If multiple tests of yours require a specific setup, you could refactor this into a setup function that you call in your tests instead of |
@ph-fritsche I've also experienced this issue, and even though I fully understand the rationale behind this decision (and think it makes sense to consider no-pointer-events as being non-clickable), I think we could perhaps improve this behaviour. Similar to how This would really ease the DX for people dealing with external libraries where you can't easily control this behaviour, animated components, and as well make it way more clear why tests are failing. Right now, it'll just 'no-op' if the element is not clickable, giving the responsibility of raising an error to the next assertion, and thus easily making the cause of the test failure quite obscure. This would also make it way easier to work around when you have animating components or inflexible libraries: you'd then simply have to wrap your click in await waitFor(() => userEvents.click(screen.getByRole('button'))) Please let me know what you think and if this deserves its own ticket. I'd also be happy to try contribute this to the project if this is something you'd be interested in. |
@vicrep Yes, throwing an error assuming someone who calls expect(() => userEvent.click(screen.getByRole('button'))).toThrow() A PR would be welcome. 😃 |
Cool! I'll try get something up next week :) |
As promised :) #647 |
It's nice to have errors if elements can't be clicked.
I tried a number of different ways to do this:
As of now I sadly can't upgrade the project away from popper v1, which is used by blueprint. In the final application the pointer events are set to I'm pretty much stuck here, the only way I know which "solves" this is by using @markivancho how did you solve this? |
This can not work. await waitFor(() => userEvent.click(screen.getByLabelText('Tue Dec 10, 2019'))) If your problem goes beyond that, please set up a codesandbox! That's the easiest way for us to help without playing a guessing game ;) |
You are right. But both don't work. I try to setup minimal sandbox. |
@beckerei you can try
|
I tried to work with I'm currently trying to setup a codesandbox, but the limited implementation of jest and testing-lib don't work together. |
Downgrade |
@ph-fritsche I was thinking, could we consider adding a Something like userEvent.click(element, null, { force: true }) |
I did get the codesandbox to work. I will need to free me some time to set this up properly. ${process.env.NODE_ENV === 'test' && 'pointer-events: auto !important;'} I still have a few failing tests, I'm not sure all of them are related to this problem. But I already caught a bug in our tests, which is nice 👍 |
@vicrep If someone does not want to mimic the browser behavior, |
@beckerei Don't forget to share it. Most mistakes aren't unique and easy to spot if you've seen them a couple of times. ;) |
@ph-fritsche I understand where you're coming from, but let me try to explain my perspective. As previously discussed, the nature of jsdom means we can't deal with actual layout-related assertions, which means that sadly, we'll basically never be able to reliably ensure that what we do on components can be done by a real user in a real browser (in jsdom).
I strongly agree with this, but don't think that's contradictory with allowing a When you reach this situation, you're left with two choices:
Most people will go for the latter, and then you lose out of the additional behaviour that user-event provides when we do a IMO, this library does two things:
Being able to disable the second aspect, which can quite easily become an issue when you don't own 100% of the UI you're testing, still allows us to benefit from the first aspect, which is what I would even say drives most people to this library in the first place. In the end, the decision is yours, but thought I'd shed some light on my train of thought, and still think it could be worth considering. PS: FWIW, Cypress allows the exact same thing, even though the JSDOM argument doesn't hold against it:
|
@vicrep Thanks for your input on this. We want to provide a consistent API. For all our changes, we've got a very straight-forward way to decide which is the desired behavior: Do the same thing in a browser. And then we look into if it is possible to mimic that. If the dev knows better, there is I also think this issue is a poor motivation to introduce such changes, as it is just the dev running |
You bring up some very good points on this, I think doing so would require a little more thought and discussion than "just adding the force flag". Also agree that this issue isn't the right thread and motivation for this, I might open a new ticket if worth a more in-depth proposal, as I still believe it could bring some value. I wasn't talking about waiting for actionability as a reason for this, but more for when you don't have a choice due to an external library's implementation, or you just want to be pragmatic and not waste time setting up something that you're not directly interested in testing (see example shared below). Our of curiosity, did you see the Cypress doc link I shared specifically about this? They give a pretty good example of when |
I have not seen a valid example for not having a choice due to 3rd party code. Yes, I've seen the Cypress docs. The described behavior for |
Okay, looks like there's enough pushback, I'll give up on this proposal :) Thank you for the discussion, appreciated it. Last thing, unless I'm missing something, I don't think |
And just for clarity, I wasn't trying to change the underlying paradigm / vision of this library, and apologies if that's how it came out. I was coming more from an adoption perspective, by giving as much incentive to consumers to consistently stick to this library as opposed to a hybrid between |
I think at the end on has to admit that tests still run in a virtual environment, which is browser like but not a real browser. While my solution may no be the best, it's okayish. The better solution would most likely be to update the underlying libs. |
@vicrep Don't get me wrong. If you feel strongly about this, a feature request in a separate issue is welcome. |
@beckerei Are you using a mock for the I noticed that I have |
It's indeed mocked. But as you also pointed out, it's mocked for a reason. We currently don't have problems with popper. But most of the tests and impl. haven't been touched since April. I assume we will upgrade to popper v2 in the near future. Not sure what problems we will encounter with it. |
If somebody still has this problem
|
Workaround for version 14.0.0+: import { screen, waitFor } from '@testing-library/react';
import userEvent, { PointerEventsCheckLevel } from '@testing-library/user-event';
test('workaround for pointer-events caching', async () => {
// keep helpful pointer-event checks enabled until
// they start causing errors (e.g. with popper.js + react-bootstrap)
const user = userEvent.setup();
// click a button with label 'Open Menu'
// that opens a menu div with transition
await user.click(screen.getByText('Open Menu'));
// wait for div[role=menu] to be interactive
await waitFor(() => {
// do a manual check that confirms the popup
// actually removes its pointer-events style
expect(
window.getComputedStyle(screen.getByRole('menu')).pointerEvents
).not.toBe('none');
});
// create a sub-instance of userEvent, disabling pointerEventsCheck,
// then click a menu item
await user
.setup({ pointerEventsCheck: PointerEventsCheckLevel.Never })
.click(await screen.findByText('Menu Item'));
}); |
@testing-library/user-event
version: 13.1.1Relevant code or config
This code opens a modal that contains some buttons and clicks on them. The modal is provided by Reactstrap (8.9.0).
What you did:
This test failed after an upgrade of user-events from 12.6.3 to 13.1.1. It worked again when I downgraded back to 12.6.3.
What happened:
The test failed at the marked spot. Adding async / await did not help. Also using the bound
getByRole
did not help.When run with the debugger the context never switched back to the React component after the click on the button. The
flow went straight to the next line in the test.
The test then failed in the next line since the button click handler had not been called the UI never updated.
Reproduction repository:
I'll try to find time to create a minimal repo that can reproduce the issue. But I hope that maybe you have an idea what could be the reason for this regression.
Problem description:
The modal component does register some event listeners on document that close it when the user clicked outside of it.
Could this be the reason?
If it helps, I can go through every release in between and try to see where the regression happened.
The text was updated successfully, but these errors were encountered: