Проблема с ожиданиями в Chrome (Selenium + Python)

Столкнулась с тем, что Action Chains не работают в Firefox, вместо него для теста использовала Chrome.
Столкнулась с проблемой, что в хроме не работает implicitly_wait. Мне нужно проверять данные, которые подгружаются по ajax после изменения фильтров, точнее, изменения в url. Использование explict waits не подходит, так как новых уникальных элементов при выборе фильтров не появляется. Строка self.driver.implicitly_wait(30) хромом игнорируется и ссылка не успевает обновиться до проверки self.assertIn(val, url)
Вопрос: как в этом случае организовать ожидания? И можно ли сделать так, чтобы Хром не закрывал окно после теста?
Версия Селениум 3.0.2, версия хромдрайвер - последняя (2.8)

# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
import unittest, time, re
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException, TimeoutException, ElementNotVisibleException
from selenium.webdriver.common.action_chains import ActionChains

class TestPro(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='/home/katy/Downloads/chromedriver')
        self.mouse = webdriver.ActionChains(self.driver)
        self.driver.implicitly_wait(30)
        self.base_url = "http://сайт/"

    # def tearDown(self):
    #     self.driver.quit()

    def test_vertical_filters(self):
        driver = self.driver
        # open main
        self.driver.maximize_window()
        driver.get(self.base_url)

        # go to catalog
        print("Переход в каталог")
        driver.find_element_by_css_selector(".main__search button.search__submit").click()

        WebDriverWait(driver, 10).until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, ".filter__holder")),
            message='Вертикальные фильтры не найдены')

        # open all filters except first and second
        print("Открыть фильтры")
 
        input_price_max = driver.find_element_by_css_selector("#id_price_max")
        val = re.sub(r'\s', '', input_price_max.get_attribute('value'))
        val = int(val) - 500
        val = str(val)
        input_price_max.click()
        ActionChains(driver).key_down(Keys.CONTROL).send_keys('a').key_up(Keys.CONTROL).send_keys(val).click(filt_title).perform()
        self.driver.implicitly_wait(30)
        print("Проверка фильтра цены")
        url = driver.current_url
        self.assertIn(val, url)

if __name__ == "__main__":
    unittest.main()

С ajax вам нужно как-то дожидаться окончания его работы. Например для jQuery как-то так:

def wait_for_ajax(_type, _locator, timeout=5):
        message = "Element '%s' was not visible in %s second(s)." % (_locator, str(timeout))
        driver = SeleniumWrapper().driver
        wait = WebDriverWait(driver, timeout)
        wait.until(EC.element_to_be_clickable(_locator) and driver.execute_script("return $.active") == 0, message=message)

Либо искать другой элемент для ожидания, который точно загружается позже того что вам нужен.

1 лайк

Сам точно также использую на одном проэкте где есть JQuery. На другом проэкте где его нет у меня на питоне есть JavaScript ожидалка, правда с извратом. Но сам Simon Stewart мне написал что лучше всего использовать прокси для таких ожиданий.

а можно поподробнее про прокси?