Как перемещаться по вкладкам при помощи python и seleniumWD?

Все же закрыть другие окна нужно, так как есть определенные действия на странице, которые могут не сработать, если окно не в фокусе, например всяческие обработчики, навешанные на события перерисовки, браузер просто не будет их взвывать, если окно не в фокусе.

1 лайк

Такое решение будет работать в большинстве случаев, но не всегда. Так как список окон, который возвращает window_handles это неупорядоченный список (set), и в нем совсем не гарантируется то, что новые окна будут отсортированы в порядке появления и иметь соответствующие индексы, особенно в ситуациях, когда уже есть открытые окна. Но такие ситуации к счастью довольно редки.

1 лайк

А это надо заменить на явное ожидание:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

wait = WebDriverWait(driver, 10)
wait.until(ec.new_window_is_opened(old_windows))
#или
wait.until(ec.number_of_windows_to_be(3)) # 2,1 etc.
1 лайк

Я что-то не пойму тут. Что значит вот это?

wait.until(ec.new_window_is_opened(old_windows))

или это

wait.until(ec.number_of_windows_to_be(3)) # 2,1 etc.

Я сделал как вы написали. Но буквально на 5 шаге, где мне надо кликнуть по картинке, мой тест падает. Страница с картинкой после логина просто не успевает загрузиться.

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//div/*/img"}

Вот пример кода моего теста.

        driver = self.driver
        wait = WebDriverWait(driver, 10)  # ожидание
        driver.get(hostname)
        window_before = driver.window_handles[0]
        wait
        driver.find_element(By.XPATH, "//div/input[@name='username']").send_keys(username)
        wait
        driver.find_element(By.XPATH, "//div/input[@name='password']").send_keys(password)
        wait
        driver.find_element(By.XPATH, "//div/input[@name='code']").send_keys(code)
        wait
        driver.find_element(By.XPATH, "//em/button[@type='button']").click()
        wait
        driver.find_element(By.XPATH, "//div/*/img").click()
        wait
        driver.find_element(By.XPATH, "//div/div[contains(text(), 'Оператор')]").click()
        wait

Кажется я нашел где почитать. Извините, что отвлек. Selenium для Python. Глава 5. Ожидания / Habr

Вы не правильно вейт юзаете. Смотрите доки. 5. Waits — Selenium Python Bindings 2 documentation

Хехе. Я попробовал сделать по инструкции и немного запутался. может вы сможете помочь.

driver = self.driver
        wait = WebDriverWait(driver, 10)
        driver.get(hostname)
        window_before = driver.window_handles[0]
        wait.until(lambda driver: driver.find_element(By.XPATH, "//div/input[@name='username']").send_keys(username)) #измененный вариант по документации
    
        driver.find_element(By.XPATH, "//div/input[@name='password']").send_keys(password)

Во время прохождения теста, он не переходит ко второму шагу - ввода пароля, а застревает на первом и 10 секунд вводит логин в поле логин.

Что я делаю не так?

В итоге сделал вот так

        driver = self.driver
        wait = WebDriverWait(driver, 10)
        driver.get(hostname)
        window_before = driver.window_handles[0]
        element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div/input[@name='username']")))
        element.send_keys(username)
        element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div/input[@name='password']")))
        element.send_keys(password)
        element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div/input[@name='code']")))
        element.send_keys(code)
        element = wait.until(EC.element_to_be_clickable((By.XPATH, "//em/button[@type='button']")))
        element.click()
        element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div/*/img")))
        element.click()
        element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div/div[contains(text(), 'Оператор')]")))
        element.click()

И тест падает на том же самом месте когда надо кликнуть по картинке, со слипами такого не происходит.

У вас там ajax случаем нет? Ну и увас слишком много вейтов. Выберите что-то одно, что дольше всех грузится. После него и начинайте искать элементы. С каким эксепшеном падает тест?

Это extjs. Сначала появляется форма входа - я ввожу логин, пароль и т.д. Затем грузится страница после логина и там мне в главном меню надо перейти на другую страницу. Главное меню это раскрывающийся список. Я его открываю при помощи нажатия на “стрелочку вниз” - по xpath это обычная картинка (By.XPATH, “//div/*/img”). Если я ставлю sleep и затем кликаю по картинке, то все норм и все открывается. А в предыдущей реализации он мне пишет

Message: unknown error: Element <img src="extjs3.3/resources/images/default/s.gif"> is not clickable at point (319, 20)

Почему получается, что при sleep я жду когда страница откроется после логина и он нормально кликает, а при waits он мне пишет, что элемент не кликабельный.

Вам нужно дожидаться завершения ajax’а. Как это сделать с extjs, я вам не подскажу. Для jQuery делается как-то так:

@staticmethod
    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(_type, _locator)
                   and driver.execute_script("return $.active") == 0, message=message)
1 лайк

Уу-у-у это уже уровень. Посижу подумаю. А пока буду использовать sleep.

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

)) А где можно посмотреть какой элемент грузится позже всего на странице?

Глазами или через инструменты разработчика )

Может просто у вас есть опыт отслеживания таких элементов, поделитесь пожалуйста.

Я же говорю, либо на глаз, либо откройте инструменты разработчика и смотрите на вкладке Network какие запросы куда идут и в какой последовательности. Еще лучше спросить у разработчиков, они смогут подсказать более точно.

А почему никто не пользует PyAutoGUI · PyPI ?
Крутая библа же, проста как 3 копейки. Эмуляция набора с клавиатуры и действия мыши. Реализовываю работу с всплывающими окнами

1 лайк

Прикольно, а вы сами используете? Можете показать какой-нибудь пример? Кусок кода?

Помогите что делать если в моем случае Как отрыть новую вкладку с определенным url в фоном режиме (приложение самое ничего не открывает) - #12 от пользователя Tatyana_Durova пожалуйста!