I want to keep Firefox Login status when using Selenium WebDriver (geckodriver). I used below python code:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time
try:
fp = webdriver.FirefoxProfile('C:/Users/admin/AppData/Roaming/Mozilla/Firefox/Profiles/mow8ff69.selenium')
options = Options()
options.headless = False
browser = webdriver.Firefox(fp, options=options)
browser.get('https://stackoverflow.com/users/login');
time.sleep(2)
txt_username = browser.find_element_by_id('email')
txt_username.clear()
txt_username.send_keys('***#gmail.com') #replace with your own username
time.sleep(1)
txt_password = browser.find_element_by_id('password')
txt_password.clear()
txt_password.send_keys('*****') #replace with your own password
time.sleep(1)
txt_password.submit()
time.sleep(10)
except Exception as ex:
print('Error: {0}'.format(ex))
finally:
browser.quit()
As shown above, I have been using a User Profile created by "Firefox -p". However, after running above code, when I reopen Firefox using that profile and then go to stackoverflow.com, I'm still not logged in.
So it looks like that Selinum WebDriver actually runs firefox in a "sandbox" which cannot write to the User Profile at all? I know that ChromeDriver has a "--no-sandbox" option but it doesn't seem to be available in geckodriver? Is there any workaround?
I cannot switch to ChromeDriver because there is another bug with it: the "--headless" option actually conflicts with "--user-data-dir" option whereas I really need both.
Related
I am trying to learn Selenium in Python and I have faced a problem which stopped me from processing.
As you might know, previous versions of Selenium have different syntax comparing the latest one, and I have tried everything to fill the form with my code but nothing happens. I am trying to find XPATH element from [https://demo.seleniumeasy.com/basic-first-form-demo.html] but whatever I do, I cannot type my message into the message field.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
import time
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
service = ChromeService(executable_path="C:/Users/SnappFood/.cache/selenium/chromedriver/win32/110.0.5481.77/chromedriver.exe")
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
time.sleep(1000)
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
By this code, I expect to fill the message field in the form and click the "SHOW MESSAGE" button to print my typed text, but what happens is that my code only opens a new Chrome webpage with empty field.
I have to mention that I don't get any errors by PyCharm and the code runs with no errors.
I would really appreciate if you help me through this to understand what I am doing wrong.
You need to wait for the page loads correctly.
For this, the best approach is using WebDriverWait:
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
# Wait for the page to load
wait = WebDriverWait(driver, 10)
wait.until(lambda driver: driver.find_element(By.XPATH, '//*[#id="user-message"]'))
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
Tested, it works fine.
Also you can use time.sleep() to wait the load if you know the loading times:
import time
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
time.sleep(5)
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
time.sleep(5)
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
time.sleep(5)
with this xpath you have two elements //*[#id="user-message"] . you need to make it unique. Try below xpath this will work as expected.
message_field = driver.find_element(By.XPATH,'//input[#id="user-message"]')
browser snapshot:
I have this code to log into cbt nuggets and afterwards i want to go into my playlists and collect some URLs
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support import ui
capabilities = DesiredCapabilities.CHROME
capabilities["goog:loggingPrefs"] = {"performance": "ALL"} # chromedriver 75+
options = webdriver.ChromeOptions()
options.add_argument(f"user-data-dir={userdata_path}") #Path to your chrome profile
# options.add_experimental_option("excludeSwitches", ['enable-automation'])
# options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors", "safebrowsing-disable-download-protection", "safebrowsing-disable-auto-update", "disable-client-side-phishing-detection"])
driver = webdriver.Chrome(executable_path=webdriver_path, options=options)
driver.get("https://www.cbtnuggets.com/login")
logs = driver.get_log("performance")
def page_is_loaded(driver):
return driver.find_element_by_tag_name("body") != None
#wait=ui.WebDriverWait(driver,300)
driver.implicitly_wait(10)
#wait.until(page_is_loaded)
USERNAME = driver.find_element_by_xpath('//*[#id="email"]')
USERNAME.send_keys("johndoe#gmail.com")
PASSWORD = driver.find_element_by_xpath("/html/body/div[1]/div[2]/main/div/div[1]/form/fieldset/div[2]/input")
PASSWORD.send_keys("password")
Login_Button=driver.find_element_by_xpath("/html/body/div[1]/div[2]/main/div/div[1]/form/fieldset/button")
Login_Button.click()
driver.get("https://www.cbtnuggets.com/learn/it-training/playlist/nrn:playlist:user:5fcf88f463ebba00155acb18/2?autostart=1")
it all works as expected, but when the last driver.get() executes, i get thrown back to the login page, but when i manually enter the second URL in the address bar it works as expected without having to log in again.
I dont know if this is a selenium issue, or if i am misunderstanding something about how HTTP Get works.
Have you tried to parse the login result? This might happen because the login request is not fully processed yet.
After Login_Button.click() you should check if the site is logged in successfully or not. You have many ways to check:
If the site redirects: check for the title of the page
If the site display a dialog: create a fluent wait to check for the dialog element to display
If you don't even bother to check, just add time.sleep(5). It's bad practice though.
After the check, now you use driver.get to go to the page you want.
I want to open several weblinks under a website in 1 browser (several tabs). The website requires login and password.
When login and password keyed in. it turns to a verification page, asks for the verification code sent to me by email.
I checked the email and key in verification code on the verification page. Login is successful.
The existing browser is in front of me.
However the codes are not picking it up, and open another tab as wanted. Seems a certain connection is lost.
How can I continue? (or as an alternative, how can Python to reuse the existing Chrome browser?)
The codes usually works well but comes to this case (login, enter verification code), it doesn't.
import os, time
from selenium.webdriver import ChromeOptions, Chrome
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
chromedriver = "C:\\Python27\\Scripts\\chromedriver.exe"
os.environ["webdriver.chrome.driver"] = chromedriver
opts = ChromeOptions() # leave browser open after code
opts.add_experimental_option("detach", True) # leave browser open after code
opts.add_argument('disable-infobars')
driver = webdriver.Chrome(chromedriver, chrome_options=opts) # leave browser open after code
driver.maximize_window()
verificationErrors = []
accept_next_alert = True
time.sleep(5)
base_url = "https://awebsite.com/"
driver.get(base_url)
window_0 = driver.window_handles[0]
driver.switch_to_window(window_0)
driver.find_element_by_id("username").clear()
driver.find_element_by_id("username").send_keys("username")
driver.find_element_by_id("password").clear()
driver.find_element_by_id("password").send_keys("password")
driver.find_element_by_id("Submit").click()
time.sleep(60)
driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + 't')
window_1 = driver.window_handles[1]
driver.switch_to_window(window_1)
time.sleep(3)
driver.get('https://anotherwebsite.com')
time.sleep(3)
sys.exit()
You can try below to perform some actions on two different pages/tabs:
# Handle base page
base_url = "https://awebsite.com/"
driver.get(base_url)
window_0 = driver.current_window_handle
...
# Handle new page
driver.execute_script('window.open("https://anotherwebsite.com");')
window_1 = [window for window in driver.window_handles if window != window_0][0]
driver.switch_to_window(window_1)
# driver.close() # To close new tab
...
# Switch back to base page
driver.switch_to_window(window_0)
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
#driver.set_preference("browser.startup.homepage_override.mstone", "ignore")
driver.get("https://url.aspx/")
username = driver.find_element_by_name("SchSel$txtUserName")
username.clear()
username.send_keys("username")
username.send_keys(Keys.RETURN)
password = driver.find_element_by_name("SchSel$txtPassword")
password.clear()
password.send_keys("pass")
password.send_keys(Keys.RETURN)
driver.get("https://.aspx")
assert "Welcome" in driver.page_source
driver.close()
I am running selenium for the first time .How many times I try blank page opens in fireFox
selenium.common.exceptions.WebDriverException: Message: The browser appears to have exited before we could connect. If you specified a log_file in the FirefoxBinary constructor, check it for details.
I think I had a similar problem and used the info at this link to help:
https://stackoverflow.com/a/30103931/6582364
Basically it suggests using xvfb and pyvirtualdisplay which wraps the firefox browser. Link also contains sample code. Doesn't take too long to install and get running but worked for me.
Hope this works for you too.
I am trying to submit information in a webpage, but selenium throws this error:
UnexpectedAlertPresentException: Alert Text: This page is asking you
to confirm that you want to leave - data you have entered may not be
saved. ,
>
It's not a leave notification; here is a pic of the notification -
.
If I click in never show this notification again, my action doesn't get saved; is there a way to save it or disable all notifications?
edit: I'm using firefox.
You can disable the browser notifications, using chrome options. Sample code below:
chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values.notifications" : 2}
chrome_options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(chrome_options=chrome_options)
With the latest version of Firefox the above preferences didn't work.
Below is the solution which disable notifications using Firefox object
_browser_profile = webdriver.FirefoxProfile()
_browser_profile.set_preference("dom.webnotifications.enabled", False)
webdriver.Firefox(firefox_profile=_browser_profile)
Disable notifications when using Remote Object:
webdriver.Remote(desired_capabilities=_desired_caps, command_executor=_url, options=_custom_options, browser_profile=_browser_profile)
selenium==3.11.0
Usually with browser settings like this, any changes you make are going to get throws away the next time Selenium starts up a new browser instance.
Are you using a dedicated Firefox profile to run your selenium tests? If so, in that Firefox profile, set this setting to what you want and then close the browser. That should properly save it for its next use. You will need to tell Selenium to use this profile though, thats done by SetCapabilities when you start the driver session.
This will do it:
from selenium.webdriver.firefox.options import Options
options = Options()
options.set_preference("dom.webnotifications.enabled", False)
browser = webdriver.Firefox(firefox_options=options)
For Google Chrome and v3 of Selenium you may receive "DeprecationWarning: use options instead of chrome_options", so you will want to do the following:
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
options = webdriver.ChromeOptions()
options.add_argument('--disable-notifications')
driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
Note: I am using webdriver-manager, but this also works with specifying the executable_path.
This answer is an improvement on TH Todorov code snippet, based on what is working as of Chrome (Version 80.0.3987.163).
lk = os.path.join(os.getcwd(), "chromedriver",) --> in this line you provide the link to the chromedriver, which you can download from chromedrive link
import os
from selenium import webdriver
lk = os.path.join(os.getcwd(), "chromedriver",)
chrome_options = webdriver.ChromeOptions()
prefs = {"profile.default_content_setting_values.notifications" : 2}
chrome_options.add_experimental_option("prefs",prefs)
driver = webdriver.Chrome(lk, options=chrome_options)