Files
aetherbound-guild/runtime/tests/p10_0/web_touch_activation_test.gd
T

199 lines
7.6 KiB
GDScript

extends SceneTree
const Controller = preload("res://p10_0/runtime_controller.gd")
const SaveService = preload("res://p10_0/save_service.gd")
const VIEWPORT := Vector2i(844, 390)
const EMULATION_SETTING := "input_devices/pointing/emulate_mouse_from_touch"
const TEST_SAVE_PATH := "user://p100_web_touch_activation_test.json"
var failures: Array[String] = []
var experience
var raw_touch_count := 0
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
var original_emulation: bool = bool(ProjectSettings.get_setting(EMULATION_SETTING, true))
ProjectSettings.set_setting(EMULATION_SETTING, false)
cleanup_save()
configure_viewport()
await verify_raw_touch_and_persistence()
ProjectSettings.set_setting(EMULATION_SETTING, original_emulation)
cleanup_save()
if failures.is_empty():
print("ABG_P10_0_WEB_TOUCH_ACTIVATION_OK emulate_mouse=false touch=%d exact_once=true disabled=true outside=true canceled=true drag=1 persistence=true resume=market mouse_regression=separate" % raw_touch_count)
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func verify_raw_touch_and_persistence() -> void:
experience = Controller.new()
experience.persistence_enabled = true
experience.save_path = TEST_SAVE_PATH
experience.battle_auto_advance = false
experience.size = Vector2(VIEWPORT)
root.add_child(experience)
await settle_frames(8)
expect(experience.screen == "title", "fresh persistence slot opens Title")
await tap("P100SettingsButton")
expect(experience.settings_open, "raw touch opens Settings")
await tap("P100NewExpeditionButton")
expect(experience.settings_open and experience.screen == "title", "Settings scrim blocks the underlying New Expedition Button")
await tap("P100CloseSettingsButton")
expect(not experience.settings_open, "raw touch closes Settings")
await tap("P100Difficulty_wayfinder")
expect(experience.selected_difficulty == "wayfinder", "raw touch selects difficulty")
await tap("P100NewExpeditionButton")
expect(experience.screen == "opening", "raw touch opens the Recruit draft")
expect(experience.market.state.run_creation_draft.opening_offers.size() == 4, "opening has four stable offers")
if experience.screen != "opening":
return
var ids: Array[String] = []
for offer in experience.market.state.run_creation_draft.opening_offers:
ids.append(String(offer.source_offer_id))
await tap("P100CommitRunButton")
expect(experience.opening_selection.is_empty(), "disabled commit does not activate")
await press_inside_release_outside("P100OpeningTarget_%s" % ids[0])
expect(experience.opening_selection.is_empty(), "outside release does not activate")
await canceled_touch("P100OpeningTarget_%s" % ids[0])
expect(experience.opening_selection.is_empty(), "canceled touch does not activate")
await tap("P100OpeningTarget_%s" % ids[0])
await tap("P100OpeningTarget_%s" % ids[1])
expect(experience.opening_selection == [ids[0], ids[1]], "each raw touch activates exactly once")
expect(FileAccess.file_exists(TEST_SAVE_PATH), "opening draft is persisted")
var loaded: Dictionary = SaveService.new().load_slot(ProjectSettings.globalize_path(TEST_SAVE_PATH))
expect(loaded.ok and loaded.snapshot.run_creation_draft.opening_offers.size() == 4, "persisted opening draft validates")
await tap("P100CommitRunButton")
expect(experience.screen == "market" and experience.market.state.current_run.company.size() == 2, "raw touch forms the Company")
var before_drag: Array = experience.market.state.current_run.deployed_recruit_ids.duplicate()
await drag("P100CompanyTarget_%s" % String(before_drag[1]), "P100CompanyTarget_%s" % String(before_drag[0]))
expect(experience.market.state.current_run.deployed_recruit_ids != before_drag, "line drag reorders without becoming an actor tap")
expect(experience.focused_company_actor.is_empty(), "line drag does not emit the actor Button signal")
experience.queue_free()
await settle_frames(45)
experience = Controller.new()
experience.persistence_enabled = true
experience.save_path = TEST_SAVE_PATH
experience.size = Vector2(VIEWPORT)
root.add_child(experience)
await settle_frames(8)
expect(experience.screen == "market" and experience.market.state.current_run.company.size() == 2, "persistence resumes the committed Company")
experience.queue_free()
await settle_frames(45)
func configure_viewport() -> 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
func tap(node_name: String) -> void:
var control := experience.find_child(node_name, true, false) as Control
expect(control != null, "%s exists before raw touch" % node_name)
if control == null:
return
var point := root.get_final_transform() * control.get_global_rect().get_center()
await touch(point, point)
func press_inside_release_outside(node_name: String) -> void:
var control := experience.find_child(node_name, true, false) as Control
expect(control != null, "%s exists before outside-release touch" % node_name)
if control == null:
return
var point := root.get_final_transform() * control.get_global_rect().get_center()
await touch(point, Vector2(4, VIEWPORT.y - 4))
func canceled_touch(node_name: String) -> void:
var control := experience.find_child(node_name, true, false) as Control
expect(control != null, "%s exists before canceled 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)
raw_touch_count += 1
await process_frame
var canceled := InputEventScreenTouch.new()
canceled.index = 0
canceled.position = point
canceled.pressed = false
canceled.canceled = true
Input.parse_input_event(canceled)
await settle_frames(4)
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, "line 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)
raw_touch_count += 1
await process_frame
var motion := InputEventScreenDrag.new()
motion.index = 1
motion.position = finish
motion.relative = finish - start
Input.parse_input_event(motion)
await process_frame
var up := InputEventScreenTouch.new()
up.index = 1
up.position = finish
up.pressed = false
Input.parse_input_event(up)
await settle_frames(4)
func touch(press_point: Vector2, release_point: Vector2) -> void:
var down := InputEventScreenTouch.new()
down.index = 0
down.position = press_point
down.pressed = true
Input.parse_input_event(down)
raw_touch_count += 1
await process_frame
var up := InputEventScreenTouch.new()
up.index = 0
up.position = release_point
up.pressed = false
Input.parse_input_event(up)
await settle_frames(4)
func settle_frames(count: int) -> void:
for _index in count:
await process_frame
func cleanup_save() -> void:
var absolute := ProjectSettings.globalize_path(TEST_SAVE_PATH)
for path in [absolute, "%s.bak" % absolute, "%s.candidate" % absolute]:
if FileAccess.file_exists(path):
DirAccess.remove_absolute(path)
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("P10.0R1 Web touch activation: %s" % message)