Files
aetherbound-guild/runtime/tests/fg2/graybox_touch_flow_test.gd
T

163 lines
6.8 KiB
GDScript

extends SceneTree
const Controller = preload("res://campaign/fg2_graybox_controller.gd")
const Fixture = preload("res://campaign/fg2_fixture.gd")
const VIEWPORT := Vector2i(844, 390)
var failures: Array[String] = []
var experience
var parsed_touches := 0
var parsed_drags := 0
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND
root.content_scale_size = VIEWPORT
root.size = VIEWPORT
await verify_victory_flow()
await verify_recovery_flow()
if is_instance_valid(experience):
experience.queue_free()
for _index in 45:
await process_frame
if failures.is_empty():
print("ABG_FG2_GRAYBOX_TOUCH_FLOW_OK canvas=422x195@2x route=risk0 order=drag battle=automatic events=wave+damage+outcome reward=coin market2=saved failure=risk2 fallen=3 recovery=protected+hire touch=%d drag=%d fallback=0 direct=0" % [parsed_touches, parsed_drags])
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func verify_victory_flow() -> void:
await mount(Fixture.canonical_market_state())
expect(experience.screen == Controller.SCREEN_MARKET, "canonical fixture opens the world-first Market")
expect(String(experience.get_meta("logical_grid", "")) == "422x195@2x", "reference viewport uses the exact 422x195 logical grid")
for layer_name in ["BackgroundLayer", "MidgroundLayer", "ActorsLayer", "ForegroundLayer", "VfxLayer"]:
expect(experience.find_child(layer_name, true, false) != null, "%s exists as an independent world layer" % layer_name)
var before: Array = Array(experience.adapter.market.state.current_run.deployed_recruit_ids).duplicate()
expect(before.size() == 2, "canonical fixture starts with the exact two-person line")
await drag("FG2CompanyTarget_%s" % String(before[-1]), "FG2CompanyTarget_%s" % String(before[0]))
expect(experience.adapter.market.state.current_run.deployed_recruit_ids != before, "parsed ScreenDrag changes the authoritative line order")
var route_id := Fixture.route_id(experience.adapter.snapshot(), 0)
await tap("FG2Route_%s" % route_id)
await tap("FG2DepartButton")
expect(experience.screen == Controller.SCREEN_BATTLE and not experience.battle_result_visible, "parsed route commit enters the real automatic battle")
var guard := 0
while not experience.battle_result_visible and guard < 260:
experience.advance_battle_ticks(8)
guard += 1
await process_frame
expect(guard < 260, "canonical battle reaches a bounded terminal")
expect(String(experience.view.battle.outcome) == "victory", "risk-zero battle preserves the real victory")
for kind in ["wave_arrived", "damage", "outcome"]:
expect(int(experience.presented_event_counts.get(kind, 0)) > 0, "graybox consumes the authoritative %s event" % kind)
await tap("FG2SettleButton")
expect(experience.screen == Controller.SCREEN_REWARD, "victory settlement exposes the real reward decision")
await tap("FG2RewardButton")
expect(experience.screen == Controller.SCREEN_MARKET, "reward returns to the changed Market world")
expect(int(experience.view.market_index) == 2 and experience.persistent_change_visible, "Market 2 and its persistent channel change are visible")
expect(experience.input_touch_count == parsed_touches and experience.input_drag_count == parsed_drags, "all commands are accounted as parsed ScreenTouch/ScreenDrag")
expect(experience.fallback_input_count == 0 and experience.direct_command_count == 0, "no fallback or direct player command path runs")
func verify_recovery_flow() -> void:
await mount(Fixture.wounded_high_risk_market_state())
var route_id := Fixture.route_id(experience.adapter.snapshot(), 2)
await tap("FG2Route_%s" % route_id)
await tap("FG2DepartButton")
var guard := 0
while not experience.battle_result_visible and guard < 260:
experience.advance_battle_ticks(8)
guard += 1
await process_frame
expect(String(experience.view.battle.outcome) == "defeat", "wounded high-risk battle produces the real defeat")
expect(experience.view.battle.fallen_recruit_ids.size() == 3, "three deployed Recruits permanently fall")
await tap("FG2SettleButton")
expect(experience.screen == Controller.SCREEN_RECOVERY and bool(experience.view.recovery_required), "settlement opens bounded recovery")
var survivors: int = experience.view.company.size()
await tap("FG2RecoveryButton")
expect(experience.screen == Controller.SCREEN_MARKET and not bool(experience.view.recovery_required), "protected hire returns to the Market")
expect(experience.view.company.size() == survivors + 1, "one new Recruit joins without resurrecting Fallen identities")
func mount(snapshot_value: Dictionary) -> void:
if is_instance_valid(experience):
experience.queue_free()
await settle_frames(12)
experience = Controller.new()
experience.battle_auto_advance = false
experience.locale = "zh_CN"
experience.text_scale = 1.0
experience.size = Vector2(VIEWPORT)
experience.configure_entry(snapshot_value)
root.add_child(experience)
await settle_frames(8)
func tap(node_name: String) -> void:
var control := experience.find_child(node_name, true, false) as Control
expect(control != null, "%s exists before parsed touch" % node_name)
if control == null:
return
var point := root.get_final_transform() * control.get_global_rect().get_center()
var down := InputEventScreenTouch.new()
down.index = 0
down.position = point
down.pressed = true
Input.parse_input_event(down)
parsed_touches += 1
await process_frame
var up := InputEventScreenTouch.new()
up.index = 0
up.position = point
up.pressed = false
Input.parse_input_event(up)
await settle_frames()
func drag(source_name: String, target_name: String) -> void:
var source := experience.find_child(source_name, true, false) as Control
var target := experience.find_child(target_name, true, false) as Control
expect(source != null and target != null, "formation drag targets exist")
if source == null or target == null:
return
var start := root.get_final_transform() * source.get_global_rect().get_center()
var finish := root.get_final_transform() * target.get_global_rect().get_center()
var down := InputEventScreenTouch.new()
down.index = 1
down.position = start
down.pressed = true
Input.parse_input_event(down)
parsed_touches += 1
await process_frame
var motion := InputEventScreenDrag.new()
motion.index = 1
motion.position = finish
motion.relative = finish - start
Input.parse_input_event(motion)
parsed_drags += 1
await process_frame
var up := InputEventScreenTouch.new()
up.index = 1
up.position = finish
up.pressed = false
Input.parse_input_event(up)
await settle_frames()
func settle_frames(count := 5) -> void:
for _index in count:
await process_frame
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("FG-2 graybox touch: %s" % message)