electron icon indicating copy to clipboard operation
electron copied to clipboard

[Bug]: Electron 17+ ignores Input.insertText commands when response body is empty

Open mxschmitt opened this issue 3 years ago • 2 comments

Preflight Checklist

Electron Version

17+

What operating system are you using?

Other (specify below)

Operating System Version

reproducible on macOS, Linux, Windows

What arch are you using?

x64

Last Known Working Electron version

16.x/16.2.8

Expected Behavior

CDP command Input.insertText ends up in a noop if the response of the site which was navigated to was empty (''):

  • Bisect range: https://github.com/electron/electron/compare/v18.0.0-nightly.20211123...v18.0.0-nightly.20211124
  • Bad: 18.0.0-nightly.20211124 bad
  • Good: 18.0.0-nightly.20211123: good

Expected: It writes the input text / processes the keyboard events.

Actual Behavior

Actual: It ends up in a noop.

Testcase Gist URL

https://gist.github.com/mxschmitt/8e85df87d970eb879dff58e8d5562cfd

Additional Information

See here for a list of downstream tests which are failing in 17+: https://github.com/microsoft/playwright/issues/16025

mxschmitt avatar Aug 01 '22 10:08 mxschmitt

Seems like there is much more IME stuff affected, e.g. Input.dispatchKeyEvent as well.

mxschmitt avatar Aug 01 '22 10:08 mxschmitt

@mxschmitt could you provide a repro that's stand-alone runnable with Fiddle? That one isn't at the moment it doesn't seem 🤔 a repro repo would also be fine!

fwiw it's probably https://github.com/electron/electron/commit/bd10b19b0cdc46cdbadb570af89305e64541b679 - i'll see what i can find!

codebytere avatar Aug 01 '22 12:08 codebytere

New Electron Fiddle repro: https://gist.github.com/d5d48f0bf8f5f18051c316f5e27f4186

Actually I was wrong that Input.insertText behaves wrongly, it's only Input.dispatchKeyEvent and Input.dispatchMouseEvent.

mxschmitt avatar Aug 05 '22 13:08 mxschmitt

Following up - it looks like this is not necessarily about the response body, but a race condition. Adding a delay after loading the page demonstrates that - so something in the roll likely affected url loading from a server? unclear yet what, but this doesn't happen when loading about:blank or an empty html file. I also determined that it happens when running:

golfed
const { app, BrowserWindow } = require('electron')
const http = require('http');

async function createWindow() {
  const server = http.createServer((req, res) => {
    res.writeHead(200, {"Content-Type": "text/html"})
    res.end('<textarea></textarea>');
  }).listen(0);

  const win = new BrowserWindow()
  await win.loadURL(`http://localhost:${server.address().port}/`)
  win.webContents.debugger.attach('1.1')

  await win.webContents.debugger.sendCommand("Runtime.evaluate", {
    expression: "document.querySelector('textarea').focus()",
  });

  await win.webContents.debugger.sendCommand('Input.dispatchKeyEvent', {
    type: "keyDown",
    modifiers: 0,
    windowsVirtualKeyCode: 84,
    code: "KeyT",
    commands: [],
    key: "T",
    text: "T",
    unmodifiedText: "T",
    autoRepeat: false,
    location: 0,
    isKeypad: false
  })

  await win.webContents.debugger.sendCommand('Input.dispatchKeyEvent', {
    type: "keyUp",
    modifiers: 0,
    key: "o",
    windowsVirtualKeyCode: 79,
    code: "KeyO",
    location: 0
  })
}

app.whenReady().then(() => {
  createWindow().catch(e => console.error(e))
})
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

to rule out a red herring with creating the textarea via Runtime.evaluate

codebytere avatar Aug 09 '22 09:08 codebytere

Verdict: this was caused by CL:3212624. See also: CRBUG:1322971

Mitigation:

app.commandLine.appendSwitch('disable-features', 'PaintHoldingCrossOrigin');

codebytere avatar Aug 09 '22 17:08 codebytere

Some more answers to previous questions:

Why did it only surface on Electron?

  • It surfaced on Android as well
  • On Chromium it did not surface because we pass the --allow-pre-commit-input switch. The same what WebDriver is doing.

How do we mitigate it? We pass our existing args to Android CR process, so Android is happy. And we pass --allow-pre-commit-input to Electron, so Electron is happy.

Thanks @codebytere for the investigation and case closed!

mxschmitt avatar Aug 10 '22 10:08 mxschmitt