Skip to content

Commit f703b2f

Browse files
authored
Merge pull request #151 from nowsprinting/feature/bump_monkey_0_15_1
Upgrade dependency package test-helper.monkey from v0.14.0 to v0.15.1; Repeating operation detection
2 parents 0e44449 + c3a8b0b commit f703b2f

File tree

11 files changed

+233
-159
lines changed

11 files changed

+233
-159
lines changed

.github/workflows/test.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ jobs:
8787
openupm add -f com.unity.testtools.codecoverage
8888
openupm add -f [email protected]
8989
openupm add -f [email protected]
90-
openupm add -f com.nowsprinting.test-helper.monkey@0.14.0
91-
openupm add -f [email protected].0
90+
openupm add -f com.nowsprinting.test-helper.monkey@0.15.1
91+
openupm add -f [email protected].1
9292
openupm add -ft "${{ env.PACKAGE_NAME }}"@file:../../
9393
working-directory: ${{ env.CREATED_PROJECT_PATH }}
9494
if: ${{ matrix.depends == 'min' }}

Editor/Localization/ja.po

+10-2
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,16 @@ msgid "No-Element Timeout [sec]"
299299
msgstr "要素なしタイムアウト[秒]"
300300

301301
# timeout tooltip
302-
msgid "Abort Autopilot when the interactable UI/2D/3D element does not appear for the specified seconds."
303-
msgstr "指定した秒数の間、対話可能なUI/2D/3D要素が出現しなければ、オートパイロットの実行を中断します"
302+
msgid "Abort Autopilot when the interactable UI/ 2D/ 3D element does not appear for the specified seconds. Disable detection if set to 0."
303+
msgstr "指定した秒数の間、対話可能な UI/ 2D/ 3D 要素が出現しなければ、オートパイロットの実行を中断します。0 に設定すると検出が無効になります。"
304+
305+
# repeating operation detection buffer length
306+
msgid "Repeating Operation Detection Buffer Length"
307+
msgstr "繰り返し操作検出バッファ長"
308+
309+
# repeating operation detection buffer length tooltip
310+
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."
311+
msgstr "指定されたバッファ長内で繰り返し操作が検出されると、オートパイロットの実行を中断します。たとえばバッファ長が 10 の場合、5 ステップまでの繰り返しシーケンスを検出できます。0 に設定すると検出が無効になります。"
304312

305313
# uGUI click and hold operator options
306314
msgid "Click and Hold Operator Options"

Editor/UI/Agents/UGUIMonkeyAgentEditor.cs

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2023-2024 DeNA Co., Ltd.
1+
// Copyright (c) 2023-2025 DeNA Co., Ltd.
22
// This software is released under the MIT License.
33

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

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

4444
private SerializedProperty _timeoutProp;
4545
private GUIContent _timeoutGUIContent;
4646

47+
private static readonly string s_repeatDetectionBuffer = L10n.Tr("Repeating Operation Detection Buffer Length");
48+
49+
private static readonly string s_repeatDetectionBufferToolTip = L10n.Tr(
50+
"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.");
51+
52+
private SerializedProperty _repeatDetectionBufferProp;
53+
private GUIContent _repeatDetectionBufferGUIContent;
54+
4755
private static readonly string s_gizmos = L10n.Tr("Enable Gizmos");
4856

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

161+
_repeatDetectionBufferProp =
162+
serializedObject.FindProperty(nameof(UGUIMonkeyAgent.bufferLengthForDetectLooping));
163+
_repeatDetectionBufferGUIContent = new GUIContent(s_repeatDetectionBuffer, s_repeatDetectionBufferToolTip);
164+
153165
_gizmosProp = serializedObject.FindProperty(nameof(UGUIMonkeyAgent.gizmos));
154166
_gizmosGUIContent = new GUIContent(s_gizmos, s_gizmosTooltip);
155167

@@ -265,6 +277,7 @@ public override void OnInspectorGUI()
265277
EditorGUILayout.PropertyField(_lifespanProp, _lifespanGUIContent);
266278
EditorGUILayout.PropertyField(_delayMillisProp, _delayMillisGUIContent);
267279
EditorGUILayout.PropertyField(_timeoutProp, _timeoutGUIContent);
280+
EditorGUILayout.PropertyField(_repeatDetectionBufferProp, _repeatDetectionBufferGUIContent);
268281
EditorGUILayout.PropertyField(_gizmosProp, _gizmosGUIContent);
269282

270283
// Screenshot options

README.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,12 @@ An instance of this Agent (.asset file) can contain the following.
281281
<dl>
282282
<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>
283283
<dt>Delay</dt><dd>Wait interval [milliseconds] between random operations</dd>
284-
<dt>No-Element Timeout</dt><dd>Abort Autopilot when the interactable UI/2D/3D element does not appear for the specified seconds</dd>
284+
<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>
285+
<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>
285286
<dt>Enable Gizmos</dt><dd>Show Gizmos on GameView during running monkey test if true</dd>
286287
</dl>
287288

288-
***Screenshot Options:***
289+
#### Screenshot Options
289290

290291
<dl>
291292
<dt>Enabled</dt><dd>Whether screenshot is enabled or not</dd>
@@ -294,13 +295,13 @@ An instance of this Agent (.asset file) can contain the following.
294295
<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>
295296
</dl>
296297

297-
***Click and Hold Operator Options:***
298+
#### Click and Hold Operator Options
298299

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

303-
***Text Input Operator Options:***
304+
#### Text Input Operator Options
304305

305306
<dl>
306307
<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>

README_ja.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,12 @@ uGUIのコンポーネントをランダムに操作するAgentです。
284284
<dl>
285285
<dt>実行時間</dt><dd>ランダム操作の実行時間を秒で指定します。0を指定するとほぼ無制限(TimeSpan.MaxValue)に動作します。この設定でAgentが終了してもオートパイロットおよびアプリ自体は終了しません。次にSceneが切り替わるまでなにもしない状態になります</dd>
286286
<dt>操作間隔</dt><dd>ランダム操作間のウェイト間隔をミリ秒で指定します</dd>
287-
<dt>要素なしタイムアウト</dt><dd>指定した秒数の間、対話可能なUI/2D/3D要素が出現しなければ、オートパイロットの実行を中断します</dd>
287+
<dt>要素なしタイムアウト</dt><dd>指定した秒数の間、対話可能なUI/ 2D/ 3D要素が出現しなければ、オートパイロットの実行を中断します。0 に設定すると検出が無効になります。</dd>
288+
<dt>繰り返し操作検出バッファ長</dt><dd>指定されたバッファ長内で繰り返し操作が検出されると、オートパイロットの実行を中断します。たとえばバッファ長が 10 の場合、5 ステップまでの繰り返しシーケンスを検出できます。0 に設定すると検出が無効になります。</dd>
288289
<dt>Gizmos を有効</dt><dd>もし有効ならモンキー操作中の GameView に Gizmo を表示します。もし無効なら GameView に Gizmo を表示しません</dd>
289290
</dl>
290291

291-
***スクリーンショット設定:***
292+
#### スクリーンショット設定
292293

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

300-
***クリック&ホールド オペレーター設定:***
301+
#### クリック&ホールド オペレーター設定
301302

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

306-
***テキスト入力オペレーター設定:***
307+
#### テキスト入力オペレーター設定
307308

308309
<dl>
309310
<dt>GameObjectの名前</dt><dd>対象のGameObject名を指定します。名前による特定が難しい場合は後述のInputFieldAnnotationも利用できます</dd>

Runtime/Agents/UGUIEmergencyExitAgent.cs

+21-16
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
// Copyright (c) 2023-2025 DeNA Co., Ltd.
22
// This software is released under the MIT License.
33

4-
using System.Text;
54
using System.Threading;
65
using Cysharp.Threading.Tasks;
76
using DeNA.Anjin.Annotations;
87
using DeNA.Anjin.Settings;
98
using DeNA.Anjin.Strategies;
9+
using TestHelper.Monkey;
10+
using TestHelper.Monkey.DefaultStrategies;
1011
using TestHelper.Monkey.Operators;
11-
using TestHelper.Monkey.ScreenshotFilenameStrategies;
12-
using TestHelper.RuntimeInternals;
1312
using UnityEngine;
1413
using UnityEngine.UI;
1514

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

34+
private IReachableStrategy _reachableStrategy;
3535
private IClickOperator _clickOperator;
36-
private IScreenshotFilenameStrategy _filenameStrategy;
36+
private ScreenshotOptions _screenshotOptions;
3737

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

43+
_reachableStrategy = new DefaultReachableStrategy();
4344
_clickOperator = new UGUIClickOperator();
44-
_filenameStrategy = new TwoTieredCounterStrategy(this.name);
45+
_screenshotOptions = screenshot
46+
? new ScreenshotOptions
47+
{
48+
// ReSharper disable once PossibleNullReferenceException
49+
Directory = AutopilotState.Instance.settings.ScreenshotsPath,
50+
FilenameStrategy = new TwoTieredCounterStrategy(this.name),
51+
}
52+
: null;
4553

4654
try
4755
{
@@ -77,25 +85,22 @@ public override async UniTask Run(CancellationToken cancellationToken)
7785
private async UniTask ClickEmergencyExitButton(EmergencyExitAnnotation emergencyExit,
7886
CancellationToken cancellationToken = default)
7987
{
80-
var button = emergencyExit.gameObject.GetComponent<Button>();
88+
var button = emergencyExit.gameObject;
8189
if (!_clickOperator.CanOperate(button))
8290
{
91+
Logger.Log(LogType.Warning,
92+
$"EmergencyExitAnnotation attached {button.name}({button.GetInstanceID()}) appears but cannot be operated");
8393
return;
8494
}
8595

86-
var message = new StringBuilder($"Click emergency exit button: {button.gameObject.name}");
87-
if (screenshot)
96+
if (!_reachableStrategy.IsReachable(button, out var raycastResult))
8897
{
89-
// ReSharper disable once PossibleNullReferenceException
90-
var directory = AutopilotState.Instance.settings.ScreenshotsPath;
91-
var filename = _filenameStrategy.GetFilename();
92-
await ScreenshotHelper.TakeScreenshot(directory, filename).ToUniTask(button);
93-
message.Append($" ({filename})");
98+
Logger.Log(LogType.Warning,
99+
$"EmergencyExitAnnotation attached {button.name}({button.GetInstanceID()}) appears but not reachable");
100+
return;
94101
}
95102

96-
Logger.Log(message.ToString());
97-
98-
await _clickOperator.OperateAsync(button, cancellationToken);
103+
await _clickOperator.OperateAsync(button, raycastResult, Logger, _screenshotOptions, cancellationToken);
99104
}
100105
}
101106
}

Runtime/Agents/UGUIMonkeyAgent.cs

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2023-2024 DeNA Co., Ltd.
1+
// Copyright (c) 2023-2025 DeNA Co., Ltd.
22
// This software is released under the MIT License.
33

44
using System;
@@ -10,6 +10,7 @@
1010
using DeNA.Anjin.Strategies;
1111
using TestHelper.Monkey;
1212
using TestHelper.Monkey.Annotations.Enums;
13+
using TestHelper.Monkey.Exceptions;
1314
using TestHelper.Monkey.Operators;
1415
using TestHelper.Monkey.Random;
1516
using TestHelper.Random;
@@ -35,11 +36,20 @@ public class UGUIMonkeyAgent : AbstractAgent
3536
public int delayMillis = 200;
3637

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

45+
/// <summary>
46+
/// Repeating operation detection buffer length.
47+
/// Abort Autopilot when repeating operation is detected within the specified buffer length.
48+
/// For example, if the buffer length is 10, repeating 5-step sequences can be detected.
49+
/// Disable detection if set to 0.
50+
/// </summary>
51+
public int bufferLengthForDetectLooping = 10;
52+
4353
/// <summary>
4454
/// Delay time for click-and-hold
4555
/// </summary>
@@ -111,6 +121,7 @@ public override async UniTask Run(CancellationToken cancellationToken)
111121
Random = random,
112122
Logger = Logger,
113123
SecondsToErrorForNoInteractiveComponent = secondsToErrorForNoInteractiveComponent,
124+
BufferLengthForDetectLooping = bufferLengthForDetectLooping,
114125
Gizmos = gizmos,
115126
Screenshots = screenshotEnabled
116127
? new ScreenshotOptions
@@ -146,6 +157,14 @@ public override async UniTask Run(CancellationToken cancellationToken)
146157
// ReSharper disable once MethodSupportsCancellation; Do not use this Agent's CancellationToken.
147158
AutopilotInstance.TerminateAsync(ExitCode.AutopilotFailed, message, e.StackTrace).Forget();
148159
}
160+
catch (InfiniteLoopException e)
161+
{
162+
var message = $"{e.GetType().Name}: {e.Message}";
163+
Logger.Log(message);
164+
165+
// ReSharper disable once MethodSupportsCancellation; Do not use this Agent's CancellationToken.
166+
AutopilotInstance.TerminateAsync(ExitCode.AutopilotFailed, message, e.StackTrace).Forget();
167+
}
149168
finally
150169
{
151170
Logger.Log($"Exit {this.name}.Run()");

0 commit comments

Comments
 (0)