Login in pop-up using Selenium and Python - python-3.x

I am trying to login on a website using the selenium webdriver in Python 3. First, I need to click the button "Inloggen", after which I need to fill in username and password and than click the (new) button "Inloggen" again.
So, I've tried to locate the first "Inloggen" button (with the code below), and tried to .click() it, but then it raises an error "selenium.common.exceptions.WebDriverException: Message: ", but without message.
from selenium import webdriver
# go to login page and sign in
driver = webdriver.Firefox()
driver.get("https://www.qassa-nl.be/")
driver.find_element_by_xpath("//a[#title='Inloggen']").click()
Secondly, if this works, I can send my login keys using the classic way I guess.
Best,
Tim

Here is the Answer to your Question:
Here is the working code block which will open the url https://www.qassa-nl.be/, click on button Inloggen, fills up email, fills up password and finally clicks on Inloggen button:
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
binary = FirefoxBinary('C:\\Program Files\\Mozilla Firefox\\firefox.exe')
caps = DesiredCapabilities().FIREFOX
caps["marionette"] = True
driver = webdriver.Firefox(capabilities=caps, firefox_binary=binary, executable_path="C:\\Utility\\BrowserDrivers\\geckodriver.exe")
driver.get("https://www.qassa-nl.be/")
driver.find_element_by_xpath("//div[#id='personal_info']//a[text()='Inloggen']").click()
driver.find_element_by_xpath("//input[#id='login_username']").send_keys("debanjan")
driver.find_element_by_xpath("//input[#id='login_password']").send_keys("debanjan")
driver.find_element_by_xpath("//button[#title='Inloggen']").click()
Let me know if this Answers your Question.

Related

How to check if Open File dialog has been open after pressing a button in a Chrome Browser tab on Python?

I'm trying to automate a process within the OpenSea Create page after having logged in with Metamask, and so far, I have managed to develop a simple program that chooses a particular image file using a path which passes to the Open File dialog "implicitly", here's the code:
import pyautogui
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
def wait_xpath(code): #function to wait for the xpath of an element to be located
WebDriverWait(driver, 60).until(EC.presence_of_element_located((By.XPATH, code)))
opt = Options() #the variable that will store the selenium options
opt.add_experimental_option("debuggerAddress", "localhost:9222") #this allows bulk-dozer to take control of your Chrome Browser in DevTools mode.
s = Service(r'C:\Users\ResetStoreX\AppData\Local\Programs\Python\Python39\Scripts\chromedriver.exe') #Use the chrome driver located at the corresponding path
driver = webdriver.Chrome(service=s, options=opt) #execute the chromedriver.exe with the previous conditions
nft_folder_path = r'C:\Users\ResetStoreX\Pictures\Cryptobote\Cryptobote NFTs\Crypto Cangrejos\SANDwich\Crabs'
start_number = 3
if driver.current_url == 'https://opensea.io/asset/create':
print('all right')
print('')
print(driver.current_window_handle)
print(driver.window_handles)
print(driver.title)
print('')
nft_to_be_selected = nft_folder_path+"\\"+str(start_number)+".png"
wait_xpath('//*[#id="main"]/div/div/section/div/form/div[1]/div/div[2]')
imageUpload = driver.find_element(By.XPATH, '//*[#id="main"]/div/div/section/div/form/div[1]/div/div[2]').click() #click on the upload image button
print(driver.current_window_handle)
print(driver.window_handles)
time.sleep(2)
pyautogui.write(nft_to_be_selected)
pyautogui.press('enter', presses = 2)
Output:
After checking the URL, the program clicks on the corresponding button to upload a file
Then it waits 2 seconds before pasting the image path into the Name textbox, for then pressing Enter
So the file ends up being correctly uploaded to this page.
The thing is, the program above works because the following conditions are met before execution:
The current window open is the Chrome Browser tab (instead of the Python program itself, i.e. Spyder environment in my case)
After clicking the button to upload a file, the Name textbox is selected by default, regardless the current path it opens with.
So, I'm kind of perfectionist, and I would like to know if there's a method (using Selenium or other Python module) to check if there's an Open File dialog open before doing the rest of the work.
I tried print(driver.window_handles) right after clicking that button, but Selenium did not recognize the Open File dialog as another Chrome Window, it just printed the tab ID of this page, so it seems to me that Selenium can't do what I want, but I'm not sure, so I would like to hear what other methods could be used in this case.
PS: I had to do this process this way because send_keys() method did not work in this page
The dialog you are trying to interact with is a native OS dialog, it's not a kind of browser handler / dialog / tab etc. So Selenium can not indicate it and can not handle it. There are several approaches to work with such OS native dialogs. I do not want to copy - paste existing solutions. You can try for example this solution. It is highly detailed and looks good.

Dismissing the accept privacy modal in selenium python

I am trying to get data from this site:
https://marketsmithindia.com/mstool/evaluation.jsp#details/symbol/VIDHIING
Once I open the page in Selenium it pops up the "Updated Privacy Policy" window. I tried using wait on the modal and click on it but it just times out. Here's the code I have tried:
click_button_path = "//[#class='modal-footer gdpr-notification-close']/[#class=''btn-primary']"
wait = WebDriverWait(driver, 10)
click_button = wait.until(EC.visibility_of_element_located((By.XPATH, click_button_path)))
click_button.click()
Later I figured that the accept button is stored as cookie and doesn't load once accepted. So I found a roundabout way. I saved the cookie using Eduard's answer here:
How to save and load cookies using Python + Selenium WebDriver
# You need to: from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium")
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("www.google.com") # Now you can see the cookies, the settings, extensions, etc., and the logins done in the previous session are present here.
This isn't perfect but solves my issue.

Login to Google with Selenium via stackoverflow error

I am trying to create a script that will login to my google slide presentations and update them. In order to do this with Selenium it appears I have to login each time which causes the 'This browser or app may not be secure' error page, shown below.
I researched online that you should be able to work around this by logging in through stackoverflow or another site that uses 'log in with google'. However my below attempt seems to still provide the same results. Following up on this, I wasn't able to find out if this is still doable or if this approach no longer works.
Could someone confirm if my approach is outdated or if there is something I've failed to grasp from my approach? Sorry if I've missed something basic, I've just started writing Python so I'm deep in the learning curve stage.
I'm using Ubuntu 20.04 if that's of any use.
Code
#!/usr/bin/env python3
import webbrowser
import pyautogui
import time
import sys
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
driver=webdriver.Firefox()
driver.implicitly_wait(30)
url='https://accounts.google.com/o/oauth2/auth/identifier?client_id=717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com&scope=profile%20email&redirect_uri=https%3A%2F%2Fstackauth.com%2Fauth%2Foauth2%2Fgoogle&state=%7B%22sid%22%3A1%2C%22st%22%3A%2259%3A3%3Abbc%2C16%3A7667a52eee989fc7%2C10%3A1611306467%2C16%3Ad5e975ab3e71c656%2Cb45db9f242e90237a65d3c06754d76a1f8a7bbfc93dffe8b19376a3a573f700e%22%2C%22cdl%22%3Anull%2C%22cid%22%3A%22717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com%22%2C%22k%22%3A%22Google%22%2C%22ses%22%3A%22451ca6a7a6c349248b04db280731cf23%22%7D&response_type=code&flowName=GeneralOAuthFlow'
driver.get(url)
username = driver.find_element_by_id("identifierId")
username.send_keys("fake.user#gmail.com")
my_btn = driver.find_element_by_id('identifierNext')
my_btn.click()
This is because automation testing frameworks are disabled by Google for security reasons
However, there are a few things you can do:
The easiest way: Open browser controlled by selenium, open stack overflow and perform authorisation manually. When you next run the script, it will log you in automatically.
Add arguments to the script that block web security:
from selenium.webdriver.firefox.options import Options
options = FirefoxOptions()
options.add_argument('--disable-web-security')
options.add_argument('--user-data-dir')
options.add_argument('--allow-running-insecure-content')
You can also do this in the terminal.
Login to stackoverflow with your google account, once logged in go to your email.
driver.get("https://accounts.google.com/signin/oauth/identifier?client_id=717762328687-iludtf96g1hinl76e4lc1b9a82g457nn."
+ "apps.googleusercontent.com&scope=profile%20email&redirect_uri=https%3A%2F%2Fstackauth"
+ ".com.com%2Fauth%2Foauth2%2Fgoogle&state=%7B%22sid%22%3A1%2C%22st%22%3A%2259%3A3%3Abbc%2C16%3Af343579f103b7116%2C10%3A1611315201%2C16%3A360adcabd84812cf%2Cc1c668aab33e5327311ff2c3a0cb356918a99d0d6cb65a0da11008340199a802%22%2C%22cdl%22%3Anull%2C%22cid%22%3A%22717762328687-iludtf96g1hinl76e4lc1b9a82g457nn.apps.googleusercontent.com%22%2C%22k%22%3A%22Google%22%2C%22ses%22%3A%225b28397546b247c7994c2d3cd480cc31%22%7D&response_type=code&flowName=GeneralOAuthFlow");
driver.find_element_by_id("identifierId")\ #entering username
.send_keys("email#gmail.com")
sleep(2)
driver.find_element_by_id("identifierNext").click() #clicking next
driver.find_element_by_name("password")\ #entering password
.send_keys("password")
driver.find_element_by_id("passwordNext").click()#clicking next
sleep(2)
driver.get("https://mail.google.com/mail/u/0/#inbox") #going to email inbox
Click Insert → Link or press Ctrl + K (Cmd + K in Mac). You can also click the Insert link button on the toolbar.and your connection problem or email id you can please refresh and restart.

How to click the Continue button using Selenium and Python

I'm trying to automate some tedious copy / paste I do monthly from my bank's online service via Selenium and Python 3. Unfortunately, I can't get Selenium to click the log-in link.
It's the blue continue button at https://www1.bmo.com/onlinebanking/cgi-bin/netbnx/NBmain?product=5.
Strangely, when I try to click that link manually in the browser launched by Selenium, it doesn't work either - whereas it does work in a browser I launch manually.
I suspect the issue is that the bank's website is smart enough to detect that I'm automating the browser activity. Is there any way to get around that?
If not, could it be something else?
I've tried using Chrome and Firefox - to no avail. I'm using a 64 bit Windows 10 machine with Chrome 73.0.3683.103 and Firefox 66.0.
Relevant code is below.
#websites and log in information
bmo_login_path = 'https://www1.bmo.com/onlinebanking/cgi-bin/netbnx/NBmain?product=5'
bmo_un = 'fake_user_name'
bmo_pw = 'fake_password'
#Selenium setup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
chrome_driver_path = 'C:\\Path\\To\\Driver\\chromedriver.exe'
gecko_driver_path = 'C:\\Path\\To\\Driver\\geckodriver.exe'
browswer_bmo = webdriver.Firefox(executable_path = gecko_driver_path)
#browswer_bmo = webdriver.Chrome(executable_path = chrome_driver_path)
#log into BMO
browswer_bmo.get(bmo_login_path)
time.sleep(5)
browswer_bmo.find_element_by_id('siBankCard').send_keys(bmo_un)
browswer_bmo.find_element_by_id('regSignInPassword').send_keys(bmo_pw)
browswer_bmo.find_element_by_id('btnBankCardContinueNoCache1').click()
Sending the keys works perfectly. I may actually have the wrong element ID (I was trying to test that in Chrome when I realized I couldn't click the link manually) - but I think the bigger issue is that I can't manually click the link in the browser launched by Selenium. Thank you for any ideas.
EDIT
This is a screenshot that I get of all I get when I try to click the continue button.
Ultimately the error message I get in my IDE (Jupyter Notebook) is:
TimeoutException: Message: timeout
(Session info: chrome=74.0.3729.108)
(Driver info: chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729#{#29}),platform=Windows NT 10.0.17134 x86_64)
To click on the button with text as Continue you can fill up the Card Number and Password field inducing WebDriverWait for the element_to_be_clickable() and you can use the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
options.add_argument('start-maximized')
options.add_argument('disable-infobars')
options.add_argument('--disable-extensions')
driver = webdriver.Chrome(chrome_options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.get('https://www1.bmo.com/onlinebanking/cgi-bin/netbnx/NBmain?product=5')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.dijitReset.dijitInputInner#siBankCard[name='FBC_Number']"))).send_keys("1234567890112233")
driver.find_element_by_css_selector("input.dijitReset.dijitInputInner#regSignInPassword[name='FBC_Password']").send_keys("fake_password")
driver.find_element_by_css_selector("span.dijitReset.dijitInline.dijitIcon.dijitNoIcon").click()
# driver.quit()
Browser Snapshot:
I was able to fix this issue and solve the problem by adding the following line below the options variables. This disables the chrome check for automation. I used the whole sale code and then added the following line in the correct location before starting the driver.
options.add_experimental_option("excludeSwitches", ['enable-automation'])
ref: https://help.applitools.com/hc/en-us/articles/360007189411--Chrome-is-being-controlled-by-automated-test-software-notification

Unable to locate the referenced ID using selenium and python

I am trying to locate a search box with id as (search2) from a website. I have been able to successfully login to the website using the below code.
import requests
from tqdm import tqdm
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(executable_path=r'C:\chromedriver_win32\chromedriver.exe', chrome_options=options)
driver.implicitly_wait(30)
tgt = "C:\\mypath"
profile = {"plugins.plugins_list": [{"enabled":False, "name":"Chrome PDF Viewer"}],
"download.default_directory" : tgt}
options.add_experimental_option("prefs",profile)
print(options)
driver.get("http://mylink.com/")
user=driver.find_element_by_id("username")
passw=driver.find_element_by_id("password")
user.send_keys("abc#xyz.com")
passw.send_keys("Pwd")
driver.find_element_by_xpath('/html/body/div[2]/div/div/div[2]/form/div[3]/button').click()
page=driver.find_element_by_id("search2")
print(page)
The code works perfectly till here but the moment I add the below to it I get an error
page.send_keys("abc")
The error that I get is as below.
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
What I am trying to do here is login to the website and search for some items and download the results. I have already tried using the implicitly wait options as mentioned in the code. Any help would be highly appreciated.
Adding the below piece of code did the trick. Had to make the current thread sleep while the program continues to run the next steps.
time.sleep(5)
Thanks everyone.

Resources