extends SceneTree var failures := 0 class ScreenHost extends Control: var shown_screen := "" func show_screen(screen_name: String, _payload: Variant = null) -> void: shown_screen = screen_name func _initialize() -> void: call_deferred("_run") func _run() -> void: var prior_environment: String = ProjectSettings.get_setting("step3/deployment_environment", "development") ProjectSettings.set_setting("step3/deployment_environment", "uat") var main_screen = load("res://scripts/ui/main.gd").new() root.add_child(main_screen) await process_frame var nav_button := main_screen.sidebar.find_child("NavCcsCases2", true, false) as Button _assert(nav_button != null and nav_button.visible, "UAT should expose a CCS Cases 2 navigation item") _assert(main_screen.screens.has("ccs_cases_2"), "UAT should register the graphical CCS screen") main_screen.queue_free() await process_frame ProjectSettings.set_setting("step3/deployment_environment", prior_environment) var service = root.get_node("CCSService") var prior_attempt: Dictionary = service.attempt.duplicate(true) var prior_cases: Array = service.cases.duplicate(true) var prior_origin: String = service.launch_origin var host := ScreenHost.new() host.size = Vector2(1200.0, 700.0) root.add_child(host) var screen = load("res://scripts/ui/ccs_cases_2_screen.gd").new() screen.main = host host.add_child(screen) await process_frame service.cases = [ {"externalId": "interactive", "title": "Interactive case", "system": "Endocrine", "difficulty": 2, "realTimeMinutes": 20, "interactiveInterviewAvailable": true}, {"externalId": "legacy", "title": "Legacy case", "interactiveInterviewAvailable": false} ] service.attempt = {} screen.cases_loaded = true screen.active_loaded = true screen._render_state() await process_frame _assert(screen.current_view == "case_selection", "CCS Cases 2 should begin with compatible case selection") _assert(screen.case_list.get_child_count() == 1, "legacy cases should be excluded from graphical selection") service.attempt = _sample_attempt(false) screen._render_state() await process_frame _assert(screen.current_view == "doctor_office", "an active interactive attempt should open the doctor office") _assert(screen.active_scene.dialogue_text.text == "Hello, doctor.", "the patient bubble should use the server-provided current node") _assert(screen.active_scene.choice_container.get_child_count() == 1, "the scene should render server-provided dialogue choices") _assert(is_equal_approx(screen.stage_root.scale.x, screen.stage_root.scale.y), "the graphical stage should preserve its aspect ratio") service.attempt = _sample_attempt(true) screen._on_attempt_changed() await process_frame _assert(screen.active_scene.dialogue_text.text == "Okay, doctor.", "attempt updates should advance the rendered patient response") _assert(screen.active_scene.choice_container.get_child_count() == 1, "terminal dialogue should expose the management handoff") screen.active_scene.interview_continue_requested.emit() _assert(host.shown_screen == "ccs_player", "terminal dialogue should hand off the same attempt to the CCS player") screen.on_hide() await process_frame _assert(screen.active_scene == null, "hiding CCS Cases 2 should release the doctor scene") host.queue_free() service.attempt = prior_attempt service.cases = prior_cases service.launch_origin = prior_origin await process_frame quit(1 if failures > 0 else 0) func _sample_attempt(completed: bool) -> Dictionary: var node := { "id": "done" if completed else "greeting", "patientText": "Okay, doctor." if completed else "Hello, doctor.", "isTerminal": completed, "choices": [] if completed else [{"id": "ask_reason", "text": "What brings you in?", "nextNodeId": "done"}] } return { "id": "attempt-1", "state": "active", "revision": 1, "openingCompleted": completed, "interview": {"currentNodeId": node.id, "currentNode": node, "visitedChoiceIds": [], "completed": completed} } func _assert(condition: bool, message: String) -> void: if condition: return failures += 1 push_error(message)