# ABOUTME: Playwright e2e tests for spec scenario 7: Harvest with yields. # ABOUTME: Tests UI flows for recording animal outcomes (harvest) with yield items. import pytest from playwright.sync_api import Page, expect pytestmark = pytest.mark.e2e class TestSpecHarvest: """Playwright e2e tests for spec scenario 7: Harvest with yields. These tests verify that the outcome recording UI works correctly, including the ability to record harvest outcomes with yield items. """ def test_outcome_form_accessible(self, page: Page, fresh_server): """Test that the outcome form is accessible.""" base_url = fresh_server.url # Create a cohort first page.goto(f"{base_url}/actions/cohort") page.select_option("#species", "duck") page.select_option("#location_id", label="Strip 1") page.fill("#count", "5") page.select_option("#life_stage", "adult") page.select_option("#sex", "female") page.select_option("#origin", "purchased") page.click('button[type="submit"]') page.wait_for_load_state("networkidle") # Navigate to outcome form page.goto(f"{base_url}/actions/outcome") expect(page.locator("body")).to_be_visible() # Should see outcome form elements expect(page.locator("#filter")).to_be_visible() expect(page.locator("#outcome")).to_be_visible() def test_outcome_form_has_yield_fields(self, page: Page, fresh_server): """Test that the outcome form includes yield item fields.""" base_url = fresh_server.url # Create a cohort first page.goto(f"{base_url}/actions/cohort") page.select_option("#species", "duck") page.select_option("#location_id", label="Strip 1") page.fill("#count", "3") page.select_option("#life_stage", "adult") page.select_option("#sex", "female") page.select_option("#origin", "purchased") page.click('button[type="submit"]') page.wait_for_load_state("networkidle") # Navigate to outcome form page.goto(f"{base_url}/actions/outcome") # Should see yield fields yield_product = page.locator("#yield_product_code") yield_quantity = page.locator("#yield_quantity") # At least the product selector should exist if yield_product.count() > 0: expect(yield_product).to_be_visible() if yield_quantity.count() > 0: expect(yield_quantity).to_be_visible() def test_harvest_outcome_flow(self, page: Page, fresh_server): """Test recording a harvest outcome through the UI. This tests the complete flow of selecting animals and recording a harvest outcome (without yields for simplicity). """ base_url = fresh_server.url # Create a cohort page.goto(f"{base_url}/actions/cohort") page.select_option("#species", "duck") page.select_option("#location_id", label="Strip 1") page.fill("#count", "5") page.select_option("#life_stage", "adult") page.select_option("#sex", "female") page.select_option("#origin", "purchased") page.click('button[type="submit"]') page.wait_for_load_state("networkidle") # Navigate to outcome form page.goto(f"{base_url}/actions/outcome") page.wait_for_load_state("networkidle") # Set filter to select animals at Strip 1 page.fill("#filter", 'location:"Strip 1"') page.keyboard.press("Tab") # Wait for all HTMX updates to complete (selection preview + facet pills) page.wait_for_load_state("networkidle") page.wait_for_timeout(500) # Extra wait for any delayed HTMX triggers # Wait for selection preview to have content page.wait_for_function( "document.querySelector('#selection-container')?.textContent?.length > 0" ) # Select harvest outcome page.select_option("#outcome", "harvest") # Fill reason reason_field = page.locator("#reason") if reason_field.count() > 0: page.fill("#reason", "Test harvest") # Wait for any HTMX updates from selecting outcome page.wait_for_load_state("networkidle") # Submit outcome - use locator with explicit wait for stability submit_btn = page.locator('button[type="submit"]') expect(submit_btn).to_be_enabled() submit_btn.click() page.wait_for_load_state("networkidle") # Verify success (should redirect or show success message) body_text = page.locator("body").text_content() or "" # Either success message, redirect, or no validation error success = ( "Recorded" in body_text or "harvest" in body_text.lower() or "Please select" not in body_text # No validation error ) assert success, f"Harvest outcome may have failed: {body_text[:300]}" def test_outcome_with_yield_item(self, page: Page, live_server): """Test that yield fields are present and accessible on outcome form. This tests the yield item UI components from Test #7 scenario. The actual harvest flow is tested by test_harvest_outcome_flow. """ # Navigate to outcome form page.goto(f"{live_server.url}/actions/outcome") page.wait_for_load_state("networkidle") # Verify yield fields exist and are accessible yield_section = page.locator("#yield-section") expect(yield_section).to_be_visible() yield_product = page.locator("#yield_product_code") yield_quantity = page.locator("#yield_quantity") yield_weight = page.locator("#yield_weight_kg") expect(yield_product).to_be_visible() expect(yield_quantity).to_be_visible() expect(yield_weight).to_be_visible() # Verify product dropdown has options options = yield_product.locator("option") assert options.count() > 1, "Yield product dropdown should have options" # Verify quantity field accepts input yield_quantity.fill("5") assert yield_quantity.input_value() == "5" # Verify weight field accepts decimal input yield_weight.fill("2.5") assert yield_weight.input_value() == "2.5" class TestOutcomeTypes: """Tests for different outcome types.""" def test_death_outcome_option_exists(self, page: Page, live_server): """Test that 'death' outcome option exists in the form.""" page.goto(f"{live_server.url}/actions/outcome") outcome_select = page.locator("#outcome") expect(outcome_select).to_be_visible() # Check that death option exists (enum value is "death", not "died") death_option = page.locator('#outcome option[value="death"]') assert death_option.count() > 0, "Death outcome option should exist" def test_harvest_outcome_option_exists(self, page: Page, live_server): """Test that 'harvest' outcome option exists in the form.""" page.goto(f"{live_server.url}/actions/outcome") outcome_select = page.locator("#outcome") expect(outcome_select).to_be_visible() # Check that harvest option exists harvest_option = page.locator('#outcome option[value="harvest"]') assert harvest_option.count() > 0, "Harvest outcome option should exist"