extends SceneTree ## Verifica le regole della schermata iniziale: ## - la partita parte SOLO dal pulsante GIOCA: click o tocco sullo sfondo, oppure ## Invio/"Vai" nel campo del nome, non devono avviare nulla; ## - il nome scelto una volta non viene piu' richiesto. ## Avviare con: --headless --path . --script res://tools/test_start_screen.gd ## (con display, per gli eventi di puntamento: --rendering-method gl_compatibility) const Profile = preload("res://scripts/player_profile.gd") const StartScreen = preload("res://scripts/start_screen.gd") var world: Node3D var screen: CanvasLayer var failures := 0 var checks := 0 var emitted := "" var start_events := 0 func _initialize() -> void: call_deferred("run_test") func check(label: String, condition: bool, detail: String = "") -> void: checks += 1 if condition: print("PASS: " + label) else: failures += 1 print("FAIL: %s %s" % [label, detail]) func run_test() -> void: await test_world_menu() await test_locked_name() await test_unlocked_name() print("%d controlli superati, %d falliti" % [checks - failures, failures]) quit(1 if failures > 0 else 0) ## --- il menu del gioco vero --------------------------------------------------- func test_world_menu() -> void: world = load("res://scenes/main.tscn").instantiate() root.add_child(world) await process_frame await process_frame screen = world.start_screen screen.started.connect(_on_started) var gioca: Button = null for button in screen.find_children("*", "Button", true, false): if button.text == "GIOCA": gioca = button var backdrop: ColorRect = screen.find_children("*", "ColorRect", true, false)[0] var outside := Vector2(40.0, root.size.y - 80.0) var button_center: Vector2 = gioca.get_global_rect().get_center() check("il pulsante GIOCA c'e' e lo sfondo usato nel test e' fuori dai controlli", gioca != null and not gioca.get_global_rect().has_point(outside), "pulsante=%s" % str(gioca)) _click(outside) await process_frame await process_frame check("il click sullo sfondo non avvia la partita", start_events == 0 and world.start_screen != null, "avvii=%d" % start_events) _touch(outside) await process_frame await process_frame check("il tocco sullo sfondo non avvia la partita", start_events == 0 and world.start_screen != null, "avvii=%d" % start_events) if screen.name_field != null: screen.name_field.text = "Prova" screen.name_field.text_submitted.emit("Prova") await process_frame await process_frame check("l'Invio nel campo del nome non avvia la partita", start_events == 0 and world.start_screen != null, "avvii=%d" % start_events) else: check("l'Invio nel campo del nome non avvia la partita", true, "(nome gia' bloccato)") _click(button_center) await process_frame await process_frame check("il pulsante GIOCA avvia la partita", start_events == 1 and world.start_screen == null, "avvii=%d schermata=%s" % [start_events, "presente" if world.start_screen != null else "via"]) # Regressione: senza --api= questa e' una build desktop di prova e non deve poter # inviare punteggi alla classifica pubblica (ci sono finite righe "Test"). check("senza --api= la build di prova non invia punteggi alla classifica pubblica", world.leaderboard.disabled == true and world.leaderboard.base_url == "", "base=%s disattivata=%s" % [str(world.leaderboard.base_url), str(world.leaderboard.disabled)]) world.queue_free() await process_frame func _on_started(player_name: String) -> void: emitted = player_name start_events += 1 ## --- nome bloccato e non ------------------------------------------------------ func menu_with(profile: Dictionary) -> CanvasLayer: var layer := CanvasLayer.new() layer.set_script(StartScreen) layer.set("profile", profile) root.add_child(layer) layer.started.connect(_on_started) return layer func test_locked_name() -> void: emitted = "" start_events = 0 var menu := menu_with({"name": "Mat", "player_id": "abcdef0123456789", "best": 300, "locked": true}) await process_frame var label_text := "" for label in menu.find_children("*", "Label", true, false): if str(label.text).begins_with("giocatore:"): label_text = str(label.text) check("con nome scelto il campo non viene richiesto", menu.get("name_field") == null and menu.get("name_locked") == true, "campo=%s bloccato=%s" % [str(menu.get("name_field")), str(menu.get("name_locked"))]) check("il nome scelto e' mostrato al giocatore", label_text == "giocatore: Mat", label_text) var gioca: Button = null for button in menu.find_children("*", "Button", true, false): if button.text == "GIOCA": gioca = button if gioca != null: gioca.pressed.emit() check("la partita usa il nome memorizzato", emitted == "Mat", "nome=%s" % emitted) menu.queue_free() await process_frame func test_unlocked_name() -> void: emitted = "" var menu := menu_with({"name": Profile.DEFAULT_NAME, "player_id": "abcdef0123456789", "best": 0}) await process_frame var field: LineEdit = menu.get("name_field") check("senza nome scelto il campo e' presente e usabile", field != null and field.editable and field.max_length == Profile.NAME_MAX, "campo=%s" % str(field)) menu.queue_free() await process_frame ## --- eventi sintetici -------------------------------------------------------- func _click(point: Vector2) -> void: var motion := InputEventMouseMotion.new() motion.position = point motion.global_position = point Input.parse_input_event(motion) for pressed in [true, false]: var event := InputEventMouseButton.new() event.button_index = MOUSE_BUTTON_LEFT event.pressed = pressed event.position = point event.global_position = point Input.parse_input_event(event) func _touch(point: Vector2) -> void: for pressed in [true, false]: var event := InputEventScreenTouch.new() event.index = 0 event.pressed = pressed event.position = point Input.parse_input_event(event)