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

Access Electron APIs without IPC bridge #308

Open
goosewobbler opened this issue Nov 30, 2023 · 9 comments
Open

Access Electron APIs without IPC bridge #308

goosewobbler opened this issue Nov 30, 2023 · 9 comments
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed investigation required
Milestone

Comments

@goosewobbler
Copy link
Member

goosewobbler commented Nov 30, 2023

It may be possible to access the Electron APIs via some other mechanism than the IPC bridge in the user-imported main / preload scripts: for instance, Playwright does not appear to use an IPC bridge. Doing this would improve user experience from the first run as a user would no longer need to amend their application code to use the service. We should investigate the use of CDP to execute code in the main process.

https://webdriver.io/docs/devtools-service
https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-evaluate

@goosewobbler goosewobbler added enhancement New feature or request help wanted Extra attention is needed investigation required labels Nov 30, 2023
@goosewobbler goosewobbler added this to the 7.0.0 milestone Dec 12, 2023
@255kb
Copy link

255kb commented Feb 29, 2024

Very interested by this, for one specific reason: I build the app using electron-builder which prune the devDependencies during the packaging. It means that this package will not be available at runtime.
Bundling this package only during tests is a bit cumbersome to do.

@goosewobbler
Copy link
Member Author

goosewobbler commented Mar 1, 2024

@255kb Yes, this is likely to be a complex piece of work but I think it would be incredibly valuable for the ease of use of the service. The bundling issue is not one I have personally experienced since I routinely bundle my electron apps, but it certainly gives more confidence that finding an alternative to the IPC bridge should be the main feature in development of v7 of the service.

@goosewobbler
Copy link
Member Author

goosewobbler commented Aug 9, 2024

BiDi is recently supported by WDIO, and has something we might leverage:

https://w3c.github.io/webdriver-bidi/#command-script-callFunction

@goosewobbler
Copy link
Member Author

This is next up, will prototype with CDP first as the service isn't using BiDi yet; can follow up to enable BiDi and look to support BiDi IPC comms when it is enabled, falling back to CDP when it is not.

@goosewobbler
Copy link
Member Author

goosewobbler commented Aug 23, 2024

Prototyping CDP comms in https://github.com/webdriverio-community/wdio-electron-service/tree/sm/cdp-ipc-bridge-replacement, using cdp-web as a starting point.

An alternative to the fallback approach above is to skip CDP completely, just use BiDi and then give users the option of either using BiDi or sticking with the existing IPC bridge (the latter is perhaps required for older Electron / Chromium versions?)

@christian-bromann
Copy link
Contributor

using cdp-web as a starting point.

You should be able to call getPuppeteer to get the CDP instance for a Chromium session, no?

@goosewobbler
Copy link
Member Author

goosewobbler commented Aug 23, 2024

You should be able to call getPuppeteer to get the CDP instance for a Chromium session, no?

I tried different combinations of .page(), .pages(), .target(), .targets() with Page.evaluate but I think it's just evaluating code in the renderer and we want access to the electron APIs in the main process. I guess we need puppeteer.cdpsession.send; getPuppeteer gives us the Browser instance which doesn't have access. The reason I didn't go for Puppeteer immediately is that my investigation showed it likely to be too high level a solution, however I'm happy to be proven wrong...

Is there another way to get CDPSession with Puppeteer in WDIO?

@goosewobbler goosewobbler added documentation Improvements or additions to documentation WIP Work in progress and removed WIP Work in progress labels Aug 24, 2024
@goosewobbler goosewobbler self-assigned this Aug 24, 2024
@christian-bromann
Copy link
Contributor

Shouldn't it be:

const page = await browser.getPuppeteer()
const cdp = await page.createCDPSession()
await client.send('Animation.enable');
client.on('Animation.animationCreated', () =>
  console.log('Animation created!')
);
const response = await client.send('Animation.getPlaybackRate');
console.log('playback rate is ' + response.playbackRate);
await client.send('Animation.setPlaybackRate', {
  playbackRate: response.playbackRate / 2,
});

@goosewobbler
Copy link
Member Author

goosewobbler commented Aug 26, 2024

Thanks for that, now I have the session I'm now looking at how to get the correct execution context - alternatively, might be able to utilise this flat mode approach. The difference with what we're looking to achieve and that SO post is that the Electron main process isn't accessible from devtools, just the isolated context which I believe is where the preload script is run.

A fair bit of trial and error with this stuff. Here is what playwright does, for reference:

https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/electron/electron.ts
https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/electron/loader.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request help wanted Extra attention is needed investigation required
Projects
None yet
Development

No branches or pull requests

3 participants