Metadata-Version: 2.4
Name: sputnikqa
Version: 0.1.0
Summary: Extensible test automation framework — built for QA engineers who value clean architecture and scalability.
License: MIT
License-File: LICENSE
Author: Crenom
Author-email: pytimdev@mail.ru
Requires-Python: >=3.13,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Provides-Extra: allure
Provides-Extra: httpx
Provides-Extra: playwright
Provides-Extra: requests
Provides-Extra: selenium
Requires-Dist: allure-python-commons (>=2.15.0,<3.0.0) ; extra == "allure"
Requires-Dist: httpx (>=0.28.1,<0.29.0) ; extra == "httpx"
Requires-Dist: playwright (>=1.58.0,<2.0.0) ; extra == "playwright"
Requires-Dist: pydantic (>=2.11.9,<3.0.0)
Requires-Dist: requests (>=2.32.0,<3.0.0) ; extra == "requests"
Requires-Dist: selenium (>=4.0.0,<5.0.0) ; extra == "selenium"
Description-Content-Type: text/markdown

# 🛰️ SputnikQA — Test Automation Framework
![PyPI version](https://img.shields.io/pypi/v/sputnikqa.svg)
![Python versions](https://img.shields.io/pypi/pyversions/sputnikqa.svg)
![License](https://img.shields.io/pypi/l/sputnikqa.svg)

**SputnikQA** — фреймворк для автотестов на Python. Внутри два booster'а с общими принципами:

- **REST API** — HTTP-клиент с middleware-пайплайном, декларативные API-секции (по аналогии с Page Object) и валидация ответов через pydantic-модели.
- **Web UI** — единый интерфейс над Playwright и Selenium: страницы, элементы, списки, композитные виджеты. Синхронный и асинхронный варианты.

Сверху — интеграция с Allure и генератор API-клиента из OpenAPI 3.x.


## Установка

```bash
pip install sputnikqa
```

Необязательные зависимости ставятся экстрами:

```bash
pip install sputnikqa[httpx]        # HTTP-транспорт на httpx
pip install sputnikqa[requests]     # HTTP-транспорт на requests
pip install sputnikqa[playwright]   # Web UI на Playwright
pip install sputnikqa[selenium]     # Web UI на Selenium
pip install sputnikqa[allure]       # Allure-отчёты

# типичный набор для API+UI проекта
pip install sputnikqa[allure,httpx,playwright]
```

Python 3.13+.


## Пример: REST API

Модель ответа и секция API — по аналогии с Page Object:

```python
from sputnikqa.boosters.restapi.clients import ApiClient
from sputnikqa.boosters.restapi.response_models import JsonResponse
from sputnikqa.boosters.restapi.sections import BaseApiSection
from sputnikqa.boosters.restapi.transports import HttpxTransport


class Pet(JsonResponse):
    id: int | None = None
    name: str
    status: str


class PetSection(BaseApiSection):
    base_url = "https://petstore.swagger.io/v2"

    def get_pet(self, pet_id: int) -> Pet:
        response = self.client.get(self.url_join(f"/pet/{pet_id}"))
        return (
            self.validator(response)
            .validate_status(200)
            .validate_response_model({200: Pet})
            .get_validated_model()
        )
```

В тесте:

```python
def test_get_pet():
    section = PetSection(ApiClient(HttpxTransport()))
    pet = section.get_pet(1)

    assert pet.name == "doggie"
```

`validate_status()` проверяет статус-код, `validate_response_model()` парсит и валидирует тело pydantic-моделью, `get_validated_model()` возвращает готовый объект. Любое несовпадение — понятная ошибка с телом ответа, а не загадочный `KeyError` где-то в тесте.


## Пример: Web UI

```python
from sputnikqa.boosters.web_ui.locators import Locator, LocatorStrategy
from sputnikqa.boosters.web_ui.sync_api import (
    BasePage,
    Element,
    create_browser,
    BrowserContext,
)


class LoginPage(BasePage):
    def __init__(self):
        self.username = Element(Locator("#username", LocatorStrategy.CSS))
        self.password = Element(Locator("#password", LocatorStrategy.CSS))
        self.submit = Element(Locator("//button[@type='submit']"))


browser = create_browser("playwright")
with BrowserContext.use_browser(browser):
    browser.open_browser(headless=True)
    browser.navigate_to("https://example.com/login")

    page = LoginPage()
    page.username.fill("admin")
    page.password.fill("secret")
    page.submit.click()
```

Локаторы ленивые: элемент ищется в момент действия. При ошибке автоматически делается скриншот. Код страницы не меняется при смене бэкенда — `create_browser("selenium")` даёт тот же интерфейс.


## Документация

| Документ | О чём |
|---|---|
| [REST API booster](docs/ru/restapi.md) | клиенты, транспорты, middleware, секции, валидация, билдеры |
| [Web UI booster](docs/ru/web_ui.md) | браузеры, страницы, элементы, локаторы, ожидания |
| [Генерация API-клиента из OpenAPI](docs/ru/openapi.md) | CLI-тулза `sputnikqa-openapi` |
| [Интеграция с Allure](docs/ru/allure.md) | шаги, аттачи запросов, скриншоты |
| [Логирование](docs/ru/logging.md) | настройка через стандартный `logging` |
| [Расширение фреймворка](docs/ru/extending.md) | свой транспорт, middleware, валидатор |


## Лицензия

MIT. Подробности — в [LICENSE](LICENSE).

---

📌 PyPI: https://pypi.org/project/sputnikqa/
📌 GitVerse: https://gitverse.ru/crenom/SputnikQA
