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") # # There is deliberately NO test for bypassing Godot's GUI routing. An earlier # attempt did that, on the theory that touches were not reaching Controls at # all - the device then reported `held=y`, proving the button had been # receiving presses through ordinary routing the whole time. The bypass was # solving a problem that did not exist, and its set_input_as_handled() call # swallowed the very events the on-screen probe was reading. var presses: int = 0 func _initialize() -> void: var button_script: GDScript = load("res://ui/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)