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

API to set chromium preferences #3671

Closed
harunhasdal opened this issue Mar 8, 2019 · 15 comments
Closed

API to set chromium preferences #3671

harunhasdal opened this issue Mar 8, 2019 · 15 comments
Labels
browser: chromium type: feature New feature that does not currently exist

Comments

@harunhasdal
Copy link

Current behavior:

We can't specify chromium preferences when running Cypress tests.
This becomes an issue when tests require certain browser configuration which is different to the defaults.

An example is to disable the popup dialog for file downloads (requires download.prompt_for_download = true).

See more preferences in the link in this comment: #433 (comment)

Desired behavior:

A Cypress API to enable setting chromium preferences as key value pairs.
This could be a new API or an extension to one of the existing APIs such as the browser-launch-api or the configuration-api.

Versions

Valid for both Chrome and Electron setups.

@cypress-bot cypress-bot bot added the stage: ready for work The issue is reproducible and in scope label Mar 8, 2019
@jennifer-shehane jennifer-shehane added type: feature New feature that does not currently exist browser: chromium and removed stage: ready for work The issue is reproducible and in scope labels Mar 8, 2019
@jennifer-shehane
Copy link
Member

jennifer-shehane commented Mar 8, 2019

@baptistepattyn
Copy link

Is this ready yet?

@pardonmeme
Copy link

Is it a thing? The prompt disabling is crucial ._ .

@CSchulz
Copy link

CSchulz commented Oct 16, 2019

I just dived a little bit through the cypress code and in my opinion we could add a plugin event similar to before:browser:launch to allow passing some preferences to the profile.

It could be executed somewhere around here:

Promise.all([
@_writeExtension(
browser,
isTextTerminal,
options.proxyUrl,
options.socketIoRoute
),
_removeRootExtension(),
_disableRestorePagesPrompt(userDir),
])

The code for reading and writing the profile can be found here:

fs.readJson(prefsPath)
.then (preferences) ->
if profile = preferences.profile
if profile["exit_type"] != "Normal" or profile["exited_cleanly"] isnt true
debug("cleaning up unclean exit status")
profile["exit_type"] = "Normal"
profile["exited_cleanly"] = true
fs.writeJson(prefsPath, preferences)

@jennifer-shehane any thoughts on it? We can also discuss it in gitter, before I would start with a small PoC pull request.

@nmschulte
Copy link

nmschulte commented Nov 5, 2019

I use this work-around currently. I haven't tried a persistent --user-data-dir (a la exec chromium $@ --user-data-dir=~/.config/cypress-chromium), but that may work as well.

$ npx cypress run -b ./cypress/chromium.sh


$ cat cypress/chromium.sh

#!/usr/bin/env bash

USER_DATA_DIR=`cut -d "=" -f 2 <<< ${*: -2:1}`
mkdir $USER_DATA_DIR/Default > $USER_DATA_DIR/Default/Preferences
cat << END_Preferences > $USER_DATA_DIR/Default/Preferences
{
"profile":{"content_settings":{"exceptions":{"cookies":{"example.com,*":{"setting":1}}}}},
"devtools":{"preferences":{"currentDockState":"\"undocked\"","panel-selectedTab":"\"sources\"","Inspector.drawerSplitViewState":"{\"horizontal\":{\"size\":0,\"showMode\":\"Both\"}}"}},
"browser":{"app_window_placement":{"DevToolsApp":{"maiximized": true}}}
}
END_Preferences
exec chromium $@

@CSchulz
Copy link

CSchulz commented Nov 20, 2019

@nmschulte Your way doesn't work, because cypress is creating an own user data dir during startup.

Another way would be to have access on the Chrome Debugging Protocol.

@jennifer-shehane Do you know if there is any possibility to get the current connection?

@flotwig
Copy link
Contributor

flotwig commented Nov 20, 2019

@CSchulz you are able to make a connection to the Chrome DevTools Protocol in before:browser:launch, since you receive the --remote-debugging-port argument there, you know what port to use for your connection. The rest is just a matter of connecting to it and sending the commands you want.

@CSchulz
Copy link

CSchulz commented Nov 20, 2019

@flotwig Thanks for your input! I will try it, but it seems Electron doesn't use anything like that, right?

@flotwig
Copy link
Contributor

flotwig commented Nov 20, 2019

@CSchulz ah yes, good point, this will only work for Chrome-family browsers.

To clarify, are you asking for CDP access from your tests, or from your pluginsfile?

@CSchulz
Copy link

CSchulz commented Nov 20, 2019

@flotwig I want to use it in the plugins file but it seems not working, because the browser is launched after the complete event handling. Using timeout seems a little bit hacky.

@flotwig
Copy link
Contributor

flotwig commented Nov 20, 2019

@CSchulz I agree, it is a little bit hacky, right now that's the only way to do it unfortunately. I wrote a plugin that does a retry loop on before:browser:launch to connect to CDP, you can see how I did it here: https://github.com/flotwig/cypress-log-to-output/blob/master/src/log-to-output.js#L106-L142

@nmschulte
Copy link

@CSchulz it works for me; Chromium from Debian Sid. Chromium loads the Preferences stored in the specified dir; pressing F12 loads the dev tools in a separate window.

Cypress:    3.6.1
Browser:    Custom Chromium 78
Version 78.0.3904.97 (Developer Build) built on Debian bullseye/sid, running on Debian bullseye/sid (64-bit)

@flotwig does the Chrome DevTools Protocol allow to change the browser settings? https://stackoverflow.com/questions/57498081/chrome-devtools-protocol-interact-with-settings

@CSchulz
Copy link

CSchulz commented Nov 21, 2019

@nmschulte Yes you are right, it is using the same one for interactive mode, you can see it in the process explorer.

The chrome driver overwrites the user-data-dir always:

utils.ensureCleanCache(browser, isTextTerminal),
pluginsBeforeBrowserLaunch(options.browser, args),
port
])
.spread (cacheDir, args, port) =>
Promise.all([
@_writeExtension(
browser,
isTextTerminal,
options.proxyUrl,
options.socketIoRoute
),
_removeRootExtension(),
_disableRestorePagesPrompt(userDir),
])
.spread (extDest) ->
## normalize the --load-extensions argument by
## massaging what the user passed into our own
args = _normalizeArgExtensions(extDest, args)
## this overrides any previous user-data-dir args
## by being the last one
args.push("--user-data-dir=#{userDir}")
args.push("--disk-cache-dir=#{cacheDir}")

To your question you can change all the settings via chrome debug protocol:
https://chromedevtools.github.io/devtools-protocol/

@jennifer-shehane
Copy link
Member

jennifer-shehane commented Feb 18, 2020

Setting Chromium preferences was releasedin #6293 in Cypress 4.0.0. You can find the new documentation on how to do this in: http://on.cypress.io/browser-launch-api

@bkucera @flotwig I'd love if one of you could provide an example of how to pass the preferences for the scenarios above.

I'm not really sure what the original download.prompt_for_download = true was asking for though.

  • Download prompts do not display in Chrome
  • Download prompts display in Electron, but I don't see an available preference to pass to Electron to change this behavior.

@jennifer-shehane jennifer-shehane removed the stage: ready for work The issue is reproducible and in scope label Feb 18, 2020
@kuceb
Copy link
Contributor

kuceb commented Feb 18, 2020

see an example for setting the default download location here #6494

currently it will not work with --browser electron due to the way we launch electron on startup, so make sure you're using chrome/firefox in CI

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
browser: chromium type: feature New feature that does not currently exist
Projects
None yet
Development

No branches or pull requests

8 participants