microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
67.32k stars 3.71k forks source link

[BUG] page.type() can’t type inside an Electron <webview> #9729

Open andersk opened 3 years ago

andersk commented 3 years ago

Context:

Code Snippet

// index.js
const { app, BrowserWindow } = require("electron");

app.whenReady().then(() => {
  const win = new BrowserWindow({
    webPreferences: { webviewTag: true },
  });
  win.loadFile("index.html");
});
app.on("window-all-closed", () => {
  app.quit();
});
<!-- index.html -->
<title>Test app</title>
<webview src="textarea.html"></webview>
<!-- textarea.html -->
<title>Text area</title>
<textarea id="text">initial text</textarea>
// test.js
const { _electron } = require("playwright-core");

(async () => {
  const app = await _electron.launch({ args: ["."] });
  const page = await app.waitForEvent("window");
  console.log("title =", await page.title());
  await page.type("#text", "NEW TEXT ");
  await page.waitForTimeout(1000);
  console.log("value =", await page.inputValue("#text"));
  await app.close();
})();

Describe the bug

When I try to use page.type() to type into a <textarea> inside an Electron <webview>, the <textarea> is focused, but no characters are added to it.

$ npm i electron playwright-core
$ node test.js
title = Text area
value = initial text

(Expected value = NEW TEXT initial text.)

andersk commented 3 years ago

This seems to be some kind of focus-related bug, because appending this to index.html makes it go away:

<script>
  window.addEventListener("DOMContentLoaded", () => {
    document.querySelector("webview").focus();
  });
</script>
andersk commented 2 years ago

This is still broken with current Playwright 1.27.1 and Electron 21.2.0. Thanks for reopening. (If there was further feedback I was supposed to provide for the P3-collecting-feedback label, what is it?)

johan-vd-merwe commented 1 year ago

I'd like to share some observations to the sample from @andersk. I have tested with electron v25.3.1 and playwright-core v1.36.1. If I was to modify the test function as below it works:

// test.js
const { _electron } = require("playwright-core");

(async () => {
    const app = await _electron.launch({ args: ["."] });
    // wait for load - there must be a more efficient way but await app.waitForEvent("window") doesn't work
    await new Promise(resolve => setTimeout(resolve, 1000));
    // the second window has the contents of the webview
    const [page1, page2] = app.windows();
    // focus the webview otherwise interactions won't work
    await page1.evaluate(() => document.querySelector("webview").focus())
    console.log("title =", await page2.title());
    await page2.type("#text", "NEW TEXT ");
    console.log("value =", await page2.inputValue("#text"));
    await app.close();
})();

I'm not sure if this sheds any light, but it got me going.