Open Bug 1994715 Opened 2 months ago Updated 2 months ago

Firefox should error when trying to click out of bounds

Categories

(Remote Protocol :: Marionette, defect, P3)

defect

Tracking

(Not tracked)

People

(Reporter: julienw, Unassigned)

Details

(Whiteboard: [webdriver:backlog])

STR:

  1. Clone the project at https://github.com/julienw/vitest-browser-mode-viewport-click
  2. run npm i
  3. run npm test -- --browser=firefox

=> notice that the test fails because of a timeout

Now run npm test -- --browser=chrome
=> the test passes but that's because the window is full screen.

Reduce the screen until approximately seeing just half of the viewport, then run the test again using the little triangle on the left.
=> the test fails now, but with a better error such as:

move target out of bounds: WebDriverError: move target out of bounds
  (Session info: chrome=141.0.7390.78) when running "actions" with method "POST" and args "{"actions":[{"id":"action17","type":"pointer","parameters":{"pointerType":"mouse"},"actions":[{"type":"pointerMove","button":0,"x":0,"y":0,"duration":100,"origin":{"element-6066-11e4-a52e-4f735466cecf":"f.CFFBE9BB5C7CFAB3896E3FC94ED76DB8.d.7CDEFC631A466F7D3CC5F530412579F5.e.141"}},{"type":"pointerDown","button":0},{"type":"pause","duration":0},{"type":"pointerUp","button":0}]}]}"

I believe Firefox should also either fail with an error, or make it possible to click the button anyway.

I also filed an issue at vitest in https://github.com/vitest-dev/vitest/issues/8723.

Julien, I haven't had the time to check the testcase yet but I assume that when the window is small enough the button is not visible at all or only partially visible? Note that when performing actions there is no automatic scroll into view (and also misses such a primitive so far) as it is done for Element click. As such the test needs to make sure that the element to interact with is within the visible viewport. I wonder why it is working with Chrome - which means what actually causes the button to be scrolled into view.

Flags: needinfo?(felash)

Hey Henrik, thanks for looking at the issue!

The bug I'm reporting here is that there should be an error like you mention, but there's no error. Instead the actions seems to fail silently, and then my test fails with a timeout instead of a good error, which makes debugging more difficult.

Chrome is reporting an error as I expect.

Flags: needinfo?(felash)

I don't have vitest so I tried with the following Marionette test (which should be equal to what you are doing):

    def test_parent_process_events(self):
        self.marionette.navigate(self.page_local)
        button = self.marionette.find_element(By.ID, "toggleButton")
        message = self.marionette.find_element(By.ID, "message")

        self.marionette.set_window_rect(width=400, height=80)

        def check_visibility():
            return self.marionette.execute_script("return arguments[0].classList;", script_args=(message,))

        def click():
            mouse_chain = self.marionette.actions.sequence("pointer", "pointer_id")
            mouse_chain.pointer_move(0, 0, origin=button)
            mouse_chain.pointer_down(0)
            mouse_chain.pointer_up(0)
            mouse_chain.perform()


        self.assertNotIn("visible", check_visibility())
        click()
        self.assertIn("visible", check_visibility())
        click()
        self.assertNotIn("visible", check_visibility())

Note that this is not failing for me. Reason is that I cannot make the visible viewport small enough that the button is no longer visible. Even with the smallest version of the browser window I can still see around 6px of the upper area of the button (while the rest is hidden). Those 6px are totally enough to click the button, and that the registered event handler toggles the visibility of the message. That's also what I can see when loading the test page and manually clicking the button.

The click point is determined by the intersection of the visible viewport and the in-view center point of the element origin. If Chrome fails that test it looks like that Chrome has a bug.

Flags: needinfo?(felash)

(In reply to Henrik Skupin [:whimboo][⌚️UTC+2] from comment #3)

I don't have vitest so I tried with the following Marionette test (which should be equal to what you are doing):

If you follow the steps in comment 0, you'll have vitest installed as part of the process.

    def test_parent_process_events(self):
        self.marionette.navigate(self.page_local)
        button = self.marionette.find_element(By.ID, "toggleButton")
        message = self.marionette.find_element(By.ID, "message")

        self.marionette.set_window_rect(width=400, height=80)

        def check_visibility():
            return self.marionette.execute_script("return arguments[0].classList;", script_args=(message,))

        def click():
            mouse_chain = self.marionette.actions.sequence("pointer", "pointer_id")
            mouse_chain.pointer_move(0, 0, origin=button)
            mouse_chain.pointer_down(0)
            mouse_chain.pointer_up(0)
            mouse_chain.perform()


        self.assertNotIn("visible", check_visibility())
        click()
        self.assertIn("visible", check_visibility())
        click()
        self.assertNotIn("visible", check_visibility())

Note that this is not failing for me. Reason is that I cannot make the visible viewport small enough that the button is no longer visible. Even with the smallest version of the browser window I can still see around 6px of the upper area of the button (while the rest is hidden). Those 6px are totally enough to click the button, and that the registered event handler toggles the visibility of the message. That's also what I can see when loading the test page and manually clicking the button.

Yes, that's because vitest runs in a different setup than marionette: there's an UI around an iframe running the actual test page. The iframe uses the size defined in the vitest config file, in this case { width: 1112, height: 834 }.

Part of the issue is that the vitest UI itself doesn't scroll (that's why I also filed a bug there). And the iframe itself isn't scrollable either. But then a large part of the iframe is out of the browser viewport. And nothing scrolls. And the button is not visible.

That's where the bug is IMO: Firefox fails silently, and Chrome fails with a proper error.

If you don't want to run vitest, I believe you can reproduce by putting index.html inside a big iframe, itself inside a page that's not scrollable.

Hope this helps!

Flags: needinfo?(felash) → needinfo?(hskupin)
Severity: -- → S3
Flags: needinfo?(hskupin)
Priority: -- → P3
Whiteboard: [webdriver:backlog]
You need to log in before you can comment on or make changes to this bug.