## Supported click scenarios
These are some clicking corner cases that we did consider and decided to support.
### Positioning
- Element is outside of the viewport.
```html
Some content
```
We use `scrollRectIntoViewIfNeeded` to scroll the element into the viewport if at all possible.
- Empty element with non-empty pseudo.
```html
```
We retrieve the actual visible regions of the target element and click at the pseudo.
- Some part of the element is always outside of the viewport.
```html
onetwo
```
We retrieve the actual visible regions of the target element and click at the visible part.
- Inline element is wrapped to the next line.
We retrieve the actual visible regions of the target element and click at one of the inline boxes.
- Element is rotated with transform.
```html
```
We retrieve the actual visible regions of the target element and click at the transformed visible point.
- Element is deep inside the iframes and/or shadow dom.
We click it.
### Dynamic changes
- Element appears dynamically using display or visibility.
```html
```
We wait for the element to be visible before clicking.
- Element is animating in.
```html
```
We wait for the element to stop moving before clicking.
- Another element is temporary obscuring the target element.
```html
```
For example, the dialog is dismissed and is slowly fading out. We wait for the obscuring element to disappear.
More precisely, we wait for the target element to actually receive pointer events.
- Element is replaced with another one after animation.
```html
```
We wait for the element to be at a stable position, detect that it has been removed from the DOM and retry.
### Targeting
- Button with span/label inside that has `pointer-events: none`.
```html
```
We assume that in such a case the first parent receiving pointer events is a click target.
This is very convenient with something like `text=Click target` selector that actually targets the inner element.
## Unsupported click scenarios
These are some clicking corner cases that we considered.
Some scenarios are marked as a bug in the web page - we believe that the page should be fixed because the real user will suffer the same issue. We try to throw when it's possible to detect the issue or timeout otherwise.
Other scenarios are perfectly fine, but we cannot support them, and usually suggest another way to handle. If Playwright logic does not work on your page, passing `{force: true}` option to the click will force the click without any checks. Use it when you know that's what you need.
### Positioning
- Element moves outside of the viewport in onscroll.
```html
Some content
```
We consider this a bug in the page and throw.
### Dynamic changes
- Element is constantly animating.
```html
```
We wait for the element to be at a stable position and timeout. A real user would be able to click in some cases.
- Element is animating in, but temporarily pauses in the middle.
```html
```
We click in the middle of the animation and could actually click at the wrong element. We do not detect this case and do not throw. A real user would probably retry and click again.
- Element is removed or hidden after `fetch` / `xhr` / `setTimeout`.
```html
```
We click the element and might be able to misclick. We do not detect this case and do not throw.
This is a typical flaky failure, because the network fetch is racing against the input driven by Playwright. The suggested solution is to wait for the response to arrive, and only then click. For example, consider a filtered list with a "Apply filters" button that fetches new data, removes all items from the list and inserts new ones.
```js
await Promise.all([
// This click triggers network fetch racing with next click.
page.click('text=Apply filters'),
// This waits for the network response to arrive.
page.waitForResponse('**/filtered?*'),
]);
// Safe to click now, because network response has been processed
// and items in the list have been updated.
await page.click('.list-item');
```
### Targeting
- A transparent overlay handles the input targeted at the content behind it.
```html
Click me
```
We consider the overlay temporary and timeout waiting for it to disappear.
When the overlay element is actually handling the input instead of the target element, use `{force: true}` option to skip the checks and click anyway.
- Hover handler creates an overlay.
```html
```
We consider this a bug in the page, because in most circumstances users will not be able to click the element.
When the overlay element is actually handling the input instead of the target element, use `{force: true}` option to skip the checks and click anyway.
- `pointer-events` changes dynamically.
```html
```
We consider this a bug in the page, because users will not be able to click the element when they see it.