My question comes from trying to understand the following code (which is meant to wait for a particular element to be loaded on the page before proceeding):
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# ... start chromium_driver
wait_timeout = 10
wait = WebDriverWait(chromium_driver, wait_timeout)
target_id = "CookiePopup"
target_element = wait.until(EC.presence_of_element_located((By.ID, target_id)))
I can understand what a locator is conceptually ("a way to identify elements on a page"), but I'm trying to wrap my head around its structure and specification as an object in this context (namely, the signature of EC.presence_of_element_located(locator)
). N.B., that the (By.ID, target_id)
part in the code above needs to be enclosed in parenthesis; i.e.,
EC.presence_of_element_located(By.ID, target_id)
causes
TypeError: __init__() takes 2 positional arguments but 3 were given
The documentation explains that "[a locator] is the argument passed to the Finding element methods".
The Finding element methods page shows that the find_element()
method in Python takes two arguments, which is the part that I find somewhat confusing:
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
In addition, By.CLASS_NAME
, By.ID
etc. are actually properties that contain strings ("class name" and "id" respectively).
Compare this to the Java (or any of the other languages) code:
WebElement vegetable = driver.findElement(By.className("tomatoes"));
which makes more sense: By.className()
is a method, which takes the (HTML) class name as an argument and returns a locator object that matches elements with that class name.
Given the above, would it be accurate to describe the locator as a tuple of two str, with the first string being the type of identifier used and the second string being the value of that identifier? And as a follow-up question, why is Python different in this way than the other languages?