104 lines
3.4 KiB
GDScript
104 lines
3.4 KiB
GDScript
extends SceneTree
|
|
|
|
const MainScene = preload("res://main.tscn")
|
|
|
|
const FIXTURES := [
|
|
{"size": Vector2i(1280, 720), "locale": "zh_CN", "scale": 1.0},
|
|
{"size": Vector2i(844, 390), "locale": "en", "scale": 1.0},
|
|
{"size": Vector2i(390, 844), "locale": "zh_CN", "scale": 1.3},
|
|
]
|
|
const PAGES := ["boot", "title"]
|
|
|
|
var failures: Array[String] = []
|
|
var fixture_count := 0
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("run_test")
|
|
|
|
|
|
func run_test() -> void:
|
|
for fixture in FIXTURES:
|
|
for page in PAGES:
|
|
await verify_fixture(fixture, page)
|
|
if failures.is_empty():
|
|
print("ABG_P9_0_LAYOUT_OK fixtures=%d viewports=3 pages=2 locales=2 text_130=true min_touch=44" % fixture_count)
|
|
quit(0)
|
|
else:
|
|
for failure in failures:
|
|
push_error(failure)
|
|
quit(1)
|
|
|
|
|
|
func verify_fixture(fixture: Dictionary, page_name: String) -> void:
|
|
var viewport := SubViewport.new()
|
|
viewport.size = fixture.size
|
|
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
|
root.add_child(viewport)
|
|
var game := MainScene.instantiate()
|
|
game.auto_boot = false
|
|
viewport.add_child(game)
|
|
await settle()
|
|
game.locale = fixture.locale
|
|
game.text_scale = fixture.scale
|
|
game.page = game.AppPage.BOOT if page_name == "boot" else game.AppPage.TITLE
|
|
game.boot_verified = page_name == "title"
|
|
game.render()
|
|
await settle()
|
|
fixture_count += 1
|
|
|
|
var label := "%sx%s/%s/%s/%s" % [fixture.size.x, fixture.size.y, fixture.locale, str(fixture.scale), page_name]
|
|
var bounds := Rect2(Vector2.ZERO, Vector2(fixture.size))
|
|
var screen_name := "BootScreen" if page_name == "boot" else "TitleScreen"
|
|
var screen := find_control(game, screen_name)
|
|
expect(screen != null, "%s missing %s" % [label, screen_name])
|
|
if screen != null:
|
|
expect(contains_rect(bounds, screen.get_global_rect()), "%s screen outside viewport: %s" % [label, screen.get_global_rect()])
|
|
if page_name == "boot":
|
|
expect(find_control(game, "StartNewGame") == null, "%s exposes Start before verification" % label)
|
|
else:
|
|
expect(find_control(game, "NoRunStatus") != null, "%s missing no-run state" % label)
|
|
expect(find_control(game, "StartNewGame") != null, "%s missing primary action" % label)
|
|
verify_interactive_bounds(game, bounds, label)
|
|
game.queue_free()
|
|
viewport.queue_free()
|
|
await drain_cleanup()
|
|
|
|
|
|
func verify_interactive_bounds(node: Node, bounds: Rect2, label: String) -> void:
|
|
if node is BaseButton and node.is_visible_in_tree():
|
|
var rect: Rect2 = node.get_global_rect()
|
|
expect(contains_rect(bounds, rect), "%s button %s outside viewport: %s" % [label, node.name, rect])
|
|
expect(rect.size.x >= 44.0 and rect.size.y >= 44.0, "%s button %s below 44pt: %s" % [label, node.name, rect.size])
|
|
for child in node.get_children():
|
|
verify_interactive_bounds(child, bounds, label)
|
|
|
|
|
|
func find_control(node: Node, node_name: String) -> Control:
|
|
if node.name == node_name and node is Control and not node.is_queued_for_deletion():
|
|
return node
|
|
for child in node.get_children():
|
|
var found := find_control(child, node_name)
|
|
if found != null:
|
|
return found
|
|
return null
|
|
|
|
|
|
func contains_rect(outer: Rect2, inner: Rect2) -> bool:
|
|
return inner.position.x >= -0.5 and inner.position.y >= -0.5 and inner.end.x <= outer.end.x + 0.5 and inner.end.y <= outer.end.y + 0.5
|
|
|
|
|
|
func settle() -> void:
|
|
for frame in range(6):
|
|
await process_frame
|
|
|
|
|
|
func drain_cleanup() -> void:
|
|
for frame in range(30):
|
|
await process_frame
|
|
|
|
|
|
func expect(condition: bool, message: String) -> void:
|
|
if not condition:
|
|
failures.append("P9.0 layout: %s" % message)
|