Documentation Index
Fetch the complete documentation index at: https://docs.qawolf.com/llms.txt
Use this file to discover all available pages before exploring further.
@qawolf/flows/web defines web flows and optional explicit launch behavior.
Primary Exports
flow(...)
launch(...)
expect
isAnonymous(...)
isPersistent(...)
isElectron(...)
testContextDependencies
It also exports web-specific target, launch, callback context, and flow definition types.
Example:
import { expect, flow } from "@qawolf/flows/web";
export default flow(
"Open homepage",
{ target: "Web - Chrome", launch: true },
async ({ page, test }) => {
await test("open homepage", async () => {
await page.goto("https://example.com");
await expect(page).toBeDefined();
});
},
);
Target Model
Web flows accept web targets only. Use the CLI entry point for Basic.
type WebFlowTargetInput =
| WebFlowTarget
| {
target: WebFlowTarget;
launch?: false | undefined;
}
| {
target: WebBrowserFlowTarget;
launch: true | BrowserLaunchOptions;
}
| {
target: WebElectronFlowTarget;
launch: ElectronFlowLaunchOptions;
};
Examples:
import { flow, isElectron, isPersistent, launch } from "@qawolf/flows/web";
export const explicitLaunchFlow = flow("Open later", "Web - Chrome", async () => {
const launchResult = await launch();
if (isElectron(launchResult)) throw new Error("Expected browser launch");
const page =
isPersistent(launchResult)
? launchResult.page
: await launchResult.context.newPage();
await page.goto("https://example.com");
});
export const launchedFlow = flow(
"Open immediately",
{ target: "Web - Chrome", launch: true },
async ({ page, test }) => {
await test("open page", async () => {
await page.goto("https://example.com");
});
},
);
Launch Shapes
Browser launch accepts the generated Playwright browser and context launch options, excluding Playwright’s raw persistentContext and userDataDir fields. QA Wolf adds browserContext, reintroduces userDataDir for persistent launches, and maps those options back to the underlying Playwright shape.
type BrowserLaunchOptions = {
kind?: "browser";
browser?: "chrome" | "chromium" | "firefox" | "msedge" | "webkit";
browserContext?: "incognito" | "persistent";
userDataDir?: string;
// Generated Playwright browser and context options are also accepted,
// except for Playwright's raw persistentContext and userDataDir fields.
headless?: boolean;
permissions?: string[];
geolocation?: {
latitude: number;
longitude: number;
accuracy?: number;
};
polyfills?: {
intlListFormat?: boolean;
};
// ...plus other generated browser/context options.
};
type LaunchOptions =
| BrowserLaunchOptions
| {
kind: "electron";
executablePath: string;
};
type ElectronFlowLaunchOptions = {
executablePath: string;
};
type LaunchResult =
| AnonymousLaunchResult
| PersistentLaunchResult
| ElectronLaunchResult;
QA Wolf maps browserContext: "persistent" to Playwright’s persistent context mode. Pass userDataDir with browserContext: "persistent" when a profile directory should be reused.
Browser example:
import { flow, launch } from "@qawolf/flows/web";
export default flow(
"Open with persistent profile",
"Web - Chrome",
async () => {
const { page } = await launch({
browserContext: "persistent",
userDataDir: "/tmp/qawolf-profile",
});
await page.goto("https://example.com");
},
);
Electron declarative launch example:
import { flow } from "@qawolf/flows/web";
export default flow(
"Open Electron app",
{
target: "Electron",
launch: {
executablePath: "/Applications/MyApp.app/Contents/MacOS/MyApp",
},
},
async ({ page, test }) => {
await test("open app", async () => {
await page.goto("about:blank");
});
},
);
Explicit launch(...) calls are not target-typed. Include kind: "electron" and use firstWindowPage from the result:
import { flow, launch } from "@qawolf/flows/web";
export default flow("Open Electron app", "Web - Chrome", async () => {
const { firstWindowPage } = await launch({
kind: "electron",
executablePath: "/Applications/MyApp.app/Contents/MacOS/MyApp",
});
await firstWindowPage.getByRole("button", { name: "Sign in" }).click();
});
Static launch options infer a narrow return type when they determine the result shape:
launch({ browserContext: "persistent" }) returns PersistentLaunchResult
launch({ browserContext: "incognito" }) returns AnonymousLaunchResult
launch({ kind: "electron", executablePath }) returns ElectronLaunchResult
launch() returns the full LaunchResult union because startup depends on the active flow target
Use isAnonymous(...), isPersistent(...), and isElectron(...) to narrow dynamic results before reading shape-specific fields.
Flow Callback Context
All web flow callbacks receive:
inputs
setOutput(...)
test(...)
Launch-enabled browser flows also receive:
page
context
- optional
browser
Electron launch-enabled flows receive the first Electron window as page.
test(...) can be omitted for simple flows where grouping steps into named sub-steps doesn’t add value. For most flows, wrapping steps in test(...) is recommended — the label appears in your results and makes failures easier to locate.
testContextDependencies
testContextDependencies is exported for runner and tooling integration. Flow authors should usually use the public callback parameters above instead of depending on the raw runner dependency list.
Defaults
- default
kind is browser launch
- default
browserContext is "incognito"
- default
browser comes from the flow target
- GPU launch behavior is derived from the flow target
- Electron declarative launch requires
target: "Electron" and executablePath
Example:
import { flow, isElectron, isPersistent, launch } from "@qawolf/flows/web";
export default flow(
"Use target browser defaults",
"Web - Firefox",
async () => {
const launchResult = await launch();
if (isElectron(launchResult))
throw new Error("Expected browser launch");
const page =
isPersistent(launchResult)
? launchResult.page
: await launchResult.context.newPage();
await page.goto("https://example.com");
},
);