astral icon indicating copy to clipboard operation
astral copied to clipboard

Broken keyboard input implementation

Open jaydenseric opened this issue 1 year ago • 8 comments

If you do await page.keyboard.down("Alt"), then this keydown listener will fire:

document.addEventListener("keydown", (event) => {
  console.log("keydown:");
  console.log(event.key);
});

Incorrectly however, event.key will be "".

At this point, because there was not yet await page.keyboard.up("Alt"), when you do .click() on an element in the page, the click event property altKey should be true. But, incorrectly it's false.

This test passes when using Puppeteer:

https://github.com/jaydenseric/ruck/blob/aa068afa7f0630c4e3e8617b2936210c14815964/useOnClickRouteLink.test.mjs#L121-L126

Here is the source code being tested:

https://github.com/jaydenseric/ruck/blob/aa068afa7f0630c4e3e8617b2936210c14815964/useOnClickRouteLink.mjs#L31

But with Astral, the test incorrectly fails when it should pass.

Here is the relevant code in Astral vs Puppeteer:

https://github.com/lino-levan/astral/blob/0a4ed055bb33984e1efdc7d540f65735383ea434/src/keyboard.ts#L278-L287

https://github.com/puppeteer/puppeteer/blob/83449567c7013ae1c87c54e42501aa74575640d0/packages/puppeteer-core/src/cdp/Input.ts#L55-L82

jaydenseric avatar Jan 01 '25 04:01 jaydenseric

@lino-levan what is a realistic expectation for when this bug might be resolved?

jaydenseric avatar Jan 19 '25 06:01 jaydenseric

I can try to prioritize working on this today. Planning to take some time off work to get Astral into much better shape, both in terms of fixing issues and documentation.

lino-levan avatar Jan 19 '25 16:01 lino-levan

Unfortunately, my test suit that passes with Puppeteer still doesn't pass with Astral v0.5.2:

// Test holding the alt key when clicking the link prevents a
// client side navigation…

await page.keyboard.down("Alt");
await page.locator('a[href="/b"]').click();
await page.keyboard.up("Alt");

assertStrictEquals(await browserPageUrl(page), urlPageA);

The assertion fails that a navigation did occur.

Do you think it's a bug with Astral, or do I need to use different capitalisation with "Alt" or something Astral specific?

jaydenseric avatar Jan 20 '25 23:01 jaydenseric

Is there some way for you to write a keyboard testcase that I can work on passing?

Here's an example of a testcase in the codebase
Deno.test("Keyboard - tab navigation", async () => {
  const browser = await launch();
  const page = await browser.newPage();

  await page.setContent(`
    <!DOCTYPE html>
    <html>
      <body>
        <input id="first" type="text" placeholder="First input">
        <input id="second" type="text" placeholder="Second input">
        <button id="button">Click me</button>
        <textarea id="textarea">Text area</textarea>
        <div id="focused"></div>
        <script>
          const focused = document.getElementById('focused');
          document.addEventListener('focusin', (e) => {
            if (e.target.id) {
              focused.textContent = (focused.textContent || '') + e.target.id + ',';
            }
          });
        </script>
      </body>
    </html>
  `);

  // Start with first input focused
  const firstInput = await page.$("input#first");
  assertExists(firstInput);
  await firstInput.click();

  // Press tab multiple times to move through elements
  await page.keyboard.press("Tab");
  await page.keyboard.press("Tab");
  await page.keyboard.press("Tab");

  // Check the focus order
  const focusOrder = await page.evaluate(() =>
    document.getElementById("focused")?.textContent || ""
  );
  assertEquals(focusOrder, "first,second,button,textarea,");

  await browser.close();
});

Would also be good for regression testing.

lino-levan avatar Jan 20 '25 23:01 lino-levan

I think the thing to test is that mouse events like click have event.altKey etc. working. Searching the codebase for dispatchMouseEvent:

https://github.com/search?q=repo%3Alino-levan%2Fastral%20dispatchMouseEvent&type=code

It seems none of the event details include the keyboard modifier properties like altKey, etc:

https://github.com/lino-levan/astral/blob/348dda34a0abe8c5719349f3a5a3c4d70bf18a31/src/mouse.ts#L47-L53

jaydenseric avatar Jan 21 '25 00:01 jaydenseric

Right, didn't even know that was in there. Great callout. Image

lino-levan avatar Jan 21 '25 00:01 lino-levan

Yes:

https://chromedevtools.github.io/devtools-protocol/tot/Input/#method-dispatchMouseEvent

I wonder if touch events, and other input events, need attention too.

jaydenseric avatar Jan 21 '25 00:01 jaydenseric

Very likely the case, this'll be fun to work through.

lino-levan avatar Jan 21 '25 00:01 lino-levan