-
Notifications
You must be signed in to change notification settings - Fork 228
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
Electron 10 and contextIsolation #693
Comments
Confirmed. It's failing for me with:
|
For me it just opens tons of electron and cmd windows, I have to abort it to make it stop, no error messages |
For me also opens tons of electron windows, and in the terminal I got that error |
Just chiming in that I'm having the same issue with the hundreds of windows opening. After upgrading to 10 I had to set |
@jkleinsc can you please have a look at this? we are still unable to use Electron 10 because of this :( |
Spectron unfortunately is written to use the remote module and setting Long term Spectron needs to be rewritten to not use the remote module. |
@jkleinsc this workaround doesn't work to get Spectron running with electron 10 as there are a few other blockers, like the chromium webdriver version mismatch. Even with enableRemoteModule: True, and manually modifying the dependency chain of electron to use the proper chrome webdriver version, spectron still opens hundreds of windows and fails with errors. Is there a plan to create a version of spectron (e.g. 12) that officially supports electron 10, at least until the remote module is completely deprecated? |
As mentioned in the issue description I think we need something that communicates between main and renderer through a preload contextbridge. The solution to this cant be "yeah just disable every suggested security feature and you can test your code" I switched so using puppeteer instead. |
@jkleinsc I'm also seeing this issue with Electron 10 opening multiple windows before failing, with the same error message about the ChromeDriver mismatch. This is with |
@Nawv can you try the newly released v12.0.0 version? |
Looks good so far, thanks John! |
@jkleinsc Yes, that's working for me - cheers! |
@Coding-Kiwi this issue is still not really resolved yet though, right? I believe that spectron still fails when |
@baparham Yes, I created this issue because we need a longterm solution. I really appreciate the 12.0.0 release but in the context of the issue, it is a make-shift solution just to get things running kinda. I understand that making spectron work without the remote module might require a major rework but I'd like this issue open so people who are experiencing issues with contextIsolation find this. |
I agree with @Coding-Kiwi about the original issue being not solved yet. However, it's nice to have a workaround allowing to use Electron 10. So thanks @jkleinsc |
^ Since a developer following the latest Electron security practices during app development (and/or just having default settings) then attempting to use Spectron will run into this issue and need to find this thread for the solution, I wonder if it is something that should be addressed in the README. My approach after following the README's Node Integration section was to reuse NODE_ENV to set web preferences: // main.js
const TESTING = process.env.NODE_ENV === 'test';
const envBasedWebPreferences = {
enableRemoteModule: TESTING,
contextIsolation: !TESTING,
};
// any new windows
new BrowserWindow({
...,
webPreferences: {
...envBasedWebPreferences,
...,
}
}) |
I tried all the solutions exposed here (including @NoneOfMaster suggestion) to use Spectron with
In Spectron, Does anyone managed to run Spectron when contextIsolation is set to true? |
@JulienBier I was under the impression that @NoneOfMaster suggestion was to set |
This will not work for several reasons:
|
This is right (and really helpful). I ran into it after writing a few more tests. So far, a conditional preload as follows, along with the // preload.js
const { contextBridge, ipcRenderer } = require('electron');
const api = {
// github.com/electron/electron/issues/21437#issuecomment-573522360
...safeApiMethods,
};
if (process.env.NODE_ENV === 'test') {
window.electronRequire = require; // github.com/electron-userland/spectron#node-integration
window.api = api;
} else {
contextBridge.exposeInMainWorld('api', api);
} |
Thanks for the help. I managed to get it to work by declaring the api in windows when running the e2e. |
This is a good idea. However, one thing needs to be added.
Summarizing all the above, we have the following solution (my example uses TypeScript): // main.ts
webPreferences: {
preload: 'path/to/preload.ts',
contextIsolation: !isTestMode, // Spectron tests can't work with contextIsolation: true
enableRemoteModule: isTestMode, // Spectron tests can't work with enableRemoteModule: false
}, // preload.ts
/**
* @see https://github.com/electron/electron/issues/21437#issuecomment-573522360
*/
const api = {
doThing: () => ipcRenderer.send('do-a-thing'),
... safeApiMethods
} as const
/**
* If contextIsolated enabled use contextBridge
* Else use fallback
*
* Note: Spectron tests can't work in isolated context
* @see https://github.com/electron-userland/spectron/issues/693#issuecomment-748482545
*/
if (process.contextIsolated) {
/**
* The "Main World" is the JavaScript context that your main renderer code runs in.
* By default, the page you load in your renderer executes code in this world.
*
* @see https://www.electronjs.org/docs/api/context-bridge
*/
contextBridge.exposeInMainWorld('electron', api)
} else {
/**
* Recursively Object.freeze() on objects and functions
* @see https://github.com/substack/deep-freeze
* @param o Object on which to lock the attributes
*/
function deepFreeze<T extends Record<string, any>>(o: T): Readonly<T> {
Object.freeze(o)
Object.getOwnPropertyNames(o).forEach(prop => {
if (o.hasOwnProperty(prop)
&& o[prop] !== null
&& (typeof o[prop] === 'object' || typeof o[prop] === 'function')
&& !Object.isFrozen(o[prop])) {
deepFreeze(o[prop])
}
})
return o
}
deepFreeze(api)
// @ts-expect-error https://github.com/electron-userland/spectron#node-integration
window.electronRequire = require
// @ts-expect-error https://github.com/electron-userland/spectron/issues/693#issuecomment-747872160
window.electron = api
} UPD UPD 2 |
Edit: This no longer works in Electron versions above 11I couldn't read // Spectron issue: https://github.com/electron-userland/spectron/issues/693
if ( contextBridge.internalContextBridge && contextBridge.internalContextBridge.contextIsolationEnabled ) {
/**
* The "Main World" is the JavaScript context that your main renderer code runs in.
* By default, the page you load in your renderer executes code in this world.
*
* @see https://www.electronjs.org/docs/api/context-bridge
*/
contextBridge.exposeInMainWorld( 'electron', api )
} else {
// ...
// deepFreeze from https://github.com/electron-userland/spectron/issues/693#issuecomment-748482545
window.electron = deepFreeze( api )
window.testing = true
// Github.com/electron-userland/spectron#node-integration
window.electronRequire = require
} |
@lacymorrow |
@cawa-93 I have no idea why it's not documented, maybe is supposed to be internal but it looks like it exactly reflects the value passed to |
as a small note, for anyone using webpack to transpile their typescript I had to alter window.electronRequire = require became --> window.electronRequire = eval('require'); Very good chance it's my poor webpack config knowledge 😅 and there's probably a better fix, but hope it helps someone. |
https://www.electronjs.org/docs/tutorial/using-selenium-and-webdriver#setting-up-spectron says: "Spectron is the officially supported ChromeDriver testing framework for Electron." It seems like there should be a prominent warning that Spectron has significant issues with recent versions of Electron (i.e. this issue). Not sure what process is for requesting a docs change (where to open an issue). |
@cawa-93 Why do you need to freeze the API |
@zhex900 From
So, if we simulate |
Thank ya'll so much. I've literally been on this ALL DAY. I'm updating the readme with this info on PR#1018. |
I have started working on a project called Spectroscope as an alternative to Spectron that doesn't require disabling all the security features and jumping through so many hoops to run your Electron tests while maintaining a secure application. Spectroscope is not compatible with the Spectron API but I'm sure if someone wanted to fix Spectron they could refer to Spectroscope for inspiration on how to. |
Could this be implemented in the https://github.com/electron/chromedriver repository? |
Spectron has not been updated to work with Electron 10 in a timely manner, and it seems like it may soon lose its ability to work with Electron at all. The only way to use spectron in the future is in completely security-disabled environments which then do not show the real-world case of an app. Currently the problems are:
contextIsolation:
From Electron Docs
enableRemoteModule
From Breaking Changes
I think it should be time to come up with a solution. I think in order to make spectron work with electron 10 and contextIsolation, the api needs a proper contextbridge script in the preload.js
The text was updated successfully, but these errors were encountered: