diff --git a/README.md b/README.md index 60902db..074514a 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ public class MyIntegrationTest `GetInteractableComponents` are extensions of `GameObject` that return interactable components. -`SelectOperators` and `SelectOperatorsOfType` are extensions of `Component` that return available operators. +`SelectOperators` and `SelectOperators` are extensions of `Component` that return available operators. Operators implements `IOperator` interface. It has `OperateAsync` method that operates on the component. Usage: @@ -183,7 +183,7 @@ public class MyIntegrationTest var button = await finder.FindByNameAsync("StartButton", interactable: true); var buttonComponent = button.GetInteractableComponents().First(); - var clickOperator = buttonComponent.SelectOperatorsOfType(_operators, OperatorType.Click).First(); + var clickOperator = buttonComponent.SelectOperators(_operators).First(); clickOperator.OperateAsync(buttonComponent); } } @@ -210,7 +210,7 @@ public class MyIntegrationTest var components = InteractiveComponentCollector.FindInteractableComponents(); var firstComponent = components.First(); - var clickAndHoldOperator = firstComponent.SelectOperatorsOfType(_operators, OperatorType.ClickAndHold).First(); + var clickAndHoldOperator = firstComponent.SelectOperators(_operators).First(); await clickAndHoldOperator.OperateAsync(firstComponent); } } @@ -238,7 +238,7 @@ public class MyIntegrationTest var components = InteractiveComponentCollector.FindReachableInteractableComponents(); var firstComponent = components.First(); - var textInputOperator = firstComponent.SelectOperatorsOfType(_operators, OperatorType.TextInput).First(); + var textInputOperator = firstComponent.SelectOperators(_operators).First(); textInputOperator.OperateAsync(firstComponent); // input random text } } diff --git a/Runtime/Extensions/ComponentExtensions.cs b/Runtime/Extensions/ComponentExtensions.cs index a67135d..735ed75 100644 --- a/Runtime/Extensions/ComponentExtensions.cs +++ b/Runtime/Extensions/ComponentExtensions.cs @@ -19,8 +19,7 @@ public static class ComponentExtensions /// /// All available operators in autopilot/tests. Usually defined in MonkeyConfig /// Available operators - public static IEnumerable SelectOperators(this Component component, - IEnumerable operators) + public static IEnumerable SelectOperators(this Component component, IEnumerable operators) { return operators.Where(iOperator => iOperator.CanOperate(component)); } @@ -30,12 +29,11 @@ public static IEnumerable SelectOperators(this Component component, /// /// /// All available operators in autopilot/tests. Usually defined in MonkeyConfig - /// Operator type /// Available operators - public static IEnumerable SelectOperatorsOfType(this Component component, - IEnumerable operators, OperatorType type) + public static IEnumerable SelectOperators(this Component component, IEnumerable operators) + where T : IOperator { - return operators.Where(iOperator => iOperator.Type == type && iOperator.CanOperate(component)); + return operators.OfType().Where(iOperator => iOperator.CanOperate(component)); } /// diff --git a/Runtime/InteractiveComponent.cs b/Runtime/InteractiveComponent.cs index 4b8e0f4..b0378c8 100644 --- a/Runtime/InteractiveComponent.cs +++ b/Runtime/InteractiveComponent.cs @@ -144,25 +144,24 @@ public IEnumerable GetOperators() /// /// Returns the operators that specify types and are available to this component. /// - /// Operator type /// Available operators - [Obsolete("Use ComponentExtensions.SelectOperatorsOfType() instead.")] - public IEnumerable GetOperatorsByType(OperatorType type) + [Obsolete("Use ComponentExtensions.SelectOperators() instead.")] + public IEnumerable GetOperatorsByType() where T : IOperator { - return component.SelectOperatorsOfType(_operators, type); + return component.SelectOperators(_operators); } /// /// Check component can receive click (tap) event. /// [Obsolete] - public bool CanClick() => GetOperatorsByType(OperatorType.Click).Any(); + public bool CanClick() => GetOperatorsByType().Any(); /// /// Click component. /// [Obsolete] - public void Click() => GetOperatorsByType(OperatorType.Click).First().OperateAsync(component); + public void Click() => GetOperatorsByType().First().OperateAsync(component); [Obsolete] public bool CanTap() => CanClick(); @@ -174,7 +173,7 @@ public IEnumerable GetOperatorsByType(OperatorType type) /// Check component can receive click (tap) and hold event. /// [Obsolete] - public bool CanClickAndHold() => GetOperatorsByType(OperatorType.ClickAndHold).Any(); + public bool CanClickAndHold() => GetOperatorsByType().Any(); /// /// Click (touch) and hold component. @@ -182,7 +181,7 @@ public IEnumerable GetOperatorsByType(OperatorType type) [Obsolete] public async UniTask ClickAndHold(CancellationToken cancellationToken = default) { - var clickAndHoldOperator = GetOperatorsByType(OperatorType.ClickAndHold).First(); + var clickAndHoldOperator = GetOperatorsByType().First(); await clickAndHoldOperator.OperateAsync(component, cancellationToken); } @@ -197,13 +196,13 @@ public async UniTask TouchAndHold(CancellationToken cancellationToken = default) /// Check component can input text. /// [Obsolete] - public bool CanTextInput() => GetOperatorsByType(OperatorType.TextInput).Any(); + public bool CanTextInput() => GetOperatorsByType().Any(); /// /// Input random text. /// [Obsolete] - public void TextInput() => GetOperatorsByType(OperatorType.TextInput).First().OperateAsync(component); + public void TextInput() => GetOperatorsByType().First().OperateAsync(component); /// /// Input specified text. @@ -211,7 +210,7 @@ public async UniTask TouchAndHold(CancellationToken cancellationToken = default) [Obsolete] public void TextInput(string text) { - var textInputOperator = (ITextInputOperator)GetOperatorsByType(OperatorType.TextInput).First(); + var textInputOperator = GetOperatorsByType().First(); textInputOperator.OperateAsync(component, text); } } diff --git a/Runtime/Operators/IClickAndHoldOperator.cs b/Runtime/Operators/IClickAndHoldOperator.cs new file mode 100644 index 0000000..2903e4a --- /dev/null +++ b/Runtime/Operators/IClickAndHoldOperator.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Click and hold operator interface. + /// a.k.a. touch and hold, long press. + /// + public interface IClickAndHoldOperator : IOperator + { + } +} diff --git a/Runtime/Operators/IClickAndHoldOperator.cs.meta b/Runtime/Operators/IClickAndHoldOperator.cs.meta new file mode 100644 index 0000000..519017f --- /dev/null +++ b/Runtime/Operators/IClickAndHoldOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 75ab8e6c6ff74a4398ca50697ad88c7a +timeCreated: 1713595251 \ No newline at end of file diff --git a/Runtime/Operators/IClickOperator.cs b/Runtime/Operators/IClickOperator.cs new file mode 100644 index 0000000..7adf58b --- /dev/null +++ b/Runtime/Operators/IClickOperator.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Click (tap) operator interface. + /// + public interface IClickOperator : IOperator + { + } +} diff --git a/Runtime/Operators/IClickOperator.cs.meta b/Runtime/Operators/IClickOperator.cs.meta new file mode 100644 index 0000000..d567676 --- /dev/null +++ b/Runtime/Operators/IClickOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f9d778389a8f4f62a326e3d41e7a344a +timeCreated: 1713595231 \ No newline at end of file diff --git a/Runtime/Operators/IDoubleClickOperator.cs b/Runtime/Operators/IDoubleClickOperator.cs new file mode 100644 index 0000000..a2c82d0 --- /dev/null +++ b/Runtime/Operators/IDoubleClickOperator.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Double click (tap) operator interface. + /// + public interface IDoubleClickOperator : IOperator + { + } +} diff --git a/Runtime/Operators/IDoubleClickOperator.cs.meta b/Runtime/Operators/IDoubleClickOperator.cs.meta new file mode 100644 index 0000000..6335bfb --- /dev/null +++ b/Runtime/Operators/IDoubleClickOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2b067feb0b124139acb3b371fbaf6383 +timeCreated: 1713595545 \ No newline at end of file diff --git a/Runtime/Operators/IDragAndDropOperator.cs b/Runtime/Operators/IDragAndDropOperator.cs new file mode 100644 index 0000000..d082c25 --- /dev/null +++ b/Runtime/Operators/IDragAndDropOperator.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Drag and drop operator interface. + /// + public interface IDragAndDropOperator : IOperator + { + // TODO: specify drop destination overloads + } +} diff --git a/Runtime/Operators/IDragAndDropOperator.cs.meta b/Runtime/Operators/IDragAndDropOperator.cs.meta new file mode 100644 index 0000000..5461f97 --- /dev/null +++ b/Runtime/Operators/IDragAndDropOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a5e39eb6666d49a596343ecad034cb9a +timeCreated: 1713595723 \ No newline at end of file diff --git a/Runtime/Operators/IFlickOperator.cs b/Runtime/Operators/IFlickOperator.cs new file mode 100644 index 0000000..c8fd03d --- /dev/null +++ b/Runtime/Operators/IFlickOperator.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Flick operator interface. + /// + public interface IFlickOperator : IOperator + { + // TODO: specify flick direction overloads + } +} diff --git a/Runtime/Operators/IFlickOperator.cs.meta b/Runtime/Operators/IFlickOperator.cs.meta new file mode 100644 index 0000000..a7b7de2 --- /dev/null +++ b/Runtime/Operators/IFlickOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 71cf80cb4ca84a159be36608c166b1ec +timeCreated: 1713595907 \ No newline at end of file diff --git a/Runtime/Operators/IHoverOperator.cs b/Runtime/Operators/IHoverOperator.cs new file mode 100644 index 0000000..db4e84b --- /dev/null +++ b/Runtime/Operators/IHoverOperator.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Hover mouse cursor operator interface. + /// + public interface IHoverOperator : IOperator + { + } +} diff --git a/Runtime/Operators/IHoverOperator.cs.meta b/Runtime/Operators/IHoverOperator.cs.meta new file mode 100644 index 0000000..908fab2 --- /dev/null +++ b/Runtime/Operators/IHoverOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b1bf31e095a547089221125f67f928b1 +timeCreated: 1713595970 \ No newline at end of file diff --git a/Runtime/Operators/IOperator.cs b/Runtime/Operators/IOperator.cs index b7f2db9..cbc1860 100644 --- a/Runtime/Operators/IOperator.cs +++ b/Runtime/Operators/IOperator.cs @@ -9,19 +9,14 @@ namespace TestHelper.Monkey.Operators { /// /// Matcher and Operator pair for monkey testing. - /// Implement the IsMatch method to determine whether an operation such as click is possible, and the Operate method to execute the operation. + /// Implement the CanOperate method to determine whether an operation such as click is possible, and the OperateAsync method to execute the operation. /// /// + /// Must be implements sub-interface (e.g., IClickOperator) to represent the type of operator. /// If required parameters for the operation, such as hold time, input text strategy, etc., keep them in instance fields of the implementation class. /// public interface IOperator { - /// - /// Returns operator type. - /// Intended for use in capture and playback features. - /// - OperatorType Type { get; } - /// /// Returns if can operate target component this Operator. /// diff --git a/Runtime/Operators/IPinchOperator.cs b/Runtime/Operators/IPinchOperator.cs new file mode 100644 index 0000000..db63ad8 --- /dev/null +++ b/Runtime/Operators/IPinchOperator.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Pinch operator interface. + /// + public interface IPinchOperator : IOperator + { + // TODO: specify pinch destination and distance overloads + } +} diff --git a/Runtime/Operators/IPinchOperator.cs.meta b/Runtime/Operators/IPinchOperator.cs.meta new file mode 100644 index 0000000..20d34df --- /dev/null +++ b/Runtime/Operators/IPinchOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3fd0bc584aad4c89a34f9e66b2825c55 +timeCreated: 1713595949 \ No newline at end of file diff --git a/Runtime/Operators/IRightClickOperator.cs b/Runtime/Operators/IRightClickOperator.cs new file mode 100644 index 0000000..863611b --- /dev/null +++ b/Runtime/Operators/IRightClickOperator.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Click right button of mouse operator interface. + /// + public interface IRightClickOperator : IOperator + { + } +} diff --git a/Runtime/Operators/IRightClickOperator.cs.meta b/Runtime/Operators/IRightClickOperator.cs.meta new file mode 100644 index 0000000..b562a79 --- /dev/null +++ b/Runtime/Operators/IRightClickOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7766db4e141049c691465b8c0e0dc479 +timeCreated: 1713595991 \ No newline at end of file diff --git a/Runtime/Operators/IScrollWheelOperator.cs b/Runtime/Operators/IScrollWheelOperator.cs new file mode 100644 index 0000000..54e6eea --- /dev/null +++ b/Runtime/Operators/IScrollWheelOperator.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Scroll wheel of mouse operator interface. + /// scrolling up/down and tilting left/right. + /// + public interface IScrollWheelOperator : IOperator + { + // TODO: specify scroll destination and distance overloads + } +} diff --git a/Runtime/Operators/IScrollWheelOperator.cs.meta b/Runtime/Operators/IScrollWheelOperator.cs.meta new file mode 100644 index 0000000..504d8bb --- /dev/null +++ b/Runtime/Operators/IScrollWheelOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 786525ae66a043468105d98db557934e +timeCreated: 1713596011 \ No newline at end of file diff --git a/Runtime/Operators/ISwipeOperator.cs b/Runtime/Operators/ISwipeOperator.cs new file mode 100644 index 0000000..507f779 --- /dev/null +++ b/Runtime/Operators/ISwipeOperator.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2023-2024 Koji Hasegawa. +// This software is released under the MIT License. + +namespace TestHelper.Monkey.Operators +{ + /// + /// Swipe operator interface. + /// + public interface ISwipeOperator : IOperator + { + // TODO: specify swipe destination overloads + } +} diff --git a/Runtime/Operators/ISwipeOperator.cs.meta b/Runtime/Operators/ISwipeOperator.cs.meta new file mode 100644 index 0000000..affa700 --- /dev/null +++ b/Runtime/Operators/ISwipeOperator.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dc35d4bcac8442a2a5185315f34eb61c +timeCreated: 1713595887 \ No newline at end of file diff --git a/Runtime/Operators/OperatorType.cs b/Runtime/Operators/OperatorType.cs deleted file mode 100644 index a48b1c8..0000000 --- a/Runtime/Operators/OperatorType.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) 2023-2024 Koji Hasegawa. -// This software is released under the MIT License. - -namespace TestHelper.Monkey.Operators -{ - /// - /// IOperator operation types. - /// Intended for use in capture and playback features. - /// - public enum OperatorType - { - Click, // a.k.a. tap - ClickAndHold, // a.k.a. touch and hold, long press - DoubleClick, // a.k.a. double tap - TextInput, // Recommended to implement ITextInputOperator - DragAndDrop, - Swipe, - Flick, - Pinch, - Hover, // Hover mouse cursor - RightClick, // Click right button on mouse - ScrollWheel, // Scroll wheel on mouse. scrolling up/down and tilting left/right. - } -} diff --git a/Runtime/Operators/OperatorType.cs.meta b/Runtime/Operators/OperatorType.cs.meta deleted file mode 100644 index c345f41..0000000 --- a/Runtime/Operators/OperatorType.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 11e480d32842484b83f7e788591ad2ea -timeCreated: 1712452936 \ No newline at end of file diff --git a/Runtime/Operators/UGUIClickAndHoldOperator.cs b/Runtime/Operators/UGUIClickAndHoldOperator.cs index 473c600..b68aa14 100644 --- a/Runtime/Operators/UGUIClickAndHoldOperator.cs +++ b/Runtime/Operators/UGUIClickAndHoldOperator.cs @@ -15,7 +15,7 @@ namespace TestHelper.Monkey.Operators /// Click and hold operator for Unity UI (uGUI) components. /// a.k.a. touch and hold, long press. /// - public class UGUIClickAndHoldOperator : IOperator + public class UGUIClickAndHoldOperator : IClickAndHoldOperator { private readonly int _holdMillis; private readonly Func _getScreenPoint; @@ -32,9 +32,6 @@ public UGUIClickAndHoldOperator(int holdMillis = 1000, Func this._getScreenPoint = getScreenPoint ?? DefaultScreenPointStrategy.GetScreenPoint; } - /// - public OperatorType Type => OperatorType.ClickAndHold; - /// public bool CanOperate(Component component) { diff --git a/Runtime/Operators/UGUIClickOperator.cs b/Runtime/Operators/UGUIClickOperator.cs index 7be8964..2bef123 100644 --- a/Runtime/Operators/UGUIClickOperator.cs +++ b/Runtime/Operators/UGUIClickOperator.cs @@ -16,7 +16,7 @@ namespace TestHelper.Monkey.Operators /// /// Click (tap) operator for Unity UI (uGUI) components. /// - public class UGUIClickOperator : IOperator + public class UGUIClickOperator : IClickOperator { private readonly Func _getScreenPoint; private readonly PointerEventData _eventData = new PointerEventData(EventSystem.current); @@ -30,9 +30,6 @@ public UGUIClickOperator(Func getScreenPoint = null) this._getScreenPoint = getScreenPoint ?? DefaultScreenPointStrategy.GetScreenPoint; } - /// - public OperatorType Type => OperatorType.Click; - /// public bool CanOperate(Component component) { diff --git a/Runtime/Operators/UGUITextInputOperator.cs b/Runtime/Operators/UGUITextInputOperator.cs index 2aeb79b..eca6d16 100644 --- a/Runtime/Operators/UGUITextInputOperator.cs +++ b/Runtime/Operators/UGUITextInputOperator.cs @@ -35,9 +35,6 @@ public UGUITextInputOperator( _randomString = randomString ?? new RandomStringImpl(new RandomWrapper()); } - /// - public OperatorType Type => OperatorType.TextInput; - /// public bool CanOperate(Component component) { diff --git a/Samples~/uGUI Demo/Tests/Runtime/ScenarioTest.cs b/Samples~/uGUI Demo/Tests/Runtime/ScenarioTest.cs index 3cf91ef..322acb4 100644 --- a/Samples~/uGUI Demo/Tests/Runtime/ScenarioTest.cs +++ b/Samples~/uGUI Demo/Tests/Runtime/ScenarioTest.cs @@ -30,7 +30,7 @@ public async Task OpenSubScreens(string target) // When click Start button, then open Home screen. var startButton = await _finder.FindByNameAsync("StartButton", interactable: true); var startComponent = startButton.GetInteractableComponents().First(); - var startOperator = startComponent.SelectOperatorsOfType(_config.Operators, OperatorType.Click).First(); + var startOperator = startComponent.SelectOperators(_config.Operators).First(); startOperator.OperateAsync(startComponent); await _finder.FindByNameAsync("Home"); @@ -38,7 +38,7 @@ public async Task OpenSubScreens(string target) // When click target button, then open target screen. var targetButton = await _finder.FindByNameAsync($"{target}Button", interactable: true); var targetComponent = targetButton.GetInteractableComponents().First(); - var targetOperator = targetComponent.SelectOperatorsOfType(_config.Operators, OperatorType.Click).First(); + var targetOperator = targetComponent.SelectOperators(_config.Operators).First(); targetOperator.OperateAsync(targetComponent); await _finder.FindByNameAsync(target); @@ -46,7 +46,7 @@ public async Task OpenSubScreens(string target) // When click Back button, then return Home screen. var backButton = await _finder.FindByPathAsync($"**/{target}/BackButton", interactable: true); var backComponent = backButton.GetInteractableComponents().First(); - var backOperator = backComponent.SelectOperatorsOfType(_config.Operators, OperatorType.Click).First(); + var backOperator = backComponent.SelectOperators(_config.Operators).First(); backOperator.OperateAsync(backComponent); await _finder.FindByNameAsync("Home"); diff --git a/Tests/Runtime/Extensions/ComponentExtensionsTest.cs b/Tests/Runtime/Extensions/ComponentExtensionsTest.cs index 9774581..6d3bac3 100644 --- a/Tests/Runtime/Extensions/ComponentExtensionsTest.cs +++ b/Tests/Runtime/Extensions/ComponentExtensionsTest.cs @@ -34,7 +34,7 @@ public void GetOperators_Button_GotClickAndClickAndHoldOperator() public void GetOperatorsByType_Button_GotClickOperator() { var button = new GameObject().AddComponent