You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
3.3 KiB
99 lines
3.3 KiB
from __future__ import annotations
|
|
|
|
from collections.abc import Callable
|
|
from pathlib import Path
|
|
from typing import Pattern
|
|
|
|
from playwright.sync_api import Download, Page, expect
|
|
|
|
|
|
def login(
|
|
page: Page,
|
|
base_url: str,
|
|
*,
|
|
username: str,
|
|
password: str,
|
|
expected_path: str | Pattern[str] | None = None,
|
|
) -> None:
|
|
page.goto(f"{base_url}/auth/login")
|
|
expect(page.get_by_label("用户名")).to_be_editable()
|
|
page.get_by_label("用户名").fill(username)
|
|
page.get_by_label("密码").fill(password)
|
|
page.get_by_role("button", name="登录").click()
|
|
if expected_path is not None:
|
|
expect_path(page, base_url, expected_path)
|
|
|
|
|
|
def logout(page: Page, base_url: str) -> None:
|
|
open_user_menu(page)
|
|
page.get_by_role("menuitem", name="退出登录").click()
|
|
expect_path(page, base_url, "/auth/login")
|
|
expect_flash(page, "您已退出登录。")
|
|
|
|
|
|
def open_user_menu(page: Page) -> None:
|
|
toggle = page.locator("#user-menu-toggle")
|
|
expect(toggle).to_be_visible()
|
|
if toggle.get_attribute("aria-expanded") != "true":
|
|
toggle.click()
|
|
expect(page.locator("#user-menu-panel")).to_be_visible()
|
|
|
|
|
|
def accept_next_dialog(page: Page, expected_message_substring: str | None = None) -> None:
|
|
def _accept(dialog) -> None:
|
|
if expected_message_substring is not None:
|
|
assert expected_message_substring in dialog.message
|
|
dialog.accept()
|
|
|
|
page.once("dialog", _accept)
|
|
|
|
|
|
def dismiss_next_dialog(page: Page, expected_message_substring: str | None = None) -> None:
|
|
def _dismiss(dialog) -> None:
|
|
if expected_message_substring is not None:
|
|
assert expected_message_substring in dialog.message
|
|
dialog.dismiss()
|
|
|
|
page.once("dialog", _dismiss)
|
|
|
|
|
|
def expect_sidebar_link(page: Page, link_name: str) -> None:
|
|
toggle_count = page.locator("[data-sidebar-toggle]").count()
|
|
for index in range(toggle_count):
|
|
toggle = page.locator("[data-sidebar-toggle]").nth(index)
|
|
if not toggle.is_visible():
|
|
continue
|
|
if toggle.get_attribute("aria-expanded") == "false":
|
|
toggle.click()
|
|
break
|
|
expect(page.get_by_role("link", name=link_name)).to_be_visible()
|
|
|
|
|
|
def expect_flash(page: Page, message: str, *, category: str | None = None) -> None:
|
|
locator = page.get_by_text(message)
|
|
expect(locator).to_be_visible()
|
|
if category is not None:
|
|
expect(page.get_by_text(f"{category}:{message}")).to_be_visible()
|
|
|
|
|
|
def expect_path(page: Page, base_url: str, expected_path: str | Pattern[str]) -> None:
|
|
if isinstance(expected_path, str):
|
|
expect(page).to_have_url(f"{base_url}{expected_path}")
|
|
return
|
|
expect(page).to_have_url(expected_path)
|
|
|
|
|
|
def upload_file(page: Page, selector: str, file_path: str | Path) -> None:
|
|
input_locator = page.locator(selector)
|
|
expect(input_locator).to_be_attached()
|
|
input_locator.set_input_files(str(file_path))
|
|
|
|
|
|
def download_via_action(page: Page, action: Callable[[], None], destination: str | Path) -> Download:
|
|
destination_path = Path(destination)
|
|
destination_path.parent.mkdir(parents=True, exist_ok=True)
|
|
with page.expect_download() as download_info:
|
|
action()
|
|
download = download_info.value
|
|
download.save_as(str(destination_path))
|
|
return download
|
|
|