How to Fix 'TypeError: __init__() takes 2 positional arguments but 3 were given' in Selenium's Invisibility_of_Element_Located

If you’re working with Selenium WebDriver to automate web testing, you’ve likely used explicit waits to handle dynamic content. A common scenario is waiting for an element to become invisible (e.g., a loading spinner disappearing after a page loads). However, you might encounter the error: TypeError: __init__() takes 2 positional arguments but 3 were given when using Invisibility_of_Element_Located.

This blog post demystifies this error, explains its root causes, and provides step-by-step solutions with examples to help you resolve it quickly. Whether you’re a beginner or an experienced Selenium user, this guide will clarify how to correctly use Invisibility_of_Element_Located in your automation scripts.

Table of Contents#

  1. Understanding the Error
  2. What is Invisibility_of_Element_Located?
  3. Common Causes of the Error
  4. Step-by-Step Fix
  5. Example Scenarios: Incorrect vs. Correct Code
  6. Best Practices to Avoid This Error
  7. Conclusion
  8. References

Understanding the Error#

Let’s start by breaking down the error message:
TypeError: __init__() takes 2 positional arguments but 3 were given

  • __init__(): This is the constructor method of a Python class, responsible for initializing new objects.
  • takes 2 positional arguments: The constructor expects 2 arguments in total. In Python, the first argument to __init__ is always self (a reference to the instance itself), so this means the constructor requires 1 additional positional argument (beyond self).
  • but 3 were given: Your code is passing 3 arguments to the constructor (including self), which exceeds the expected count.

What is Invisibility_of_Element_Located?#

Invisibility_of_Element_Located is a class in selenium.webdriver.support.expected_conditions (often imported as EC). It is used with WebDriverWait to wait until a target element is no longer visible on the page.

Purpose:#

  • Ideal for scenarios like waiting for a loading spinner, pop-up, or temporary message to disappear.
  • Returns True when the element is invisible (or not present in the DOM); otherwise, it raises a TimeoutException if the wait exceeds the specified duration.

Correct Constructor Signature:#

The Invisibility_of_Element_Located constructor accepts exactly one argument: a locator tuple defining how to find the element. The locator tuple follows the format:
(By.STRATEGY, "value")

Where:

  • By.STRATEGY: The method to locate the element (e.g., By.ID, By.XPATH, By.CSS_SELECTOR).
  • "value": The identifier for the strategy (e.g., id="loader", xpath="//div[@class='spinner']").

Common Causes of the Error#

The primary cause of TypeError: __init__() takes 2 positional arguments but 3 were given is passing the locator components as separate arguments instead of a single tuple.

Example of Incorrect Usage:#

from selenium.webdriver.support import expected_conditions as EC
 
# ❌ Incorrect: Passing locator components as separate arguments
EC.invisibility_of_element_located(By.ID, "loading-spinner")

Here, By.ID and "loading-spinner" are passed as two separate arguments to Invisibility_of_Element_Located. Since the constructor expects only one argument (the locator tuple), Python interprets this as:
Invisibility_of_Element_Located(self, By.ID, "loading-spinner")
This results in 3 arguments (self, By.ID, "loading-spinner"), triggering the error.

Step-by-Step Fix#

To resolve the error, wrap the locator components in a tuple so they are treated as a single argument.

Step 1: Understand the Locator Tuple#

The locator must be a tuple (By.STRATEGY, "value"). For example:

  • (By.ID, "loading-spinner")
  • (By.XPATH, "//div[@class='loader']")

Step 2: Correct the Code#

Pass the locator tuple to Invisibility_of_Element_Located instead of separate arguments.

Example of Correct Usage:#

from selenium.webdriver.support import expected_conditions as EC
 
# ✅ Correct: Passing locator as a single tuple
EC.invisibility_of_element_located((By.ID, "loading-spinner"))

Now, only one argument (the tuple) is passed to the constructor:
Invisibility_of_Element_Located(self, (By.ID, "loading-spinner"))
This matches the expected 2 arguments (self + 1 locator tuple), resolving the error.

Example Scenarios#

Let’s walk through full working examples to see the error in context and how to fix it.

Scenario 1: Waiting for a Spinner to Disappear#

Suppose you want to wait 10 seconds for a loading spinner (with id="loader") to become invisible before interacting with the page.

Incorrect Code (Triggers Error):#

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
 
driver = webdriver.Chrome()
driver.get("https://example.com")
 
try:
    # ❌ Incorrect: Locator components passed separately
    WebDriverWait(driver, 10).until(
        EC.invisibility_of_element_located(By.ID, "loader")  # Error here!
    )
    print("Spinner is invisible. Proceeding...")
except TypeError as e:
    print(f"Error: {e}")  # Output: TypeError: __init__() takes 2 positional arguments but 3 were given
finally:
    driver.quit()

Correct Code (Fixes Error):#

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
 
driver = webdriver.Chrome()
driver.get("https://example.com")
 
try:
    # ✅ Correct: Locator wrapped in a tuple
    WebDriverWait(driver, 10).until(
        EC.invisibility_of_element_located((By.ID, "loader"))  # Fixed!
    )
    print("Spinner is invisible. Proceeding...")
except TimeoutException:
    print("Spinner did not disappear within 10 seconds.")
finally:
    driver.quit()

Scenario 2: Using XPath Locator#

If you’re using By.XPATH, the fix is identical—wrap the strategy and value in a tuple.

Incorrect:#

# ❌ Incorrect
EC.invisibility_of_element_located(By.XPATH, "//div[@class='popup']")

Correct:#

# ✅ Correct
EC.invisibility_of_element_located((By.XPATH, "//div[@class='popup']"))

Scenario 3: Full Workflow with WebDriverWait#

Here’s a complete example of waiting for an element to become invisible using WebDriverWait:

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 selenium.common.exceptions import TimeoutException
 
# Initialize driver
driver = webdriver.Chrome()
driver.get("https://example.com/login")
 
# Click a button that triggers a loading spinner
driver.find_element(By.ID, "submit-btn").click()
 
try:
    # Wait 15 seconds for the spinner to disappear
    WebDriverWait(driver, 15).until(
        # ✅ Correct: Locator tuple for the spinner
        EC.invisibility_of_element_located((By.CSS_SELECTOR, "div.spinner"))
    )
    print("Spinner is invisible. Logged in successfully!")
except TimeoutException:
    print("Timeout: Spinner did not disappear.")
finally:
    driver.quit()

Best Practices to Avoid the Error#

1. Always Use Locator Tuples#

For all Selenium expected conditions that require a locator (e.g., presence_of_element_located, visibility_of_element_located), pass the locator as a tuple (By.STRATEGY, "value").

2. Import By Explicitly#

Ensure By is imported from selenium.webdriver.common.by to avoid undefined errors:

from selenium.webdriver.common.by import By  # Required for locator strategies

3. Validate Locators First#

Test locators in browser dev tools (e.g., Chrome DevTools) to ensure they target the correct element. Invalid locators won’t trigger this TypeError but may cause TimeoutException.

4. Avoid Extra Arguments#

Never pass additional arguments (e.g., timeouts) to Invisibility_of_Element_Located. Timeouts are handled by WebDriverWait, not the expected condition:

# ✅ Correct: Timeout is set in WebDriverWait, not the expected condition
WebDriverWait(driver, 10).until(EC.invisibility_of_element_located((By.ID, "loader")))

Conclusion#

The TypeError: __init__() takes 2 positional arguments but 3 were given in Invisibility_of_Element_Located is a common but easily fixable mistake. It occurs when the locator is passed as separate arguments instead of a single tuple. By wrapping the locator strategy and value in a tuple (By.STRATEGY, "value"), you ensure the constructor receives the correct number of arguments.

Remember: Consistently using locator tuples with Selenium expected conditions will prevent this error and make your automation scripts more robust.

References#