Files
site/WESP_REL/tests/helpers/recipes_ui_inventory.py
2026-07-17 12:57:18 +03:00

211 lines
9.4 KiB
Python

"""Инвентарь UI страницы /recipes — источник правды для контракт- и E2E-тестов."""
from __future__ import annotations
from pathlib import Path
from typing import Dict, List, Tuple
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
STATIC = PROJECT_ROOT / "static"
# Ключевые DOM id (dashboard + editor + mobile)
DOM_IDS: List[str] = [
"wespZootechNavMount",
"recipesMobileNav",
"recipesMobileNavTitle",
"recipesDashboard",
"dispensersCol",
"periodsCol",
"recipesCol",
"dispensersList",
"periodsList",
"recipesList",
"recipesCardHeaderText",
"createRecipeBtn",
"recipeEdit",
"recipeEditSkeletonPanel",
"recipeForm",
"recipeName",
"headsCount",
"mixingTime",
"tripPercent",
"ingredientsTable",
"ingredientsTableBody",
"unloadingGroupsCard",
"unloadingGroupsTableBody",
"componentSelectionCard",
"targetComponentSelect",
"ingredientMobileSheet",
"unloadingGroupMobileSheet",
"recipeHelpModal",
]
# data-action → файл(ы), где должен быть handler
DATA_ACTION_HANDLERS: Dict[str, List[str]] = {
"mobile-dashboard-back": ["static/js/pages/recipes-page.js"],
"open-recipe-help": ["static/js/pages/recipes-page.js"],
"close-recipe-help": ["static/js/pages/recipes-page.js"],
"logout": ["static/js/pages/recipes-page.js", "static/js/wesp-zootech-nav.js"],
"add-ingredient": ["static/js/modules/recipes/recipe-editor.js"],
"toggle-unloading-link": ["static/js/modules/recipes/recipe-editor.js"],
"add-unloading-group": ["static/js/modules/recipes/recipe-editor.js"],
"show-recipe-edit-off": ["static/js/modules/recipes/recipe-editor.js"],
"print-all-recipes": ["static/js/modules/recipes/recipe-editor.js"],
"print-recipe": ["static/js/modules/recipes/recipe-editor.js"],
"save-and-exit": ["static/js/modules/recipes/recipe-editor.js"],
"move-group-up": ["static/js/modules/recipes/recipe-editor.js"],
"move-group-down": ["static/js/modules/recipes/recipe-editor.js"],
"remove-unloading-group": ["static/js/modules/recipes/recipe-editor.js"],
"move-ingredient-up": ["static/js/modules/recipes/recipe-editor.js"],
"move-ingredient-down": ["static/js/modules/recipes/recipe-editor.js"],
"remove-ingredient": ["static/js/modules/recipes/recipe-editor.js"],
"open-ingredient-sheet": ["static/js/modules/recipes/recipe-editor.js"],
"close-ingredient-sheet": ["static/js/modules/recipes/recipe-editor.js"],
"open-unloading-group-sheet": ["static/js/modules/recipes/recipe-editor.js"],
"close-unloading-group-sheet": ["static/js/modules/recipes/recipe-editor.js"],
"group-type-change": ["static/js/modules/recipes/recipe-editor.js"],
"group-value-change": ["static/js/modules/recipes/recipe-editor.js"],
"ingredient-change": ["static/js/modules/recipes/recipe-editor.js"],
"dry-matter-percent-change": ["static/js/modules/recipes/recipe-editor.js"],
"recalculate-weights": ["static/js/modules/recipes/recipe-editor.js"],
"recalculate-total-weight": ["static/js/modules/recipes/recipe-editor.js"],
"select-dispenser": ["static/js/modules/recipes/dispenser-selector.js"],
"select-recipe": ["static/js/modules/recipes/dispenser-selector.js"],
"select-period": ["static/js/modules/recipes/dispenser-selector.js"],
"copy-recipe": ["static/js/modules/recipes/dispenser-selector.js"],
"delete-recipe": ["static/js/modules/recipes/dispenser-selector.js"],
"unskip-recipe-today": ["static/js/modules/recipes/dispenser-selector.js"],
"unskip-ingredient-parts-today": ["static/js/modules/recipes/dispenser-selector.js"],
"unskip-group-parts-today": ["static/js/modules/recipes/dispenser-selector.js"],
"paste-recipe": ["static/js/modules/recipes/dispenser-selector.js"],
"create-recipe": ["static/js/modules/recipes/dispenser-selector.js"],
"move-recipe-up": ["static/js/modules/recipes/dispenser-selector.js"],
"move-recipe-down": ["static/js/modules/recipes/dispenser-selector.js"],
"recipe-drag-handle": ["static/js/modules/recipes/dispenser-selector.js"],
"open-settings": ["static/js/modules/recipes/sync-panel.js", "static/js/wesp-zootech-nav.js"],
"close-settings": ["static/js/modules/recipes/sync-panel.js"],
"toggle-credentials-form": ["static/js/modules/recipes/sync-panel.js"],
"toggle-sync-form": ["static/js/modules/recipes/sync-panel.js"],
"change-credentials": ["static/js/modules/recipes/sync-panel.js"],
"sync-edit-client": ["static/js/modules/recipes/sync-panel.js"],
"sync-delete-client": ["static/js/modules/recipes/sync-panel.js"],
"sync-save-client": ["static/js/modules/recipes/sync-panel.js"],
"sync-cancel-edit": ["static/js/modules/recipes/sync-panel.js"],
}
# data-action → уровень теста, который должен покрывать action (e2e | api | contract)
ACTION_COVERAGE_TARGET: Dict[str, str] = {
"mobile-dashboard-back": "e2e",
"open-recipe-help": "e2e",
"close-recipe-help": "e2e",
"logout": "e2e",
"add-ingredient": "e2e",
"toggle-unloading-link": "e2e",
"add-unloading-group": "contract",
"show-recipe-edit-off": "contract",
"print-all-recipes": "e2e",
"print-recipe": "e2e",
"save-and-exit": "e2e",
"move-group-up": "api",
"move-group-down": "api",
"remove-unloading-group": "contract",
"move-ingredient-up": "api",
"move-ingredient-down": "api",
"remove-ingredient": "e2e",
"open-ingredient-sheet": "e2e",
"close-ingredient-sheet": "e2e",
"open-unloading-group-sheet": "contract",
"close-unloading-group-sheet": "contract",
"group-type-change": "e2e",
"group-value-change": "contract",
"ingredient-change": "contract",
"dry-matter-percent-change": "e2e",
"recalculate-weights": "contract",
"recalculate-total-weight": "contract",
"select-dispenser": "e2e",
"select-recipe": "e2e",
"select-period": "e2e",
"copy-recipe": "e2e",
"delete-recipe": "e2e",
"unskip-recipe-today": "api",
"unskip-ingredient-parts-today": "api",
"unskip-group-parts-today": "api",
"paste-recipe": "e2e",
"create-recipe": "e2e",
"move-recipe-up": "e2e",
"move-recipe-down": "e2e",
"recipe-drag-handle": "e2e",
"open-settings": "e2e",
"close-settings": "e2e",
"toggle-credentials-form": "e2e",
"toggle-sync-form": "e2e",
"change-credentials": "contract",
"sync-edit-client": "contract",
"sync-delete-client": "contract",
"sync-save-client": "contract",
"sync-cancel-edit": "contract",
}
# fetch URL patterns в JS страницы рецептов
API_ENDPOINTS: List[Tuple[str, List[str]]] = [
("/api/feed_dispensers", ["static/js/pages/recipes-data-controller.js"]),
("/api/feed_dispensers/", ["static/js/pages/recipes-data-controller.js", "static/js/pages/recipes-operations-controller.js"]),
("/api/periods/", ["static/js/pages/recipes-data-controller.js", "static/js/pages/recipes-operations-controller.js"]),
("/api/recipes/calculate", ["static/recipes.html"]),
("/api/recipes/", ["static/recipes.html", "static/js/pages/recipes-operations-controller.js", "static/js/pages/recipes-editor-controller.js"]),
("/api/auth/check", ["static/recipes.html", "static/js/pages/recipes-auth-settings.js"]),
("/api/auth/logout", ["static/js/pages/recipes-auth-settings.js"]),
("/api/auth/change_credentials", ["static/js/pages/recipes-auth-settings.js"]),
("/api/sync/clients", ["static/js/pages/recipes-auth-settings.js"]),
]
# CSS анимации / transition-классы
CSS_ANIMATION_MARKERS: List[Tuple[str, List[str]]] = [
("dashboard-skeleton-shimmer", ["static/css/wesp-recipes-skeleton.css"]),
("dashboard-list-skeleton--exit", ["static/css/wesp-recipes-skeleton.css"]),
("recipe-form--enter", ["static/css/wesp-recipes-editor.css", "static/recipes.html"]),
("dashboard-mobile-step-", ["static/css/wesp-recipes-mobile.css", "static/js/pages/recipes-data-controller.js"]),
]
# Скелетон-templates
SKELETON_TEMPLATE_IDS: List[str] = [
"recipe-card-skeleton-inner",
"recipe-card-skeleton-inner--mill",
"dashboard-list-skeleton-dispensers",
"dashboard-list-skeleton-periods",
]
# Mill-ветки в JS/HTML
MILL_MARKERS: List[Tuple[str, List[str]]] = [
("loadMillRecipes", ["static/js/pages/recipes-data-controller.js"]),
("getCurrentDispenserType() === \"mill\"", [
"static/js/pages/recipes-data-controller.js",
"static/js/pages/recipes-operations-controller.js",
"static/js/pages/recipes-editor-controller.js",
]),
("deleted_ingredient_ids", ["static/recipes.html"]),
("deleted_unloading_group_ids", ["static/recipes.html"]),
("target_component_id", ["static/recipes.html", "static/js/pages/recipes-editor-controller.js"]),
("unlinkFromPeriodOnly", ["static/js/pages/recipes-operations-controller.js"]),
]
# Скрипты, импортируемые из recipes.html (type=module)
RECIPES_PAGE_SCRIPTS: List[str] = [
"recipes-boot.js",
"recipes-page.js",
"recipes-data-controller.js",
"recipes-operations-controller.js",
"recipes-editor-controller.js",
"recipes-auth-settings.js",
"recipe-list-dnd.js",
"recipe-period-transfer.js",
"recipe-mobile-sheet-gestures.js",
]
# Модули, подключаемые через recipes-page.js
RECIPES_PAGE_NESTED_MODULES: List[str] = [
"recipe-editor.js",
"dispenser-selector.js",
"sync-panel.js",
]