extends MainWindowTestSuite ## All popups share PopupWindow: clicking outside the panel closes them, the backdrop ## dims the window behind them, and the closing click does not reach the main window. const POPUP_NODES: Array[String] = [ "Search", "SyncWindow", "SettingsWindow", "QRWindow", "NewCharacterSelect", "ShortcutsWindow", "AboutWindow", "WinnerWindow", "Log", ] func _popup(node_name: String) -> PopupWindow: return _window.get_node(node_name) func _backdrop() -> ColorRect: return _window.get_node("PopupBackdrop") ## Clicks at [param position], given in the window's 1920x1080 layout coordinates. func _click_at(position: Vector2) -> void: # The runner takes window pixels; the headless test window is much smaller than the # layout, so convert like a real mouse position would be _runner.set_mouse_position(_window.get_viewport().get_final_transform() * position) await _runner.simulate_mouse_button_pressed(MOUSE_BUTTON_LEFT) await _runner.await_input_processed() ## A point on screen outside the popup's panel. func _outside(popup: PopupWindow) -> Vector2: var rect: Rect2 = popup.panel.get_global_rect() return Vector2(rect.end.x + 5, rect.end.y + 5) if rect.end.x < 1900 \ else Vector2(rect.position.x - 5, rect.position.y - 5) func test_backdrop_is_hidden_without_popups() -> void: assert_bool(_backdrop().visible).is_false() func test_backdrop_covers_the_whole_window() -> void: _popup("SettingsWindow").open() assert_vector(_backdrop().get_global_rect().size).is_equal(_window.get_viewport_rect().size) func test_every_popup_is_a_popup_window() -> void: for node_name: String in POPUP_NODES: assert_object(_window.get_node(node_name)).is_instanceof(PopupWindow) func test_every_popup_shows_backdrop_and_closes_on_outside_click() -> void: for node_name: String in POPUP_NODES: var popup: PopupWindow = _popup(node_name) popup.open() await _runner.simulate_frames(1) assert_bool(_backdrop().visible).override_failure_message( "%s: backdrop not shown" % node_name).is_true() await _click_at(_outside(popup)) assert_bool(popup.visible).override_failure_message( "%s: not closed by outside click" % node_name).is_false() assert_bool(_backdrop().visible).override_failure_message( "%s: backdrop still shown" % node_name).is_false() func test_click_inside_popup_keeps_it_open() -> void: var settings: PopupWindow = _popup("SettingsWindow") settings.open() await _runner.simulate_frames(1) await _click_at(settings.panel.get_global_rect().get_center()) assert_bool(settings.visible).is_true() func test_closing_click_does_not_press_button_behind_popup() -> void: var settings: PopupWindow = _popup("SettingsWindow") var reset_button: Button = _window.get_node("ResetPlaylistButton") settings.open() await _runner.simulate_frames(1) assert_bool(settings.panel.get_global_rect().intersects(reset_button.get_global_rect())) \ .is_false() await _click_at(reset_button.get_global_rect().get_center()) assert_bool(settings.visible).is_false() assert_int(_server.count("/music/reset")).is_equal(0) func test_button_works_again_after_popup_closed() -> void: var reset_button: Button = _window.get_node("ResetPlaylistButton") await _click_at(reset_button.get_global_rect().get_center()) assert_int(_server.count("/music/reset")).is_equal(1) func test_closing_search_clears_the_search() -> void: var search: PopupWindow = _popup("Search") search.open() var search_bar: TextEdit = search.get_node("Searchbar") search_bar.text = "mario" search.close() assert_str(search_bar.text).is_empty() func test_closing_character_select_allows_song_clicks_again() -> void: var character_select: PopupWindow = _popup("NewCharacterSelect") character_select.show_grid("Crono") assert_bool(Settings.character_select_open).is_true() character_select.close() assert_bool(Settings.character_select_open).is_false() func test_toggle_opens_and_closes() -> void: var shortcuts: PopupWindow = _popup("ShortcutsWindow") shortcuts.toggle() assert_bool(shortcuts.visible).is_true() shortcuts.toggle() assert_bool(shortcuts.visible).is_false()