Skip to content

components

django_spire.testing.playwright.components

__all__ = ['Accordion', 'AttributeElement', 'AttributeList', 'Breadcrumb', 'Card', 'DeleteModal', 'Dropdown', 'EllipsisDropdown', 'EllipsisModalDropdown', 'EllipsisTableDropdown', 'FilterForm', 'FormCard', 'FormModal', 'InfiniteScroll', 'InfiniteScrollCard', 'InfiniteScrollList', 'InfiniteScrollTable', 'LazyTab', 'Modal', 'NavAccordion', 'NotificationBell', 'SideNavigation', 'ThemeSelector', 'TitleCard', 'TitleModal', 'Toast', 'TopNavigation', 'UserMenu'] module-attribute

Accordion

Playwright component for django_spire/accordion/accordion.html

Source code in django_spire/testing/playwright/components/accordion.py
def __init__(self, parent_locator: Locator) -> None:
    self.parent = parent_locator

parent = parent_locator instance-attribute

content property

toggle property

close

Source code in django_spire/testing/playwright/components/accordion.py
def close(self) -> None:
    if self.is_open():
        self.toggle.click()

is_open

Source code in django_spire/testing/playwright/components/accordion.py
def is_open(self) -> bool:
    return self.content.is_visible()

open

Source code in django_spire/testing/playwright/components/accordion.py
def open(self) -> None:
    if not self.is_open():
        self.toggle.click()

NavAccordion

Bases: Accordion

Playwright component for django_spire/navigation/accordion/nav_accordion.html

Source code in django_spire/testing/playwright/components/accordion.py
def __init__(self, parent_locator: Locator) -> None:
    self.parent = parent_locator

chevron property

icon property

title property

get_title_text

Source code in django_spire/testing/playwright/components/accordion.py
def get_title_text(self) -> str:
    return self.title.inner_text()

is_expanded

Source code in django_spire/testing/playwright/components/accordion.py
def is_expanded(self) -> bool:
    chevron_classes = self.chevron.get_attribute('class') or ''
    return 'bi-chevron-down' in chevron_classes

AttributeElement

Playwright component for django_spire/element/attribute_element.html

Source code in django_spire/testing/playwright/components/attribute_element.py
def __init__(self, page: Page, container_selector: str = 'body') -> None:
    self.container_selector = container_selector
    self.page = page

container_selector = container_selector instance-attribute

page = page instance-attribute

container property

get_attribute_by_title

Source code in django_spire/testing/playwright/components/attribute_element.py
def get_attribute_by_title(self, title: str) -> Locator:
    return self.container.locator(f'.fs-7.text-app-attribute-color:has-text("{title}")').locator('..')

get_value_by_title

Source code in django_spire/testing/playwright/components/attribute_element.py
def get_value_by_title(self, title: str) -> str:
    attribute = self.get_attribute_by_title(title)
    return attribute.locator('.fs-6, a').inner_text()

get_value_href_by_title

Source code in django_spire/testing/playwright/components/attribute_element.py
def get_value_href_by_title(self, title: str) -> str | None:
    attribute = self.get_attribute_by_title(title)
    link = attribute.locator('a')

    if link.count() > 0:
        return link.get_attribute('href')

    return None

has_attribute

Source code in django_spire/testing/playwright/components/attribute_element.py
def has_attribute(self, title: str) -> bool:
    return self.get_attribute_by_title(title).count() > 0
Source code in django_spire/testing/playwright/components/attribute_element.py
def is_value_link(self, title: str) -> bool:
    attribute = self.get_attribute_by_title(title)
    return attribute.locator('a').count() > 0

AttributeList

Helper for pages with multiple attribute elements

Source code in django_spire/testing/playwright/components/attribute_element.py
def __init__(self, page: Page, container_selector: str = 'body') -> None:
    self.container_selector = container_selector
    self.page = page

container_selector = container_selector instance-attribute

page = page instance-attribute

container property

attributes property

get_all_titles

Source code in django_spire/testing/playwright/components/attribute_element.py
def get_all_titles(self) -> list[str]:
    count = self.attributes.count()
    return [self.attributes.nth(i).inner_text() for i in range(count)]

get_attribute_count

Source code in django_spire/testing/playwright/components/attribute_element.py
def get_attribute_count(self) -> int:
    return self.attributes.count()

get_values_dict

Source code in django_spire/testing/playwright/components/attribute_element.py
def get_values_dict(self) -> dict[str, str]:
    result = {}
    attr_element = AttributeElement(self.page, self.container_selector)

    for title in self.get_all_titles():
        result[title] = attr_element.get_value_by_title(title)

    return result

FilterForm

Playwright component for django_spire/filtering/form/base_session_filter_form.html

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def __init__(self, page: Page, form_selector: str = 'form[action*="filter"], form[action*="search"]') -> None:
    self.form_selector = form_selector
    self.page = page

form_selector = form_selector instance-attribute

page = page instance-attribute

clear_button property

filter_button property

form property

search_button property

search_input property

clear

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def clear(self) -> None:
    self.clear_button.click()

fill_field

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def fill_field(self, name: str, value: str) -> None:
    self.form.locator(f'[name="{name}"]').fill(value)

filter

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def filter(self) -> None:
    self.filter_button.click()

get_field_value

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def get_field_value(self, name: str) -> str:
    return self.form.locator(f'[name="{name}"]').input_value()

search

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def search(self, query: str) -> None:
    self.search_input.fill(query)
    self.search_button.click()

select_option

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def select_option(self, name: str, value: str) -> None:
    self.form.locator(f'select[name="{name}"]').select_option(value)

submit

Source code in django_spire/testing/playwright/components/base_session_filter_form.py
def submit(self) -> None:
    submit_btn = self.form.locator('button[type="submit"], input[type="submit"]').first
    submit_btn.click()

Breadcrumb

Playwright component for django_spire/element/breadcrumb_element.html

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

breadcrumb property

items property

click_item

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def click_item(self, index: int) -> None:
    link = self.get_item(index).locator('a')

    if link.count() > 0:
        link.click()

get_item

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def get_item(self, index: int) -> Locator:
    return self.items.nth(index)

get_item_count

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def get_item_count(self) -> int:
    return self.items.count()

get_item_href

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def get_item_href(self, index: int) -> str | None:
    link = self.get_item(index).locator('a')

    if link.count() > 0:
        return link.get_attribute('href')

    return None

get_item_text

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def get_item_text(self, index: int) -> str:
    return self.get_item(index).inner_text()

get_items_text

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def get_items_text(self) -> list[str]:
    return [self.get_item_text(i) for i in range(self.get_item_count())]

get_last_item_text

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def get_last_item_text(self) -> str:
    return self.items.last.inner_text()

is_item_clickable

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def is_item_clickable(self, index: int) -> bool:
    return self.get_item(index).locator('a').count() > 0

is_visible

Source code in django_spire/testing/playwright/components/breadcrumb_element.py
def is_visible(self) -> bool:
    return self.breadcrumb.is_visible()

Card

Playwright component for django_spire/card/card.html

Source code in django_spire/testing/playwright/components/card.py
def __init__(self, page: Page, card_selector: str = '.card') -> None:
    self.card_selector = card_selector
    self.page = page

card_selector = card_selector instance-attribute

page = page instance-attribute

card property

content property

is_visible

Source code in django_spire/testing/playwright/components/card.py
def is_visible(self) -> bool:
    return self.card.is_visible()

FormCard

Bases: TitleCard

Playwright component for django_spire/card/form_card.html

Source code in django_spire/testing/playwright/components/card.py
def __init__(self, page: Page, card_selector: str = '.card') -> None:
    self.card_selector = card_selector
    self.page = page

description property

form property

fill_field

Source code in django_spire/testing/playwright/components/card.py
def fill_field(self, name: str, value: str) -> None:
    self.form.locator(f'[name="{name}"]').fill(value)

get_field_value

Source code in django_spire/testing/playwright/components/card.py
def get_field_value(self, name: str) -> str:
    return self.form.locator(f'[name="{name}"]').input_value()

submit

Source code in django_spire/testing/playwright/components/card.py
def submit(self) -> None:
    self.form.locator('button[type="submit"], input[type="submit"]').click()

InfiniteScrollCard

Bases: TitleCard

Playwright component for django_spire/card/infinite_scroll_card.html

Source code in django_spire/testing/playwright/components/card.py
def __init__(self, page: Page, card_selector: str = '.card') -> None:
    self.card_selector = card_selector
    self.page = page

loaded_count_text property

scroll_container property

total_count_text property

get_loaded_count

Source code in django_spire/testing/playwright/components/card.py
def get_loaded_count(self) -> int:
    return int(self.loaded_count_text.inner_text())

get_total_count

Source code in django_spire/testing/playwright/components/card.py
def get_total_count(self) -> int:
    return int(self.total_count_text.inner_text())

scroll_to_bottom

Source code in django_spire/testing/playwright/components/card.py
def scroll_to_bottom(self) -> None:
    self.scroll_container.evaluate('el => el.scrollTop = el.scrollHeight')

TitleCard

Bases: Card

Playwright component for django_spire/card/title_card.html

Source code in django_spire/testing/playwright/components/card.py
def __init__(self, page: Page, card_selector: str = '.card') -> None:
    self.card_selector = card_selector
    self.page = page

button property

dropdown_content property

title property

click_button

Source code in django_spire/testing/playwright/components/card.py
def click_button(self) -> None:
    self.button.locator('button, a').first.click()

get_title_text

Source code in django_spire/testing/playwright/components/card.py
def get_title_text(self) -> str:
    return self.title.inner_text()

has_button

Source code in django_spire/testing/playwright/components/card.py
def has_button(self) -> bool:
    return self.button.locator('button, a').count() > 0

is_dropdown_open

Source code in django_spire/testing/playwright/components/card.py
def is_dropdown_open(self) -> bool:
    return self.dropdown_content.is_visible()

toggle_dropdown

Source code in django_spire/testing/playwright/components/card.py
def toggle_dropdown(self) -> None:
    self.card.locator('[\\@click*="toggle_card_title_dropdown"]').click()

Dropdown

Playwright component for django_spire/dropdown/dropdown.html

Source code in django_spire/testing/playwright/components/dropdown.py
def __init__(self, parent_locator: Locator) -> None:
    self.parent = parent_locator

menu_selector = '.position-absolute.shadow-lg.card' class-attribute instance-attribute

trigger_selector = '[x-bind="trigger"]' class-attribute instance-attribute

parent = parent_locator instance-attribute

menu property

trigger property

click_option

Source code in django_spire/testing/playwright/components/dropdown.py
def click_option(self, text: str) -> None:
    self.menu.locator(f'text={text}').click()

close

Source code in django_spire/testing/playwright/components/dropdown.py
def close(self) -> None:
    if self.is_open():
        self.trigger.click()

get_option

Source code in django_spire/testing/playwright/components/dropdown.py
def get_option(self, text: str) -> Locator:
    return self.menu.locator(f'text={text}')

has_option

Source code in django_spire/testing/playwright/components/dropdown.py
def has_option(self, text: str) -> bool:
    return self.get_option(text).is_visible()

is_open

Source code in django_spire/testing/playwright/components/dropdown.py
def is_open(self) -> bool:
    return self.menu.is_visible()

open

Source code in django_spire/testing/playwright/components/dropdown.py
def open(self) -> None:
    if not self.is_open():
        self.trigger.click()

EllipsisDropdown

Bases: Dropdown

Playwright component for django_spire/dropdown/ellipsis_dropdown.html

Source code in django_spire/testing/playwright/components/dropdown.py
def __init__(self, parent_locator: Locator) -> None:
    self.parent = parent_locator

trigger_selector = '.bi-three-dots-vertical' class-attribute instance-attribute

click_delete

Source code in django_spire/testing/playwright/components/dropdown.py
def click_delete(self) -> None:
    self.click_option('Delete')

click_edit

Source code in django_spire/testing/playwright/components/dropdown.py
def click_edit(self) -> None:
    self.click_option('Edit')

click_view

Source code in django_spire/testing/playwright/components/dropdown.py
def click_view(self) -> None:
    self.click_option('View')

has_delete_option

Source code in django_spire/testing/playwright/components/dropdown.py
def has_delete_option(self) -> bool:
    return self.has_option('Delete')

has_edit_option

Source code in django_spire/testing/playwright/components/dropdown.py
def has_edit_option(self) -> bool:
    return self.has_option('Edit')

has_view_option

Source code in django_spire/testing/playwright/components/dropdown.py
def has_view_option(self) -> bool:
    return self.has_option('View')

EllipsisModalDropdown

Bases: EllipsisDropdown

Playwright component for django_spire/dropdown/ellipsis_modal_dropdown.html Dropdown options trigger modals via dispatch_modal_view()

Source code in django_spire/testing/playwright/components/dropdown.py
def __init__(self, parent_locator: Locator) -> None:
    self.parent = parent_locator

EllipsisTableDropdown

Bases: EllipsisDropdown

Playwright component for django_spire/dropdown/ellipsis_table_dropdown.html Used in table rows, positioned start-0 instead of end-0

Source code in django_spire/testing/playwright/components/dropdown.py
def __init__(self, parent_locator: Locator) -> None:
    self.parent = parent_locator

trigger_selector = 'td .bi-three-dots-vertical' class-attribute instance-attribute

InfiniteScroll

Playwright component for django_spire/infinite_scroll/base.html and django_spire/infinite_scroll/scroll.html

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def __init__(self, page: Page, container_selector: str = '[x-ref="scroll_container"]') -> None:
    self.container_selector = container_selector
    self.page = page

container_selector = container_selector instance-attribute

page = page instance-attribute

content_container property

loaded_count_text property

scroll_container property

spinner property

total_count_text property

get_loaded_count

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_loaded_count(self) -> int:
    return int(self.loaded_count_text.inner_text())

get_total_count

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_total_count(self) -> int:
    return int(self.total_count_text.inner_text())

is_loading

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def is_loading(self) -> bool:
    return self.spinner.is_visible()

scroll_to_bottom

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def scroll_to_bottom(self) -> None:
    self.scroll_container.evaluate('el => el.scrollTop = el.scrollHeight')

scroll_to_top

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def scroll_to_top(self) -> None:
    self.scroll_container.evaluate('el => el.scrollTop = 0')

wait_for_count_to_increase

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def wait_for_count_to_increase(self, initial_count: int, timeout: int = 5000) -> None:
    self.page.wait_for_function(
        f'() => parseInt(document.querySelector("[x-text=\\"loaded_count\\"]").textContent) > {initial_count}',
        timeout=timeout
    )

wait_for_items_to_load

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def wait_for_items_to_load(self) -> None:
    self.loaded_count_text.wait_for()

InfiniteScrollList

Bases: InfiniteScroll

Playwright component for infinite scroll with list items

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def __init__(self, page: Page, container_selector: str = '[x-ref="scroll_container"]') -> None:
    self.container_selector = container_selector
    self.page = page

item_selector = '[data-row-id]' class-attribute instance-attribute

items property

get_item

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_item(self, index: int) -> Locator:
    return self.items.nth(index)

get_item_count

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_item_count(self) -> int:
    return self.items.count()

get_item_ids

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_item_ids(self) -> list[str]:
    items = self.items
    return [items.nth(i).get_attribute('data-row-id') for i in range(items.count())]

InfiniteScrollTable

Bases: InfiniteScroll

Playwright component for django_spire/table/base.html

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def __init__(self, page: Page, container_selector: str = '.table-container[x-ref="scroll_container"]') -> None:
    super().__init__(page, container_selector)

row_selector = 'tbody tr[data-row-id]' class-attribute instance-attribute

skeleton_selector = '.skeleton-box' class-attribute instance-attribute

rows property

select_all_checkbox property

selected_count_text property

skeleton_rows property

table property

click_header

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def click_header(self, header_text: str) -> None:
    self.get_header(header_text).click()

deselect_all_rows

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def deselect_all_rows(self) -> None:
    self.select_all_checkbox.click()

deselect_row

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def deselect_row(self, index: int) -> None:
    self.get_row(index).locator('input[type="checkbox"]').click()

get_first_row_text

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_first_row_text(self) -> str:
    return self.rows.first.inner_text()

get_header

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_header(self, header_text: str) -> Locator:
    return self.page.locator(f'th:has-text("{header_text}")')

get_row

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_row(self, index: int) -> Locator:
    return self.rows.nth(index)

get_row_count

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_row_count(self) -> int:
    return self.rows.count()

get_selected_count

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_selected_count(self) -> int:
    return int(self.selected_count_text.inner_text())

get_sort_icon

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def get_sort_icon(self, header_text: str) -> Locator:
    return self.get_header(header_text).locator('i.bi')

is_sorted_ascending

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def is_sorted_ascending(self, header_text: str) -> bool:
    icon = self.get_sort_icon(header_text)
    return 'bi-chevron-up' in (icon.get_attribute('class') or '')

is_sorted_descending

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def is_sorted_descending(self, header_text: str) -> bool:
    icon = self.get_sort_icon(header_text)
    return 'bi-chevron-down' in (icon.get_attribute('class') or '')

select_all_rows

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def select_all_rows(self) -> None:
    self.select_all_checkbox.click()

select_row

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def select_row(self, index: int) -> None:
    self.get_row(index).locator('input[type="checkbox"]').click()

wait_for_rows_to_load

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def wait_for_rows_to_load(self) -> None:
    self.rows.first.wait_for()

wait_for_table

Source code in django_spire/testing/playwright/components/infinite_scroll.py
def wait_for_table(self) -> None:
    self.table.wait_for()

LazyTab

Playwright component for django_spire/lazy_tab/lazy_tab.html

Source code in django_spire/testing/playwright/components/lazy_tab.py
def __init__(self, page: Page, container_selector: str, tab_id: str | None = None) -> None:
    self.container_selector = container_selector
    self.page = page
    self.tab_id = tab_id

selected_class = 'tab-item' class-attribute instance-attribute

container_selector = container_selector instance-attribute

page = page instance-attribute

tab_id = tab_id instance-attribute

container property

sections property

triggers property

click_tab

Source code in django_spire/testing/playwright/components/lazy_tab.py
def click_tab(self, index: int) -> None:
    self.get_trigger(index).click()

get_section

Source code in django_spire/testing/playwright/components/lazy_tab.py
def get_section(self, index: int) -> Locator:
    return self.sections.nth(index)

get_section_count

Source code in django_spire/testing/playwright/components/lazy_tab.py
def get_section_count(self) -> int:
    return self.sections.count()

get_trigger

Source code in django_spire/testing/playwright/components/lazy_tab.py
def get_trigger(self, index: int) -> Locator:
    return self.triggers.nth(index)

get_trigger_count

Source code in django_spire/testing/playwright/components/lazy_tab.py
def get_trigger_count(self) -> int:
    return self.triggers.count()

get_url_param

Source code in django_spire/testing/playwright/components/lazy_tab.py
def get_url_param(self) -> str | None:
    if not self.tab_id:
        return None

    url = self.page.url
    match = re.search(f'{self.tab_id}=([^&]+)', url)

    if match:
        return match.group(1)

    return None

get_visible_section

Source code in django_spire/testing/playwright/components/lazy_tab.py
def get_visible_section(self) -> Locator | None:
    for i in range(self.sections.count()):
        section = self.sections.nth(i)

        if section.is_visible():
            return section

    return None

get_visible_section_text

Source code in django_spire/testing/playwright/components/lazy_tab.py
def get_visible_section_text(self) -> str:
    section = self.get_visible_section()

    if section:
        return section.inner_text()

    return ''

is_loading

Source code in django_spire/testing/playwright/components/lazy_tab.py
def is_loading(self, index: int) -> bool:
    section = self.get_section(index)
    spinner = section.locator('.spinner-border')
    return spinner.is_visible()

is_tab_selected

Source code in django_spire/testing/playwright/components/lazy_tab.py
def is_tab_selected(self, index: int) -> bool:
    trigger = self.get_trigger(index)
    classes = trigger.get_attribute('class') or ''
    return self.selected_class in classes

wait_for_section_content

Source code in django_spire/testing/playwright/components/lazy_tab.py
def wait_for_section_content(self, index: int, timeout: int = 5000) -> None:
    section = self.get_section(index)
    section.locator('.spinner-border').wait_for(state='hidden', timeout=timeout)

wait_for_tabs_to_load

Source code in django_spire/testing/playwright/components/lazy_tab.py
def wait_for_tabs_to_load(self) -> None:
    self.triggers.first.wait_for()

DeleteModal

Bases: TitleModal

Playwright component for delete confirmation modals

Source code in django_spire/testing/playwright/components/modal.py
def __init__(self, page: Page) -> None:
    self.page = page

cancel_button property

confirm_button property

cancel

Source code in django_spire/testing/playwright/components/modal.py
def cancel(self) -> None:
    self.cancel_button.click()

confirm

Source code in django_spire/testing/playwright/components/modal.py
def confirm(self) -> None:
    self.confirm_button.click()

FormModal

Bases: TitleModal

Playwright component for modals containing forms

Source code in django_spire/testing/playwright/components/modal.py
def __init__(self, page: Page) -> None:
    self.page = page

cancel_button property

form property

submit_button property

cancel

Source code in django_spire/testing/playwright/components/modal.py
def cancel(self) -> None:
    self.cancel_button.click()

fill_field

Source code in django_spire/testing/playwright/components/modal.py
def fill_field(self, name: str, value: str) -> None:
    self.form.locator(f'[name="{name}"]').fill(value)

get_field_value

Source code in django_spire/testing/playwright/components/modal.py
def get_field_value(self, name: str) -> str:
    return self.form.locator(f'[name="{name}"]').input_value()

submit

Source code in django_spire/testing/playwright/components/modal.py
def submit(self) -> None:
    self.submit_button.click()

Modal

Playwright component for django_spire/modal/modal.html

Source code in django_spire/testing/playwright/components/modal.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

close_button property

content property

modal property

overlay property

close

Source code in django_spire/testing/playwright/components/modal.py
def close(self) -> None:
    self.close_button.click()

close_by_overlay

Source code in django_spire/testing/playwright/components/modal.py
def close_by_overlay(self) -> None:
    self.overlay.click()

is_open

Source code in django_spire/testing/playwright/components/modal.py
def is_open(self) -> bool:
    return self.modal.is_visible()

wait_for_close

Source code in django_spire/testing/playwright/components/modal.py
def wait_for_close(self, timeout: int = 5000) -> None:
    self.modal.wait_for(state='hidden', timeout=timeout)

wait_for_open

Source code in django_spire/testing/playwright/components/modal.py
def wait_for_open(self, timeout: int = 5000) -> None:
    self.modal.wait_for(state='visible', timeout=timeout)

TitleModal

Bases: Modal

Playwright component for django_spire/modal/title_modal.html

Source code in django_spire/testing/playwright/components/modal.py
def __init__(self, page: Page) -> None:
    self.page = page

title property

get_title_text

Source code in django_spire/testing/playwright/components/modal.py
def get_title_text(self) -> str:
    return self.title.inner_text()

SideNavigation

Playwright component for django_spire/navigation/side_navigation.html

Source code in django_spire/testing/playwright/components/navigation.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

container property

scroll_container property

Source code in django_spire/testing/playwright/components/navigation.py
def click_link(self, text: str) -> None:
    self.get_link_by_text(text).click()
Source code in django_spire/testing/playwright/components/navigation.py
def get_link_by_text(self, text: str) -> Locator:
    return self.container.locator(f'a.nav-link:has-text("{text}")')
Source code in django_spire/testing/playwright/components/navigation.py
def get_link_count(self) -> int:
    return self.links.count()
Source code in django_spire/testing/playwright/components/navigation.py
def get_link_texts(self) -> list[str]:
    return [self.links.nth(i).inner_text() for i in range(self.get_link_count())]
Source code in django_spire/testing/playwright/components/navigation.py
def has_link(self, text: str) -> bool:
    return self.get_link_by_text(text).count() > 0

is_visible

Source code in django_spire/testing/playwright/components/navigation.py
def is_visible(self) -> bool:
    return self.container.is_visible()

TopNavigation

Playwright component for django_spire/navigation/top_navigation.html

Source code in django_spire/testing/playwright/components/navigation.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

container property

notification_bell property

theme_selector property

title property

user_menu property

click_notification_bell

Source code in django_spire/testing/playwright/components/navigation.py
def click_notification_bell(self) -> None:
    self.notification_bell.click()

click_theme_selector

Source code in django_spire/testing/playwright/components/navigation.py
def click_theme_selector(self) -> None:
    self.theme_selector.click()

click_user_menu

Source code in django_spire/testing/playwright/components/navigation.py
def click_user_menu(self) -> None:
    self.user_menu.click()

get_title_text

Source code in django_spire/testing/playwright/components/navigation.py
def get_title_text(self) -> str:
    return self.title.inner_text()

is_visible

Source code in django_spire/testing/playwright/components/navigation.py
def is_visible(self) -> bool:
    return self.container.is_visible()

UserMenu

Playwright component for user dropdown menu in top navigation

Source code in django_spire/testing/playwright/components/navigation.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

menu property

trigger property

click_admin_panel

Source code in django_spire/testing/playwright/components/navigation.py
def click_admin_panel(self) -> None:
    self.menu.locator('a:has-text("Admin Panel")').click()

click_change_password

Source code in django_spire/testing/playwright/components/navigation.py
def click_change_password(self) -> None:
    self.menu.locator('a:has-text("Change Password")').click()

click_logout

Source code in django_spire/testing/playwright/components/navigation.py
def click_logout(self) -> None:
    self.menu.locator('a:has-text("Logout")').click()

click_theme_dashboard

Source code in django_spire/testing/playwright/components/navigation.py
def click_theme_dashboard(self) -> None:
    self.menu.locator('a:has-text("Theme Dashboard")').click()

is_open

Source code in django_spire/testing/playwright/components/navigation.py
def is_open(self) -> bool:
    return self.menu.is_visible()

open

Source code in django_spire/testing/playwright/components/navigation.py
def open(self) -> None:
    if not self.is_open():
        self.trigger.click()

NotificationBell

Playwright component for django_spire/notification/app/element/notification_bell.html

Source code in django_spire/testing/playwright/components/notification_bell.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

badge property

bell property

dropdown property

click

Source code in django_spire/testing/playwright/components/notification_bell.py
def click(self) -> None:
    self.bell.click()

get_badge_count

Source code in django_spire/testing/playwright/components/notification_bell.py
def get_badge_count(self) -> int:
    if not self.has_badge():
        return 0

    text = self.badge.inner_text()

    if text.isdigit():
        return int(text)

    return 0

has_badge

Source code in django_spire/testing/playwright/components/notification_bell.py
def has_badge(self) -> bool:
    return self.badge.count() > 0 and self.badge.is_visible()

has_notifications

Source code in django_spire/testing/playwright/components/notification_bell.py
def has_notifications(self) -> bool:
    return self.has_badge() and self.get_badge_count() > 0

is_dropdown_open

Source code in django_spire/testing/playwright/components/notification_bell.py
def is_dropdown_open(self) -> bool:
    return self.dropdown.is_visible()

is_visible

Source code in django_spire/testing/playwright/components/notification_bell.py
def is_visible(self) -> bool:
    return self.bell.is_visible()

open_dropdown

Source code in django_spire/testing/playwright/components/notification_bell.py
def open_dropdown(self) -> None:
    if not self.is_dropdown_open():
        self.click()

close_dropdown

Source code in django_spire/testing/playwright/components/notification_bell.py
def close_dropdown(self) -> None:
    if self.is_dropdown_open():
        self.click()

ThemeSelector

Playwright component for django_spire/theme/element/theme_selector.html

Source code in django_spire/testing/playwright/components/theme_selector.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

icon property

click

Source code in django_spire/testing/playwright/components/theme_selector.py
def click(self) -> None:
    self.icon.click()

get_current_mode

Source code in django_spire/testing/playwright/components/theme_selector.py
def get_current_mode(self) -> str:
    html = self.page.locator('html')
    return html.get_attribute('data-theme') or 'light'

get_current_theme_family

Source code in django_spire/testing/playwright/components/theme_selector.py
def get_current_theme_family(self) -> str:
    html = self.page.locator('html')
    return html.get_attribute('data-theme-family') or ''

is_dark_mode

Source code in django_spire/testing/playwright/components/theme_selector.py
def is_dark_mode(self) -> bool:
    return self.get_current_mode() == 'dark'

is_light_mode

Source code in django_spire/testing/playwright/components/theme_selector.py
def is_light_mode(self) -> bool:
    return self.get_current_mode() == 'light'

is_visible

Source code in django_spire/testing/playwright/components/theme_selector.py
def is_visible(self) -> bool:
    return self.icon.is_visible()

toggle

Source code in django_spire/testing/playwright/components/theme_selector.py
def toggle(self) -> None:
    self.click()

wait_for_theme_change

Source code in django_spire/testing/playwright/components/theme_selector.py
def wait_for_theme_change(self, expected_mode: str, timeout: int = 5000) -> None:
    self.page.wait_for_function(
        f'() => document.documentElement.getAttribute("data-theme") === "{expected_mode}"',
        timeout=timeout
    )

Toast

Playwright component for django_spire/messages/messages.html

Source code in django_spire/testing/playwright/components/toast.py
def __init__(self, page: Page) -> None:
    self.page = page

page = page instance-attribute

container property

toasts property

get_toast

Source code in django_spire/testing/playwright/components/toast.py
def get_toast(self, index: int = 0) -> Locator:
    return self.toasts.nth(index)

get_toast_count

Source code in django_spire/testing/playwright/components/toast.py
def get_toast_count(self) -> int:
    return self.toasts.count()

get_toast_icon

Source code in django_spire/testing/playwright/components/toast.py
def get_toast_icon(self, index: int = 0) -> Locator:
    return self.get_toast(index).locator('i.bi').first

get_toast_message

Source code in django_spire/testing/playwright/components/toast.py
def get_toast_message(self, index: int = 0) -> str:
    return self.get_toast(index).locator('[x-text="notification.message"]').inner_text()

get_toast_type

Source code in django_spire/testing/playwright/components/toast.py
def get_toast_type(self, index: int = 0) -> str:
    toast = self.get_toast(index)
    classes = toast.get_attribute('class') or ''

    if 'border-app-success' in classes:
        return 'success'

    if 'border-app-warning' in classes:
        return 'warning'

    if 'border-app-danger' in classes:
        return 'error'

    if 'border-app-primary' in classes:
        return 'info'

    return 'unknown'

close_toast

Source code in django_spire/testing/playwright/components/toast.py
def close_toast(self, index: int = 0) -> None:
    self.get_toast(index).locator('.bi-x-lg').click()

has_success_toast

Source code in django_spire/testing/playwright/components/toast.py
def has_success_toast(self) -> bool:
    return self.page.locator('.border-app-success').count() > 0

has_warning_toast

Source code in django_spire/testing/playwright/components/toast.py
def has_warning_toast(self) -> bool:
    return self.page.locator('.border-app-warning').count() > 0

has_error_toast

Source code in django_spire/testing/playwright/components/toast.py
def has_error_toast(self) -> bool:
    return self.page.locator('.border-app-danger').count() > 0

has_info_toast

Source code in django_spire/testing/playwright/components/toast.py
def has_info_toast(self) -> bool:
    return self.page.locator('.border-app-primary').count() > 0

wait_for_toast

Source code in django_spire/testing/playwright/components/toast.py
def wait_for_toast(self, timeout: int = 5000) -> None:
    self.toasts.first.wait_for(state='visible', timeout=timeout)

wait_for_toast_to_disappear

Source code in django_spire/testing/playwright/components/toast.py
def wait_for_toast_to_disappear(self, timeout: int = 10000) -> None:
    self.toasts.first.wait_for(state='hidden', timeout=timeout)