chrome-devtools-frontend
Version:
Chrome DevTools UI
559 lines (530 loc) • 22.3 kB
TypeScript
import { Browser, Page } from 'puppeteer';
import * as lighthouse from 'lighthouse';
type ExcludeType<T, U> = {
[K in keyof T]-?: T[K] extends U ? K : never;
}[keyof T];
type PickType<T, U> = Pick<T, ExcludeType<T, U>>;
type JSONValue = null | string | number | boolean | JSONObject | JSONArray;
interface JSONObject {
[key: string]: JSONValue;
}
type JSONArray = JSONValue[];
type JSONSerializable<Object extends object> = PickType<Object, JSONValue>;
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
type Target = string;
type Pattern = string;
type Selector = string | string[];
type FrameSelector = number[];
declare enum SelectorType {
CSS = "css",
ARIA = "aria",
Text = "text",
XPath = "xpath",
Pierce = "pierce"
}
declare enum StepType {
Change = "change",
Click = "click",
Close = "close",
CustomStep = "customStep",
DoubleClick = "doubleClick",
EmulateNetworkConditions = "emulateNetworkConditions",
Hover = "hover",
KeyDown = "keyDown",
KeyUp = "keyUp",
Navigate = "navigate",
Scroll = "scroll",
SetViewport = "setViewport",
WaitForElement = "waitForElement",
WaitForExpression = "waitForExpression"
}
declare enum AssertedEventType {
Navigation = "navigation"
}
interface NavigationEvent {
type: AssertedEventType.Navigation;
url?: Pattern;
title?: Pattern;
}
type AssertedEvent = NavigationEvent;
interface BaseStep {
type: StepType;
timeout?: number;
assertedEvents?: AssertedEvent[];
}
interface StepWithTarget extends BaseStep {
/**
* Defaults to main
*/
target?: Target;
}
interface StepWithFrame extends StepWithTarget {
/**
* Defaults to main frame
*/
frame?: FrameSelector;
}
interface StepWithSelectors extends StepWithFrame {
/**
* A list of alternative selectors that lead to selection of a single element
* to perform the step on. Currently, we support CSS selectors, ARIA selectors
* (start with 'aria/'), XPath selectors (start with `xpath/`) and text
* selectors (start with `text/`). Each selector could be a string or an array
* of strings. If it's a string, it means that the selector points directly to
* the target element. If it's an array, the last element is the selector for
* the target element and the preceding selectors point to the ancestor
* elements. If the parent element is a shadow root host, the subsequent
* selector is evaluated only against the shadow DOM of the host (i.e.,
* `parent.shadowRoot.querySelector`). If the parent element is not a shadow
* root host, the subsequent selector is evaluated in the regular DOM (i.e.,
* `parent.querySelector`).
*
* During the execution, it's recommended that the implementation tries out
* all of the alternative selectors to improve reliability of the replay as
* some selectors might get outdated over time.
*/
selectors: Selector[];
}
type PointerDeviceType = 'mouse' | 'pen' | 'touch';
type PointerButtonType = 'primary' | 'auxiliary' | 'secondary' | 'back' | 'forward';
interface ClickAttributes {
/**
* Pointer type for the event. Defaults to 'mouse'.
*/
deviceType?: PointerDeviceType;
/**
* Defaults to 'primary' if the device type is a mouse.
*/
button?: PointerButtonType;
/**
* in px, relative to the top-left corner of the element content box. Defaults
* to the center of the element
*/
offsetX: number;
/**
* in px, relative to the top-left corner of the element content box. Defaults
* to the center of the element
*/
offsetY: number;
/**
* Delay (in ms) between the mouse up and mouse down of the click.
*
* @defaultValue `50`
*/
duration?: number;
}
interface DoubleClickStep extends ClickAttributes, StepWithSelectors {
type: StepType.DoubleClick;
}
interface ClickStep extends ClickAttributes, StepWithSelectors {
type: StepType.Click;
}
interface HoverStep extends StepWithSelectors {
type: StepType.Hover;
}
interface ChangeStep extends StepWithSelectors {
type: StepType.Change;
value: string;
}
interface EmulateNetworkConditionsStep extends StepWithTarget {
type: StepType.EmulateNetworkConditions;
download: number;
upload: number;
latency: number;
}
interface KeyDownStep extends StepWithTarget {
type: StepType.KeyDown;
key: Key;
}
interface KeyUpStep extends StepWithTarget {
type: StepType.KeyUp;
key: Key;
}
interface CloseStep extends StepWithTarget {
type: StepType.Close;
}
interface SetViewportStep extends StepWithTarget {
type: StepType.SetViewport;
width: number;
height: number;
deviceScaleFactor: number;
isMobile: boolean;
hasTouch: boolean;
isLandscape: boolean;
}
interface ScrollPageStep extends StepWithFrame {
type: StepType.Scroll;
/**
* Absolute scroll x position in px. Defaults to 0
*/
x?: number;
/**
* Absolute scroll y position in px. Defaults to 0
*/
y?: number;
}
type ScrollElementStep = ScrollPageStep & StepWithSelectors;
type ScrollStep = ScrollPageStep | ScrollElementStep;
interface NavigateStep extends StepWithTarget {
type: StepType.Navigate;
url: string;
}
interface CustomStepParams {
type: StepType.CustomStep;
name: string;
parameters: unknown;
}
type CustomStep = (CustomStepParams & StepWithTarget) | (CustomStepParams & StepWithFrame);
type UserStep = ChangeStep | ClickStep | HoverStep | CloseStep | CustomStep | DoubleClickStep | EmulateNetworkConditionsStep | KeyDownStep | KeyUpStep | NavigateStep | ScrollStep | SetViewportStep;
/**
* `waitForElement` allows waiting for the presence (or absence) of the number
* of elements identified by the selector.
*
* For example, the following step would wait for less than three elements
* to be on the page that match the selector `.my-class`.
*
* ```
* {
* "type": "waitForElement",
* "selectors": [".my-class"],
* "operator": "<=",
* "count": 2,
* }
* ```
*/
interface WaitForElementStep extends StepWithSelectors {
type: StepType.WaitForElement;
/**
* @defaultValue `'=='`
*/
operator?: '>=' | '==' | '<=';
/**
* @defaultValue `1`
*/
count?: number;
/**
* Whether to wait for elements matching this step to be hidden. This can be
* thought of as an inversion of this step.
*
* @defaultValue `true`
*/
visible?: boolean;
/**
* Whether to also check the element(s) for the given properties.
*/
properties?: Partial<JSONSerializable<HTMLElement>> & {
[key: string]: JSONValue;
};
/**
* Whether to also check the element(s) for the given attributes.
*/
attributes?: {
[name: string]: string;
};
}
/**
* `waitForExpression` allows for a JavaScript expression to resolve to truthy
* value.
*
* For example, the following step pauses for two seconds and then resolves to
* true allowing the replay to continue.
*
* ```
* {
* "type": "waitForExpression",
* "expression": "new Promise(resolve => setTimeout(() => resolve(true),
* 2000))",
* }
* ```
*/
interface WaitForExpressionStep extends StepWithFrame {
type: StepType.WaitForExpression;
expression: string;
}
type AssertionStep = WaitForElementStep | WaitForExpressionStep;
type Step = UserStep | AssertionStep;
interface UserFlow {
/**
* Human-readble title describing the recorder user flow.
*/
title: string;
/**
* Timeout in milliseconds.
*/
timeout?: number;
/**
* The name of the attribute to use to generate selectors instead of regular
* CSS selectors. For example, specifying `data-testid` would generate the
* selector `[data-testid=value]` for the element `<div data-testid=value>`.
*/
selectorAttribute?: string;
steps: Step[];
}
type Key = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'Power' | 'Eject' | 'Abort' | 'Help' | 'Backspace' | 'Tab' | 'Numpad5' | 'NumpadEnter' | 'Enter' | '\r' | '\n' | 'ShiftLeft' | 'ShiftRight' | 'ControlLeft' | 'ControlRight' | 'AltLeft' | 'AltRight' | 'Pause' | 'CapsLock' | 'Escape' | 'Convert' | 'NonConvert' | 'Space' | 'Numpad9' | 'PageUp' | 'Numpad3' | 'PageDown' | 'End' | 'Numpad1' | 'Home' | 'Numpad7' | 'ArrowLeft' | 'Numpad4' | 'Numpad8' | 'ArrowUp' | 'ArrowRight' | 'Numpad6' | 'Numpad2' | 'ArrowDown' | 'Select' | 'Open' | 'PrintScreen' | 'Insert' | 'Numpad0' | 'Delete' | 'NumpadDecimal' | 'Digit0' | 'Digit1' | 'Digit2' | 'Digit3' | 'Digit4' | 'Digit5' | 'Digit6' | 'Digit7' | 'Digit8' | 'Digit9' | 'KeyA' | 'KeyB' | 'KeyC' | 'KeyD' | 'KeyE' | 'KeyF' | 'KeyG' | 'KeyH' | 'KeyI' | 'KeyJ' | 'KeyK' | 'KeyL' | 'KeyM' | 'KeyN' | 'KeyO' | 'KeyP' | 'KeyQ' | 'KeyR' | 'KeyS' | 'KeyT' | 'KeyU' | 'KeyV' | 'KeyW' | 'KeyX' | 'KeyY' | 'KeyZ' | 'MetaLeft' | 'MetaRight' | 'ContextMenu' | 'NumpadMultiply' | 'NumpadAdd' | 'NumpadSubtract' | 'NumpadDivide' | 'F1' | 'F2' | 'F3' | 'F4' | 'F5' | 'F6' | 'F7' | 'F8' | 'F9' | 'F10' | 'F11' | 'F12' | 'F13' | 'F14' | 'F15' | 'F16' | 'F17' | 'F18' | 'F19' | 'F20' | 'F21' | 'F22' | 'F23' | 'F24' | 'NumLock' | 'ScrollLock' | 'AudioVolumeMute' | 'AudioVolumeDown' | 'AudioVolumeUp' | 'MediaTrackNext' | 'MediaTrackPrevious' | 'MediaStop' | 'MediaPlayPause' | 'Semicolon' | 'Equal' | 'NumpadEqual' | 'Comma' | 'Minus' | 'Period' | 'Slash' | 'Backquote' | 'BracketLeft' | 'Backslash' | 'BracketRight' | 'Quote' | 'AltGraph' | 'Props' | 'Cancel' | 'Clear' | 'Shift' | 'Control' | 'Alt' | 'Accept' | 'ModeChange' | ' ' | 'Print' | 'Execute' | '\u0000' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'Meta' | '*' | '+' | '-' | '/' | ';' | '=' | ',' | '.' | '`' | '[' | '\\' | ']' | "'" | 'Attn' | 'CrSel' | 'ExSel' | 'EraseEof' | 'Play' | 'ZoomOut' | ')' | '!' | '@' | '#' | '$' | '%' | '^' | '&' | '(' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | ':' | '<' | '_' | '>' | '?' | '~' | '{' | '|' | '}' | '"' | 'SoftLeft' | 'SoftRight' | 'Camera' | 'Call' | 'EndCall' | 'VolumeDown' | 'VolumeUp';
type Schema_AssertedEvent = AssertedEvent;
type Schema_AssertedEventType = AssertedEventType;
declare const Schema_AssertedEventType: typeof AssertedEventType;
type Schema_AssertionStep = AssertionStep;
type Schema_BaseStep = BaseStep;
type Schema_ChangeStep = ChangeStep;
type Schema_ClickAttributes = ClickAttributes;
type Schema_ClickStep = ClickStep;
type Schema_CloseStep = CloseStep;
type Schema_CustomStep = CustomStep;
type Schema_CustomStepParams = CustomStepParams;
type Schema_DoubleClickStep = DoubleClickStep;
type Schema_EmulateNetworkConditionsStep = EmulateNetworkConditionsStep;
type Schema_FrameSelector = FrameSelector;
type Schema_HoverStep = HoverStep;
type Schema_Key = Key;
type Schema_KeyDownStep = KeyDownStep;
type Schema_KeyUpStep = KeyUpStep;
type Schema_NavigateStep = NavigateStep;
type Schema_NavigationEvent = NavigationEvent;
type Schema_Pattern = Pattern;
type Schema_PointerButtonType = PointerButtonType;
type Schema_PointerDeviceType = PointerDeviceType;
type Schema_ScrollElementStep = ScrollElementStep;
type Schema_ScrollPageStep = ScrollPageStep;
type Schema_ScrollStep = ScrollStep;
type Schema_Selector = Selector;
type Schema_SelectorType = SelectorType;
declare const Schema_SelectorType: typeof SelectorType;
type Schema_SetViewportStep = SetViewportStep;
type Schema_Step = Step;
type Schema_StepType = StepType;
declare const Schema_StepType: typeof StepType;
type Schema_StepWithFrame = StepWithFrame;
type Schema_StepWithSelectors = StepWithSelectors;
type Schema_StepWithTarget = StepWithTarget;
type Schema_Target = Target;
type Schema_UserFlow = UserFlow;
type Schema_UserStep = UserStep;
type Schema_WaitForElementStep = WaitForElementStep;
type Schema_WaitForExpressionStep = WaitForExpressionStep;
declare namespace Schema {
export { Schema_AssertedEventType as AssertedEventType, Schema_SelectorType as SelectorType, Schema_StepType as StepType };
export type { Schema_AssertedEvent as AssertedEvent, Schema_AssertionStep as AssertionStep, Schema_BaseStep as BaseStep, Schema_ChangeStep as ChangeStep, Schema_ClickAttributes as ClickAttributes, Schema_ClickStep as ClickStep, Schema_CloseStep as CloseStep, Schema_CustomStep as CustomStep, Schema_CustomStepParams as CustomStepParams, Schema_DoubleClickStep as DoubleClickStep, Schema_EmulateNetworkConditionsStep as EmulateNetworkConditionsStep, Schema_FrameSelector as FrameSelector, Schema_HoverStep as HoverStep, Schema_Key as Key, Schema_KeyDownStep as KeyDownStep, Schema_KeyUpStep as KeyUpStep, Schema_NavigateStep as NavigateStep, Schema_NavigationEvent as NavigationEvent, Schema_Pattern as Pattern, Schema_PointerButtonType as PointerButtonType, Schema_PointerDeviceType as PointerDeviceType, Schema_ScrollElementStep as ScrollElementStep, Schema_ScrollPageStep as ScrollPageStep, Schema_ScrollStep as ScrollStep, Schema_Selector as Selector, Schema_SetViewportStep as SetViewportStep, Schema_Step as Step, Schema_StepWithFrame as StepWithFrame, Schema_StepWithSelectors as StepWithSelectors, Schema_StepWithTarget as StepWithTarget, Schema_Target as Target, Schema_UserFlow as UserFlow, Schema_UserStep as UserStep, Schema_WaitForElementStep as WaitForElementStep, Schema_WaitForExpressionStep as WaitForExpressionStep };
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
declare function assertAllStepTypesAreHandled(s: never): never;
declare const typeableInputTypes: ReadonlySet<string>;
declare const pointerDeviceTypes: ReadonlySet<string>;
declare const mouseButtonMap: ReadonlyMap<string, 'left' | 'middle' | 'right' | 'back' | 'forward'>;
declare function parseStep(step: unknown, idx?: number): Step;
declare const minTimeout = 1;
declare const maxTimeout = 30000;
declare function validTimeout(timeout: number): boolean;
declare function parse(data: unknown): UserFlow;
/**
* Detects what type of a selector the string contains. For example,
* `aria/Label` is a SelectorType.ARIA.
*
* Note that CSS selectors are special and usually don't require a prefix,
* therefore, SelectorType.CSS is the default type if other types didn't match.
*/
declare function getSelectorType(selector: string): SelectorType;
/**
* Converts a selector or an array of selector parts into a Puppeteer selector.
*
* @see https://pptr.dev/guides/query-selectors#p-elements
*/
declare function selectorToPElementSelector(selector: string[] | string): string;
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
interface LineWriter {
appendLine(line: string): LineWriter;
startBlock(): LineWriter;
endBlock(): LineWriter;
getIndent(): string;
getSize(): number;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
declare class StringifyExtension {
beforeAllSteps?(out: LineWriter, flow: UserFlow): Promise<void>;
afterAllSteps?(out: LineWriter, flow: UserFlow): Promise<void>;
beforeEachStep?(out: LineWriter, step: Step, flow?: UserFlow): Promise<void>;
stringifyStep(out: LineWriter, step: Step, flow?: UserFlow): Promise<void>;
afterEachStep?(out: LineWriter, step: Step, flow?: UserFlow): Promise<void>;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Stringifies a user flow to JSON with source maps.
*
* You probably want to strip the source map because not all
* parsers support comments in JSON.
*/
declare class JSONStringifyExtension extends StringifyExtension {
beforeAllSteps(out: LineWriter, flow: UserFlow): Promise<void>;
afterAllSteps(out: LineWriter): Promise<void>;
stringifyStep(out: LineWriter, step: Step, flow?: UserFlow): Promise<void>;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
interface StringifyOptions {
extension?: StringifyExtension;
writer?: LineWriter;
indentation?: string;
}
/**
* The format is [version, [lineNo, length], [lineNo, length] ... [lineNo, length]].
*/
type SourceMap = Array<number>;
/**
* Stringifes an entire recording. The following hooks are invoked with the `flow` parameter containing the entire flow:
* - `beforeAllSteps` (once)
* - `beforeEachStep` (per step)
* - `stringifyStep` (per step)
* - `afterEachStep` (per step)
* - `afterAllSteps` (once)
*/
declare function stringify(flow: UserFlow, opts?: StringifyOptions): Promise<string>;
/**
* Stringifes a single step. Only the following hooks are invoked with the `flow` parameter as undefined:
* - `beforeEachStep`
* - `stringifyStep`
* - `afterEachStep`
*/
declare function stringifyStep(step: Step, opts?: StringifyOptions): Promise<string>;
/**
* Extracts a source map from a text.
*/
declare function parseSourceMap(text: string): SourceMap | undefined;
declare function stripSourceMap(text: string): string;
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
declare class RunnerExtension {
beforeAllSteps?(flow?: UserFlow): Promise<void>;
afterAllSteps?(flow?: UserFlow): Promise<void>;
beforeEachStep?(step: Step, flow?: UserFlow): Promise<void>;
runStep(step: Step, flow?: UserFlow): Promise<void>;
afterEachStep?(step: Step, flow?: UserFlow): Promise<void>;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
declare class Runner {
#private;
abort(): void;
set flow(flow: UserFlow);
runBeforeAllSteps(flow?: UserFlow): Promise<void>;
runAfterAllSteps(flow?: UserFlow): Promise<void>;
/**
* Runs the provided `step` with `beforeEachStep` and `afterEachStep` hooks.
* Parameters from the `flow` apply if the `flow` is set.
*/
runStep(step: Step): Promise<void>;
/**
* Run all the steps in the flow
* @returns whether all the steps are run or the execution is aborted
*/
run(): Promise<boolean>;
}
declare function createRunner(): Promise<Runner>;
declare function createRunner(flow: UserFlow): Promise<Runner>;
declare function createRunner(extension: RunnerExtension): Promise<Runner>;
declare function createRunner(flow: UserFlow, extension: RunnerExtension): Promise<Runner>;
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
declare class PuppeteerRunnerExtension extends RunnerExtension {
#private;
protected browser: Browser;
protected page: Page;
protected timeout: number;
constructor(browser: Browser, page: Page, opts?: {
timeout?: number;
});
runStep(step: Step, flow?: UserFlow): Promise<void>;
}
declare class PuppeteerRunnerOwningBrowserExtension extends PuppeteerRunnerExtension {
afterAllSteps(): Promise<void>;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
type TargetBrowser = 'chrome' | 'firefox';
declare class PuppeteerStringifyExtension extends StringifyExtension {
#private;
constructor(targetBrowser?: TargetBrowser);
beforeAllSteps(out: LineWriter, flow: UserFlow): Promise<void>;
afterAllSteps(out: LineWriter, flow: UserFlow): Promise<void>;
stringifyStep(out: LineWriter, step: Step, flow: UserFlow): Promise<void>;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Stringifies a user flow to a script that uses \@puppeteer/replay's own API.
*/
declare class PuppeteerReplayStringifyExtension extends StringifyExtension {
beforeAllSteps(out: LineWriter): Promise<void>;
afterAllSteps(out: LineWriter): Promise<void>;
stringifyStep(out: LineWriter, step: Step): Promise<void>;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
declare class LighthouseStringifyExtension extends PuppeteerStringifyExtension {
#private;
beforeAllSteps(out: LineWriter, flow: UserFlow): Promise<void>;
stringifyStep(out: LineWriter, step: Step, flow: UserFlow): Promise<void>;
afterAllSteps(out: LineWriter, flow: UserFlow): Promise<void>;
}
declare class LighthouseRunnerExtension extends PuppeteerRunnerExtension {
#private;
createFlowResult(): Promise<lighthouse.FlowResult>;
beforeAllSteps(flow: UserFlow): Promise<void>;
beforeEachStep(step: Step, flow?: UserFlow): Promise<void>;
afterEachStep(step: Step, flow?: UserFlow): Promise<void>;
afterAllSteps(flow: UserFlow): Promise<void>;
}
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Copyright (c) 2020 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
declare function formatJSONAsJS(json: unknown, indent: string): string;
declare const formatAsJSLiteral: (content: string) => string;
export { AssertedEventType, JSONStringifyExtension, LighthouseRunnerExtension, LighthouseStringifyExtension, PuppeteerReplayStringifyExtension, PuppeteerRunnerExtension, PuppeteerRunnerOwningBrowserExtension, PuppeteerStringifyExtension, Runner, RunnerExtension, Schema, SelectorType, StepType, StringifyExtension, assertAllStepTypesAreHandled, createRunner, formatAsJSLiteral, formatJSONAsJS, getSelectorType, maxTimeout, minTimeout, mouseButtonMap, parse, parseSourceMap, parseStep, pointerDeviceTypes, selectorToPElementSelector, stringify, stringifyStep, stripSourceMap, typeableInputTypes, validTimeout };
export type { AssertedEvent, AssertionStep, BaseStep, ChangeStep, ClickAttributes, ClickStep, CloseStep, CustomStep, CustomStepParams, DoubleClickStep, EmulateNetworkConditionsStep, FrameSelector, HoverStep, Key, KeyDownStep, KeyUpStep, LineWriter, NavigateStep, NavigationEvent, Pattern, PointerButtonType, PointerDeviceType, ScrollElementStep, ScrollPageStep, ScrollStep, Selector, SetViewportStep, SourceMap, Step, StepWithFrame, StepWithSelectors, StepWithTarget, StringifyOptions, Target, UserFlow, UserStep, WaitForElementStep, WaitForExpressionStep };