Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade dependency package test-helper.monkey from v0.14.0 to v0.15.1; Repeating operation detection #151

Merged
merged 4 commits into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ jobs:
openupm add -f com.unity.testtools.codecoverage
openupm add -f [email protected]
openupm add -f [email protected]
openupm add -f com.nowsprinting.test-helper.monkey@0.14.0
openupm add -f [email protected].0
openupm add -f com.nowsprinting.test-helper.monkey@0.15.1
openupm add -f [email protected].1
openupm add -ft "${{ env.PACKAGE_NAME }}"@file:../../
working-directory: ${{ env.CREATED_PROJECT_PATH }}
if: ${{ matrix.depends == 'min' }}
Expand Down
12 changes: 10 additions & 2 deletions Editor/Localization/ja.po
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,16 @@ msgid "No-Element Timeout [sec]"
msgstr "要素なしタイムアウト[秒]"

# timeout tooltip
msgid "Abort Autopilot when the interactable UI/2D/3D element does not appear for the specified seconds."
msgstr "指定した秒数の間、対話可能なUI/2D/3D要素が出現しなければ、オートパイロットの実行を中断します"
msgid "Abort Autopilot when the interactable UI/ 2D/ 3D element does not appear for the specified seconds. Disable detection if set to 0."
msgstr "指定した秒数の間、対話可能な UI/ 2D/ 3D 要素が出現しなければ、オートパイロットの実行を中断します。0 に設定すると検出が無効になります。"

# repeating operation detection buffer length
msgid "Repeating Operation Detection Buffer Length"
msgstr "繰り返し操作検出バッファ長"

# repeating operation detection buffer length tooltip
msgid "Abort Autopilot when repeating operation is detected within the specified buffer length. For example, if the buffer length is 10, repeating 5-step sequences can be detected. Disable detection if set to 0."
msgstr "指定されたバッファ長内で繰り返し操作が検出されると、オートパイロットの実行を中断します。たとえばバッファ長が 10 の場合、5 ステップまでの繰り返しシーケンスを検出できます。0 に設定すると検出が無効になります。"

# uGUI click and hold operator options
msgid "Click and Hold Operator Options"
Expand Down
17 changes: 15 additions & 2 deletions Editor/UI/Agents/UGUIMonkeyAgentEditor.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2023-2024 DeNA Co., Ltd.
// Copyright (c) 2023-2025 DeNA Co., Ltd.
// This software is released under the MIT License.

using System.Diagnostics.CodeAnalysis;
Expand Down Expand Up @@ -38,12 +38,20 @@ public class UGUIMonkeyAgentEditor : UnityEditor.Editor
L10n.Tr("No-Element Timeout [sec]");

private static readonly string s_timeoutToolTip = L10n.Tr(
"Abort Autopilot when the interactable UI/2D/3D element does not appear for the specified seconds."
"Abort Autopilot when the interactable UI/ 2D/ 3D element does not appear for the specified seconds. Disable detection if set to 0."
);

private SerializedProperty _timeoutProp;
private GUIContent _timeoutGUIContent;

private static readonly string s_repeatDetectionBuffer = L10n.Tr("Repeating Operation Detection Buffer Length");

private static readonly string s_repeatDetectionBufferToolTip = L10n.Tr(
"Abort Autopilot when repeating operation is detected within the specified buffer length. For example, if the buffer length is 10, repeating 5-step sequences can be detected. Disable detection if set to 0.");

private SerializedProperty _repeatDetectionBufferProp;
private GUIContent _repeatDetectionBufferGUIContent;

private static readonly string s_gizmos = L10n.Tr("Enable Gizmos");

private static readonly string s_gizmosTooltip =
Expand Down Expand Up @@ -150,6 +158,10 @@ private void Initialize()
serializedObject.FindProperty(nameof(UGUIMonkeyAgent.secondsToErrorForNoInteractiveComponent));
_timeoutGUIContent = new GUIContent(s_timeout, s_timeoutToolTip);

_repeatDetectionBufferProp =
serializedObject.FindProperty(nameof(UGUIMonkeyAgent.bufferLengthForDetectLooping));
_repeatDetectionBufferGUIContent = new GUIContent(s_repeatDetectionBuffer, s_repeatDetectionBufferToolTip);

_gizmosProp = serializedObject.FindProperty(nameof(UGUIMonkeyAgent.gizmos));
_gizmosGUIContent = new GUIContent(s_gizmos, s_gizmosTooltip);

Expand Down Expand Up @@ -265,6 +277,7 @@ public override void OnInspectorGUI()
EditorGUILayout.PropertyField(_lifespanProp, _lifespanGUIContent);
EditorGUILayout.PropertyField(_delayMillisProp, _delayMillisGUIContent);
EditorGUILayout.PropertyField(_timeoutProp, _timeoutGUIContent);
EditorGUILayout.PropertyField(_repeatDetectionBufferProp, _repeatDetectionBufferGUIContent);
EditorGUILayout.PropertyField(_gizmosProp, _gizmosGUIContent);

// Screenshot options
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,12 @@ An instance of this Agent (.asset file) can contain the following.
<dl>
<dt>Lifespan</dt><dd>Duration of random operation execution time in secounds. If 0 is specified, the operation is almost unlimited (TimeSpan.MaxValue). With this setting, neither Autopilot nor the app itself will exit when the Agent exits. It will not do anything until the next Scene switch</dd>
<dt>Delay</dt><dd>Wait interval [milliseconds] between random operations</dd>
<dt>No-Element Timeout</dt><dd>Abort Autopilot when the interactable UI/2D/3D element does not appear for the specified seconds</dd>
<dt>No-Element Timeout</dt><dd>Abort Autopilot when the interactable UI/ 2D/ 3D element does not appear for the specified seconds. Disable detection if set to 0.</dd>
<dt>Repeating Operation Detection Buffer Length</dt><dd>Abort Autopilot when repeating operation is detected within the specified buffer length. For example, if the buffer length is 10, repeating 5-step sequences can be detected. Disable detection if set to 0.</dd>
<dt>Enable Gizmos</dt><dd>Show Gizmos on GameView during running monkey test if true</dd>
</dl>

***Screenshot Options:***
#### Screenshot Options

<dl>
<dt>Enabled</dt><dd>Whether screenshot is enabled or not</dd>
Expand All @@ -294,13 +295,13 @@ An instance of this Agent (.asset file) can contain the following.
<dt>Stereo Capture Mode</dt><dd>The eye texture to capture when stereo rendering is enabled. Neither this nor Resolution Factor can be specified</dd>
</dl>

***Click and Hold Operator Options:***
#### Click and Hold Operator Options

<dl>
<dt>Click and Hold Millis</dt><dd>Delay time for click-and-hold [ms]</dd>
</dl>

***Text Input Operator Options:***
#### Text Input Operator Options

<dl>
<dt>GameObject Name</dt><dd>Target GameObject name. If it is difficult to identify the GameObject by name, you can also use InputFieldAnnotation, which will be described later.</dd>
Expand Down
9 changes: 5 additions & 4 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,11 +284,12 @@ uGUIのコンポーネントをランダムに操作するAgentです。
<dl>
<dt>実行時間</dt><dd>ランダム操作の実行時間を秒で指定します。0を指定するとほぼ無制限(TimeSpan.MaxValue)に動作します。この設定でAgentが終了してもオートパイロットおよびアプリ自体は終了しません。次にSceneが切り替わるまでなにもしない状態になります</dd>
<dt>操作間隔</dt><dd>ランダム操作間のウェイト間隔をミリ秒で指定します</dd>
<dt>要素なしタイムアウト</dt><dd>指定した秒数の間、対話可能なUI/2D/3D要素が出現しなければ、オートパイロットの実行を中断します</dd>
<dt>要素なしタイムアウト</dt><dd>指定した秒数の間、対話可能なUI/ 2D/ 3D要素が出現しなければ、オートパイロットの実行を中断します。0 に設定すると検出が無効になります。</dd>
<dt>繰り返し操作検出バッファ長</dt><dd>指定されたバッファ長内で繰り返し操作が検出されると、オートパイロットの実行を中断します。たとえばバッファ長が 10 の場合、5 ステップまでの繰り返しシーケンスを検出できます。0 に設定すると検出が無効になります。</dd>
<dt>Gizmos を有効</dt><dd>もし有効ならモンキー操作中の GameView に Gizmo を表示します。もし無効なら GameView に Gizmo を表示しません</dd>
</dl>

***スクリーンショット設定:***
#### スクリーンショット設定

<dl>
<dt>有効</dt><dd>スクリーンショット撮影を有効にします</dd>
Expand All @@ -297,13 +298,13 @@ uGUIのコンポーネントをランダムに操作するAgentです。
<dt>ステレオキャプチャモード</dt><dd>ステレオレンダリングが有効な場合にどちらのカメラを使用するかを指定できます。拡大係数と同時には設定できません</dd>
</dl>

***クリック&ホールド オペレーター設定:***
#### クリック&ホールド オペレーター設定

<dl>
<dt>クリック&ホールド時間</dt><dd>クリック&ホールドの継続時間をミリ秒で指定します</dd>
</dl>

***テキスト入力オペレーター設定:***
#### テキスト入力オペレーター設定

<dl>
<dt>GameObjectの名前</dt><dd>対象のGameObject名を指定します。名前による特定が難しい場合は後述のInputFieldAnnotationも利用できます</dd>
Expand Down
37 changes: 21 additions & 16 deletions Runtime/Agents/UGUIEmergencyExitAgent.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
// Copyright (c) 2023-2025 DeNA Co., Ltd.
// This software is released under the MIT License.

using System.Text;
using System.Threading;
using Cysharp.Threading.Tasks;
using DeNA.Anjin.Annotations;
using DeNA.Anjin.Settings;
using DeNA.Anjin.Strategies;
using TestHelper.Monkey;
using TestHelper.Monkey.DefaultStrategies;
using TestHelper.Monkey.Operators;
using TestHelper.Monkey.ScreenshotFilenameStrategies;
using TestHelper.RuntimeInternals;
using UnityEngine;
using UnityEngine.UI;

Expand All @@ -32,16 +31,25 @@ public class UGUIEmergencyExitAgent : AbstractAgent
/// </summary>
public bool screenshot;

private IReachableStrategy _reachableStrategy;
private IClickOperator _clickOperator;
private IScreenshotFilenameStrategy _filenameStrategy;
private ScreenshotOptions _screenshotOptions;

/// <inheritdoc />
public override async UniTask Run(CancellationToken cancellationToken)
{
Logger.Log($"Enter {this.name}.Run()");

_reachableStrategy = new DefaultReachableStrategy();
_clickOperator = new UGUIClickOperator();
_filenameStrategy = new TwoTieredCounterStrategy(this.name);
_screenshotOptions = screenshot
? new ScreenshotOptions
{
// ReSharper disable once PossibleNullReferenceException
Directory = AutopilotState.Instance.settings.ScreenshotsPath,
FilenameStrategy = new TwoTieredCounterStrategy(this.name),
}
: null;

try
{
Expand Down Expand Up @@ -77,25 +85,22 @@ public override async UniTask Run(CancellationToken cancellationToken)
private async UniTask ClickEmergencyExitButton(EmergencyExitAnnotation emergencyExit,
CancellationToken cancellationToken = default)
{
var button = emergencyExit.gameObject.GetComponent<Button>();
var button = emergencyExit.gameObject;
if (!_clickOperator.CanOperate(button))
{
Logger.Log(LogType.Warning,
$"EmergencyExitAnnotation attached {button.name}({button.GetInstanceID()}) appears but cannot be operated");
return;
}

var message = new StringBuilder($"Click emergency exit button: {button.gameObject.name}");
if (screenshot)
if (!_reachableStrategy.IsReachable(button, out var raycastResult))
{
// ReSharper disable once PossibleNullReferenceException
var directory = AutopilotState.Instance.settings.ScreenshotsPath;
var filename = _filenameStrategy.GetFilename();
await ScreenshotHelper.TakeScreenshot(directory, filename).ToUniTask(button);
message.Append($" ({filename})");
Logger.Log(LogType.Warning,
$"EmergencyExitAnnotation attached {button.name}({button.GetInstanceID()}) appears but not reachable");
return;
}

Logger.Log(message.ToString());

await _clickOperator.OperateAsync(button, cancellationToken);
await _clickOperator.OperateAsync(button, raycastResult, Logger, _screenshotOptions, cancellationToken);
}
}
}
25 changes: 22 additions & 3 deletions Runtime/Agents/UGUIMonkeyAgent.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2023-2024 DeNA Co., Ltd.
// Copyright (c) 2023-2025 DeNA Co., Ltd.
// This software is released under the MIT License.

using System;
Expand All @@ -10,6 +10,7 @@
using DeNA.Anjin.Strategies;
using TestHelper.Monkey;
using TestHelper.Monkey.Annotations.Enums;
using TestHelper.Monkey.Exceptions;
using TestHelper.Monkey.Operators;
using TestHelper.Monkey.Random;
using TestHelper.Random;
Expand All @@ -35,11 +36,20 @@ public class UGUIMonkeyAgent : AbstractAgent
public int delayMillis = 200;

/// <summary>
/// No-Element Timeout [sec].
/// Abort Autopilot when the interactable UI/2D/3D element does not appear for the specified seconds.
/// No-element timeout [sec].
/// Abort Autopilot when the interactable UI/ 2D/ 3D element does not appear for the specified seconds.
/// Disable detection if set to 0.
/// </summary>
public int secondsToErrorForNoInteractiveComponent = 5;

/// <summary>
/// Repeating operation detection buffer length.
/// Abort Autopilot when repeating operation is detected within the specified buffer length.
/// For example, if the buffer length is 10, repeating 5-step sequences can be detected.
/// Disable detection if set to 0.
/// </summary>
public int bufferLengthForDetectLooping = 10;

/// <summary>
/// Delay time for click-and-hold
/// </summary>
Expand Down Expand Up @@ -111,6 +121,7 @@ public override async UniTask Run(CancellationToken cancellationToken)
Random = random,
Logger = Logger,
SecondsToErrorForNoInteractiveComponent = secondsToErrorForNoInteractiveComponent,
BufferLengthForDetectLooping = bufferLengthForDetectLooping,
Gizmos = gizmos,
Screenshots = screenshotEnabled
? new ScreenshotOptions
Expand Down Expand Up @@ -146,6 +157,14 @@ public override async UniTask Run(CancellationToken cancellationToken)
// ReSharper disable once MethodSupportsCancellation; Do not use this Agent's CancellationToken.
AutopilotInstance.TerminateAsync(ExitCode.AutopilotFailed, message, e.StackTrace).Forget();
}
catch (InfiniteLoopException e)
{
var message = $"{e.GetType().Name}: {e.Message}";
Logger.Log(message);

// ReSharper disable once MethodSupportsCancellation; Do not use this Agent's CancellationToken.
AutopilotInstance.TerminateAsync(ExitCode.AutopilotFailed, message, e.StackTrace).Forget();
}
finally
{
Logger.Log($"Exit {this.name}.Run()");
Expand Down
Loading