Chapitre 07 — ocarina-example#

Suite e2e conçue pour tester l’Igoristan. C’est l’exemple de référence : tout projet Ocarina commence par lire ce dépôt et copier ses adapters.

Plan#

#FichierSujet
0101-tree.mdL’arborescence src/ complète : pages/, lib/, api/, caches/, constants/, tests/.
0202-adapters.mdLes 5 adapters (act, match_page, TestSuite, TestCampaign, EnvGetters).
0303-scenarios-login.mdScénarios Dashboard login : happy / unhappy / data-driven.
0404-scenarios-corsicamon.mdScénarios Corsicamon : api_key, draw, add, back.
0505-scenarios-randomness.mdScénarios randomness (4 levels) : random_error, random_loaders, dsed, madness, chaotic_form, walkthrough.
0606-scenarios-sacred-upload.mdScénarios sacred upload : upload_files, back_to_igoristan.
0707-humanized-driver.mdHumanizedDriver : proxy Selenium pour simuler la saisie humaine.
0808-caches-locks.mdCache L1 (dogpile.cache.memory) + clés réservées + locks Redis distribués.
0909-watcher-catch-me.mdLe watcher catch_me_if_you_can pour le chaotic form.
1010-env-getters.mdEnvGetters[_CredsKeys, _ValuesKeys] typé strictement via Literal.
1111-ci.mdCI : main_ci.yml + dev_ci.yml (lint+typecheck) + e2e.yml (Redis + Firefox manuel).

Objectif#

Citation du Holy Book (chapitre « Premiers pas ») :

Note : Ce livre a pour but de faciliter la prise en main du projet ocarina-example fourni, qui reste la source de vérité à consulter en toutes circonstances.

→ Le projet est documenté comme la référence canonique. Toute question sur comment faire X commence par : « regarde comment c’est fait dans ocarina-example ».

main.py#

if __name__ == "__main__":
    CliStoreSingleton().push(create_selenium_auto_cli_store())

    drivers_pool = create_selenium_drivers_pool(...)
    logger = create_matching_logger(CliStoreSingleton().get("logger"))
    logger.info("Warming up the Redis client...")
    warmup_redis_client()
    logger.success("Redis client initialized!")

    def _post_exec(results: TestCycleResults) -> None:
        print()
        pretty_print_results(results, with_colors=True)
        if has_test_cycle_failed(results):
            sys.exit(1)

    with timing(prefix="Tests duration:"):
        bootstrap(
            post_exec=_post_exec,
            test_cycle=create_e2e_test_cycle(drivers_pool),
            run_plugins=lambda results: run_plugins(
                lambda: generate_docx_proof(...),
                lambda: generate_json_results(results=results, ...),
                exceptions_logger=...,
            ),
        )

Cycle e2e#

# src/tests/cycles/e2e.py
E2E_CYCLE_NAME = "e2e"

def create_e2e_test_cycle(drivers_pool: SeleniumWebDriversPool):
    return TestCycle(
        name=E2E_CYCLE_NAME,
        campaigns=[
            create_igoristan_login_campaign(drivers_pool=drivers_pool),
            create_igoristan_randomness_campaign(drivers_pool=drivers_pool),
            create_igoristan_sacred_upload_campaign(drivers_pool=drivers_pool),
            create_igoristan_corsicamon_campaign(drivers_pool=drivers_pool),
        ],
        smoke_tests_campaigns=[
            create_igoristan_global_smoke_campaign(drivers_pool=drivers_pool),
            create_igoristan_corsicamon_smoke_campaign(drivers_pool=drivers_pool),
        ],
        mode="wait-for-all-smoke-tests",
    )
  • Mode : wait-for-all-smoke-tests (les deux smoke tournent même si l’un fail).
  • 2 smoke campaigns (global + corsicamon).
  • 4 main campaigns (login, randomness, sacred upload, corsicamon).