t.me/atinfo_chat Telegram группа по автоматизации тестирования

Как достичь определенного состояния загрузки страницы

Добрый день.
Подскажите, пожалуйста, как прописать ожидание определенной степени загрузки страницы? Или спустя некоторое время данную загрузку отключить. Нашла следующее, но что-то делаю не так:

# -*- coding: utf-8 -*-

from selenium.webdriver.firefox.webdriver import WebDriver
import unittest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def is_alert_present(wd):
    try:
        wd.switch_to_alert().text
        return True
    except:
        return False

class test_auth(unittest.TestCase):
    def setUp(self):
        self.profile = FirefoxProfile()
        self.profile.set_preference("WebDriver.load.strategy", "unstable")
        self.profile.update_preferences()
        self.wd = WebDriver(firefox_profile=self.profile)
        self.wd.implicitly_wait(60)
    
    def open_home_page(self, wd):
        wd.get("url")

    def login(self, wd, username, password):
        wd.find_element_by_css_selector(".form--body .inputDef:nth-child(3) .inputDef--input").click()
        wd.find_element_by_css_selector(".form--body .inputDef:nth-child(3) .inputDef--input").click()
        wd.find_element_by_css_selector(".form--body .inputDef:nth-child(3) .inputDef--input").send_keys(username)
        wd.find_element_by_css_selector(".form--body .inputDef:last-child .inputDef--input").click()
        wd.find_element_by_css_selector(".form--body .inputDef:last-child .inputDef--input").click()
        wd.find_element_by_css_selector(".form--body .inputDef:last-child .inputDef--input").send_keys(password)
        wd.find_element_by_css_selector(".button.button__primary").click()

    def move_to_shops(self, wd):
        #wait = WebDriverWait(wd, 30)
        #wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".leftPanel .leftPanel--menu .leftPanel--menuItem:nth-child(5) .leftPanel--menuLink")))
	wd.find_element_by_css_selector(".leftPanel .leftPanel--menu .leftPanel--menuItem:nth-child(5) .leftPanel--menuLink").click()

    def click_add(self, wd):
        #wait = WebDriverWait(wd, 30)
	#wait.until_not(EC.visibility_of_element_located((By.CSS_SELECTOR, '.loader')))
       	time.sleep(3)
        wd.find_element_by_css_selector('.decoratedOpacity .sectionWrap .secondaryTopPanel .secondaryTopPanel--left .button').click()

    def add_shop(self, wd, group_for_shop):
        wd.find_element_by_css_selector(".form--body .inputDef:first-child .inputDef--input").clear()
        wd.find_element_by_css_selector(".form--body .inputDef:first-child .inputDef--input").send_keys(group_for_shop.shopname)
        wd.find_element_by_css_selector(".form--body .inputDef:nth-child(2) .inputDef--input").click()
        wd.find_element_by_css_selector(".form--body .inputDef:nth-child(2) .inputDef--input").clear()
        wd.find_element_by_css_selector(".form--body .inputDef:nth-child(2) .inputDef--input").send_keys(group_for_shop.kpp)
        wd.find_element_by_css_selector(".form--body .addressArea:nth-child(3) .inputDef .inputDef--textArea").click()
        wd.find_element_by_css_selector(".form--body .addressArea:nth-child(3) .inputDef .inputDef--textArea").clear()
        wd.find_element_by_css_selector(".form--body .addressArea:nth-child(3) .inputDef .inputDef--textArea").send_keys(group_for_shop.address)
        wd.find_element_by_css_selector(".form .button").click()

    def test_add_shop1(self):
        wd = self.wd
        self.open_home_page(wd)
        self.login(wd, username="user", password="pass")
        self.move_to_shops(wd)
        self.click_add(wd)
        self.add_shop(wd, Group(shopname="Новая точка продаж", kpp="999999999", address=""))
        if ("Поле обязательно для заполнения" in wd.find_element_by_css_selector(".form--globalError").text):
            print("Адрес не введен")

    def test_add_shop2(self):
        wd = self.wd
        self.open_home_page(wd)
        self.login(wd, username="user", password="pass")
        self.move_to_shops(wd)
        self.click_add(wd)
        self.add_shop(wd, Group(shopname="", kpp="", address=""))
        if ("Новая точка продаж" in wd.find_element_by_css_selector(".form--globalError").text):
            print("Ни одно поле для добавления точки продаж не заполнено")


    def tearDown(self):
        self.wd.quit()

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

Также хотела бы уточнить, как правильнее использовать явные ожидания, так как опять же используемый вариант не работает, пришлось вставить time.sleep.
Дело в том, что при переходе из одного раздела в другой сначала появляется элемент loader, и если сразу кликать на нужную кнопку, то клик происходит не по ней, а по этому лоадеру.
Заранее благодарю за советы.

implicity и explicity ожидания не нужно использовать оба сразу

Вам нужно дождаться появления этого лоадера на странице, а затем его исчезновения, у меня была похожая проблема. У меня из-за лоадера просто вылетали ошибки, т.к. он делал не кликабельным все остальные элементы. Попробуйте поискать что-то вроде “ожидание элементов selenium” + требуемый язык, я думаю будет достаточно примеров. Есть отличная презентация про selenium, про паттерны и ожидания.