I didn't find an answer to this. To automate some tests I have used Firefox and Selenium. I thought to give a try to Selenium 3.0 and its Marionette interface. Everything works with an old Firefox binary and the old webdriver way, so my code as such works.
For my tests I have created a Firefox profile, which I then pass to Selenium. Previously I did it like this:
p = webdriver.FirefoxProfile("profilename")
driver = webdriver.Firefox(firefox_profile=p, firefox_binary="/path/to/ff")
This works. My browser starts and whatever modifications it makes to the profile (cookies), seem to be there when I restart the browser with the same profile.
With Marionette/geckodriver the instructions tell me to use capabilities["profile"] for this, and they state this should be "Base64-encoded zip of a profile directory to use as the profile for the Firefox instance".
Ok. First, how do I create a base64-encoded zip in Python? Or do I just use shell for this?
Second, how does this work in practice? If I zip and base64 encode my profile directory, how do I then get the modified version back after my tests complete? If I created this file in shell and kept passing the same file for consecutive attempts, every modification, for example a login cookie, would be lost, and I would need to start from the scratch again, which in this case is not desirable.
I can keep using the old system at least for now, this is just to satisfy my curiosity.
Hannu
Related
I'm trying to do some chrome automation using selenium on python, and I want to have my login info saved for youtube, so that I don't have to automate the login process. I read that the way to have chrome read my saved info is by using the user-data-dir option, but I can't get it to work.
I have looked at some questions here, such as this, and they seem to indicate that the correct usage of the argument user-data-dir in selenium for chrome is the profile path inside: C:\Users\adassa\AppData\Local\Google\Chrome\User Data. Such as Default or Profile 1. I can't seem to get the intended result using this kind of path. The only path that works for me is the User Data folder itself.
So when I do:
chrome_options.add_argument("--user-data-dir=" + r'C:\\Users\\adassa\AppData\\Local\\Google\\Chrome\\User Data')
The chrome instance is opened with the preferences set for the default profile. But that only works correctly when I close all other instances of chrome, otherwise it raises the error: invalid argument: user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
Which I believe is caused by my manual chrome instance blocking access to the info on the folder because I'm using it. I read that I can create a new chrome profile, so that it doesn't conflict with the one I normally use, but if I create a new profile manually on chrome, and use the profile path, as in:
chrome_options.add_argument("--user-data-dir=" + r'C:\\Users\\adassa\AppData\\Local\\Google\\Chrome\\User Data\\Profile 1')
the new instance doesn't have the info I saved to the profile. That happens even if I use as path the User Data\Default folder. I have also tried different combinations using the option profile-dir, with no success.
After reading the docs, I tried using a folder that does not exist. In that case selenium does create the new folder, but when I try to login to youtube trough that selenium created instance, in order to save the info for the browser to use on the next time, I get this message (translation mine):
It was not possible to login. This browser or app may not be safe.
I would love to find a way to have my data saved so that I don't have to login everytime, and also not have to close all other chrome instances when running my script. Any help is appreciated.
chrome_options.add_argument("--user-data-dir=C:\\Users\\adassa\AppData\\Local\\Google\\Chrome\\User Data")
chrome_options.add_argument("--profile-directory=Profile 1")
as the name says usr-dir is for user-data folder and profile-directory is to specify the profile.
if profile folder is default , you don't have to specify that chrome takes it by default else specify it "--profile-directory=Profile 1"
I would like to create a new session for each tab I open and then control the sessions individually using Selenium python. Is this possible?
#reynoldsnp: Firefox has an official addon that does this, but I'm not sure if you can get selenium to interact with the addon. addons.mozilla.org/en-GB/firefox/addon/multi-account-containers If you figure out a way to do it, I would love to know how.
(I can't comment yet due to my reputation score, therefore quoted comment).
I don't know how to actually interact with the extension but if you have a known set of sites you would like to open:
Try this:
Make a firefox profile for your use with selenium. Multiple profiles
Windows 8/8.1/10:
Press Win + R on your keyboard.
Type firefox --new-instance --ProfileManager
Open Firefox in that profile by selecting the new profile in the setup wizard. Install the extension in that profile.
Set up the containers you would like in the extension, to, by default, open up with a specific site.
Ensure that the checkbox is ticked.
Start selenium with that profile like this:
from selenium import webdriver
profile = webdriver.FirefoxProfile('path/to/your/profile') # on windows found here: %APPDATA%/Mozilla/Firefox/Profiles
driver = webdriver.Firefox(firefox_profile=profile)
Navigate between tabs, effectively containers, using selenuium.
First, no, you cannot. While tabs runs as a process, they are attached to the session ID which initially open the browser. This is how the protocol works https://www.w3.org/TR/webdriver/#new-session
They have, however, a unique ID which you can use to identify them by and switch between them.
driver.window_handles
will give you the list of open tabs. Each tab is fully isolated. You can now choose between
driver.switch_to_window("any open tab taken from windows handles list")
driver.do_something
driver.switch_to_window("any other tab from windows handles list")
driver.do_something_else_on_other_tab
# or (this option can let you run in parallel)
driver a = ChromeDriver()
driver b = ChromeDriver()
a.do_something
b.do_something
As suggested (and I personally do myself) open new session for each tab you want, that way you can parallel them and run much faster, all in all.
I am not sure the performance difference is that significant between multiple browsers or multiple tabs... they should use almost the same resources.
Trynig to add a new, persistent, Firefox profile with Selenium. AFAIK, when executing FirefoxProfile(), a new profile is generated using a temporary file. Ideally, this profile should be able to remain available to subsequent processes - even after the creator is closed.
Problem:
Create a new Firefox profile from within Python code. This should return a FirefoxProfile object that is usable with the Firefox webdriver Selenium uses.
The profile created should persist after the process ends - i.e. it should be a full-fledged profile, not just a temporary profile.
Some pointers:
The profiles.ini file seems to be key. I have read some code that uses the Java class ProfilesIni to modify profile information. If this class is available for Python code, it should probably take care of most of this.
If the only way to do this is to manually modify the profiles.ini file, that's acceptable. A better, more standardized solution (one that uses a library or Selenium code) would be preferable, however.
Thanks very much!
If this helps anyone, what needs to be done is run:
firefox[.exe] -CreateProfile <profile_name>
The .exe in brackets is intended to provide for it being run under Windows.
Yes, this does not use the Selenium library in Python, but it does provide the desired result.
I'm experimenting with Firefox's WebDriver and I'd like to ask if it is possible to handle "Download" window (to accept or decline incoming download request)?
For example, simple piece of code:
import selenium.firefox.webdriver
dr = selenium.firefox.webdriver.WebDriver()
# Firefox is showed up.
# Let's say I'd want to download python.
dr.get('http://python.org/ftp/python/3.1.3/python-3.1.3.msi')
# Download window is showed up.
# How could I accept the download request?
# As I understand, the method below should return
# two handles but I get only main window's handle.
handles = dr.get_window_handles()
# Seems like WebDriver cannot "see" this popup.
I've experimented with this a little bit but haven't found the solution yet. I'd really appreciate any hint.
Many thanks,
- V
One solution to this is changing WebDriver's Firefox profile to automatically download some MIME types to a given directory.
I'm not sure how (or if) this is exposed in Python, but it's mentioned on the Ruby bindings page on the Selenium wiki (under "Tweaking Firefox preferences").
I don't think that this is the sort of thing that WebDriver was built for, but I'll take a crack at it. There is nothing built into the Firefox WebDriver to handle this specific case, but there are a few approaches you may take.
You can open FF with the profile that your WebDriver script uses and edit the preferences to always save the file instead of asking (Options > Applications > Windows Installer Package - set to "Save File"). Now, however, there's no way to tell that the file is downloading from the browser unless you get redirected to a 404 page. If not, you can check if the file exists in the Downloads directory for the same profile (Options > Main > Donwloads). If it's still in the process of downloading, the filename will be WhateverFileName.ext.part
Your other option is to use the non-visual HTMLUnit driver, navigate to the download link, click it, and the get the page source (will be the contents of the file). This works with textual files, I can't guarantee that it will work similarly for binaries, nor do I know how it will be encoded in such a case.
Best of luck
i came across this when i was trying to download a file using capybara
and got halted by the download prompt
SeleniumHQ : Selenium WebDriver
profile = Selenium::WebDriver::Firefox::Profile.new
profile['browser.download.dir'] = "/Downloads"
profile['browser.download.folderList'] = 2
profile['browser.helperApps.neverAsk.saveToDisk'] = "audio/wav"
driver = Selenium::WebDriver.for :firefox, :profile => profile
driver.navigate.to('http://www.address.com/file.wav')
this just downloads the file into the directory specified, no prompt :)
the other option that i came across was
Determining file MIME types to autosave using Firefox & Watir-WebDriver
i have tried watir before and it proved very useful
I'm not sure how to find this information, I have found a few tutorials so far about using Python with selenium but none have so much as touched on this.. I am able to run some basic test scripts through python that automate selenium but it just shows the browser window for a few seconds and then closes it.. I need to get the browser output into a string / variable (ideally) or at least save it to a file so that python can do other things on it (parse it, etc).. I would appreciate if anyone can point me towards resources on how to do this. Thanks
using Selenium Webdriver and Python, you would simply access the .page_source property to get the source of the current page.
for example, using Firefox() driver:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.example.com/')
print(driver.page_source)
driver.quit()
There's a Selenium.getHtmlSource() method in Java, most likely it is also available in Python. It returns the source of the current page as string, so you can do whatever you want with it
Ok, so here is how I ended up doing this, for anyone who needs this in the future..
You have to use firefox for this to work.
1) create a new firefox profile (not necessary but ideal so as to separate this from normal firefox usage), there is plenty of info on how to do this on google, it depends on your OS how you do this
2) get the firefox plugin: https://addons.mozilla.org/en-US/firefox/addon/2704/ (this automatically saves all pages for a given domain name), you need to configure this to save whichever domains you intend on auto-saving.
3) then just start the selenium server to use the profile you created (below is an example for linux)
cd /root/Downloads/selenium-remote-control-1.0.3/selenium-server-1.0.3
java -jar selenium-server.jar -firefoxProfileTemplate /path_to_your_firefox_profile/
Thats it, it will now save all the pages for a given domain name whenever selenium visits them, selenium does create a bunch of garbage pages too so you could just delete these via a simple regex parsing and its up to you, from there how to manipulate the saved pages