Compare commits

..

5 Commits

4 changed files with 220 additions and 57 deletions

127
README.md
View File

@ -70,94 +70,108 @@ python -m venv venv
.\venv\Scripts\playwright.exe install chromium
```
### 3. Настроить учётные данные
### 3. Настроить конфигурацию и учётные данные
```powershell
Copy-Item .env.example .env
# Открыть .env и заполнить логины/пароли
# Открыть .env и указать BASE_URL, логины и пароли ролей
```
### 4. (Опционально) Настройка ГОСТ-браузера
Если целевой портал защищён ГОСТ TLS (ГОСТ Р 34.12-2015, 34.10-2012) или вы хотите тестировать ГОСТ-контур:
1. Скачайте архив **[Chromium-GOST](https://github.com/deemru/chromium-gost/releases)** (например, `chromium-gost-...-windows-amd64.zip`).
2. Распакуйте его в стандартный каталог `%LOCALAPPDATA%\Chromium-Gost` (или `C:\Program Files\Chromium-Gost`). Механизм тестов обнаружит его **автоматически**.
3. *Альтернатива:* если браузер распакован в произвольную папку, укажите путь в `.env`:
```ini
CHROMIUM_GOST_PATH=C:\MyPrograms\chromium-gost\chrome.exe
```
4. Убедитесь, что на компьютере установлен криптопровайдер с ГОСТ-алгоритмами (КриптоПро CSP, Security Code CSP / Континент-АП).
---
## Запуск тестов
> Все команды выполняются из корня проекта (`e2e_Pets/`).
> HTML-отчёт автоматически создаётся в `html-report/report.html`.
> Все команды выполняются из корня проекта (`e2e_Pets/`).
> HTML-отчёт со статусом, типом TLS и запущенным браузером автоматически формируется в `html-report/report.html`.
---
### Запустить ВСЕ тесты
### Автоматический запуск (рекомендуемый)
По умолчанию включён режим `--tls-mode=auto`. Система перед стартом проверяет сокет целевого `BASE_URL`:
- Если сайт доступен по **стандартному TLS** → автоматически запускается встроенный **Chromium Playwright**.
- Если сайт защищён **ГОСТ TLS** → автоматически запускается **Chromium-GOST**.
```powershell
# Запуск всех тестов в авто-режиме
.\venv\Scripts\pytest.exe
```
---
### Запустить тесты конкретного ЛК (роли)
### Принудительный выбор режима TLS
Если вы хотите явно зафиксировать браузер в обход автоопределения:
```powershell
# ЛК Управление ветеринарии
# Принудительно запустить через Chromium-GOST
.\venv\Scripts\pytest.exe --tls-mode=gost
# Принудительно запустить через стандартный Chromium Playwright
.\venv\Scripts\pytest.exe --tls-mode=standard
```
---
### Запуск тестов конкретного ЛК (роли)
```powershell
# ЛК Управление ветеринарии (все бизнес-процессы)
.\venv\Scripts\pytest.exe tests/01_vetdept/
# ЛК Ветеринарная станция
# ЛК Ветеринарная станция (все бизнес-процессы)
.\venv\Scripts\pytest.exe tests/02_vetstation/
```
---
### Запустить конкретный бизнес-процесс
### Запуск конкретного бизнес-процесса или шага
```powershell
# BP01 навигации в ЛК Управление ветеринарии
# Запуск BP01 в ЛК Управление ветеринарии
.\venv\Scripts\pytest.exe tests/01_vetdept/BP01_navigation/
# BP01 дашборда в ЛК Ветеринарная станция
.\venv\Scripts\pytest.exe tests/02_vetstation/BP01_dashboard/
# Запуск только шага 1 (Dashboard)
.\venv\Scripts\pytest.exe tests/01_vetdept/BP01_navigation/ -k "s01"
# Запуск шагов 1 и 2
.\venv\Scripts\pytest.exe tests/01_vetdept/BP01_navigation/ -k "s01 or s02"
```
---
### Запустить конкретный шаг
```powershell
# Только шаг 3 из BP01 ветстанции
.\venv\Scripts\pytest.exe tests/02_vetstation/BP01_dashboard/ -k "s03"
# Только шаги 1 и 2
.\venv\Scripts\pytest.exe tests/02_vetstation/BP01_dashboard/ -k "s01 or s02"
```
---
### Полезные флаги
### Полезные флаги запуска
| Флаг | Описание |
|---|---|
| `-v` | Подробный вывод с именами шагов |
| `--headed` | Показывать браузер (по умолчанию включён в `pytest.ini`) |
| `--headless` | Запустить без браузера (быстрее) |
| `--slowmo 500` | Замедление действий на 500мс (для отладки) |
| `-k "BP01"` | Запустить только тесты содержащие "BP01" в имени |
| `--co -q` | Только показать список тестов без запуска |
| `--tls-mode=auto` | Режим TLS: `auto` (по умолчанию — автоопределение), `gost` или `standard` |
| `--ignore-https-errors` | Игнорировать ошибки SSL сертификатов (по умолчанию включено) |
| `-v` | Подробный вывод с отображением docstring каждого шага |
| `--tls-mode=auto` | Режим TLS: `auto` (по умолчанию), `gost` или `standard` |
| `--ignore-https-errors` | Игнорировать ошибки сертификатов SSL (по умолчанию включено) |
| `-k "BP01"` | Фильтр тестов по подстроке в имени класса или метода |
| `--co -q` | Только показать список тестов без их выполнения |
| `--slowmo 500` | Замедление действий в браузере (в мс, по умолчанию 1000мс в `pytest.ini`) |
| `-o addopts=""` | Сбросить дефолтные флаги `pytest.ini` (например, для headless-запуска в CI) |
```powershell
# Показать список всех тестов (без запуска)
# Просмотр дерева тестов без запуска браузера
.\venv\Scripts\pytest.exe --co -q
# Запустить без браузера и без замедления
.\venv\Scripts\pytest.exe --headless --slowmo 0
# Быстрый запуск без задержки slowmo
.\venv\Scripts\pytest.exe tests/01_vetdept/ --slowmo 0
# Запустить в headless-режиме только vetdept
.\venv\Scripts\pytest.exe tests/01_vetdept/ --headless --slowmo 0
# Принудительный запуск в режиме ГОСТ TLS (через Chromium-GOST / Яндекс.Браузер)
.\venv\Scripts\pytest.exe --tls-mode=gost
# Принудительный запуск в режиме стандартного TLS (встроенный Chromium Playwright)
.\venv\Scripts\pytest.exe --tls-mode=standard
# Запуск в режиме ГОСТ с подробным выводом
.\venv\Scripts\pytest.exe tests/01_vetdept/ --tls-mode=gost -v
```
---
@ -358,17 +372,32 @@ Python-код, который воспроизводит твои действи
### Запуск рекордера
#### Вариант 1: Универсальный запуск с поддержкой ГОСТ TLS (рекомендуемый)
Штатная команда `playwright codegen` не умеет работать со сторонними браузерами напрямую. Для записи тестов на сайтах с **ГОСТ TLS** (а также обычным TLS) используйте встроенный скрипт `codegen.py`:
```powershell
# Открыть браузер с рекордером (без авторизации)
# Запуск для URL по умолчанию из .env (с автоопределением TLS и выбором браузера):
.\venv\Scripts\python.exe codegen.py
# Принудительный запуск в режиме ГОСТ TLS (через Chromium-GOST):
.\venv\Scripts\python.exe codegen.py --gost
# Запуск для произвольного адреса:
.\venv\Scripts\python.exe codegen.py https://vet.goznak.ru
```
#### Вариант 2: Штатный запуск (только для сайтов со стандартным TLS)
```powershell
# Открыть встроенный Chromium с рекордером
.\venv\Scripts\playwright.exe codegen https://vet.goznak.ru
# Открыть браузер с рекордером и сохранить результат в файл
# Открыть рекордер и сразу сохранить результат в файл
.\venv\Scripts\playwright.exe codegen https://vet.goznak.ru --output tests\codegen_draft.py
```
Откроются два окна:
- **Браузер** — управляй им как обычно: кликай, заполняй формы, переходи по разделам
- **Playwright Inspector** — в реальном времени показывает сгенерированный код
При запуске откроются два окна:
- **Браузер (Chromium-GOST или Playwright Chromium)** — кликайте, заполняйте формы и переходите по разделам.
- **Playwright Inspector** — окно записи, в котором в реальном времени формируется Python-код.
### Порядок работы

125
codegen.py Normal file
View File

@ -0,0 +1,125 @@
"""
Инструмент запуска визуального рекордера Playwright Codegen
с автоматической поддержкой Стандартного и ГОСТ TLS.
Использование:
.\\venv\\Scripts\\python.exe codegen.py [URL] [опции]
Примеры:
# Автоопределение TLS для URL из .env (по умолчанию):
.\\venv\\Scripts\\python.exe codegen.py
# Запуск для конкретного URL:
.\\venv\\Scripts\\python.exe codegen.py https://vet.goznak.ru
# Принудительно через Chromium-GOST:
.\\venv\\Scripts\\python.exe codegen.py --gost
# Принудительно через стандартный Chromium:
.\\venv\\Scripts\\python.exe codegen.py --standard
"""
import argparse
import os
import sys
# pyrefly: ignore [missing-import]
from dotenv import load_dotenv
# pyrefly: ignore [missing-import]
from playwright.sync_api import sync_playwright
from tests.utils.tls import detect_tls_mode, find_gost_browser_executable
load_dotenv()
DEFAULT_URL = os.getenv("BASE_URL", "https://vet.goznak.ru")
def main():
parser = argparse.ArgumentParser(
description="Визуальный рекордер Playwright с поддержкой Chromium-GOST и стандартного Chromium."
)
parser.add_argument(
"url",
nargs="?",
default=DEFAULT_URL,
help=f"Целевой URL портала (по умолчанию из .env: {DEFAULT_URL})",
)
parser.add_argument(
"--gost",
action="store_true",
help="Принудительно запустить рекордер через Chromium-GOST",
)
parser.add_argument(
"--standard",
action="store_true",
help="Принудительно запустить рекордер через встроенный Chromium Playwright",
)
args = parser.parse_args()
# Если передан URL без схемы (например, paws.vet.goznak.ru) — добавляем https://
url = args.url
if not url.startswith("http://") and not url.startswith("https://"):
url = f"https://{url}"
# Определение режима TLS
if args.gost:
is_gost = True
tls_desc = "Принудительно (ГОСТ TLS)"
elif args.standard:
is_gost = False
tls_desc = "Принудительно (Стандартный TLS)"
else:
is_gost, tls_desc = detect_tls_mode(url)
print(f"\n{'=' * 70}")
print("ЗАПУСК ВИЗУАЛЬНОГО РЕКОРДЕРА PLAYWRIGHT")
print(f"Целевой URL: {url}")
print(f"Режим TLS: {tls_desc}")
# Включаем режим отладчика/инспектора Playwright
os.environ["PWDEBUG"] = "1"
with sync_playwright() as playwright:
if is_gost:
gost_path = find_gost_browser_executable()
if not gost_path or not os.path.exists(gost_path):
print("\n[ОШИБКА] Chromium-GOST не найден в системе!")
print("Скачайте его с https://github.com/deemru/chromium-gost/releases")
print("и распакуйте в %LOCALAPPDATA%\\Chromium-Gost,")
print("либо укажите путь в .env: CHROMIUM_GOST_PATH=...")
sys.exit(1)
print(f"Браузер: Chromium GOST22 ({gost_path})")
browser = playwright.chromium.launch(
executable_path=gost_path,
headless=False,
)
else:
print("Браузер: Chromium (Playwright)")
browser = playwright.chromium.launch(headless=False)
context = browser.new_context(
ignore_https_errors=True,
viewport={"width": 1920, "height": 1080},
)
page = context.new_page()
print(f"{'=' * 70}")
print("1. Открылись окна: Браузер и Playwright Inspector.")
print("2. В окне инспектора нажмите кнопку записи (красный кружок 'Record').")
print("3. Кликайте и заполняйте формы — код генерируется в окне инспектора.")
print("4. Для завершения просто закройте окно браузера.")
print(f"{'=' * 70}\n")
try:
page.goto(url)
except Exception as e:
print(f"Переход на {url}: {e}")
# page.pause() активирует панель рекордера/инспектора
page.pause()
context.close()
browser.close()
if __name__ == "__main__":
main()

View File

@ -66,6 +66,7 @@ def pytest_sessionstart(session):
browser_name = "Chromium (Playwright)"
try:
# pyrefly: ignore [missing-import]
from pytest_metadata.plugin import metadata_key
metadata = config.stash[metadata_key]
except (ImportError, KeyError):

View File

@ -38,22 +38,29 @@ def find_gost_browser_executable() -> Optional[str]:
prog_files_x86 = os.environ.get("ProgramFiles(x86)", "")
candidates = [
# Chromium-Gost (AppData / Program Files)
# Пути официального установщика Chromium-GOST (устанавливается в папку Chromium\Application)
os.path.join(local_app_data, "Chromium", "Application", "chrome.exe"),
os.path.join(local_app_data, "Chromium", "chrome.exe"),
os.path.join(local_app_data, "Programs", "Chromium", "Application", "chrome.exe"),
os.path.join(prog_files, "Chromium", "Application", "chrome.exe"),
os.path.join(prog_files, "Chromium", "chrome.exe"),
os.path.join(prog_files_x86, "Chromium", "Application", "chrome.exe"),
os.path.join(prog_files_x86, "Chromium", "chrome.exe"),
# Портативные пути и архивы Chromium-Gost
os.path.join(local_app_data, "Chromium-Gost", "chrome.exe"),
os.path.join(local_app_data, "Chromium-Gost", "Application", "chrome.exe"),
os.path.join(local_app_data, "Programs", "Chromium-Gost", "chrome.exe"),
os.path.join(local_app_data, "Programs", "Chromium-Gost", "Application", "chrome.exe"),
os.path.join(prog_files, "Chromium-Gost", "chrome.exe"),
os.path.join(prog_files, "Chromium-Gost", "Application", "chrome.exe"),
os.path.join(prog_files_x86, "Chromium-Gost", "chrome.exe"),
os.path.join(prog_files_x86, "Chromium-Gost", "Application", "chrome.exe"),
# Яндекс.Браузер (поддерживает ГОСТ TLS при наличии КриптоПро CSP)
os.path.join(local_app_data, "Yandex", "YandexBrowser", "Application", "browser.exe"),
os.path.join(prog_files, "Yandex", "YandexBrowser", "Application", "browser.exe"),
os.path.join(prog_files_x86, "Yandex", "YandexBrowser", "Application", "browser.exe"),
# Linux / macOS пути
"/opt/chromium-gost/chrome",
"/usr/bin/chromium-gost",
"/Applications/Chromium-Gost.app/Contents/MacOS/Chromium-Gost",
"/Applications/Yandex.app/Contents/MacOS/Yandex",
]
for path in candidates:
@ -61,7 +68,7 @@ def find_gost_browser_executable() -> Optional[str]:
return os.path.abspath(path)
# 3. Поиск в системном PATH
for name in ("chromium-gost", "chrome-gost", "yandex-browser"):
for name in ("chromium-gost", "chrome-gost", "chromium"):
found = shutil.which(name)
if found:
return os.path.abspath(found)
@ -195,7 +202,8 @@ def launch_browser_for_tls(
browser_name = "Яндекс.Браузер" if "yandex" in gost_path.lower() else "Chromium GOST"
return browser, f"{browser_name} ({gost_path})"
except Exception as e:
print(f"\n[GOST] Предупреждение: ошибка прямого запуска ({gost_path}): {e}")
err_msg = str(e).encode("ascii", errors="replace").decode("ascii")
print(f"\n[GOST] Предупреждение: ошибка прямого запуска ({gost_path}): {err_msg}")
print("[GOST] Пробуем подключение по CDP...")
# ГОСТ TLS: Вариант 2 — подключение по CDP