Chapter 07 — ocarina-example#

E2E suite designed to test Igoristan. The reference example: every Ocarina project starts by reading this repo and copying its adapters.

Outline#

#FileTopic
0101-tree.mdThe full src/ tree: pages/, lib/, api/, caches/, constants/, tests/.
0202-adapters.mdThe 5 adapters (act, match_page, TestSuite, TestCampaign, EnvGetters).
0303-scenarios-login.mdDashboard login scenarios: happy / unhappy / data-driven.
0404-scenarios-corsicamon.mdCorsicamon scenarios: api_key, draw, add, back.
0505-scenarios-randomness.mdRandomness scenarios (4 levels): random_error, random_loaders, dsed, madness, chaotic_form, walkthrough.
0606-scenarios-sacred-upload.mdSacred upload scenarios: upload_files, back_to_igoristan.
0707-humanized-driver.mdHumanizedDriver: Selenium proxy to simulate human typing.
0808-caches-locks.mdL1 cache (dogpile.cache.memory) + reserved keys + distributed Redis locks.
0909-watcher-catch-me.mdThe catch_me_if_you_can watcher for the chaotic form.
1010-env-getters.mdEnvGetters[_CredsKeys, _ValuesKeys] strictly typed via Literal.
1111-ci.mdCI: main_ci.yml + dev_ci.yml (lint+typecheck) + e2e.yml (Redis + manual Firefox).

Goal#

Holy Book quote (chapter “First steps”):

Note: This manual is intended to help you get familiar with the provided ocarina-example project, which remains the source of truth to refer to in all circumstances.

The project is documented as the canonical reference. Any question about how to do X starts with: “look at how it’s done in 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=...,
            ),
        )

E2E cycle#

# 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 (both smokes run even if one fails).
  • 2 smoke campaigns (global + corsicamon).
  • 4 main campaigns (login, randomness, sacred upload, corsicamon).