2019-07-29 13:30:46 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq ;
using NUnit.Framework ;
using osu.Framework.Allocation ;
using osu.Framework.Graphics.Containers ;
2020-07-10 17:13:58 +08:00
using osu.Framework.Screens ;
2020-09-14 02:49:16 +08:00
using osu.Framework.Testing ;
2019-10-10 10:58:43 +08:00
using osu.Game.Beatmaps ;
2021-04-05 21:46:01 +08:00
using osu.Game.Graphics.UserInterface ;
2021-06-08 16:54:54 +08:00
using osu.Game.Online.Multiplayer ;
2019-07-31 18:47:41 +08:00
using osu.Game.Overlays ;
2019-07-29 13:30:46 +08:00
using osu.Game.Overlays.Mods ;
2020-09-14 02:49:16 +08:00
using osu.Game.Overlays.Toolbar ;
2021-06-03 13:37:38 +08:00
using osu.Game.Rulesets.Mods ;
2021-02-15 14:02:58 +08:00
using osu.Game.Rulesets.Osu.Mods ;
2021-06-08 16:54:54 +08:00
using osu.Game.Screens.OnlinePlay.Components ;
2019-10-10 10:58:43 +08:00
using osu.Game.Screens.Play ;
2021-02-15 14:02:58 +08:00
using osu.Game.Screens.Ranking ;
2019-07-29 13:30:46 +08:00
using osu.Game.Screens.Select ;
2020-09-15 02:21:39 +08:00
using osu.Game.Screens.Select.Options ;
2019-10-10 10:58:43 +08:00
using osu.Game.Tests.Beatmaps.IO ;
2021-06-08 16:54:54 +08:00
using osu.Game.Tests.Visual.Multiplayer ;
2019-07-31 15:03:05 +08:00
using osuTK ;
2019-07-29 13:30:46 +08:00
using osuTK.Input ;
2020-01-29 13:23:23 +08:00
namespace osu.Game.Tests.Visual.Navigation
2019-07-29 13:30:46 +08:00
{
2020-01-29 13:23:23 +08:00
public class TestSceneScreenNavigation : OsuGameTestScene
2019-07-29 13:30:46 +08:00
{
2019-08-13 11:26:06 +08:00
private const float click_padding = 25 ;
2020-01-29 13:23:23 +08:00
private Vector2 backButtonPosition = > Game . ToScreenSpace ( new Vector2 ( click_padding , Game . LayoutRectangle . Bottom - click_padding ) ) ;
2019-07-29 13:30:46 +08:00
2020-01-29 13:23:23 +08:00
private Vector2 optionsButtonPosition = > Game . ToScreenSpace ( new Vector2 ( click_padding , click_padding ) ) ;
2019-07-29 13:30:46 +08:00
[Test]
2019-07-30 17:18:03 +08:00
public void TestExitSongSelectWithEscape ( )
2019-07-29 13:30:46 +08:00
{
2021-05-16 23:14:23 +08:00
TestPlaySongSelect songSelect = null ;
2019-07-29 13:30:46 +08:00
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > songSelect = new TestPlaySongSelect ( ) ) ;
2019-07-29 13:30:46 +08:00
AddStep ( "Show mods overlay" , ( ) = > songSelect . ModSelectOverlay . Show ( ) ) ;
AddAssert ( "Overlay was shown" , ( ) = > songSelect . ModSelectOverlay . State . Value = = Visibility . Visible ) ;
2019-10-10 10:58:43 +08:00
pushEscape ( ) ;
2019-07-29 13:30:46 +08:00
AddAssert ( "Overlay was hidden" , ( ) = > songSelect . ModSelectOverlay . State . Value = = Visibility . Hidden ) ;
exitViaEscapeAndConfirm ( ) ;
}
2021-04-08 14:20:53 +08:00
/// <summary>
/// This tests that the F1 key will open the mod select overlay, and not be handled / blocked by the music controller (which has the same default binding
/// but should be handled *after* song select).
/// </summary>
[Test]
public void TestOpenModSelectOverlayUsingAction ( )
{
2021-05-16 23:14:23 +08:00
TestPlaySongSelect songSelect = null ;
2021-04-08 14:20:53 +08:00
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > songSelect = new TestPlaySongSelect ( ) ) ;
2021-04-08 14:20:53 +08:00
AddStep ( "Show mods overlay" , ( ) = > InputManager . Key ( Key . F1 ) ) ;
AddAssert ( "Overlay was shown" , ( ) = > songSelect . ModSelectOverlay . State . Value = = Visibility . Visible ) ;
}
2021-03-31 13:09:38 +08:00
[Test]
public void TestRetryCountIncrements ( )
{
Player player = null ;
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > new TestPlaySongSelect ( ) ) ;
2021-03-31 13:09:38 +08:00
AddStep ( "import beatmap" , ( ) = > ImportBeatmapTest . LoadQuickOszIntoOsu ( Game ) . Wait ( ) ) ;
AddUntilStep ( "wait for selected" , ( ) = > ! Game . Beatmap . IsDefault ) ;
AddStep ( "press enter" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddUntilStep ( "wait for player" , ( ) = > ( player = Game . ScreenStack . CurrentScreen as Player ) ! = null ) ;
AddAssert ( "retry count is 0" , ( ) = > player . RestartCount = = 0 ) ;
AddStep ( "attempt to retry" , ( ) = > player . ChildrenOfType < HotkeyRetryOverlay > ( ) . First ( ) . Action ( ) ) ;
AddUntilStep ( "wait for old player gone" , ( ) = > Game . ScreenStack . CurrentScreen ! = player ) ;
AddUntilStep ( "get new player" , ( ) = > ( player = Game . ScreenStack . CurrentScreen as Player ) ! = null ) ;
AddAssert ( "retry count is 1" , ( ) = > player . RestartCount = = 1 ) ;
}
2021-02-15 14:02:58 +08:00
[Test]
public void TestRetryFromResults ( )
{
Player player = null ;
ResultsScreen results = null ;
WorkingBeatmap beatmap ( ) = > Game . Beatmap . Value ;
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > new TestPlaySongSelect ( ) ) ;
2021-02-15 14:02:58 +08:00
2021-02-22 13:48:04 +08:00
AddStep ( "import beatmap" , ( ) = > ImportBeatmapTest . LoadQuickOszIntoOsu ( Game ) . Wait ( ) ) ;
2021-02-15 14:02:58 +08:00
AddUntilStep ( "wait for selected" , ( ) = > ! Game . Beatmap . IsDefault ) ;
2021-06-03 13:37:38 +08:00
AddStep ( "set mods" , ( ) = > Game . SelectedMods . Value = new Mod [ ] { new OsuModNoFail ( ) , new OsuModDoubleTime { SpeedChange = { Value = 2 } } } ) ;
2021-02-15 14:02:58 +08:00
AddStep ( "press enter" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddUntilStep ( "wait for player" , ( ) = > ( player = Game . ScreenStack . CurrentScreen as Player ) ! = null ) ;
2021-06-03 13:37:38 +08:00
AddUntilStep ( "wait for track playing" , ( ) = > beatmap ( ) . Track . IsRunning ) ;
AddStep ( "seek to near end" , ( ) = > player . ChildrenOfType < GameplayClockContainer > ( ) . First ( ) . Seek ( beatmap ( ) . Beatmap . HitObjects [ ^ 1 ] . StartTime - 1000 ) ) ;
2021-02-15 14:02:58 +08:00
AddUntilStep ( "wait for pass" , ( ) = > ( results = Game . ScreenStack . CurrentScreen as ResultsScreen ) ! = null & & results . IsLoaded ) ;
AddStep ( "attempt to retry" , ( ) = > results . ChildrenOfType < HotkeyRetryOverlay > ( ) . First ( ) . Action ( ) ) ;
AddUntilStep ( "wait for player" , ( ) = > Game . ScreenStack . CurrentScreen ! = player & & Game . ScreenStack . CurrentScreen is Player ) ;
}
2019-10-10 19:12:47 +08:00
[TestCase(true)]
[TestCase(false)]
public void TestSongContinuesAfterExitPlayer ( bool withUserPause )
2019-10-10 10:58:43 +08:00
{
Player player = null ;
2020-01-29 13:23:23 +08:00
WorkingBeatmap beatmap ( ) = > Game . Beatmap . Value ;
2019-10-10 10:58:43 +08:00
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > new TestPlaySongSelect ( ) ) ;
2019-10-10 10:58:43 +08:00
2020-01-29 13:23:23 +08:00
AddStep ( "import beatmap" , ( ) = > ImportBeatmapTest . LoadOszIntoOsu ( Game , virtualTrack : true ) . Wait ( ) ) ;
2019-10-10 10:58:43 +08:00
2020-01-29 13:23:23 +08:00
AddUntilStep ( "wait for selected" , ( ) = > ! Game . Beatmap . IsDefault ) ;
2019-10-10 10:58:43 +08:00
2019-10-10 19:12:47 +08:00
if ( withUserPause )
2020-11-02 13:56:50 +08:00
AddStep ( "pause" , ( ) = > Game . Dependencies . Get < MusicController > ( ) . Stop ( true ) ) ;
2019-10-10 19:12:47 +08:00
2020-11-05 22:41:56 +08:00
AddStep ( "press enter" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
2019-10-10 10:58:43 +08:00
2020-01-29 13:23:23 +08:00
AddUntilStep ( "wait for player" , ( ) = > ( player = Game . ScreenStack . CurrentScreen as Player ) ! = null ) ;
2019-10-10 10:58:43 +08:00
AddUntilStep ( "wait for fail" , ( ) = > player . HasFailed ) ;
2020-08-07 21:06:04 +08:00
AddUntilStep ( "wait for track stop" , ( ) = > ! Game . MusicController . IsPlaying ) ;
AddAssert ( "Ensure time before preview point" , ( ) = > Game . MusicController . CurrentTrack . CurrentTime < beatmap ( ) . Metadata . PreviewTime ) ;
2019-10-10 10:58:43 +08:00
pushEscape ( ) ;
2020-08-07 21:06:04 +08:00
AddUntilStep ( "wait for track playing" , ( ) = > Game . MusicController . IsPlaying ) ;
AddAssert ( "Ensure time wasn't reset to preview point" , ( ) = > Game . MusicController . CurrentTrack . CurrentTime < beatmap ( ) . Metadata . PreviewTime ) ;
2019-10-10 10:58:43 +08:00
}
2020-07-10 17:13:58 +08:00
[Test]
public void TestMenuMakesMusic ( )
{
2021-05-16 23:14:23 +08:00
TestPlaySongSelect songSelect = null ;
2020-07-10 17:13:58 +08:00
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > songSelect = new TestPlaySongSelect ( ) ) ;
2020-07-10 17:13:58 +08:00
2020-08-07 21:06:04 +08:00
AddUntilStep ( "wait for no track" , ( ) = > Game . MusicController . CurrentTrack . IsDummyDevice ) ;
2020-07-10 17:13:58 +08:00
AddStep ( "return to menu" , ( ) = > songSelect . Exit ( ) ) ;
2020-08-11 12:14:20 +08:00
AddUntilStep ( "wait for track" , ( ) = > ! Game . MusicController . CurrentTrack . IsDummyDevice & & Game . MusicController . IsPlaying ) ;
2020-07-10 17:13:58 +08:00
}
2021-06-08 16:03:46 +08:00
[Test]
public void TestPushSongSelectAndPressBackButtonImmediately ( )
{
AddStep ( "push song select" , ( ) = > Game . ScreenStack . Push ( new TestPlaySongSelect ( ) ) ) ;
AddStep ( "press back button" , ( ) = > Game . ChildrenOfType < BackButton > ( ) . First ( ) . Action ( ) ) ;
2021-06-08 16:09:03 +08:00
AddWaitStep ( "wait two frames" , 2 ) ;
2021-06-08 16:03:46 +08:00
}
2019-07-29 13:30:46 +08:00
[Test]
2019-07-30 17:18:03 +08:00
public void TestExitSongSelectWithClick ( )
2019-07-29 13:30:46 +08:00
{
2021-05-16 23:14:23 +08:00
TestPlaySongSelect songSelect = null ;
2019-07-29 13:30:46 +08:00
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > songSelect = new TestPlaySongSelect ( ) ) ;
2019-07-29 13:30:46 +08:00
AddStep ( "Show mods overlay" , ( ) = > songSelect . ModSelectOverlay . Show ( ) ) ;
AddAssert ( "Overlay was shown" , ( ) = > songSelect . ModSelectOverlay . State . Value = = Visibility . Visible ) ;
2019-07-31 18:30:35 +08:00
AddStep ( "Move mouse to backButton" , ( ) = > InputManager . MoveMouseTo ( backButtonPosition ) ) ;
2019-07-29 13:30:46 +08:00
// BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered.
2021-04-05 21:46:01 +08:00
AddUntilStep ( "Back button is hovered" , ( ) = > Game . ChildrenOfType < BackButton > ( ) . First ( ) . Children . Any ( c = > c . IsHovered ) ) ;
2019-07-29 13:30:46 +08:00
AddStep ( "Click back button" , ( ) = > InputManager . Click ( MouseButton . Left ) ) ;
2019-07-31 15:03:05 +08:00
AddUntilStep ( "Overlay was hidden" , ( ) = > songSelect . ModSelectOverlay . State . Value = = Visibility . Hidden ) ;
2019-07-29 13:30:46 +08:00
exitViaBackButtonAndConfirm ( ) ;
}
[Test]
public void TestExitMultiWithEscape ( )
{
2020-12-25 23:50:00 +08:00
PushAndConfirm ( ( ) = > new Screens . OnlinePlay . Playlists . Playlists ( ) ) ;
2019-07-29 13:30:46 +08:00
exitViaEscapeAndConfirm ( ) ;
}
[Test]
public void TestExitMultiWithBackButton ( )
{
2020-12-25 23:50:00 +08:00
PushAndConfirm ( ( ) = > new Screens . OnlinePlay . Playlists . Playlists ( ) ) ;
2019-07-29 13:30:46 +08:00
exitViaBackButtonAndConfirm ( ) ;
}
2019-07-31 18:47:41 +08:00
[Test]
public void TestOpenOptionsAndExitWithEscape ( )
{
2020-01-29 13:23:23 +08:00
AddUntilStep ( "Wait for options to load" , ( ) = > Game . Settings . IsLoaded ) ;
2020-11-05 22:41:56 +08:00
AddStep ( "Enter menu" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
2019-07-31 18:47:41 +08:00
AddStep ( "Move mouse to options overlay" , ( ) = > InputManager . MoveMouseTo ( optionsButtonPosition ) ) ;
AddStep ( "Click options overlay" , ( ) = > InputManager . Click ( MouseButton . Left ) ) ;
2020-01-29 13:23:23 +08:00
AddAssert ( "Options overlay was opened" , ( ) = > Game . Settings . State . Value = = Visibility . Visible ) ;
2020-11-05 22:41:56 +08:00
AddStep ( "Hide options overlay using escape" , ( ) = > InputManager . Key ( Key . Escape ) ) ;
2020-01-29 13:23:23 +08:00
AddAssert ( "Options overlay was closed" , ( ) = > Game . Settings . State . Value = = Visibility . Hidden ) ;
2019-07-31 18:47:41 +08:00
}
2020-03-05 16:12:14 +08:00
[Test]
public void TestWaitForNextTrackInMenu ( )
{
bool trackCompleted = false ;
AddUntilStep ( "Wait for music controller" , ( ) = > Game . MusicController . IsLoaded ) ;
AddStep ( "Seek close to end" , ( ) = >
{
2020-08-07 21:06:04 +08:00
Game . MusicController . SeekTo ( Game . MusicController . CurrentTrack . Length - 1000 ) ;
Game . MusicController . CurrentTrack . Completed + = ( ) = > trackCompleted = true ;
2020-03-05 16:12:14 +08:00
} ) ;
AddUntilStep ( "Track was completed" , ( ) = > trackCompleted ) ;
2020-08-07 21:06:04 +08:00
AddUntilStep ( "Track was restarted" , ( ) = > Game . MusicController . IsPlaying ) ;
2020-03-05 16:12:14 +08:00
}
2020-09-14 02:49:16 +08:00
[Test]
public void TestModSelectInput ( )
{
2021-05-16 23:14:23 +08:00
TestPlaySongSelect songSelect = null ;
2020-09-14 02:49:16 +08:00
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > songSelect = new TestPlaySongSelect ( ) ) ;
2020-09-14 02:49:16 +08:00
AddStep ( "Show mods overlay" , ( ) = > songSelect . ModSelectOverlay . Show ( ) ) ;
AddStep ( "Change ruleset to osu!taiko" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
2020-11-05 22:41:56 +08:00
InputManager . Key ( Key . Number2 ) ;
2020-09-14 02:49:16 +08:00
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
AddAssert ( "Ruleset changed to osu!taiko" , ( ) = > Game . Toolbar . ChildrenOfType < ToolbarRulesetSelector > ( ) . Single ( ) . Current . Value . ID = = 1 ) ;
AddAssert ( "Mods overlay still visible" , ( ) = > songSelect . ModSelectOverlay . State . Value = = Visibility . Visible ) ;
}
2020-09-15 02:21:39 +08:00
[Test]
public void TestBeatmapOptionsInput ( )
{
2021-05-16 23:14:23 +08:00
TestPlaySongSelect songSelect = null ;
2020-09-15 02:21:39 +08:00
2021-05-16 23:14:23 +08:00
PushAndConfirm ( ( ) = > songSelect = new TestPlaySongSelect ( ) ) ;
2020-09-15 02:21:39 +08:00
AddStep ( "Show options overlay" , ( ) = > songSelect . BeatmapOptionsOverlay . Show ( ) ) ;
AddStep ( "Change ruleset to osu!taiko" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
2020-11-05 22:41:56 +08:00
InputManager . Key ( Key . Number2 ) ;
2020-09-15 02:21:39 +08:00
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
AddAssert ( "Ruleset changed to osu!taiko" , ( ) = > Game . Toolbar . ChildrenOfType < ToolbarRulesetSelector > ( ) . Single ( ) . Current . Value . ID = = 1 ) ;
AddAssert ( "Options overlay still visible" , ( ) = > songSelect . BeatmapOptionsOverlay . State . Value = = Visibility . Visible ) ;
}
2021-02-25 13:51:23 +08:00
[Test]
public void TestSettingsViaHotkeyFromMainMenu ( )
{
AddAssert ( "toolbar not displayed" , ( ) = > Game . Toolbar . State . Value = = Visibility . Hidden ) ;
AddStep ( "press settings hotkey" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
InputManager . Key ( Key . O ) ;
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
AddUntilStep ( "settings displayed" , ( ) = > Game . Settings . State . Value = = Visibility . Visible ) ;
}
2020-11-10 06:43:06 +08:00
[Test]
public void TestToolbarHiddenByUser ( )
{
AddStep ( "Enter menu" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddUntilStep ( "Wait for toolbar to load" , ( ) = > Game . Toolbar . IsLoaded ) ;
AddStep ( "Hide toolbar" , ( ) = >
{
InputManager . PressKey ( Key . ControlLeft ) ;
InputManager . Key ( Key . T ) ;
InputManager . ReleaseKey ( Key . ControlLeft ) ;
} ) ;
pushEscape ( ) ;
AddStep ( "Enter menu" , ( ) = > InputManager . Key ( Key . Enter ) ) ;
AddAssert ( "Toolbar is hidden" , ( ) = > Game . Toolbar . State . Value = = Visibility . Hidden ) ;
AddStep ( "Enter song select" , ( ) = >
{
InputManager . Key ( Key . Enter ) ;
InputManager . Key ( Key . Enter ) ;
} ) ;
AddAssert ( "Toolbar is hidden" , ( ) = > Game . Toolbar . State . Value = = Visibility . Hidden ) ;
}
2021-06-08 16:54:54 +08:00
[Test]
public void TestPushMatchSubScreenAndPressBackButtonImmediately ( )
{
TestMultiplayer multiplayer = null ;
PushAndConfirm ( ( ) = > multiplayer = new TestMultiplayer ( ) ) ;
AddStep ( "open room" , ( ) = > multiplayer . OpenNewRoom ( ) ) ;
AddStep ( "press back button" , ( ) = > Game . ChildrenOfType < BackButton > ( ) . First ( ) . Action ( ) ) ;
AddWaitStep ( "wait two frames" , 2 ) ;
}
2019-10-10 10:58:43 +08:00
private void pushEscape ( ) = >
2020-11-05 22:41:56 +08:00
AddStep ( "Press escape" , ( ) = > InputManager . Key ( Key . Escape ) ) ;
2019-10-10 10:58:43 +08:00
2019-07-29 13:30:46 +08:00
private void exitViaEscapeAndConfirm ( )
{
2019-10-10 10:58:43 +08:00
pushEscape ( ) ;
2020-01-29 13:23:23 +08:00
ConfirmAtMainMenu ( ) ;
2019-07-29 13:30:46 +08:00
}
private void exitViaBackButtonAndConfirm ( )
{
2019-07-31 18:30:35 +08:00
AddStep ( "Move mouse to backButton" , ( ) = > InputManager . MoveMouseTo ( backButtonPosition ) ) ;
2019-07-29 13:30:46 +08:00
AddStep ( "Click back button" , ( ) = > InputManager . Click ( MouseButton . Left ) ) ;
2020-01-29 13:23:23 +08:00
ConfirmAtMainMenu ( ) ;
2019-07-29 13:30:46 +08:00
}
2021-05-16 23:14:23 +08:00
public class TestPlaySongSelect : PlaySongSelect
2019-07-29 13:30:46 +08:00
{
public ModSelectOverlay ModSelectOverlay = > ModSelect ;
2020-09-15 02:21:39 +08:00
public BeatmapOptionsOverlay BeatmapOptionsOverlay = > BeatmapOptions ;
2021-05-16 23:14:23 +08:00
protected override bool DisplayStableImportPrompt = > false ;
2019-07-29 13:30:46 +08:00
}
2021-06-08 16:54:54 +08:00
private class TestMultiplayer : Screens . OnlinePlay . Multiplayer . Multiplayer
{
[Cached(typeof(MultiplayerClient))]
public readonly TestMultiplayerClient Client ;
public TestMultiplayer ( )
{
Client = new TestMultiplayerClient ( ( TestMultiplayerRoomManager ) RoomManager ) ;
}
protected override RoomManager CreateRoomManager ( ) = > new TestMultiplayerRoomManager ( ) ;
}
2019-07-29 13:30:46 +08:00
}
}