// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using OpenTK.Input; using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Framework.Input.EventArgs; using osu.Framework.Logging; using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual { [Description("player pause/fail screens")] public class TestCaseGameplayMenuOverlay : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(FailOverlay), typeof(PauseContainer) }; private FailOverlay failOverlay; private PauseContainer.PauseOverlay pauseOverlay; [BackgroundDependencyLoader] private void load() { Add(pauseOverlay = new PauseContainer.PauseOverlay { OnResume = () => Logger.Log(@"Resume"), OnRetry = () => Logger.Log(@"Retry"), OnQuit = () => Logger.Log(@"Quit"), }); Add(failOverlay = new FailOverlay { OnRetry = () => Logger.Log(@"Retry"), OnQuit = () => Logger.Log(@"Quit"), }); var retryCount = 0; AddStep("Add retry", () => { retryCount++; pauseOverlay.Retries = failOverlay.Retries = retryCount; }); AddToggleStep("Toggle pause overlay", t => pauseOverlay.ToggleVisibility()); AddToggleStep("Toggle fail overlay", t => failOverlay.ToggleVisibility()); testHideResets(); testEnterWithoutSelection(); testKeyUpFromInitial(); testKeyDownFromInitial(); testKeyUpWrapping(); testKeyDownWrapping(); testMouseSelectionAfterKeySelection(); testKeySelectionAfterMouseSelection(); testMouseDeselectionResets(); testClickSelection(); testEnterKeySelection(); } /// /// Test that hiding the overlay after hovering a button will reset the overlay to the initial state with no buttons selected. /// private void testHideResets() { AddStep("Show overlay", () => failOverlay.Show()); AddStep("Hover first button", () => failOverlay.Buttons.First().TriggerOnMouseMove(null)); AddStep("Hide overlay", () => failOverlay.Hide()); AddAssert("Overlay state is reset", () => !failOverlay.Buttons.Any(b => b.Selected)); } /// /// Tests that pressing enter after an overlay shows doesn't trigger an event because a selection hasn't occurred. /// private void testEnterWithoutSelection() { AddStep("Show overlay", () => pauseOverlay.Show()); AddStep("Press enter", () => pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Enter })); AddAssert("Overlay still open", () => pauseOverlay.State == Visibility.Visible); AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// /// Tests that pressing the up arrow from the initial state selects the last button. /// private void testKeyUpFromInitial() { AddStep("Show overlay", () => pauseOverlay.Show()); AddStep("Up arrow", () => pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Up })); AddAssert("Last button selected", () => pauseOverlay.Buttons.Last().Selected); AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// /// Tests that pressing the down arrow from the initial state selects the first button. /// private void testKeyDownFromInitial() { AddStep("Show overlay", () => pauseOverlay.Show()); AddStep("Down arrow", () => pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down })); AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected); AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// /// Tests that pressing the up arrow repeatedly causes the selected button to wrap correctly. /// private void testKeyUpWrapping() { AddStep("Show overlay", () => failOverlay.Show()); AddStep("Up arrow", () => failOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Up })); AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected); AddStep("Up arrow", () => failOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Up })); AddAssert("First button selected", () => failOverlay.Buttons.First().Selected); AddStep("Up arrow", () => failOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Up })); AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected); AddStep("Hide overlay", () => failOverlay.Hide()); } /// /// Tests that pressing the down arrow repeatedly causes the selected button to wrap correctly. /// private void testKeyDownWrapping() { AddStep("Show overlay", () => failOverlay.Show()); AddStep("Down arrow", () => failOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down })); AddAssert("First button selected", () => failOverlay.Buttons.First().Selected); AddStep("Down arrow", () => failOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down })); AddAssert("Last button selected", () => failOverlay.Buttons.Last().Selected); AddStep("Down arrow", () => failOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down })); AddAssert("First button selected", () => failOverlay.Buttons.First().Selected); AddStep("Hide overlay", () => failOverlay.Hide()); } /// /// Tests that hovering a button that was previously selected with the keyboard correctly selects the new button and deselects the previous button. /// private void testMouseSelectionAfterKeySelection() { AddStep("Show overlay", () => pauseOverlay.Show()); var secondButton = pauseOverlay.Buttons.Skip(1).First(); AddStep("Down arrow", () => pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down })); AddStep("Hover second button", () => secondButton.TriggerOnMouseMove(null)); AddAssert("First button not selected", () => !pauseOverlay.Buttons.First().Selected); AddAssert("Second button selected", () => secondButton.Selected); AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// /// Tests that pressing a key after selecting a button with a hover event correctly selects a new button and deselects the previous button. /// private void testKeySelectionAfterMouseSelection() { AddStep("Show overlay", () => pauseOverlay.Show()); var secondButton = pauseOverlay.Buttons.Skip(1).First(); AddStep("Hover second button", () => secondButton.TriggerOnMouseMove(null)); AddStep("Up arrow", () => pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Up })); AddAssert("Second button not selected", () => !secondButton.Selected); AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected); AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// /// Tests that deselecting with the mouse by losing hover will reset the overlay to the initial state. /// private void testMouseDeselectionResets() { AddStep("Show overlay", () => pauseOverlay.Show()); var secondButton = pauseOverlay.Buttons.Skip(1).First(); AddStep("Hover second button", () => secondButton.TriggerOnMouseMove(null)); AddStep("Unhover second button", () => secondButton.TriggerOnHoverLost(null)); AddStep("Down arrow", () => pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down })); AddAssert("First button selected", () => pauseOverlay.Buttons.First().Selected); // Initial state condition AddStep("Hide overlay", () => pauseOverlay.Hide()); } /// /// Tests that clicking on a button correctly causes a click event for that button. /// private void testClickSelection() { AddStep("Show overlay", () => pauseOverlay.Show()); var retryButton = pauseOverlay.Buttons.Skip(1).First(); bool triggered = false; AddStep("Click retry button", () => { var lastAction = pauseOverlay.OnRetry; pauseOverlay.OnRetry = () => triggered = true; retryButton.TriggerOnClick(); pauseOverlay.OnRetry = lastAction; }); AddAssert("Action was triggered", () => triggered); AddAssert("Overlay is closed", () => pauseOverlay.State == Visibility.Hidden); } /// /// Tests that pressing the enter key with a button selected correctly causes a click event for that button. /// private void testEnterKeySelection() { AddStep("Show overlay", () => pauseOverlay.Show()); AddStep("Select second button", () => { pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down }); pauseOverlay.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Down }); }); var retryButton = pauseOverlay.Buttons.Skip(1).First(); bool triggered = false; AddStep("Press enter", () => { var lastAction = pauseOverlay.OnRetry; pauseOverlay.OnRetry = () => triggered = true; retryButton.TriggerOnKeyDown(null, new KeyDownEventArgs { Key = Key.Enter }); pauseOverlay.OnRetry = lastAction; }); AddAssert("Action was triggered", () => triggered); AddAssert("Overlay is closed", () => pauseOverlay.State == Visibility.Hidden); } } }