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#
- Understanding the Error
- What is
Invisibility_of_Element_Located? - Common Causes of the Error
- Step-by-Step Fix
- Example Scenarios: Incorrect vs. Correct Code
- Best Practices to Avoid This Error
- Conclusion
- 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 alwaysself(a reference to the instance itself), so this means the constructor requires 1 additional positional argument (beyondself).but 3 were given: Your code is passing 3 arguments to the constructor (includingself), 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
Truewhen the element is invisible (or not present in the DOM); otherwise, it raises aTimeoutExceptionif 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 strategies3. 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.