Skip to content

DropdownList

Модуль dropdown_list_component содержит класс для работы с выпадающими списками.

Класс DropdownList наследует базовый функционал BaseComponent и добавляет методы для взаимодействия с выпадающими списками на странице.

DropdownList

Bases: BaseComponent

Класс для работы с выпадающими списками.

Наследует функциональность BaseElement и добавляет специфичные методы для выбора и проверки элементов списка.

Source code in components\dropdown_list_component.py
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
class DropdownList(BaseComponent):
    """Класс для работы с выпадающими списками.

    Наследует функциональность BaseElement и добавляет специфичные
    методы для выбора и проверки элементов списка.
    """

    def __init__(self, page: Page):
        """Инициализирует компонент выпадающего списка.

        Args:
           page: Экземпляр страницы Playwright.
        """

        super().__init__(page)

    # Действия:
    def click_item_with_text(self, text: str) -> None:
        """Выбирает элемент списка по указанному тексту.

        Args:
            text (str): Текст элемента для выбора.
        """

        element = self.page.get_by_role("listitem").filter(has_text=text)
        if element.count() > 1:
            rtext = f"^{text}$"
            element = self.page.get_by_role("listitem").filter(has_text=re.compile(rtext))
        element.click()

    def get_item_names(self, locator: str | Locator) -> list[str]:
        """Возвращает тексты всех элементов по указанному локатору.

        Args:
            locator: Локатор элементов или строка с CSS/XPath.

        Returns:
            Список текстов элементов.
        """

        loc = self.get_locator(locator)
        texts = loc.all_inner_texts()
        return texts[0].splitlines()

    def scroll_until_end(self, locator: str | Locator) -> None:
        """
        Скроллит список до тех пор, пока не перестанут подгружаться новые элементы.

        Args:
            locator: Локатор элементов или строка с CSS/XPath.
        """

        loc = self.get_locator(locator)

        items_count = 0
        attempts = 0
        max_attempts = 3
        last_item_name = ""

        while attempts < max_attempts:
            self.page.wait_for_timeout(300)

            item_names = self.get_item_names(loc)
            current_count = len(item_names)

            if current_count == items_count:
                attempts += 1
            else:
                items_count = current_count
                attempts = 0

            last_item_name = item_names[current_count-1]
            element = self.page.get_by_role("listitem").filter(has_text=last_item_name)
            element.scroll_into_view_if_needed()

        self.page.wait_for_timeout(300)
        self.check_item_with_text(last_item_name)

    # Проверки:
    def check_item_with_text(self, text: str) -> None:
        """Проверяет наличие и доступность элемента списка.

        Args:
            text (str): Текст элемента для проверки.

        Raises:
            AssertionError: Если элемент отсутствует или недоступен.
        """

        element = self.page.get_by_role("listitem").filter(has_text=text)
        if element.count() > 1:
            rtext = f"^{text}$"
            element = self.page.get_by_role("listitem").filter(has_text=re.compile(rtext))
        enabled = element.is_enabled()
        if not enabled:
            assert False, f"Dropdown list item '{text}' is missing or disabled"

    def check_vertical_scrolling(self, locator: str | Locator) -> bool:
        """
        Проверяет функцию вертикального скроллинга списка.

        Args:
            locator: Локатор элементов или строка с CSS/XPath.

        Returns:
            True или False значение в зависимости от скроллируемый список или нет.
        """

        loc = self.get_locator(locator)

        is_scrollable_vertically = self.is_scrollable_vertically(loc)
        if  is_scrollable_vertically:
            self.scroll_until_end(loc)

            item_names = self.get_item_names(loc)
            first_item_name = item_names[0]

            self.scroll_up(loc)
            self.page.wait_for_timeout(300)
            self.check_item_with_text(first_item_name)

        return is_scrollable_vertically

__init__(page)

Инициализирует компонент выпадающего списка.

Parameters:

Name Type Description Default
page Page

Экземпляр страницы Playwright.

required
Source code in components\dropdown_list_component.py
20
21
22
23
24
25
26
27
def __init__(self, page: Page):
    """Инициализирует компонент выпадающего списка.

    Args:
       page: Экземпляр страницы Playwright.
    """

    super().__init__(page)

check_item_with_text(text)

Проверяет наличие и доступность элемента списка.

Parameters:

Name Type Description Default
text str

Текст элемента для проверки.

required

Raises:

Type Description
AssertionError

Если элемент отсутствует или недоступен.

Source code in components\dropdown_list_component.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def check_item_with_text(self, text: str) -> None:
    """Проверяет наличие и доступность элемента списка.

    Args:
        text (str): Текст элемента для проверки.

    Raises:
        AssertionError: Если элемент отсутствует или недоступен.
    """

    element = self.page.get_by_role("listitem").filter(has_text=text)
    if element.count() > 1:
        rtext = f"^{text}$"
        element = self.page.get_by_role("listitem").filter(has_text=re.compile(rtext))
    enabled = element.is_enabled()
    if not enabled:
        assert False, f"Dropdown list item '{text}' is missing or disabled"

check_vertical_scrolling(locator)

Проверяет функцию вертикального скроллинга списка.

Parameters:

Name Type Description Default
locator str | Locator

Локатор элементов или строка с CSS/XPath.

required

Returns:

Type Description
bool

True или False значение в зависимости от скроллируемый список или нет.

Source code in components\dropdown_list_component.py
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def check_vertical_scrolling(self, locator: str | Locator) -> bool:
    """
    Проверяет функцию вертикального скроллинга списка.

    Args:
        locator: Локатор элементов или строка с CSS/XPath.

    Returns:
        True или False значение в зависимости от скроллируемый список или нет.
    """

    loc = self.get_locator(locator)

    is_scrollable_vertically = self.is_scrollable_vertically(loc)
    if  is_scrollable_vertically:
        self.scroll_until_end(loc)

        item_names = self.get_item_names(loc)
        first_item_name = item_names[0]

        self.scroll_up(loc)
        self.page.wait_for_timeout(300)
        self.check_item_with_text(first_item_name)

    return is_scrollable_vertically

click_item_with_text(text)

Выбирает элемент списка по указанному тексту.

Parameters:

Name Type Description Default
text str

Текст элемента для выбора.

required
Source code in components\dropdown_list_component.py
30
31
32
33
34
35
36
37
38
39
40
41
def click_item_with_text(self, text: str) -> None:
    """Выбирает элемент списка по указанному тексту.

    Args:
        text (str): Текст элемента для выбора.
    """

    element = self.page.get_by_role("listitem").filter(has_text=text)
    if element.count() > 1:
        rtext = f"^{text}$"
        element = self.page.get_by_role("listitem").filter(has_text=re.compile(rtext))
    element.click()

get_item_names(locator)

Возвращает тексты всех элементов по указанному локатору.

Parameters:

Name Type Description Default
locator str | Locator

Локатор элементов или строка с CSS/XPath.

required

Returns:

Type Description
list[str]

Список текстов элементов.

Source code in components\dropdown_list_component.py
43
44
45
46
47
48
49
50
51
52
53
54
55
def get_item_names(self, locator: str | Locator) -> list[str]:
    """Возвращает тексты всех элементов по указанному локатору.

    Args:
        locator: Локатор элементов или строка с CSS/XPath.

    Returns:
        Список текстов элементов.
    """

    loc = self.get_locator(locator)
    texts = loc.all_inner_texts()
    return texts[0].splitlines()

scroll_until_end(locator)

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

Parameters:

Name Type Description Default
locator str | Locator

Локатор элементов или строка с CSS/XPath.

required
Source code in components\dropdown_list_component.py
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def scroll_until_end(self, locator: str | Locator) -> None:
    """
    Скроллит список до тех пор, пока не перестанут подгружаться новые элементы.

    Args:
        locator: Локатор элементов или строка с CSS/XPath.
    """

    loc = self.get_locator(locator)

    items_count = 0
    attempts = 0
    max_attempts = 3
    last_item_name = ""

    while attempts < max_attempts:
        self.page.wait_for_timeout(300)

        item_names = self.get_item_names(loc)
        current_count = len(item_names)

        if current_count == items_count:
            attempts += 1
        else:
            items_count = current_count
            attempts = 0

        last_item_name = item_names[current_count-1]
        element = self.page.get_by_role("listitem").filter(has_text=last_item_name)
        element.scroll_into_view_if_needed()

    self.page.wait_for_timeout(300)
    self.check_item_with_text(last_item_name)