web-ext
web-ext copied to clipboard
Unable to open the Extensions page with --start-url when running in Chrome
Is this a feature request or a bug?
Bug
What is the current behavior?
Running an extension in Chrome with --start-url "chrome://extensions" (or "about:extensions") fails to open the Extensions page. (The extensions page is useful for inspecting your extension's background page.)
Using --start-url to open about:debugging does work in Firefox.
Versions
Chrome 84 web-ext 5.0.0
It seems that Chrome does ignore chrome://extensions (also other chrome:// urls, like chrome://version) passed on the command line, e.g. executing on the command line
google-chrome http://developer.mozilla.org
does start Chrome with the given url loaded in the first tab
On the contrary:
google-chrome chrome://version
does start Chrome but it doesn't load that chrome url in the first tab.
I have the feeling that this may be an intended behavior, I briefly looked if Chrome does provide a command line flag to override this behavior, but at the moment I haven't spotted any that may be related.
We may have to close this as a wontfix if we don't have a way to tell Chrome to allow chrome:// urls as start urls, but for now I'm keeping this open to take another look and think a bit if there may be other options to achieve that.
Chrome extensions can open many chrome:-pages.
Chrome extensions can open many
chrome:-pages.
that's true, and I just verified that chrome://extensions is one of those that can be opened successfully using chrome.tabs.create, and so one option to fix this in web-ext would be to special case the chrome://extension url (or any chrome url) in the chrome extension runner and make the companion extension that we install automatically to auto-reload the target extension able to call chrome.tabs.create for us.
I'll mentor this bug.
Hi @Rob--W !
May I work on this bug? If yes, can I have the STR? I went through https://extensionworkshop.com/documentation/develop/getting-started-with-web-ext/, but a little more clarity on where chrome comes into the picture will be more helpful. Thanks!
@DeepikaKaranji Taking a step back, the core of the issue is that trying to open chrome://extensions doesn't work from the command line. Extensions are able to do so though, by passing that url to chrome.tabs.create.
web-ext uses a helper extension (via createReloadManagerExtension) in Chrome to support its functionality. To resolve this bug you have to forward the URL to that helper extension instead of the command line. The relevant source code is around these lines: https://github.com/mozilla/web-ext/blob/9353e260d016a6c301cac520fbdc57d5e3e89375/src/extension-runners/chromium.js#L153-L227
With those two code snippets, you can probably get started. Let me know if there are still questions!
Hey @DeepikaKaranji, how's it going with this issue?
Hello @caitmuenster , I was AFK for a bit, I've set up the environment, and I have gotten started with this issue yesterday.
@Rob--W
How I thought I'll approach this was:
- See what gets called when I run google-chrome http://developer.mozilla.org from command line.
- From that, understand which variable exactly holds the URL that is being passed in command line.
- See where that
httpURL is getting passed. - Find out when the
createReloadManagerExtensionis actually called. - And of course, other in-between things I need check as I work.
What I've understood/ not understood so far:
createReloadManagerExtension()is called everytimeChromiumExtensionRunnerobject is instantiated.bg.jsis run as a background task, but I'm not sure where to find bg.js to see what it does, and if I actually need to worry about it.- I can see that
setEnabledhas someextensionIDandvaluesin it, which is what I think I should carry thechrome:-URL, but I'm not too clear on why its being passed as a string tosetEnabled. I could also use some help in understanding how to log these values to see ifchrome:-URL is actually getting passed there when I do eventually write my logic. https://github.com/mozilla/web-ext/blob/bd2974b47c2ed80dd5f6d7b3afb755aed6660c61/src/extension-runners/chromium.js#L312-L331 - Can you also please tell me how I can achieve Step-1 in my above approach? Thank you.
@Rob--W
How I thought I'll approach this was:
- See what gets called when I run google-chrome http://developer.mozilla.org from command line.
This step is incorrect. I think that the misunderstanding is that you think that you need to change the behavior of how google-chrome [url] is handled. That is not the case; how Chrome handles command-line flags is not something that we can control.
google-chrome http://developer.mozilla.org works, and is not a surprise.
google-chrome chrome://extensions does not, however. That's why we want to filter that URL, and open it via the helper extension (in bg.js) instead. So the part to change is what parameters are passed to the Chrome binary (i.e. without chrome://extensions) and forward the URL in a different way instead (see below).
bg.jsis run as a background task, but I'm not sure where to find bg.js to see what it does, and if I actually need to worry about it.
bg.js is written to a temporary directory that is loaded as a background page of the helper extension. That directory is loaded as an extension via the --load-extension flag for Chrome.
- I can see that
setEnabledhas someextensionIDandvaluesin it, which is what I think I should carry thechrome:-URL, but I'm not too clear on why its being passed as a string tosetEnabled. I could also use some help in understanding how to log these values to see ifchrome:-URL is actually getting passed there when I do eventually write my logic.
setEnabled is not the interesting part. Rather, the part that handles the communication between the web-ext application and the helper extension is. A WebSocket is used for communication, and the message is received and handled at the ws.onmessage listener in bg.js. I suggest to look at how the (only) existing message is sent (you can search/grep for the message type in the code base) to try and understand how the communication happens.
Hey @DeepikaKaranji, how's it going with this issue?
Hi @caitmuenster ! I already spoke to @Rob--W and told him that have some exams going on right now. I will resume work on 20th October. He said its alright, so I hope its okay.
No worries at all, @DeepikaKaranji! :) Good luck on your exams!
@Rob--W @caitmuenster can I work on this issue, I have a rough idea about the solution now after reading the above conversation...
Hi @ariain , I have already started working on this, will make the PR soon. I hope that is okay. Thanks for understanding :)
Hi @ariain, there are some other good-first-bugs in our add-ons repositories if you'd like to work on one of those. It looks like this issue on the code manager repo is currently open, as is this issue in the webextension-polyfill repo.
@DeepikaKaranji I totally understand... @caitmuenster I would like to work on them, thanks for suggesting...
@Rob--W I wrote a small test in test-chromium.js (which I know isn't entirely right), so as to pass the "chrome://" urls and catch them.
it('does open chrome:// urls', async () => {
const {params} = prepareExtensionRunnerParams({
params: {startUrl: 'chrome://extensions'},
});
const runnerInstance = new ChromiumExtensionRunner(params);
await runnerInstance.run();
const {reloadManagerExtension} = runnerInstance;
sinon.assert.calledOnce(params.chromiumLaunch);
sinon.assert.calledWithMatch(params.chromiumLaunch, {
ignoreDefaultFlags: true,
enableExtensions: true,
chromePath: undefined,
chromeFlags: [
...DEFAULT_CHROME_FLAGS,
'--load-extension=${reloadManagerExtension},/fake/sourceDir',
],
startingUrl: 'chrome://extensions',
});
await runnerInstance.exit();
});
I added the below snippet at line 221 in chromium.js:
if (startingUrl.startsWith('chrome://')) {
console.log('*********** CAUGHT ************');
console.log(this.params.extensions);
this.reloadManagerExtension = await this.createReloadManagerExtension();
// Start chrome pointing it to a given profile dir
const PseudoExtension = [this.reloadManagerExtension].concat(
this.params.extensions.map(({sourceDir}) => sourceDir)
).join(',');
console.log(PseudoExtension);
}
chromeFlags.push(...startingUrls);
}
I called it PseudoExtension because from you have mentioned that Extensions are able launch "chrome://" URLs. I also think I should remove chromeFlags.push(), because my assumption is that any normal url is being added to the chromeFlags string array - to be executed by command line.
But in this case, I need to prevent that from happening, and pass the "chrome://" url to the createReloadManagerExtension helper extension.
The test however does not work, but I just wanted to check if I'm on the right track. Thank you!
The test expectation is incorrect. The chrome://extensions URL shouldn't be on the command line at all (because Chrome's command line does not support the chrome:-URL, which is what this bug is about).
I don't know what you're trying to do with the PseudoExtension. There is already an extension (the reload manager). You don't have to load a new extension or anything like that, just send a message to the existing extension.
Alright, I'll do that, thanks.
Hey @DeepikaKaranji, just wanted to check in with you about this issue. Are you still interested in working on it?
Hey @DeepikaKaranji, we are going to open this up to other contributors since we haven't heard from you in awhile. If you'd like to finish it off, please feel free to come back to it! O
Hello @caitmuenster, I was looking for good-first-issues in the add-ons repositories and this one seemed ideal - may I work on it?
Go for it, @CatWithNineLives! If you need any help, please tag [@]Rob--W in a comment.
Hey @CatWithNineLives, we haven't heard from you in awhile so we're going to open this up to other contributors. If you want to work on it, please feel free to submit a PR. :)
Hi @caitmuenster, I saw this issue a few days ago and realized that it's open for contribution. I would like to work on this bug and hopefully fix it if I may? :)
Hey @Rob--W. I have looked a bit in the code and based on your comments above, I believe I have an understanding how to fix this bug.
I have made some changes at chromium.js to detect presence of chrome://extensins in the url array list, and have added necessary code for Websocket communications also at chromium.js and chromium.js
My issue at the moment is that I can't seem to find the appropriate location in code to invoke the new websocket communication openTabWithExtensionsUrl() method which is supposed to communicates with bg.js, and get it to work. I invoke openTabWithExtensionsUrl() in chromium.js method setupInstance() after line this.chromiumInstance = await this.chromiumLaunch is run, which supposedly would launch chrome. But this has no effect, and when I look closely, at that stage wssBroadcast() isn't able to send messages to bg.js, because number of wss clients is zero. (code execution ends up in if (clients.size === 0) )
I tried to confirm this by testing what happens when I swap the current websocket message with the new one I created when R is pressed, so that whenever you press R to reload it sends the new message instead of webExtReloadAllExtensions, and then I can see that a new tab is being opened and loads chrome's extension page.
I'm not sure if there is some extra action taking place outside of chromium.js before which chrome is fully loaded, and asynchronous JavaScript isn't my strong side, so I'm a bit confused in the multitude of asyncs and promises used in code, so I'd appreciate if you could give me some tips. My current commit is available at https://github.com/kodergeek/web-ext/blob/bug-1979/src/extension-runners/chromium.js
You could wait for the first WebSocket connection and post the initialization message to open the extension tab.
Feel free to open a pull request for work-in-progress code; then it is easier to provide feedback at specific lines.
Thanks for your feedback. I have created a pull request so you can point to specific lines easily.