- addons
Create a Modern Condition Addon
An action passes or fails. A condition instead answers a yes or no question that drives control flow: which branch an IF step takes, or whether a WHILE loop runs again.
Prerequisites
- A Modern addon exists and its scaffold is downloaded.
- You have read Create an action addon.
Declare the Condition
Set stepActionType on an ordinary action declaration.
| stepActionType | Where it appears |
|---|---|
| "IF_CONDITION" | The condition picker of an IF step |
| "WHILE_LOOP" | The condition picker of a WHILE step |
A condition addon is hidden from the ordinary action list and shows up only in the matching picker.
export const countAbove = defineAddonTemplate({
name: "cond.countAbove",
description: "Loop while the count of matched elements exceeds a threshold",
actionText: "While count of ${target} is greater than ${threshold}",
applicationType: ["WEB", "MOBILE_WEB"],
stepActionType: "WHILE_LOOP",
testData: z.object({ threshold: z.string().describe("Count to compare against") }),
elements: { target: { description: "Element whose match count drives the loop" } },
outputs: { count: { type: "runtimeVar", description: "Match count at the last evaluation" } },
async execute({ testData, elements }, ctx) {
if (ctx.ui.kind !== "web") throw new Error("requires a web platform");
const count = await ctx.ui.browser.locate(elements.target).count();
return {
message: {
success: `Count of '${elements.target.name}' is ${count}`,
failure: `Count is ${count} — not above ${testData.threshold}`,
},
outputs: { count },
conditionMet: count > Number(testData.threshold),
};
},
});Return a Verdict
When stepActionType is set, execute() must return a boolean conditionMet. The worker rejects the result otherwise.
Returning false is not an error. It reads as "condition not met", so the loop exits or the IF takes its other branch, and the step is not a failure.
Reserve throw for something genuinely going wrong, such as a malformed threshold or an element that could not be queried. A thrown error records its message on the condition step and produces the same control-flow outcome as a built-in condition step.
Read Outputs After a Loop
Declared outputs are written on every evaluation, including the final one that ends a loop. A runtime variable bound to count therefore holds the value that stopped the loop.
Use conditionMet in Ordinary Actions
conditionMet also works on actions that declare no stepActionType. There it is an explicit pass or fail verdict, and false fails the step with message.failure.
