Open lionelnicolas opened 1 year ago
@lionelnicolas Thanks for this reminder issue. Technically though it is still there. In that commit [2c1575baad97fdff0fac41d6dba03850908484eb] I did remove it, but just temporarily as I was still figuring out the design. I was going back and forth between a simple hotfix and a bit more log term design and architecture. It was added back in a28d3a9353cfb3f1211442c1e90e0ca248e6424c. Actually the title of that commit hints towards the decision of simple over complex. I would like to add in a Service class similar to the Options class that allows a user to easily set the Services on the browser. But for now left it simple.
Also I think it makes sense to remove the ff_profile_dir argument on the Open Browser keyword instead instructing people to add it to the options structure. @lionelnicolas , I would prefer to go ahead and keep this ticket open and i am attaching to the 6.2.0 milestone as a reminder of the issues around firefox_profile.
We have started to test on Firefox again and our years-old existing Open Browser (OB) is failing with popup that user profile cannot be found.
For a while we have used the selenium.webdriver python module to create a FirefoxProfile that is pass to OB.
From research I have found the creation of the FirefoxProfile is failing:
$ python
Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import selenium.webdriver
>>> sys.modules['selenium.webdriver'].FirefoxProfile()
<stdin>:1: **DeprecationWarning: firefox_profile has been deprecated, please use an Options object**
So I am not sure I understand how adding this option back will work. The solution we use was taken from the SeleniumLibrary Keywords doc years ago and checking the 6.1.2 version of this doc still shows this as a viable solution.
I am researching on how to use OB 'options' argument as also mentioned in the OB keyword section but nothing yet as I have just started and came upon this bug in my research.
So I wanted to ensure my understanding of the DeprecationWarning is correct.
For reference our RF code to open FF:
Open Firefox Browser
| | [Documentation] | Open page with Firefox browser
| | [Arguments] | ${url}
| |
| | ${folder-list} | Convert To Integer | 2
| | ${firefox profile}= | Evaluate | sys.modules['selenium.webdriver'].FirefoxProfile() | sys
| | Call Method | ${firefox profile} | set_preference | browser.download.lastDir | ${REPORT_DIR}
| | Call Method | ${firefox profile} | set_preference | browser.download.dir | ${REPORT_DIR}
| | Call Method | ${firefox profile} | set_preference | browser.download.folderList | ${folder-list}
| | Call Method | ${firefox profile} | set_preference | browser.download.useDownloadDir | false
| | Call Method | ${firefox profile} | set_preference | services.sync.prefs.sync.browser.download.useDownloadDir | false
| | Call Method | ${firefox profile} | set_preference | browser.download.manager.showWhenStarting | false
| | Call Method | ${firefox profile} | set_preference | browser.helperApps.neverAsk.saveToDisk | application/octet-stream,application/text
| | Open Browser | ${url} | browser=${BROWSER} | ff_profile_dir=${firefox profile}
Our versions used:
Tool | Version
---------------------+--------------------
Linux Dist | Ubuntu 22.04.2 LTS
Linux Kernel | 6.2.0-32-generic
Python | 3.10.6
RF | 6.0.2
RF Selenium | 6.1.1
RF Requests | 0.9.4
Selenium | 4.11.2
Requests | 2.30.0
Easysnmp2 | 0.3.1
Poster3 | 0.8.1
Pabot | 2.15.0
Geckodriver | 0.32.2
chromedriver | 113.0.5672.63
Chrome | 113.0.5672.126
Firefox | 117.0.1
Net-SNMP | 5.9.1
@glueologist I believe the following will correctly setup your Firefox as your previously had done, shown here within the context of a test case
*** Settings ***
Library SeleniumLibrary
Library DebugLibrary
*** Variables ***
${REPORT_DIR} ./.
${BROWSER} firefox
*** Test Cases ***
Test Open Browser with profile
Open Firefox Browser about:config
*** Keywords ***
Open Firefox Browser
| | [Documentation] | Open page with Firefox browser
| | [Arguments] | ${url}
| |
| | Open Browser | ${url} | browser=${BROWSER} | options=set_preference("browser.download.lastDir", "${REPORT_DIR}") ; set_preference("browser.download.dir", "${REPORT_DIR}") ; set_preference("browser.download.folderList", 2) ; set_preference("browser.download.useDownloadDir", ${False}) ; set_preference("services.sync.prefs.sync.browser.download.useDownloadDir", ${False}) ; set_preference("browser.download.manager.showWhenStarting", ${False}) ; set_preference("browser.helperApps.neverAsk.saveToDisk", "application/octet-stream,application/text")
| | Debug
Note I am using the DebugLibrary here which then you may need to install with pip install robotframework-debuglibrary
. Of course I am not closing the browser in the above test script so the debug pause might be overkill.
Also I was unsure myself in want form should the arguments for these preference take. I know from the selenium side they should be boolean, integer or string. But how did that translate into the string representation of the options. So I also tried, for example,
# | | Open Browser | ${url} | browser=${BROWSER} | options=set_preference("browser.download.useDownloadDir", "false") ;
but when reviewing the setting within the about:config page I see that this setting was true. So it appears string values should be quoted, integer values should be without quotes, and boolean should be a robot framework ${True} or ${False.}.
How I got to this solution included some misinformation from the Selenium docs. For configuring browsers I general start with the Selenium documentation. For example, there is the Firefox specific functionality page which has some raw Python code for the Profile and setting preferences. which shows
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
options=Options()
firefox_profile = FirefoxProfile()
firefox_profile.set_preference("javascript.enabled", False)
options.profile = firefox_profile
which I then interpret that preferences are set on the FirefoxProfile; similar to what you did. But if we look at the selenium python API for the Firefox Options class we see that the profile argument is a read-only parameter. There is though a set_preference
method on the option class. Knowing this is a method then we can use the string representation of the options like,
| | Open Browser | about:blank | firefox | options=<method>(<argiments>)
or more specifically for the set_preference method
| | Open Browser | about:blank | firefox | options=set_prefence("Key","Value")
Hopefully this is helpful. Sorry for the late reply but just saw your message on this.
As of commit 2c1575baad97fdff0fac41d6dba03850908484eb, it's not possible to set
firefox_profile
anymore.It's mentioned in the commit message that it needs to be re-added, so I'm just creating this ticket to log that TODO.