changedInput schema / properties / scenarios / items / properties / steps / description
Previous value: -"Ordered steps, alternating an ACTION with an ASSERTION about the reply to the action right before it. When accepted checks are supplied, use {\"do\":\"expect_check\",\"checkId\":\"<accepted id>\"} for their outcomes; the server selects the observation channel. Optional contains:[\"literal journey value\"] strengthens message/notification checks only. An expect_check about someone other than the acting person (an outcome for person \"other\") needs \"other\": \"<as_contact id>\", the id that person has in this scenario (\"$SELF\" is the first person, once another one acts); e.g. {\"do\":\"start\",\"command\":\"/start\"}, {\"do\":\"tap\",\"button\":\"Apply\"}, {\"do\":\"as_contact\",\"id\":\"admin\"}, {\"do\":\"tap\",\"button\":\"Approve\"}, {\"do\":\"expect_check\",\"checkId\":\"c2\",\"other\":\"$SELF\"}. Each step is one object keyed by `do`: {\"do\":\"start\",\"command\":\"/start\"}, {\"do\":\"send\",\"text\":\"...\"}, {\"do\":\"send\",\"text\":\"...\",\"aiChooses\":\"<exit name>\"} (the AI assistant block answering this message takes that exit: an intent or tool name as the block lists it, or \"no_match\" / \"frustration\" — no AI runs in tests, so without aiChooses the block only chats and no branch behind an exit runs), {\"do\":\"send_media\",\"kind\":\"photo\"|\"video\"|\"audio\"|\"document\",\"caption\":\"...\"}, {\"do\":\"tap\",\"button\":\"<substring of the label>\"}, {\"do\":\"pay\"}, {\"do\":\"abandon_payment\",\"text\":\"...\"}, {\"do\":\"resume_delays\"}, {\"do\":\"simulate_event\",\"event\":\"member_join\"|\"join_request\"}, {\"do\":\"expect\",\"anyOf\":[\"verbatim fragment the bot really sends\"],\"not\":[\"text that must NOT appear\"]} (expect needs anyOf: a list of at least one verbatim fragment of what the bot sends after the action right before it; not (texts that must NOT appear) is optional and is checked only beside anyOf, because an expect with only not passes when the bot says nothing; a text in anyOf or not that the bot cannot send is removed: a {{…}} template, an internal id (no spaces, joined by _ . : or -), and, when the bot's texts are known, a button label or words it never writes; a removed text makes the scenario an invalid test), {\"do\":\"expect_var\",\"name\":\"<variable handle>\",\"contains\":\"...\",\"changed\":true}, {\"do\":\"seed_var\",\"name\":\"...\",\"value\":\"...\"} (seed_var value \"$SELF\" becomes the simulated user id, for a gate that compares the user id with a stored owner-id variable; a workspace-owner or tag gate is opened with assume.actors, never with seed_var), {\"do\":\"as_contact\",\"id\":\"user_b\"} (every later step acts as a SECOND person — for anything two people do together: one builds or sends, the other sees it; after the switch that person sees what the bot sent them earlier and can tap its buttons, and cannot tap a button on another person's screen), {\"do\":\"expect_peer_message\",\"to\":\"user_b\",\"contains\":\"...\",\"mediaType\":\"IMAGE\"} (mediaType is optional; assert proof photos/files on the same peer message), {\"do\":\"expect_http_request\",\"urlContains\":\"/orders\",\"method\":\"POST\",\"bodyContains\":\"orderId\",\"count\":1} (assert the outgoing request; method, bodyContains and count are optional). A scenario with no expect / expect_var / expect_peer_message step asserts nothing. At most 15 steps; malformed or truncated steps make the scenario an invalid test, never a pass."New value: +"Ordered steps, alternating an ACTION with an ASSERTION about the reply to the action right before it. When accepted checks are supplied, use {\"do\":\"expect_check\",\"checkId\":\"<accepted id>\"} for their outcomes; the server selects the observation channel. Optional contains:[\"literal journey value\"] strengthens message/notification checks only. An expect_check about someone other than the acting person (an outcome for person \"other\") needs \"other\": \"<as_contact id>\", the id that person has in this scenario (\"$SELF\" is the first person, once another one acts), or \"<numeric chat id>\" of the channel or group the bot posts to — the same value the scenario seeded into the bot's chat-id variable, with no as_contact for a chat; e.g. {\"do\":\"start\",\"command\":\"/start\"}, {\"do\":\"tap\",\"button\":\"Apply\"}, {\"do\":\"as_contact\",\"id\":\"admin\"}, {\"do\":\"tap\",\"button\":\"Approve\"}, {\"do\":\"expect_check\",\"checkId\":\"c2\",\"other\":\"$SELF\"}. Each step is one object keyed by `do`: {\"do\":\"start\",\"command\":\"/start\"}, {\"do\":\"send\",\"text\":\"...\"}, {\"do\":\"send\",\"text\":\"...\",\"aiChooses\":\"<exit name>\"} (the AI assistant block answering this message takes that exit: an intent or tool name as the block lists it, or \"no_match\" / \"frustration\" — no AI runs in tests, so without aiChooses the block only chats and no branch behind an exit runs), {\"do\":\"send_media\",\"kind\":\"photo\"|\"video\"|\"audio\"|\"document\",\"caption\":\"...\"}, {\"do\":\"tap\",\"button\":\"<substring of the label>\"}, {\"do\":\"pay\"}, {\"do\":\"abandon_payment\",\"text\":\"...\"}, {\"do\":\"resume_delays\"}, {\"do\":\"simulate_event\",\"event\":\"member_join\"|\"join_request\"}, {\"do\":\"expect\",\"anyOf\":[\"verbatim fragment the bot really sends\"],\"not\":[\"text that must NOT appear\"]} (expect needs anyOf: a list of at least one verbatim fragment of what the bot sends after the action right before it; not (texts that must NOT appear) is optional and is checked only beside anyOf, because an expect with only not passes when the bot says nothing; a text in anyOf or not that the bot cannot send is removed: a {{…}} template, an internal id (no spaces, joined by _ . : or -), and, when the bot's texts are known, a button label or words it never writes; a removed text makes the scenario an invalid test), {\"do\":\"expect_var\",\"name\":\"<variable handle>\",\"contains\":\"...\",\"changed\":true}, {\"do\":\"seed_var\",\"name\":\"...\",\"value\":\"...\"} (seed_var value \"$SELF\" becomes the simulated user id, for a gate that compares the user id with a stored owner-id variable; a workspace-owner or tag gate is opened with assume.actors, never with seed_var), {\"do\":\"as_contact\",\"id\":\"user_b\"} (every later step acts as a SECOND person — for anything two people do together: one builds or sends, the other sees it; after the switch that person sees what the bot sent them earlier and can tap its buttons, and cannot tap a button on another person's screen), {\"do\":\"expect_peer_message\",\"to\":\"user_b\",\"contains\":\"...\",\"mediaType\":\"IMAGE\"} (mediaType is optional; assert proof photos/files on the same peer message), {\"do\":\"expect_http_request\",\"urlContains\":\"/orders\",\"method\":\"POST\",\"bodyContains\":\"orderId\",\"count\":1} (assert the outgoing request; method, bodyContains and count are optional). A scenario with no expect / expect_var / expect_peer_message step asserts nothing. At most 15 steps; malformed or truncated steps make the scenario an invalid test, never a pass."