diff --git a/COMPATIBILITY.md b/COMPATIBILITY.md index a18dfcd4..8e3d4c43 100644 --- a/COMPATIBILITY.md +++ b/COMPATIBILITY.md @@ -129,7 +129,7 @@ Names are C# versions of the JavaScript API: `agent.act` is `ActAsync`, `screen. - The full locator action set (`dragTo`, `swipe`, `hover`, `setInputFiles`, `secondaryTap`, `longPress`, pointer points). `secondaryTap` and `longPress` have no counterpart in the document engine - The screen-level `screen.tapAt` and `screen.swipe` - Per-action options other than `timeout` (and `delay` for `pressSequentially`): click `modifiers` on a locator (the agent's `tap` and `double_tap` hold them, above), tap `position`, and the `{ label, value, index }` form of `selectOption` -- Diff-only observations. Each model turn receives a full text snapshot +- Diff-only observations. Each model turn receives a full text snapshot, cut at the observation byte budget (see [Agents](#agents)) - Telemetry - `STEP_NOT_AWAITED`, the error that fails a test body, hook, or fixture teardown that returns before its `expect.poll` finished, and cancels that poll. The step recorder has `AbandonRunning` and records a step the test did not await as `STEP_NOT_AWAITED`, but no fixture calls it yet, and `expect.poll` is not a step. Nothing cancels a poll the test does not await, so it keeps reading until its timeout or the `CancellationToken` passed to it. The compiler warns (CS4014) only for a bare, un-awaited `Task` call in an `async` method - Value expectations (`expect(value).toBe`, `toEqual`, `toMatchObject`, `toHaveProperty`, `toMatchSchema`, and the rest) and their `expect.soft` form. Use NUnit `Assert.That` with constraints, and `Assert.EnterMultipleScope` (or `Assert.Multiple`) for soft value checks. `expect.poll` takes NUnit constraints through `ToMatchAsync` in their place @@ -507,9 +507,7 @@ Not ported: - `AssertAsync` on an agent with an executor goes to it as a step of kind `Assert`, with the agent's budgets and `JudgmentTimeout`. An assert is never cached, and a passing one verifies the acts before it. `Vision` is refused with `UNSUPPORTED_CAPABILITY`, since the executor decides what its model sees, and `Screenshot` keeps its evidence after the verdict, bounded by the action timeout: a capture that outlives it is dropped and the verdict stands. `WaitForAsync` and `ExtractAsync` keep the judge, which is the executor's `Judge` or `Model`. `ExecutorCache.Off` never replays or records, and takes no look before the step. A step with the cache on that cannot read its first screen (no app opened) still runs, and records nothing - `TypeSecretAsync` fills a secret the step's params declared, and refuses with `POLICY_DENIED` any other name, a disabled or non-editable field, and a field whose purpose does not fit a password secret. A secret the attempt does not know is `AUTH_CREDENTIAL_UNAVAILABLE`. The built-in agent's `fill_secret` goes through the same check, so its refusals read as the dispatcher's messages and not as `Secret fill refused: ...`. `ExecutorStep.Params` is JSON: a `Secret` is its name and, when set, its purpose, and every string and key that holds a secret value the attempt knows is redacted. `ExecutorAttempt` has the session's `TestTitle` as `TestId`, a fresh id per session, and `Index` as the attempt number minus one; `ExecutorStep.Index` counts the agent steps of the attempt, where upstream's counts every step. `AttachTranscript` and `AttachScreenshotAsync` write under the attempt's results directory (`transcript-.txt`, `screenshots/-