Reputation: 323
This program works fine when you're focused on the window (Chrome), but when you switch to another window like Mozilla, or another app to continue doing your work, the Selenium fails to locate the element.
It should locate the element perfectly fine whether or not I open other apps over it, switch to other windows, and login without issues - that's what I want to accomplish so I can turn it into headless when it isn't giving me this error.
I tried to use driver waits too but to no avail.
The error I get:
selenium.common.exceptions.TimeoutException: Message:
Stacktrace:
Backtrace:
Ordinal0 [0x00986903+2517251]
Ordinal0 [0x0091F8E1+2095329]
Ordinal0 [0x00822848+1058888]
Ordinal0 [0x0084D448+1233992]
Ordinal0 [0x0084D63B+1234491]
Ordinal0 [0x00877812+1406994]
Ordinal0 [0x0086650A+1336586]
Ordinal0 [0x00875BBF+1399743]
Ordinal0 [0x0086639B+1336219]
Ordinal0 [0x008427A7+1189799]
Ordinal0 [0x00843609+1193481]
GetHandleVerifier [0x00B15904+1577972]
GetHandleVerifier [0x00BC0B97+2279047]
GetHandleVerifier [0x00A16D09+534521]
GetHandleVerifier [0x00A15DB9+530601]
Ordinal0 [0x00924FF9+2117625]
Ordinal0 [0x009298A8+2136232]
Ordinal0 [0x009299E2+2136546]
Ordinal0 [0x00933541+2176321]
BaseThreadInitThunk [0x770EFA29+25]
RtlGetAppContainerNamedObjectPath [0x77B47A9E+286]
RtlGetAppContainerNamedObjectPath [0x77B47A6E+238]
Code:
import tkinter as tk
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.chrome.options import Options
import time
from time import sleep
root = tk.Tk()
app_width = 300
app_height = 320
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = (screen_width / 2) - (app_width / 2)
y = (screen_height / 2) - (app_height / 2)
root.geometry(f'{app_width}x{app_height}+{int(x)}+{int(y)}')
testbtn_txt = tk.StringVar()
testbtn = tk.Button(root, textvariable=testbtn_txt, command=lambda:open_browser_func(), font="Arial", bg="#808080", fg="white", height=1, width=10)
testbtn_txt.set("Test")
testbtn.grid(row=10, column=0, columnspan=2, pady=5, padx=5)
def open_browser_func():
global driver
driver = webdriver.Chrome("C:\Program Files (x86)\chromedriver.exe")
driver.get("https://twitter.com/i/flow/login")
sleep(5)
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[5]/label/div/div[2]/div/input')))
loginuser.send_keys("Username")
sleep(5)
loginuser.send_keys(Keys.RETURN)
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[3]/div/label/div/div[2]/div[1]/input')))
loginuser.send_keys("Password")
sleep(5)
loginuser.send_keys(Keys.RETURN)
return driver
root.mainloop()
This is really annoying as it works sometimes, and sometimes not. I am unable to make this completely automated because of the error that happens when I switch to other processes.
Upvotes: 1
Views: 1504
Reputation: 11
Not sure about sendkeys but for click events try executing JavaScript like this ....
Submit = driver.find_element(By.XPATH, "Locator path")
driver.execute_script("arguments[0].click();", Submit)
This works in every worst case scenario including in the background process...
Upvotes: 1
Reputation: 193218
Selenium needs to focus on both:
When you bring another window like Mozilla, or another app to the foreground and continue doing your work Selenium looses the focus from the Browser Context. Hence you see the error.
You can find a couple of relevant detailed discussions in:
Upvotes: 2
Reputation: 29362
You should use either one of the below locators before jumping to XPath.
Also, make sure that you should not be using absolute xpath
, rather it should be relative xpath
.
So, Instead of these
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[5]/label/div/div[2]/div/input')))
loginuser.send_keys("Username")
sleep(5)
loginuser.send_keys(Keys.RETURN)
loginuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="layers"]/div/div/div/div/div/div/div[2]/div[2]/div/div/div[2]/div[2]/div[1]/div/div[3]/div/label/div/div[2]/div[1]/input')))
loginuser.send_keys("Password")
sleep(5)
loginuser.send_keys(Keys.RETURN)
Use this:
wait = WebDriverWait(driver, 30)
loginuser = wait.until(EC.visibility_of_element_located((By.NAME, "text")))
loginuser.send_keys("Username", Keys.RETURN)
loginPassword = wait.until(EC.visibility_of_element_located((By.NAME, "password")))
loginPassword.send_keys("password here", Keys.RETURN)
Upvotes: 1