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

Extend testlib with an easier keyboard API #20344

Closed
jelly opened this issue Apr 22, 2024 · 2 comments · Fixed by #20563
Closed

Extend testlib with an easier keyboard API #20344

jelly opened this issue Apr 22, 2024 · 2 comments · Fixed by #20563

Comments

@jelly
Copy link
Member

jelly commented Apr 22, 2024

In files we recently had to support testing ArrowDown and ArrowUp keys, I noticed that puppeteer/playwright have a nice API for this which is something like:

keyboard.press("ArrowDown")
keyboard.up("ArrowDown")
keyboard.down("ArrowDown")

This makes tests easier readable, as we usually do:

b.key_press(chr(27))  # escape

Our key_press function can also write text:

        b.key_press("logs")

Which in pupeteer/playwright is:

keyboard.type("logs")

Furthermore key_press is split into a Firefox and Chrome specific function which in essence does:

For chromium:

  • Set windowsVirtualKeyCode for when use_ord is set or modifiers is set or key is not alphanum or ord(key) < 32 (special keys).
    For Firefox:
    *we have a small dict with key maps for Backspace/enter if use_ord is set or order(key) < 32 we convert the key into Escape.

So for example escape becomes this for Chromium:

        # -> Input.dispatchKeyEvent({"type": "keyDown", "modifiers": 0, "text": "\u001b", "windowsVirtualKeyCode": 27})

What playwright does, is keep a map with keycodes for all special keys https://github.com/microsoft/playwright/blob/dd1a9f5e9637c37b25ca05e83c860b32abb7930d/packages/playwright-core/src/server/usKeyboardLayout.ts#L28

And then send this over to CDP. Another notable difference is that they send rawKeydown for non-text, I am assume that would for example be Enter.

https://github.com/microsoft/playwright/blob/dd1a9f5e9637c37b25ca05e83c860b32abb7930d/packages/playwright-core/src/server/chromium/crInput.ts#L58

From my testing I have found out sending special keys do work as Firefox in Chromium for Delete/Arrow keys in files with:

    def press_special_key(self, name):
        args = {"type": "keyDown", "key": name}
        self.browser.cdp.invoke("Input.dispatchKeyEvent", **args)

However in Cockpit this does not work for TestPages.testMenuSearch and I need to send windowsVirtualKey.

Proposal

Split off our API, add:

b.keyboard.press b.keyboard.down b.keyboard.up and b.keyboard.type and deprecate b.key_press

Alternative:

Keep key_press and add type_text.

Some interesting usage:

[jelle@t14s][~/projects/cockpit-machines]%git grep key_press
test/check-machines-consoles:            b.key_press("\r")
test/check-machines-create:            b.key_press(self.os_search_name or self.os_name)
test/check-machines-disks:        b.key_press(chr(40), use_ord=True)
test/check-machines-disks:            b.key_press(chr(40), use_ord=True)
b.key_press("\b\b\b\b")

\b == Backspace so writing press_key(Backspace`) is way easier to read but not as usable (it would need a loop).

@martinpitt
Copy link
Member

I just played around with this a little bit, and read https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchKeyEvent and various google hits. I confirm that Firefox works really nicely, but I didn't find a way to convince chromium to take self.cdp.invoke("Input.dispatchKeyEvent", type="keyDown", name="Backspace"), or any combination with rawKeyDown, code=, and so on. It does work fine with "Tab" and "Enter" though -- somehow Backspace is special?

@martinpitt
Copy link
Member

#20563 has a workaround for that.

martinpitt added a commit to martinpitt/cockpit that referenced this issue Jun 8, 2024
`input_text()` is now solely for plain characters, no control ones or
modifiers. That keeps the implementation very simple and browser independent.

Fixes cockpit-project#20344
martinpitt added a commit to martinpitt/cockpit that referenced this issue Jun 9, 2024
`input_text()` is now solely for plain characters, no control ones or
modifiers. That keeps the implementation very simple and browser independent.

Fixes cockpit-project#20344
martinpitt added a commit to martinpitt/cockpit that referenced this issue Jun 9, 2024
`input_text()` is now solely for plain characters, no control ones or
modifiers. That keeps the implementation very simple and browser independent.

Fixes cockpit-project#20344
martinpitt added a commit to martinpitt/cockpit that referenced this issue Jun 10, 2024
`input_text()` is now solely for plain characters, no control ones or
modifiers. That keeps the implementation very simple and browser independent.

Fixes cockpit-project#20344
martinpitt added a commit that referenced this issue Jun 10, 2024
`input_text()` is now solely for plain characters, no control ones or
modifiers. That keeps the implementation very simple and browser independent.

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

Successfully merging a pull request may close this issue.

2 participants