Files
aetherbound-guild/runtime/tests/p9_8/layout_accessibility_runtime_test.gd
T

157 lines
6.7 KiB
GDScript

extends SceneTree
const Controller = preload("res://p9_8/runtime_controller.gd")
const Fixture = preload("res://tests/p9_8/runtime_fixture.gd")
const BossService = preload("res://p9_8/boss_service.gd")
const BossBattleService = preload("res://p9_8/boss_battle_service.gd")
var failures: Array[String] = []
var experience
var capture_root := ""
var captures := 0
func _initialize() -> void:
call_deferred("run_test")
func run_test() -> void:
capture_root = OS.get_environment("ABG_P9_8_LAYOUT_CAPTURE_ROOT")
if not capture_root.is_empty():
DirAccess.make_dir_recursive_absolute(capture_root)
var market8 := Fixture.market8()
await fixture("01-artifact-small-zh", market8, Vector2i(760, 360), "zh_CN", 1.0, false, false)
var promotion := BossService.new(market8)
promotion.choose_artifact("layout-artifact", "AR-002")
await fixture("02-promotion-reference-en130", promotion.state.snapshot(), Vector2i(844, 390), "en", 1.3, false, false)
if not promotion.state.promotion_draft.is_empty():
var recruit_id := String(promotion.state.promotion_draft.recruit_id)
promotion.confirm_promotion("layout-promotion", recruit_id, String(promotion.state.promotion_draft.offer_ids[1]))
await fixture("03-market-large-reduced", promotion.state.snapshot(), Vector2i(1280, 720), "zh_CN", 1.0, true, false)
var muster := Fixture.boss_muster()
await fixture("04-boss-muster-reference", muster, Vector2i(844, 390), "zh_CN", 1.0, false, false)
await mount(muster, Vector2i(844, 390), "en", 1.0, false, true)
experience.choose_boss_plan("rotate")
for _tick in 90:
experience.advance_battle_ticks(1)
await settle_frames()
verify_current("05-boss-battle-low-power", Vector2i(844, 390), false)
await capture("05-boss-battle-low-power")
var recovery := boss_recovery_state(muster)
await fixture("06-boss-recovery-zh130", recovery, Vector2i(844, 390), "zh_CN", 1.3, true, false)
var result := boss_result_state(muster)
await fixture("07-contract-result-en", result, Vector2i(844, 390), "en", 1.0, false, false)
var closed_service = BossService.new()
closed_service.state.restore_snapshot(result)
closed_service.close_contract("layout-close")
await fixture("08-persistent-result-large", closed_service.state.snapshot(), Vector2i(1280, 720), "zh_CN", 1.0, false, false)
await fixture("09-portrait-rotate", market8, Vector2i(390, 844), "zh_CN", 1.0, false, false, true)
if is_instance_valid(experience):
experience.queue_free()
for _index in 45:
await process_frame
if failures.is_empty():
print("ABG_P9_8_LAYOUT_ACCESSIBILITY_OK fixtures=9 states=artifact,promotion,market,boss_muster,boss_battle,recovery,contract_result,persistent,rotate viewports=760x360,844x390,1280x720,390x844 locales=zh_CN,en text_130=true reduced_motion=true muted=true low_power=true controls=48 cards=0 captures=%d" % captures)
quit(0)
else:
for failure in failures:
push_error(failure)
quit(1)
func fixture(label: String, snapshot: Dictionary, viewport: Vector2i, locale: String, text_scale: float, reduced: bool, low_power: bool, portrait := false) -> void:
await mount(snapshot, viewport, locale, text_scale, reduced, low_power)
verify_current(label, viewport, portrait)
await capture(label)
func mount(snapshot: Dictionary, viewport: Vector2i, locale: String, text_scale: float, reduced: bool, low_power: bool) -> void:
if is_instance_valid(experience):
experience.queue_free()
await settle_frames()
root.size = viewport
root.content_scale_mode = Window.CONTENT_SCALE_MODE_CANVAS_ITEMS
root.content_scale_aspect = Window.CONTENT_SCALE_ASPECT_EXPAND
root.content_scale_size = viewport
experience = Controller.new()
experience.persistence_enabled = false
experience.battle_auto_advance = false
experience.locale = locale
experience.text_scale = text_scale
experience.reduced_motion = reduced
experience.muted = true
experience.low_power = low_power
experience.size = Vector2(viewport)
experience.configure_entry(snapshot)
root.add_child(experience)
await settle_frames()
func verify_current(label: String, viewport: Vector2i, portrait: bool) -> void:
var bounds := Rect2(Vector2.ZERO, Vector2(viewport))
if portrait:
expect(experience.find_child("P97RotateNotice", true, false) != null, "%s shows the landscape notice" % label)
return
expect(experience.find_child("P97RotateNotice", true, false) == null, "%s renders the game world" % label)
expect(experience.get_meta("visible_world_ratio", 0.0) >= 0.80, "%s keeps a world-first composition" % label)
expect(experience.find_children("*", "Panel", true, false).is_empty(), "%s adds no app panels" % label)
for node in experience.find_children("*", "Button", true, false):
var button := node as Button
expect(button.size.x >= 48 and button.size.y >= 48, "%s target %s is at least 48px" % [label, button.name])
expect(bounds.encloses(button.get_global_rect()), "%s target %s stays inside the viewport" % [label, button.name])
for node in experience.find_children("*", "Control", true, false):
var lowered := String(node.name).to_lower()
expect("card" not in lowered and "modal" not in lowered and "dialog" not in lowered, "%s has no card/modal surface" % label)
func boss_recovery_state(muster: Dictionary) -> Dictionary:
var service = BossService.new()
service.state.restore_snapshot(muster)
var fragile_id := "Farstring" if "Farstring" in service.state.company else String(service.state.company[-1])
var line: Array[String] = [fragile_id]
service.commit_deployment("layout-fragile", line)
service.commit_boss_plan("layout-defeat-plan", "rotate")
var battle = BossBattleService.new()
battle.start_from_contract(service.state)
var guard := 0
while not battle.state.terminal and guard < 1800:
battle.advance_ticks(1)
guard += 1
service.settle_boss("layout-defeat-settle", battle.state.snapshot())
return service.state.snapshot()
func boss_result_state(muster: Dictionary) -> Dictionary:
var service = BossService.new()
service.state.restore_snapshot(muster)
service.commit_boss_plan("layout-win-plan", "brace")
var battle = BossBattleService.new()
battle.start_from_contract(service.state)
var guard := 0
while not battle.state.terminal and guard < 1800:
battle.advance_ticks(1)
guard += 1
service.settle_boss("layout-win-settle", battle.state.snapshot())
return service.state.snapshot()
func capture(label: String) -> void:
if capture_root.is_empty():
return
await RenderingServer.frame_post_draw
var error := root.get_texture().get_image().save_png(capture_root.path_join(label + ".png"))
expect(error == OK, "%s capture writes" % label)
if error == OK:
captures += 1
await process_frame
func settle_frames() -> void:
await process_frame
await process_frame
func expect(condition: bool, message: String) -> void:
if not condition:
failures.append("P9.8 layout: %s" % message)