1

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.

Cassano
  • 253
  • 5
  • 36

3 Answers3

2

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:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
1

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)
cruisepandey
  • 28,520
  • 6
  • 20
  • 38
  • Thank you so much. It seems to work much better now but I'll have to see if any issues arise. I have one last problem which is similar to this, and it's not working the same way. – Cassano Dec 20 '21 at 14:56
  • I have this code for follow button (to click on follow), but it doesn't work properly as well. I tried to search for name like you did above but couldn't find anything to locate other than xpath. Code: followuser = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="react-root"]/div/div/div[2]/main/div/div/div/div/div/div[2]/div/div/div[1]/div/div[1]/div[2]/div[3]/div/div'))) followuser.click() – Cassano Dec 20 '21 at 14:56
  • 1
    In that case, Please use XPath based on text `//span[text()='Follow']`, The locator that you are using should be unique in nature. XPath has the least precedence but it is one of the powerful locators. – cruisepandey Dec 20 '21 at 17:46
  • I just found out that the error still happens even with your new code, and using headless mode. – Cassano Dec 20 '21 at 20:34
1

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...

GR Rabby
  • 11
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community May 16 '23 at 09:20