test(runtime): add unattended connected R6 soak

Drive turn, movement, jump, and combat through the production InputDispatcher so connected Release testing works without an interactive Windows desktop. Track held automation actions through normal completion and every shutdown path.

Add a seven-destination ACE route with post-liveness memory, allocation, update, fatal-log, outbound-movement, and graceful-close gates. Record dynamic ACE population changes as context instead of a false lifetime oracle, and document the accepted rebaseline.

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-20 12:12:08 +02:00
parent f961d70023
commit a755b764bf
14 changed files with 1021 additions and 20 deletions

View file

@ -3,6 +3,7 @@ using System.IO;
using AcDream.App.UI;
using AcDream.App.UI.Testing;
using AcDream.Core.Items;
using AcDream.UI.Abstractions.Input;
namespace AcDream.App.Tests.UI;
@ -441,4 +442,89 @@ public sealed class RetailUiAutomationProbeTests
File.Delete(path);
}
}
[Fact]
public void ScriptRunner_input_drivesSemanticPressAndHeldEdges()
{
var (root, _, _, _, objects) = RootWithTwoItemLists();
var probe = new RetailUiAutomationProbe(root, objects);
var presses = new List<InputAction>();
var held = new List<(InputAction Action, bool Held)>();
string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".ui-probe.txt");
File.WriteAllLines(path,
[
"input down MovementForward",
"sleep 10",
"input up MovementForward",
"input press CombatToggleCombat",
]);
try
{
using var runner = new RetailUiAutomationScriptRunner(
probe,
path,
dumpOnStart: false,
pressInput: action =>
{
presses.Add(action);
return true;
},
setInputHeld: (action, isHeld) =>
{
held.Add((action, isHeld));
return true;
});
runner.Tick(0d);
Assert.Equal([(InputAction.MovementForward, true)], held);
Assert.False(runner.Completed);
runner.Tick(0.010d);
Assert.True(runner.Completed);
Assert.Equal(
[(InputAction.MovementForward, true), (InputAction.MovementForward, false)],
held);
Assert.Equal([InputAction.CombatToggleCombat], presses);
}
finally
{
File.Delete(path);
}
}
[Fact]
public void ScriptRunner_dispose_releasesInjectedHeldActions()
{
var (root, _, _, _, objects) = RootWithTwoItemLists();
var probe = new RetailUiAutomationProbe(root, objects);
var held = new List<(InputAction Action, bool Held)>();
string path = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".ui-probe.txt");
File.WriteAllLines(path, ["input down MovementForward", "sleep 10000"]);
try
{
var runner = new RetailUiAutomationScriptRunner(
probe,
path,
dumpOnStart: false,
setInputHeld: (action, isHeld) =>
{
held.Add((action, isHeld));
return true;
});
runner.Tick(0d);
runner.Dispose();
Assert.Equal(
[(InputAction.MovementForward, true), (InputAction.MovementForward, false)],
held);
}
finally
{
File.Delete(path);
}
}
}