Фрагмент
EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, name.split(' ', 1)[0])) and
EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, name.split(' ', 1)[1]))
просто оценивает
EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, name.split(' ', 1)[1]))
Таким образом, он всегда проверяет только это условие и только это условие, то есть всегда пытается найти только Doe
, полностью игнорируя John
. Вот почему вы находите Jane Doe
, так как он появляется раньше.
Это не то, как вы проверяете несколько условий, вам нужно передать объект, похожий на функцию, в .until
, который может проверять несколько условий и возвращать истинное/ложное значение.
Для ваших конкретных потребностей эта функция может выглядеть так:
def presence_of_element_with_both(driver):
name = "John Doe"
first = EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, name.split(' ', 1)[0]))(driver)
second = EC.presence_of_element_located((By.PARTIAL_LINK_TEXT, name.split(' ', 1)[1]))(driver)
if first == second:
# Both elements exist and they are the same
return first
else:
return False
Это попытается найти элемент с частичным текстом ссылки Джон, а затем попытается найти элемент с частичным текстом ссылки Доу - если оба элемента найдены и если оба указывают на один и тот же элемент - вы золотой.
Вы можете использовать его в своем, пока так-
WebDriverWait(driver, 10).until(presence_of_element_with_both)
Однако вы можете счесть удобным обобщить это:
def presence_of_element_with_all(locators):
def inner(driver):
# Get all the elements that match each given locator
results = [EC.presence_of_element_located(locator)(driver) for locator in locators]
# Check if all the elements are the same
# If they are, all the conditions have been met
# If they are not, all the conditions did not meet
return results[0] if len(set(results)) == 1 else False
return inner
Это найдет сингулярный элемент, который удовлетворяет всем заданным локаторам.
Вы можете использовать это так:
first_name, last_name = "John Doe".split(' ')
WebDriverWait(driver, 10).until(presence_of_element_with_all([(By.PARTIAL_LINK_TEXT, first_name), (By.PARTIAL_LINK_TEXT, last_name)]))
Обратите внимание, что для этого я использую шаблон закрытия. Внутри selenium
использует class
с функцией __init__
и __call__
. сделать то же самое - это называется функцией, подобной объекту, и вы также можете использовать это, если хотите -
class presence_of_element_with_all:
def __init__(self, locators):
self.locators = locators
def __call__(self, driver):
results = [EC.presence_of_element_located(locator)(driver) for locator in self.locators]
# Check if all the elements are the same
# If they are, all the conditions have been met
# If they are not, all the conditions did not meet
return results[0] if len(set(results)) == 1 else False
Вы бы использовали это точно так же, как шаблон закрытия.
person
Chase
schedule
27.10.2020
.until
? так как вы по существу пытаетесь найти 2 элемента - person Chase   schedule 27.10.2020