94 lines
3.7 KiB
GDScript3
94 lines
3.7 KiB
GDScript3
|
|
extends SceneTree
|
||
|
|
|
||
|
|
# Headless test: run with
|
||
|
|
# godot --headless -s res://tests/test_icon_button_press_fires.gd
|
||
|
|
# A browser on a phone delivers the touch DOWN and never delivers the
|
||
|
|
# release. Measured on the deployed web build: presses arrived with correct
|
||
|
|
# coordinates, landed inside the button, the button latched into its held
|
||
|
|
# state, and no release ever followed. IconButton emits `pressed` only on
|
||
|
|
# release, so on the web nothing ever fired - the "Play does nothing" bug.
|
||
|
|
#
|
||
|
|
# fire_on_press exists for exactly that platform. This test does not care
|
||
|
|
# whether THIS run is a web build; it exercises both settings directly, which
|
||
|
|
# is the only way a headless Linux run can cover the web path at all.
|
||
|
|
#
|
||
|
|
# Covers:
|
||
|
|
# A. with fire_on_press, a press alone emits - and emits ONCE even if a
|
||
|
|
# release does arrive after it
|
||
|
|
# B. with fire_on_press, the button does not stay latched in its held
|
||
|
|
# state (nothing is coming to clear it)
|
||
|
|
# C. without it, the release still drives the press, and dragging off
|
||
|
|
# still cancels - the behaviour every other platform keeps
|
||
|
|
# D. the default follows OS.has_feature("web")
|
||
|
|
|
||
|
|
var presses: int = 0
|
||
|
|
|
||
|
|
|
||
|
|
func _initialize() -> void:
|
||
|
|
var button_script: GDScript = load("res://IconButton.gd")
|
||
|
|
|
||
|
|
# --- D. the default is the platform rule --------------------------
|
||
|
|
var default_button: Control = button_script.new()
|
||
|
|
default_button.size = Vector2(120, 120)
|
||
|
|
if default_button.fire_on_press != OS.has_feature("web"):
|
||
|
|
return _fail("fire_on_press defaults to %s, expected OS.has_feature('web') = %s" \
|
||
|
|
% [default_button.fire_on_press, OS.has_feature("web")])
|
||
|
|
default_button.free()
|
||
|
|
print("fire_on_press defaults to the web feature flag (%s here)" % OS.has_feature("web"))
|
||
|
|
|
||
|
|
# --- A + B. the web path ------------------------------------------
|
||
|
|
var web_button: Control = button_script.new()
|
||
|
|
web_button.size = Vector2(120, 120)
|
||
|
|
web_button.fire_on_press = true
|
||
|
|
web_button.pressed.connect(_count)
|
||
|
|
root.add_child(web_button)
|
||
|
|
|
||
|
|
presses = 0
|
||
|
|
web_button._handle_press(true, Vector2(60, 60))
|
||
|
|
if presses != 1:
|
||
|
|
return _fail("a press alone emitted %d times with fire_on_press, expected 1" % presses)
|
||
|
|
if web_button.pressed_down:
|
||
|
|
return _fail("the button latched held with fire_on_press - nothing will ever clear it")
|
||
|
|
# A release may still arrive on a platform that sends one; it must not
|
||
|
|
# produce a second press for the same tap.
|
||
|
|
web_button._handle_press(false, Vector2(60, 60))
|
||
|
|
if presses != 1:
|
||
|
|
return _fail("a release after a fired press emitted again (%d total)" % presses)
|
||
|
|
print("fire_on_press: one tap emits exactly once and does not latch")
|
||
|
|
|
||
|
|
# --- C. every other platform --------------------------------------
|
||
|
|
var native_button: Control = button_script.new()
|
||
|
|
native_button.size = Vector2(120, 120)
|
||
|
|
native_button.fire_on_press = false
|
||
|
|
native_button.pressed.connect(_count)
|
||
|
|
root.add_child(native_button)
|
||
|
|
|
||
|
|
presses = 0
|
||
|
|
native_button._handle_press(true, Vector2(60, 60))
|
||
|
|
if presses != 0:
|
||
|
|
return _fail("a press emitted without a release while fire_on_press was off")
|
||
|
|
if not native_button.pressed_down:
|
||
|
|
return _fail("the button did not latch held while waiting for its release")
|
||
|
|
native_button._handle_press(false, Vector2(60, 60))
|
||
|
|
if presses != 1:
|
||
|
|
return _fail("the release did not emit (%d)" % presses)
|
||
|
|
|
||
|
|
# Dragging off before lifting still cancels.
|
||
|
|
presses = 0
|
||
|
|
native_button._handle_press(true, Vector2(60, 60))
|
||
|
|
native_button._handle_press(false, Vector2(400, 400))
|
||
|
|
if presses != 0:
|
||
|
|
return _fail("releasing outside the button still counted as a press")
|
||
|
|
print("release path unchanged: release fires, dragging off cancels")
|
||
|
|
|
||
|
|
print("TEST_ICON_BUTTON_PRESS_FIRES: PASS")
|
||
|
|
quit(0)
|
||
|
|
|
||
|
|
|
||
|
|
func _count() -> void:
|
||
|
|
presses += 1
|
||
|
|
|
||
|
|
|
||
|
|
func _fail(message: String) -> void:
|
||
|
|
print("TEST_ICON_BUTTON_PRESS_FIRES: FAIL (%s)" % message)
|
||
|
|
quit(1)
|