Задать вопрос
@its_southpaw

Как написать автоматизированный тест для тестирования сортировки по цене?

Логикой понимаю как это можно сделать, но толи идентификатор нужный найти не получается толи что-то делаю не так. На сайте https://arnypraht.com/category/bags/ есть span по клику на который открывается выпадающее меню с различными видами сортировки (конкретно интересуют цена по возврастанию и цена по убыванию) 6758b101d89dc665684857.jpeg 6758b11f9b9cf361220914.jpeg. При запуске моего теста, осуществляется переход на страницу с сумками, а клика по соответствующему span не происходит.

from selenium.webdriver.common.by import By
from pages.base_page import BasePage
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException

class FiltersPage(BasePage):
    # Локатор кнопки "Фильтры"
    FILTER_BUTTON = (By.CSS_SELECTOR, "button.button[data-filter-bar-opener]")

    # Локатор для списка доступных фильтров (по цветам, например)
    FILTER_LIST = (By.CSS_SELECTOR, "ul[data-switches='mse2_tvcolor']")

    # Локатор для отдельных пунктов фильтра
    FILTER_OPTION = (By.CSS_SELECTOR, "li.swatch.is-sorted.tooltipstered")

    # Локатор для закрытия фильтров
    CLOSE_FILTER_BUTTON = (By.CSS_SELECTOR, "button.cross[data-filter-bar-closer]")

    # Локатор названия цвета в карточке товара
    PRODUCT_COLOR_NAME = (By.CSS_SELECTOR, "div.card__subtitle.text--light.color-name[data-card-subtitle]")

    # Обновленные локаторы
    SORT_BUTTON = (By.CSS_SELECTOR, "span.select2-selection--single.select2-selection--buttoned")

    SORT_OPTION = (By.CSS_SELECTOR, "li.select2-results__option")
    ITEM_PRICE = (By.CLASS_NAME, "price")

    MENU_ITEM = (By.CLASS_NAME, 'header__menu-item')  # Локатор для пункта меню
    SORT_RENDERED = (By.CSS_SELECTOR, '[class="select2-selection__rendered"]')  # Локатор для кнопки сортировки
    SORT_ASC_OPTION = (By.ID, 'select2-catalog_sorting-dn-result-fnn9-price:asc')  # Локатор для варианта сортировки "Цена по возрастанию"

    def open_filters(self):
        """Открывает панель фильтров."""
        self.click(self.FILTER_BUTTON)

    def select_filter_option_by_index(self, index):
        """
        Выбирает пункт фильтра по индексу.

        :param index: Позиция элемента в списке фильтров (0 - первый элемент).
        """
        filter_options = self.find_elements(self.FILTER_OPTION)
        if 0 <= index < len(filter_options):
            filter_options[index].click()
        else:
            raise IndexError(f"Фильтр с индексом {index} не найден.")

    def close_filters(self):
        """Закрывает панель фильтров."""
        self.click(self.CLOSE_FILTER_BUTTON)

    def get_all_displayed_colors(self):
        """
        Возвращает список цветов всех отображаемых товаров.
        """
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_all_elements_located(self.PRODUCT_COLOR_NAME)
        )
        elements = self.find_elements(self.PRODUCT_COLOR_NAME)
        return [element.text.strip() for element in elements if element.text.strip()]

    def go_to_page(self):
        elements = self.driver.find_elements(By.CSS_SELECTOR, 'a.header__menu-item-link')

        menu_item = WebDriverWait(self.driver, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, 'a.header__menu-item-link'))
        )
        menu_item.click()

    def scroll_to_element(self, element):
        """
        Прокручивает страницу до указанного элемента.
        :param element: Веб-элемент, до которого нужно прокрутить.
        """
        self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", element)

    def select_sort_option(self, sort_option_text):
        """
        Кликает на кликабельный span, открывает выпадающее меню и выбирает нужный вариант сортировки.
        """
        try:
            # Ожидаем, пока span станет кликабельным
            sort_button = WebDriverWait(self.driver, 10).until(
                EC.element_to_be_clickable(self.SORT_BUTTON)
            )
            self.scroll_to_element(sort_button)
            sort_button.click()  # Кликаем по span, чтобы открыть выпадающее меню

            # Ожидаем появления выпадающего меню с опциями сортировки
            WebDriverWait(self.driver, 20).until(
                EC.presence_of_all_elements_located(self.SORT_OPTION)
            )

            # Находим нужный вариант сортировки и кликаем по нему
            sort_options = self.find_elements(self.SORT_OPTION)
            for option in sort_options:
                if option.text.strip() == sort_option_text:
                    self.scroll_to_element(option)
                    option.click()  # Кликаем по варианту сортировки
                    WebDriverWait(self.driver, 10).until(EC.staleness_of(option))  # Ждем обновления страницы
                    return
            raise ValueError(f"Не удалось найти вариант сортировки: {sort_option_text}")
        except TimeoutException:
            raise AssertionError("Не удалось найти span для сортировки или выпадающее меню.")

    def sort_by_price(self):
        """
        Выполняет сортировку товаров по цене по возрастанию и проверяет результат.
        """
        # Кликаем на пункт меню "Товары" (или подходящий пункт)
        menu_items = self.find_elements(self.MENU_ITEM)
        if len(menu_items) > 2:
            self.scroll_to_element(menu_items[2])
            menu_items[2].click()
        else:
            raise IndexError("Пункт меню для выбора товаров не найден.")

        # Кликаем на кнопку сортировки
        sort_button = self.find_element(self.SORT_RENDERED)
        self.scroll_to_element(sort_button)
        sort_button.click()

        # Выбираем вариант сортировки "Цена по возрастанию"
        sort_asc_option = self.find_element(self.SORT_ASC_OPTION)
        self.scroll_to_element(sort_asc_option)
        sort_asc_option.click()

    def get_sorted_prices(self):
        """
        Возвращает список цен с текущей страницы как числа.
        """
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_all_elements_located((By.CSS_SELECTOR, ".card .price"))
        )
        price_elements = self.find_elements((By.CSS_SELECTOR, ".card .price"))
        return [int(price.text.strip().replace(" ", "").replace("₽", "")) for price in price_elements if
                price.text.strip()]


import pytest
from pages.filters_page import FiltersPage



@pytest.mark.parametrize(
    "sort_option, expected_order",
    [
        ("Цена по возрастанию", "asc"),
        ("Цена по убыванию", "desc"),
    ],
)
def test_sort_by_price(browser, sort_option, expected_order):
    filters_page = FiltersPage(browser)
    filters_page.go_to_page()

    # Выбираем опцию сортировки
    filters_page.select_sort_option(sort_option)

    # Проверяем порядок цен
    prices = filters_page.get_sorted_prices()
    if expected_order == "asc":
        assert prices == sorted(prices), f"Цены не отсортированы по возрастанию: {prices}"
    elif expected_order == "desc":
        assert prices == sorted(prices, reverse=True), f"Цены не отсортированы по убыванию: {prices}"
  • Вопрос задан
  • 52 просмотра
Подписаться 1 Простой 5 комментариев
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
11 дек. 2024, в 22:30
250000 руб./за проект
11 дек. 2024, в 22:15
10000 руб./за проект
11 дек. 2024, в 22:10
3000 руб./за проект