Add Playwright e2e tests for all 8 spec acceptance scenarios
All checks were successful
Deploy / deploy (push) Successful in 1m49s
All checks were successful
Deploy / deploy (push) Successful in 1m49s
Implement browser-based e2e tests covering: - Tests 1-5: Stats progression (cohort, feed, eggs, moves, backdating) - Test 6: Event viewing and deletion UI - Test 7: Harvest outcomes with yield items - Test 8: Optimistic lock selection validation Includes page objects for reusable form interactions and fresh_db fixtures for tests requiring isolated database state. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -120,3 +120,96 @@ def live_server(e2e_db_path):
|
||||
def base_url(live_server):
|
||||
"""Provide the base URL for the live server."""
|
||||
return live_server.url
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Function-scoped fixtures for tests that need isolated state
|
||||
# =============================================================================
|
||||
|
||||
|
||||
def _create_fresh_db(tmp_path) -> str:
|
||||
"""Create a fresh migrated and seeded database.
|
||||
|
||||
Helper function used by function-scoped fixtures.
|
||||
"""
|
||||
db_path = str(tmp_path / f"animaltrack_{random.randint(0, 99999)}.db")
|
||||
run_migrations(db_path, "migrations", verbose=False)
|
||||
db = get_db(db_path)
|
||||
run_seeds(db)
|
||||
return db_path
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fresh_db_path(tmp_path):
|
||||
"""Create a fresh database for a single test.
|
||||
|
||||
Function-scoped so each test gets isolated state.
|
||||
Use this for tests that need a clean slate (e.g., deletion, harvest).
|
||||
"""
|
||||
return _create_fresh_db(tmp_path)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fresh_server(fresh_db_path):
|
||||
"""Start a fresh server for a single test.
|
||||
|
||||
Function-scoped so each test gets isolated state.
|
||||
This fixture is slower than the session-scoped live_server,
|
||||
so only use it when you need a clean database for each test.
|
||||
"""
|
||||
port = 33760 + random.randint(0, 99)
|
||||
harness = ServerHarness(port)
|
||||
harness.start(fresh_db_path)
|
||||
yield harness
|
||||
harness.stop()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fresh_base_url(fresh_server):
|
||||
"""Provide the base URL for a fresh server."""
|
||||
return fresh_server.url
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Page object fixtures
|
||||
# =============================================================================
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def animals_page(page, base_url):
|
||||
"""Page object for animal management."""
|
||||
from tests.e2e.pages import AnimalsPage
|
||||
|
||||
return AnimalsPage(page, base_url)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def feed_page(page, base_url):
|
||||
"""Page object for feed management."""
|
||||
from tests.e2e.pages import FeedPage
|
||||
|
||||
return FeedPage(page, base_url)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def eggs_page(page, base_url):
|
||||
"""Page object for egg collection."""
|
||||
from tests.e2e.pages import EggsPage
|
||||
|
||||
return EggsPage(page, base_url)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def move_page(page, base_url):
|
||||
"""Page object for animal moves."""
|
||||
from tests.e2e.pages import MovePage
|
||||
|
||||
return MovePage(page, base_url)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def harvest_page(page, base_url):
|
||||
"""Page object for harvest/outcome recording."""
|
||||
from tests.e2e.pages import HarvestPage
|
||||
|
||||
return HarvestPage(page, base_url)
|
||||
|
||||
Reference in New Issue
Block a user