I've got InvalidArgumentException when i used switch_to.window b

ghz 昨天 ⋅ 1 views

I've got InvalidArgumentException when i used switch_to.window by selenium / Python

I've seen many example script on how to use selenium switch_to.window

Here is an example script regarding what I learned, doesn't work at all:

    from selenium import webdriver
    from pprint import pprint
    
    browser = webdriver.Firefox()
    
    
    script="""
        myWindow = window.open("", "ChildWindow", "width=200,height=100");
    """
    browser.execute_script(script)
    
    wHandles = browser.window_handles
    pprint(wHandles)
    
    handle = wHandles[1]
    print(handle, type(handle))
    
    browser.switch_to.window(handle)

I've got that error message:

InvalidArgumentException: Expected "handle" to be a string, got [object Undefined] undefined

Obviously i tired with normal web page with same result a as well.

Is there anyone with same problem?

Answer

The issue you're encountering (InvalidArgumentException: Expected "handle" to be a string, got [object Undefined] undefined) occurs because the window handle you're passing to switch_to.window() is not being properly retrieved or passed.

Let's break down the issues and possible fixes:

1. The window_handles Method Returns List of Window Handles:

The window_handles method correctly returns a list of handles for all open browser windows. However, the error you're seeing suggests that something is going wrong when trying to retrieve the window handle.

2. Timing Issue:

After executing the window.open() JavaScript, the new window (or tab) may not have been fully created or ready before you attempt to switch to it. This can be especially true in the context of asynchronous behavior.

Solution Steps:

  1. Ensure that the new window is fully opened: You need to give the browser some time to open the new window, and then check the window handles list again.

  2. Using window_handles Correctly: You should retrieve the window handles after waiting for the new window to open.

Updated Example:

Here’s how you can adjust your script to make sure everything works correctly:

from selenium import webdriver
import time  # for adding delay (or use WebDriverWait for a more robust solution)
from pprint import pprint

# Initialize the WebDriver
browser = webdriver.Firefox()

# Open a blank window using JavaScript
script = """
    myWindow = window.open("", "ChildWindow", "width=200,height=100");
"""
browser.execute_script(script)

# Wait for the new window to be opened
time.sleep(2)  # Add a delay to give time for the window to open

# Get all window handles and print them
wHandles = browser.window_handles
pprint(wHandles)

# Ensure that there are more than 1 window handles (parent + child)
if len(wHandles) > 1:
    handle = wHandles[1]  # Get the second window handle (child window)
    print(handle, type(handle))
    
    # Switch to the child window
    browser.switch_to.window(handle)

    # Now you can interact with the new window
    print("Switched to new window")
else:
    print("No child window found")

Key Changes:

  1. Added a time.sleep(2): This gives the browser some time to actually open the new window before we try to switch to it. In practice, a more robust approach would be to use WebDriverWait, but this should suffice for now.

  2. Checked if there are more than one window handles: After opening the new window, it's important to check that the list window_handles actually contains more than one window handle.

  3. Switched to the child window properly: Once we confirm there is a second handle (the child window), we switch to it with switch_to.window(handle).

Optional: Using WebDriverWait

A more robust solution would be to use WebDriverWait to ensure the new window has been fully opened before switching. For example:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pprint import pprint

browser = webdriver.Firefox()

script = """
    myWindow = window.open("", "ChildWindow", "width=200,height=100");
"""
browser.execute_script(script)

# Wait for the new window to appear
WebDriverWait(browser, 10).until(EC.number_of_windows_to_be(2))

wHandles = browser.window_handles
pprint(wHandles)

handle = wHandles[1]
print(handle, type(handle))

browser.switch_to.window(handle)

# Now interact with the new window
print("Switched to the new window")

In this version:

  • WebDriverWait(browser, 10).until(EC.number_of_windows_to_be(2)) waits for exactly 2 windows to open (the parent and the new child window). This is more reliable than a fixed sleep delay.

Summary:

  • Make sure to add some delay or wait until the new window is fully opened.
  • Use the correct window handle from window_handles.
  • Ensure you're switching to the correct window (usually the second one, if it's the child).