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.
CodePudding user response:
You should use either one of the below locators before jumping to XPath.
- ID
- name
- classname
- linkText
- partialLinkText
- tagName
- css selector
- 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)
CodePudding user response:
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.
References
You can find a couple of relevant detailed discussions in: