diff --git a/tests/02_vetstation/002_login_test.py b/tests/02_vetstation/002_login_test.py deleted file mode 100644 index ef3e91c..0000000 --- a/tests/02_vetstation/002_login_test.py +++ /dev/null @@ -1,13 +0,0 @@ -import re -from playwright.sync_api import Page, expect - - -def test_example(page: Page) -> None: - page.goto("https://vet.goznak.ru/auth") - page.get_by_role("textbox", name="Email").click() - page.get_by_role("textbox", name="Email").click() - page.get_by_role("textbox", name="Email").fill("gz_vetstation@vet.goznak.ru") - page.get_by_role("textbox", name="Введите пароль").click() - page.get_by_role("textbox", name="Введите пароль").fill("A6wrpzpD5T") - page.get_by_role("button", name="Войти в аккаунт").click() - expect(page.locator("#app")).to_match_aria_snapshot("- text: Ветеринарная станция \"ГОЗНАК\" - Демо\n- combobox: /\\d+\\.\\d+\\.\\d+ - \\d+\\.\\d+\\.\\d+/\n- button \"Создать отчет\":\n - img\n - text: \"\"\n- text: Статистика регистрации домашних животных\n- img\n- text: 0 всего особей Всего особей\n- paragraph: \"0\"\n- list:\n - listitem:\n - img\n - text: \"0\"\n - img\n - text: \"0\"\n- text: Из них с биометрией\n- paragraph: \"0\"\n- list:\n - listitem:\n - img\n - text: \"0\"\n - img\n - text: \"0\"\n- text: Динамика регистраций в ветстанции\n- img\n- text: Последние зарегистрированные особи\n- button \"Перейти к списку\"\n- table:\n - rowgroup:\n - row \"ID особи Дата № регистрации Тип маркировки № маркировки Кличка Тип владелеца\":\n - columnheader \"ID особи\"\n - columnheader \"Дата\"\n - columnheader \"№ регистрации\"\n - columnheader \"Тип маркировки\"\n - columnheader \"№ маркировки\"\n - columnheader \"Кличка\"\n - columnheader \"Тип владелеца\"\n - columnheader\n - rowgroup:\n - row /homeless \\d+ \\d+\\.\\d+\\.\\d+ \\d+ С \\d+ \\d+ \\d+ Нет информации о маркировке Без номера Кличко Юридическое лицо/:\n - cell /homeless \\d+/:\n - img \"homeless\"\n - img\n - img\n - text: \"\"\n - cell /\\d+\\.\\d+\\.\\d+/\n - cell /\\d+ С \\d+ \\d+ \\d+/\n - cell \"Нет информации о маркировке\"\n - cell \"Без номера\"\n - cell \"Кличко\"\n - cell \"Юридическое лицо\"\n - cell:\n - button:\n - img\n - row /homeless \\d+ \\d+\\.\\d+\\.\\d+ \\d+ К \\d+ \\d+ \\d+ Нет информации о маркировке Без номера Звезда Юридическое лицо/:\n - cell /homeless \\d+/:\n - img \"homeless\"\n - img\n - img\n - text: \"\"\n - cell /\\d+\\.\\d+\\.\\d+/\n - cell /\\d+ К \\d+ \\d+ \\d+/\n - cell \"Нет информации о маркировке\"\n - cell \"Без номера\"\n - cell \"Звезда\"\n - cell \"Юридическое лицо\"\n - cell:\n - button:\n - img\n - row /homeless \\d+ \\d+\\.\\d+\\.\\d+ \\d+ К \\d+ \\d+ \\d+ Клеймо К-\\d+ Симба Физическое лицо/:\n - cell /homeless \\d+/:\n - img \"homeless\"\n - img\n - img\n - text: \"\"\n - cell /\\d+\\.\\d+\\.\\d+/\n - cell /\\d+ К \\d+ \\d+ \\d+/\n - cell \"Клеймо\"\n - cell /К-\\d+/\n - cell \"Симба\"\n - cell \"Физическое лицо\"\n - cell:\n - button:\n - img\n - row /homeless \\d+ \\d+\\.\\d+\\.\\d+ \\d+ С \\d+ \\d+ \\d+ Микрочип Ч-\\d+ Жорик Юридическое лицо/:\n - cell /homeless \\d+/:\n - img \"homeless\"\n - img\n - img\n - text: \"\"\n - cell /\\d+\\.\\d+\\.\\d+/\n - cell /\\d+ С \\d+ \\d+ \\d+/\n - cell \"Микрочип\"\n - cell /Ч-\\d+/\n - cell \"Жорик\"\n - cell \"Юридическое лицо\"\n - cell:\n - button:\n - img\n - row /homeless \\d+ \\d+\\.\\d+\\.\\d+ \\d+ С \\d+ \\d+ \\d+ Нет информации о маркировке Без номера Дружок Физическое лицо/:\n - cell /homeless \\d+/:\n - img \"homeless\"\n - img\n - img\n - text: \"\"\n - cell /\\d+\\.\\d+\\.\\d+/\n - cell /\\d+ С \\d+ \\d+ \\d+/\n - cell \"Нет информации о маркировке\"\n - cell \"Без номера\"\n - cell \"Дружок\"\n - cell \"Физическое лицо\"\n - cell:\n - button:\n - img") diff --git a/tests/02_vetstation/BP01_dashboard/__init__.py b/tests/02_vetstation/BP01_dashboard/__init__.py new file mode 100644 index 0000000..481308e --- /dev/null +++ b/tests/02_vetstation/BP01_dashboard/__init__.py @@ -0,0 +1 @@ +# BP01: Навигация по разделам ЛК ветеринарной станции diff --git a/tests/02_vetstation/BP01_dashboard/test_bp01_dashboard.py b/tests/02_vetstation/BP01_dashboard/test_bp01_dashboard.py new file mode 100644 index 0000000..e31425a --- /dev/null +++ b/tests/02_vetstation/BP01_dashboard/test_bp01_dashboard.py @@ -0,0 +1,85 @@ +import os +# pyrefly: ignore [missing-import] +import pytest +# pyrefly: ignore [missing-import] +from playwright.sync_api import Page, expect + +BASE_URL = os.getenv("BASE_URL", "https://vet.goznak.ru") + + +@pytest.mark.vetstation +@pytest.mark.usefixtures("browser_page") +class TestBP01Dashboard: + """ + BP01: Навигация по разделам личного кабинета ветеринарной станции + + Проверяет что пользователь с ролью 'Ветеринарная станция' может: + - Открыть главную страницу (Статистика/Dashboard) + - Видеть заголовок своей организации + - Видеть блок статистики регистрации животных + - Видеть таблицу последних зарегистрированных особей + - Перейти в раздел Животные + - Перейти в раздел Владельцы животных + - Перейти в раздел Единый реестр + """ + + @pytest.mark.dependency(name="VSBP01::s01") + def test_s01_open_dashboard(self, browser_page: Page, bp_state: dict): + """Шаг 1: Открыть главную страницу (Статистика)""" + browser_page.goto(BASE_URL + "/dashboard") + expect(browser_page).to_have_url(BASE_URL + "/dashboard") + + @pytest.mark.dependency(name="VSBP01::s02", depends=["VSBP01::s01"]) + def test_s02_check_org_header(self, browser_page: Page, bp_state: dict): + """Шаг 2: Проверить заголовок организации""" + expect(browser_page.locator("#app")).to_contain_text( + "Ветеринарная станция" + ) + + @pytest.mark.dependency(name="VSBP01::s03", depends=["VSBP01::s02"]) + def test_s03_check_stats_block(self, browser_page: Page, bp_state: dict): + """Шаг 3: Проверить блок статистики регистрации животных""" + expect( + browser_page.get_by_text("Статистика регистрации домашних животных") + ).to_be_visible(timeout=10000) + expect( + browser_page.get_by_text("Всего особей").first + ).to_be_visible(timeout=10000) + + + @pytest.mark.dependency(name="VSBP01::s04", depends=["VSBP01::s03"]) + def test_s04_check_animals_table(self, browser_page: Page, bp_state: dict): + """Шаг 4: Проверить таблицу последних зарегистрированных особей""" + expect( + browser_page.get_by_text("Последние зарегистрированные особи") + ).to_be_visible(timeout=10000) + # Проверяем наличие колонок таблицы + expect(browser_page.get_by_role("columnheader", name="Кличка")).to_be_visible() + expect(browser_page.get_by_role("columnheader", name="Дата")).to_be_visible() + + @pytest.mark.dependency(name="VSBP01::s05", depends=["VSBP01::s04"]) + def test_s05_go_to_animals(self, browser_page: Page, bp_state: dict): + """Шаг 5: Перейти в раздел Животные""" + browser_page.get_by_role("link", name="Животные").click() + expect(browser_page).to_have_url(BASE_URL + "/animals", timeout=10000) + expect(browser_page.locator("#app")).to_be_visible(timeout=10000) + + @pytest.mark.dependency(name="VSBP01::s06", depends=["VSBP01::s05"]) + def test_s06_go_to_owners(self, browser_page: Page, bp_state: dict): + """Шаг 6: Перейти в раздел Владельцы животных""" + import re + browser_page.get_by_role("link", name="Владельцы животных").click() + # Страница открывается с query-параметром (?type=individual), поэтому regex + expect(browser_page).to_have_url( + re.compile(r".*/owners.*"), timeout=10000 + ) + expect(browser_page.locator("#app")).to_be_visible(timeout=10000) + + + + @pytest.mark.dependency(name="VSBP01::s07", depends=["VSBP01::s06"]) + def test_s07_go_to_registry(self, browser_page: Page, bp_state: dict): + """Шаг 7: Перейти в раздел Единый реестр""" + browser_page.get_by_role("link", name="Единый реестр").click() + expect(browser_page).to_have_url(BASE_URL + "/registry", timeout=10000) + expect(browser_page.locator("#app")).to_be_visible(timeout=10000) diff --git a/tests/02_vetstation/conftest.py b/tests/02_vetstation/conftest.py new file mode 100644 index 0000000..4dcd5ba --- /dev/null +++ b/tests/02_vetstation/conftest.py @@ -0,0 +1,47 @@ +# pyrefly: ignore [missing-import] +import pytest +from pathlib import Path + + +# --------------------------------------------------------------------------- +# Пути к статическим артефактам роли (фото, документы, файлы) +# --------------------------------------------------------------------------- + +@pytest.fixture(scope="session") +def fixtures_dir() -> Path: + """ + Путь к папке со статическими артефактами роли vetstation. + Структура папки: + fixtures/ + ├── images/ ← фотографии животных, документы-сканы + └── docs/ ← PDF, сертификаты и прочие документы + """ + return Path(__file__).parent / "fixtures" + + +# --------------------------------------------------------------------------- +# Готовые фикстуры для конкретных артефактов +# Добавляй новые по мере появления новых файлов в папке fixtures/ +# --------------------------------------------------------------------------- + +# @pytest.fixture(scope="session") +# def animal_photo(fixtures_dir) -> Path: +# """Фото животного для теста регистрации.""" +# return fixtures_dir / "images" / "animal_photo.jpg" + + +# --------------------------------------------------------------------------- +# Контейнер для передачи данных между разными БП одной роли (scope=session) +# --------------------------------------------------------------------------- + +@pytest.fixture(scope="session") +def shared_state() -> dict: + """ + Словарь для передачи данных между разными бизнес-процессами + в рамках одной тестовой сессии для роли vetstation. + + Пример: + # В BP02 создаём животное → BP03 проверяет его в реестре + shared_state["animal_id"] = "96416" + """ + return {} diff --git a/tests/02_vetstation/fixtures/docs/.gitkeep b/tests/02_vetstation/fixtures/docs/.gitkeep new file mode 100644 index 0000000..c5774ed --- /dev/null +++ b/tests/02_vetstation/fixtures/docs/.gitkeep @@ -0,0 +1 @@ +# PDF, сертификаты, ветпаспорта для роли vetstation diff --git a/tests/02_vetstation/fixtures/images/.gitkeep b/tests/02_vetstation/fixtures/images/.gitkeep new file mode 100644 index 0000000..1779a9b --- /dev/null +++ b/tests/02_vetstation/fixtures/images/.gitkeep @@ -0,0 +1 @@ +# Фотографии животных и документы-сканы для роли vetstation diff --git a/tests/testdata/generators.py b/tests/testdata/generators.py index aa5180b..50fc765 100644 --- a/tests/testdata/generators.py +++ b/tests/testdata/generators.py @@ -61,6 +61,7 @@ import random import string from datetime import date, timedelta +# pyrefly: ignore [missing-import] from faker import Faker # Единственный экземпляр Faker на весь модуль — не создавай новые в функциях