Cassano
Cassano

Reputation: 323

Selenium locate element fails when Chrome in background

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

Answers (3)

GR Rabby
GR Rabby

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

undetected Selenium
undetected Selenium

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.


References

You can find a couple of relevant detailed discussions in:

Upvotes: 2

cruisepandey
cruisepandey

Reputation: 29362

You should use either one of the below locators before jumping to XPath.

  1. ID
  2. name
  3. classname
  4. linkText
  5. partialLinkText
  6. tagName
  7. css selector
  8. 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

Related Questions