Common Control Methods

The following sections introduce the basic operation and property methods shared by every control (except virtual controls). These methods are applicable regardless of the specific type of the control. Some methods simulate user operations, while others complete operations based on the underlying Accessibility API.

API Overview

Action Methods

Method Name Description
click Simulates a mouse click on the control, with optional position and mouse button.
dblClick Simulates a mouse double-click on the control, with optional position and mouse button.
moveMouse Moves the mouse to a specified position on the control, with optional speed.
wheel Scrolls the mouse wheel.
exists Checks if the control exists, with an optional timeout.
hScroll Scrolls horizontally on the control.
vScroll Scrolls vertically on the control.
pressKeys Inputs key combinations or strings.
property Gets a specified property of the control.
waitProperty Waits for a specified property of the control to reach a certain value.
checkImage Verifies if the control's image matches the expected reference image.
checkProperty Verifies if a property of the control matches the expected value.
drag Simulates the first step of a drag operation: mouse press.
drop Simulates the second step of a drag operation: mouse release.
highlight Highlights the control for debugging and verification.
takeScreenshot Takes a screenshot of the control, with an optional file path.
doDefaultAction Executes the default action of the control.
scrollIntoView Scrolls the control into the visible area.
modelImage Gets the screenshot snapshot of the control cached in the model.
modelProperties Gets the properties of the control cached in the model.

Property Methods

Method Name Description
type Gets the type of the control.
text Gets the text content of the control.
rawText Gets the internal text information of the control.
name Gets the name of the control.
hwnd Gets the window handle of the control.
height Gets the height of the control.
width Gets the width of the control.
enabled Checks if the control is enabled.
focused Checks if the control is focused/selected.
visible Checks if the control is visible and not finding.
helpText Gets the help text of the control.
value Gets the value of the control.
processId Gets the process ID of the application the control belongs to.
rect Gets the position and size of the control.
allProperties Gets all runtime properties of the target control.
Method Name Description
firstChild Gets the first child control.
lastChild Gets the last child control.
next Gets the next sibling control.
previous Gets the previous sibling control.
parent Gets the parent control.
all Gets all matching sibling controls.
findControls Finds controls based on conditions.

Type Definitions

These methods are defined on the base class of controls. You can view the definition in the leanpro.win library as follows:

JavaScript
Python
export interface IWinControl extends IWinContainer {
  //methods
  click(x?: number, y?: number, mousekey?: MouseKey): Promise<void>;
  dblClick(x?: number, y?: number, mousekey?: MouseKey): Promise<void>;
  moveMouse(x?: number, y?: number, seconds?: number): Promise<void>
  wheel(value: number): Promise<void>;
  exists(time?: number): Promise<boolean>;
  hScroll(value: number | ScrollAmount): Promise<void>;
  vScroll(value: number | ScrollAmount): Promise<void>;
  property(propertyIds: PropertyIds | string): Promise<string | boolean | number | Rect>;
  checkImage(options?: CheckImageCompareOptions | string): Promise<void>;
  checkProperty(propertyName: string, expectedValue: string | number | boolean | RegExp, message: string): Promise<void>;
  checkProperty(propertyName: string, expectedValue: string | number | boolean | RegExp, options: {message: string, operation: any}): Promise<void>;
  waitProperty(propertyIds: PropertyIds, value: string, timeoutSeconds?: number/* default value 5 seconds */): Promise<boolean>;
  drop(x?: number, y?: number, seconds?: number): Promise<void>;
  drag(x?: number, y?: number): Promise<void>;
  pressKeys(keys: string, opt?: PressKeysOptions | number): Promise<void>;
  takeScreenshot(filePath?: string): Promise<void | string>;
  highlight(duration?: number);

  //properties
  type(): Promise<string>;
  text(): Promise<string>;
  name(): Promise<string>;
  hwnd(): Promise<number>;
  x(): Promise<number>;
  y(): Promise<number>;
  height(): Promise<number>;
  width(): Promise<number>;
  enabled(): Promise<boolean>;
  focused(): Promise<boolean>;
  helpText(): Promise<string>;
  labeledText(): Promise<string>;
  value(): Promise<string | number>;
  processId(): Promise<number>;
  rect(): Promise<Rect>;
  visible(): Promise<boolean>;
  
  //navigation methods
  firstChild(controlType?: ControlType): Promise<IWinControl>;
  lastChild(controlType?: ControlType): Promise<IWinControl>;
  next(controlType?: ControlType): Promise<IWinControl>;
  previous(controlType?: ControlType): Promise<IWinControl>;
  parent(): Promise<IWinControl>;
  all(): Promise<IWinControl[]>;
  findControls(...conditions: ConditionFilter[]): Promise<IWinControl[]>; //used to be getControls
  
  modelImage(options?: {encoding: 'buffer' | 'base64'}): Promise<string | Buffer>;  //base64 is the default
  modelProperties(all?: boolean): {[x: string]: any};
  allProperties(): Promise<object>;
  doDefaultAction(): Promise<void>;
  rawText(): Promise<string>;
  scrollIntoView(): Promise<void>;
}
class WinControl(WinContainer):
  def click(x: Optional[int]=None, y: Optional[int]=None, mousekey: Optional[int]=None) -> None
  def dblClick(x: Optional[int]=None, y: Optional[int]=None, mousekey: Optional[int]=None) -> None
  def moveMouse(x: Optional[int]=None, y: Optional[int]=None, seconds: Optional[int]=None) -> None
  def wheel(value: int) -> None
  def exists(time: Optional[int]=None) -> bool
  def hScroll(value: int) -> None
  def vScroll(value: int) -> None
  def property(propertyds: str) -> Union[str, int, bool, Rect]
  def waitProperty(propertyds: str, value: str, timeoutSeconds: Optional[int]=None) -> bool
  def checkProperty(propertyName: str, expectedValue: Union[str, int, bool], optionsOrMessage: Optional[Union[str, TypedDict]]=None) -> None
  def checkImage(options: Optional[any]=None) -> None
  def drop(x: Optional[int]=None, y: Optional[int]=None) -> None
  def drag(x: Optional[int]=None, y: Optional[int]=None) -> None
  def pressKeys(keys: str, opt: Optional[Union[int, PressKeysOptions]]=None) -> None
  def takeScreenshot(filePath: Optional[str]=None) -> Union[str, None]
  def highlight(duration: Optional[int]=None) -> None
  def type() -> str
  def text() -> str
  def name() -> str
  def hwnd() -> int
  def x() -> int
  def y() -> int
  def height() -> int
  def width() -> int
  def enabled() -> bool
  def focused() -> bool
  def visible() -> bool
  def helpText() -> str
  def labeledText() -> str
  def value() -> Union[str, int]
  def processId() -> int
  def rect() -> "Rect"
  def firstChild(controlType: Optional[str]=None) -> "WinControl"
  def lastChild(controlType: Optional[str]=None) -> "WinControl"
  def next(controlType: Optional[str]=None) -> "WinControl"
  def previous(controlType: Optional[str]=None) -> "WinControl"
  def parent() -> "WinControl"
  def findControls(*conditions: List[Union[str, Dict]]) -> List[WinControl]
  def modelmage(encoding: Optional[str]=None) -> Union[str, bytearray]
  def modelProperties(all: Optional[bool]=None) -> TypedDict
  def all() -> List[WinControl]
  def allProperties() -> TypedDict
  def doDefaultAction() -> None
  def rawText() -> str
  def scrollIntoView() -> None

The following are some type definitions that may be used when calling shared APIs.

Control Property Enum: PropertyIds

JavaScript
export enum PropertyIds {
    automationId,
    name,
    text,
    url,
    title,
    handle,
    x,
    y,
    height,
    width,
    enabled,
    focused,
    helpText,
    value,
    labeledText,
    processId,
    rect,
    ...
}

In addition to the properties listed above, each control also maintains some unique property names. You can refer to the fields in the object returned by the allProperties() method.

Control Type Enum: ControlType

All control types recognized in CukeTest can be found in this enumeration class. It can be used to specify the control type in the findControls() method, or as the return value type of the type() method of a control.

JavaScript
enum ControlType {
    Button,
    Calendar,
    CheckBox,
    ComboBox,
    Custom,
    DataGrid,
    DataItem,
    Document,
    Edit,
    Group,
    Generic,
    Header,
    HeaderItem,
    Hyperlink,
    Image,
    List,
    ListItem,
    MenuItem,
    MenuBar,
    Menu,
    Pane,
    RadioButton,
    ScrollBar,
    Slider,
    Spinner,
    Tab,
    TabItem,
    Table,
    Text,
    Thumb,
    ToolBar,
    Tree,
    TreeItem,
    Window,

    //virtual types
    TableRow,
    TreeCell,
}

Control Criteria Class Criteria

CukeTest uses Criteria objects as conditions to filter controls in the current environment to retrieve and operate on target controls. See Criteria Class.

Process Spawn Options Class SpawnOptions

A class used to configure process startup options. Supported properties are listed below. For details, refer to child_process.spawn:

  • cwd: string or URL type. Working directory for the child process. Default is the project directory, i.e., process.cwd().
  • env: Object type. Environment key-value pairs. Default: process.env.
  • argv0: string type. Explicitly sets the value of argv[0] sent to the child process. If not specified, this will be set to the command.
  • detached: boolean type. Prepares the child process to run independently of its parent process. Specific behavior depends on the platform, see options.detached.
  • uid: number type. Sets the user identity of the process (see setuid(2)).
  • gid: number type. Sets the group identity of the process (see setgid(2)).
  • serialization: string type. Specifies the type of serialization used to send messages between processes. Possible values are "json" and "advanced". See Advanced Serialization for details. Default: json.
  • shell: boolean or string type. If true, runs the command inside a shell. Uses '/bin/sh' on Unix, and process.env.ComSpec on Windows. A string can be passed to specify the path to the shell. Default: false (no shell).
  • windowsVerbatimArguments: boolean type. No quoting or escaping of arguments is done on Windows. Ignored on Unix. Automatically set to true when shell is specified and is CMD. Default: false.
  • windowsHide: boolean type. Hide the console window that would normally be created on Windows systems. Default: false.
  • timeout: number type. The maximum amount of time the process is allowed to run, in milliseconds. Default: undefined.
  • killSignal: string or int type. The signal value to be used when the spawned process will be killed by timeout or abort signal. Default: "SIGTERM".

Action Methods

click(x, y, mousekey)

Simulates a mouse click on the control. You can modify the relative click position (offset) and the mouse button used by passing parameters.

Parameters:

  • x: number type. Horizontal pixel point relative to the top-left corner of the control. 0 represents the horizontal center of the control. Default value is 0.
  • y: number type. Vertical pixel point relative to the top-left corner of the control. 0 represents the vertical center of the control. Default value is 0.
  • mouseKey: MouseKey Type. The mouse button to operate. Default is 1, which is the left mouse button.

Returns:

  • Asynchronous method that returns no value.

Example

The simplest way to call it is without passing any parameters, which clicks the exact center of the control:

JavaScript
Python
// Click the center of the button
await model.getButton("Button").click();
# Click the center of the button
model.getButton("Button").click()

If you need to click a specific coordinate position on the control, you can pass the horizontal pixel value (x) and vertical pixel value (y) relative to the top-left corner:

JavaScript
Python
// Click position 590 pixels horizontally and 10 pixels vertically from top-left corner
await model.getButton("Button").click(590, 10);
# Click position 590 pixels horizontally and 10 pixels vertically from top-left corner
model.getButton("Button").click(590, 10)

Note: click(0, 0) will not click the top-left origin of the control, but the exact center. If you expect to click the top-left corner, please use click(1, 1).

If you need to right-click the control, you need to pass the third parameter and set it to 2:

JavaScript
Python
// Right-click a specific position on the button
await model.getButton("Button").click(590, 10, 2);
# Right-click a specific position on the button
model.getButton("Button").click(590, 10, 2)

If you need to right-click the exact center of the control, you can use the following way:

JavaScript
Python
// Right-click the button center
await model.getButton("Button").click(0, 0, 2);
await model.getButton("Button").click(null, null, 2);
# Right-click the button center
model.getButton("Button").click(0, 0, 2)
model.getButton("Button").click(None, None, 2)

dblClick(x, y, mousekey)

Simulates a mouse double-click on the control. The calling method is consistent with click().

Parameters:

  • x: number type. Horizontal pixel point relative to the top-left corner of the control. Default value is 0.
  • y: number type. Vertical pixel point relative to the top-left corner of the control. Default value is 0.
  • mouseKey: MouseKey Type. The mouse button to operate. Default is 1.

Returns:

  • Asynchronous method that returns no value.

Example

Double-click the exact center of the control:

JavaScript
Python
// Double-click button center
await model.getButton("Button").dblClick();
# Double-click button center
model.getButton("Button").dblClick()

moveMouse(x, y, seconds)

Moves the mouse cursor to the specified position on the control.

Parameters:

  • x: number type. Horizontal pixel point relative to the top-left corner of the control. Default value is 0.
  • y: number type. Vertical pixel point relative to the top-left corner of the control. Default value is 0.
  • seconds: number type. Duration of mouse movement in seconds.

Returns:

  • Asynchronous method that returns no value.

Example

Move mouse to the center position of the control:

JavaScript
Python
// Move mouse to Pane control center
await model.getPane("Pane").moveMouse();
# Move mouse to Pane control center
model.getPane("Pane").moveMouse()

If you need to move the mouse to a specified position on the control and control the speed:

JavaScript
Python
// Move mouse to specified position (500, 70) in 5 seconds
await model.getPane("Pane").moveMouse(500, 70, 5);
# Move mouse to specified position (500, 70) in 5 seconds
model.getPane("Pane").moveMouse(500, 70, 5)

wheel(value)

Scrolls the mouse wheel. The unit of the input parameter is the number of notches the wheel rolls. Only scrolls one page at most. If you need to scroll multiple pages, please call in a loop.

Parameters:

  • value: number type. Wheel notches.

Returns:

  • Asynchronous method that returns no value.

Example

Scroll mouse wheel up one notch:

JavaScript
Python
// Scroll up one notch on Pane control
await model.getPane("Pane").wheel(1);
# Scroll up one notch on Pane control
model.getPane("Pane").wheel(1)

exists(time)

This method is used to determine whether a control exists. You can specify a maximum wait time. If the control is found within the specified time, it returns true; otherwise, it returns false. Default call checks only once without retry and wait.

Parameters:

  • time: number type. Maximum seconds to wait for the control to appear. If omitted, default waits 0 seconds, i.e., check only once.

Returns:

  • Asynchronously returns whether the control exists. true for exists, false for does not exist.

Example

  1. Without specifying wait time

JavaScript
Python
// Immediately check if control exists
let exists = await model.getApplication("dirview").exists();
# Immediately check if control exists
exists = model.getApplication("dirview").exists()
This code will check immediately once. If the control is found, exists is true, otherwise it is false.

  1. Specify wait time

JavaScript
Python
// Wait up to 10 seconds until control appears
let bool = await model.getApplication("dirview").exists(10);
assert.strictEqual(bool, true);
# Wait up to 10 seconds until control appears
bool = model.getApplication("dirview").exists(10)
assert bool == True
This code will wait up to 10 seconds. If the control is found within these 10 seconds, bool is true, otherwise it is false.

hScroll(value)

Performs horizontal scrolling on the control (Horizontal Scroll). Parameter is percentage of scrolling.

Parameters:

  • value: number type. Percentage of scrolling. 0 is scroll to leftmost, 100 is scroll to rightmost.

Returns:

  • Asynchronous method that returns no value.

Example

JavaScript
Python
// Scroll control horizontally to middle position (50%)
await model.getPane("Pane").hScroll(50);
# Scroll control horizontally to middle position (50%)
model.getPane("Pane").hScroll(50)

vScroll(value)

Performs vertical scrolling on the control (Vertical Scroll). Parameter is percentage of scrolling.

Parameters:

  • value: number type. Percentage of scrolling. 0 is scroll to top, 100 is scroll to bottom.

Returns:

  • Asynchronous method that returns no value.

Example

JavaScript
Python
// Scroll control vertically to bottom
await model.getPane("Pane").vScroll(100);
# Scroll control vertically to bottom
model.getPane("Pane").vScroll(100)

property(propertyIds)

Gets the specified property value of the control. You can get various properties like text, visibility, position, etc., as needed. For example, for a control, calling method .property("rect") is effectively equivalent to directly calling property method .rect(). The values returned by both operations are always the same.

Parameters:

Returns:

  • Asynchronously returns property values of various types corresponding to the property name, including string, number, boolean, Rect type, etc., depending on propertyIds.

Example

Get the text content of the control:

JavaScript
Python
// Get text property of button
let text = await model.getButton("Button").property("text");
console.log("Button text:", text);
# Get text property of button
text = model.getButton("Button").property("text")
print(f"Button text: {text}")

You can also directly use fields from allProperties() method:

JavaScript
Python
// Get custom property of control
let objectName = await model.getButton("Button").property('objectName');
# Get custom property of control
objectName = model.getButton("Button").property('objectName')

waitProperty(propertyIds, value, timeoutSeconds)

Waits for the specified property of the control to become a specific value. You can use it to determine whether the state of the control meets expectations, such as waiting for a button to become enabled.

Parameters:

  • propertyIds: PropertyIds Type. Property name to wait for.
  • value: string type. Property value to wait for.
  • timeoutSeconds: number type. Wait time in seconds. Default is 5 seconds. -1 means wait indefinitely.

Returns:

  • boolean type. Wait result. true indicates successfully waited for the value, conversely it means timed out. If an error occurs, it represents the control was not matched, possibly because the control did not appear or there is a problem with object name.

Example

Wait for the button to change from disabled state to clickable, then click it:

JavaScript
Python
// Wait for button to become enabled
await model.getButton("Next").waitProperty("enabled", true);
// Click it after button is enabled
await model.getButton("Next").click();
# Wait for button to become enabled
model.getButton("Next").waitProperty("enabled", True)
# Click it after button is enabled
model.getButton("Next").click()

If this control might be constantly disabled, you can judge by its return value before performing click or other operations.

checkImage(options?: CheckImageCompareOptions | string)

Used to verify if the current image of the control matches the specified reference image. This method is a key tool for visual verification in automated testing, ensuring that the visual appearance of UI controls meets expectations.

The checkImage() method supports multiple parameter configurations. For more explanations and usage examples of this method, please refer to Introduction to Virtual.checkImage() method.

Parameters:

It supports various parameter configurations, allowing you to provide a reference image in the following ways:

  • Directly pass the path string of the image file.
  • Use a configuration object where you can specify:
    • image: Base64 encoded image data.
    • imagePath: Path to the image file.
    • Various comparison options (such as pixelPercentTolerance, colorTolerance, etc.) to adjust the sensitivity of the comparison.
  • If no specific image source is provided, it defaults to comparing with the reference image stored for that control in the model.

Returns:

  • Promise<void>: Asynchronous method that returns no value. If the comparison fails, an error will be thrown.

Example

Assuming we have a control Button, we can use checkImage() to verify if its currently displayed image matches expectations. For example:

JavaScript
Python
await model.getButton("Button").checkImage();
model.getButton("Button").checkImage()

checkProperty(propertyName, expectedValue, optionsOrMessage)

Verifies if the property value of the control meets expectations. If the specified property value does not match the expected value, an error will be thrown.

You can quickly generate property check scripts based on this method during recording. For details, please refer to Adding Property Checkpoints during Recording.

Parameters:

  • propertyName: string type. The name of the property to check. Supported property names include enabled, text, value, etc., as well as all fields returned by the allProperties() method.
  • expectedValue: string | number | boolean | RegExp type. The expected property value. When the control's property value matches the expected value, the test will pass; otherwise, an error will be thrown.
  • optionsOrMessage: string | object type, optional parameter. If it is a string, it will be used as a custom error message; if it is an object, it can contain the following fields:
    • message: string type. Custom error message.
    • operation: any type. Specify the operator used to compare the control property with the expected value. The default value is equal, which verifies whether the property value is equal to the expected value.

Returns:

  • Asynchronous method that returns no value.

Example

For examples of using regular expressions in checkProperty(), please refer to Check via Regex.

Verify if the text property of the text box control is "Hello World":

JavaScript
Python
// Verify text content of text box
await model.getEdit("textEdit").checkProperty('text', 'Hello World', 'Text does not match expected value');
# Verify text content of text box
model.getEdit("textEdit").checkProperty('text', 'Hello World', 'Text does not match expected value')

If the text does not meet expectations, an error will be thrown with the error message "Text does not match expected value".

drag(x, y, mouseKey)

Presses the left mouse button at the control position, which is the first step of a drag operation, and waits for the command to release the mouse. The passed (x, y) are coordinates relative to the control. When x and y are both 0 or omitted, it clicks the control center.

Parameters:

  • x: (Optional) number type. Horizontal pixel point of drag start relative to the top-left corner of the control.
  • y: (Optional) number type. Vertical pixel point of drag start relative to the top-left corner of the control.
  • mouseKey: (Optional) MouseKey Type. Mouse button used, default is 1.

Returns:

  • Asynchronous method that returns no value.

Example

Start dragging from control center:

JavaScript
Python
// Press mouse at button center, start dragging
await model.getButton("sourceButton").drag(0, 0);
# Press mouse at button center, start dragging
model.getButton("sourceButton").drag(0, 0)

drop(x, y, options)

Releases the left mouse button at the control position, which is the second step of a drag operation. The passed (x, y) are coordinates relative to the control. When x and y are both 0 or omitted, it clicks the control center.

You can execute drag() method on A control and drop() method on B control to achieve the effect of dragging A control to B control. For detailed documentation, please check Drag and Drop Methods.

Parameters:

  • x: (Optional) number type. Horizontal pixel point of mouse release relative to the top-left corner of the control. Default is 0.
  • y: (Optional) number type. Vertical pixel point of mouse release relative to the top-left corner of the control. Default is 0.
  • options: (Optional) object type. Configuration object for custom drag behavior. Supported options include:
    • duration: number type. Duration of mouse movement to target position in seconds. Default is 1, i.e., 1 second.
    • mouseKeys: number type. Mouse button used in drag operation. 1 represents left button, 2 represents right button. Default is left button (1).

Returns:

  • Asynchronous method that returns no value.

Example

Complete drag operation:

JavaScript
Python
// Drag button to another control
await model.getButton("sourceButton").drag(0, 0);
await model.getButton("targetButton").drop(10, 10);
# Drag button to another control
model.getButton("sourceButton").drag(0, 0)
model.getButton("targetButton").drop(10, 10)

pressKeys(keys, options?)

Implements string input or key combination operations by simulating keyboard signals. Therefore, it can be used not only for simple text input but also for complex keyboard operations, such as simulating login, finding, navigation, cut, and paste operations.

Note that some special characters in the string (such as ^+~%{}()) will be parsed as control keys (such as Shift, Ctrl) instead of being input as characters. For detailed key instructions, please refer to Appendix: Key Code Table. If you wish to input plain text ignoring these control key symbols, please use {textOnly: true} option, call like this: pressKeys(str, {textOnly: true}).

Parameters:

  • keys: string type. Keys, key combinations, or strings to input. Supports up to 1024 characters.
  • options: PressKeysOptions | number (optional) Optional parameter to control input mode, including:

    • textOnly: boolean type. When set to true, treats all characters as plain text input, ignoring control key instructions.
    • cpm: number type. Characters per minute, used to control input speed. Recommended cpm value is above 200. Since different systems and applications handle input speed differently, actual input speed may deviate from the set value.

    If a number is passed directly as options, this value will be treated as cpm parameter.

Returns:

  • Asynchronous method that returns no value.

Example

Input plain text:

JavaScript
Python
// Input text in edit box, ignoring control key function of special characters
await model.getEdit("Edit").pressKeys("Hello, World!", { textOnly: true });
# Input text in edit box, ignoring control key function of special characters
model.getEdit("Edit").pressKeys("Hello, World!", { "textOnly": True })

For more relevant instructions or examples, please refer to Simulate Key Input pressKeys Method.

takeScreenshot(filePath)

Takes a screenshot of the control. You can pass a path to save the screenshot to that location.

Parameters:

  • filePath: string type. Save path for screenshot file, e.g., "./images/screenshot1.png".

Returns:

  • Asynchronously returns base64 string of the screenshot.

Example

JavaScript
Python
// Screenshot button control and save to file
await model.getButton("Button").takeScreenshot("./screenshots/button.png");
# Screenshot button control and save to file
model.getButton("Button").takeScreenshot("./screenshots/button.png")

The base64 encoded image returned by takeScreenshot() method can be directly inserted into reports as an image. Please refer to Report Attachments.

highlight(duration)

Highlights the control. Used for debugging and verification. You can pass the duration of the highlight box (in milliseconds).

Parameters:

  • duration: number type. Duration of highlight in milliseconds.

Returns:

  • Asynchronous method that returns no value.

Example

JavaScript
Python
// Highlight button for 2 seconds for debugging verification
await model.getButton("Button").highlight(2000);
# Highlight button for 2 seconds for debugging verification
model.getButton("Button").highlight(2000)

doDefaultAction()

Executes the default action defined internally by the control, such as toggle for checkbox, edit for input box, etc. These default action definitions can be viewed by calling the control's allProperties() method and checking the LegacyIAccessible.defaultAction property in the result.

Returns:

  • Asynchronous method that returns no value.

Example

JavaScript
Python
// Execute default action of checkbox (toggle state)
await model.getCheckBox("CheckBox").doDefaultAction();
# Execute default action of checkbox (toggle state)
model.getCheckBox("CheckBox").doDefaultAction()

scrollIntoView()

Scrolls the control into the visible area.

Returns:

  • Asynchronous method that returns no value.

Example

JavaScript
Python
// Scroll control to visible area
await model.getButton("Button").scrollIntoView();
# Scroll control to visible area
model.getButton("Button").scrollIntoView()

Property Methods

Note that control property methods are asynchronous. After calling, CukeTest will communicate with the target control to get the current properties of the control, i.e., real-time properties, not properties in the model object. The properties listed below are supported by all controls, but may not necessarily have values. You can try similar property methods to get the target property based on suggestions.

type()

The type of the control, possible values are usually shown in the Control Type Enum.

Returns:

  • Asynchronously returns control type string.

Example

JavaScript
Python
// Get type of control
let controlType = await model.getButton("Button").type();
console.log("Control Type:", controlType); // Output: "Button"
# Get type of control
control_type = model.getButton("Button").type()
print(f"Control Type: {control_type}")  # Output: "Button"

text()

The text content of the control, usually editable content, such as Edit, Document controls, etc. have this property. If the return value is not as expected, you can try name() or value() property methods.

Returns:

  • Asynchronously returns control text content.

Example

Verify if input text meets expectation:

JavaScript
Python
// Get content of text editor and verify
let actual = await model.getDocument("Editor").text();
let expected = 'Hello World!';
assert.equal(actual, expected);
# Get content of text editor and verify
actual = model.getDocument("Editor").text()
expected = 'Hello World!'
assert actual == expected

rawText()

Returns the internal text information of the control. Requires plugin support to get rendered text information in the target control from the system bottom layer. When name(), value() and text() methods all return empty results, you can try rawText() method to get text.

This method can only get values on the app under test started through the "Start Windows App" menu, because the app started this way will load the corresponding plugin.

Returns:

  • Asynchronously returns internal text information of the control.

Example

JavaScript
Python
// When other methods cannot get text, try rawText
let text = await model.getGeneric("CustomControl").rawText();
console.log("Control internal text:", text);
# When other methods cannot get text, try rawText
text = model.getGeneric("CustomControl").rawText()
print(f"Control internal text: {text}")

name()

The name of the control, this name is usually consistent with the identification property Name of the object in the Model Manager, so almost all controls have this property value. If the return value is not as expected, you can try text() or value() property methods.

Returns:

  • Asynchronously returns control name.

Example

Verify obtained child element:

JavaScript
Python
// Scroll to first item of list and verify its name
let item = await model.getList("List").scrollTo(0);
assert.strictEqual(await item.name(), 'First Normal Item');
# Scroll to first item of list and verify its name
item = model.getList("List").scrollTo(0)
assert item.name() == 'First Normal Item'

hwnd()

The window handle of the control (Handle of WiNDow).

Returns:

  • Asynchronously returns handle value.

Example

JavaScript
Python
// Get window handle
let handle = await model.getWindow("Window").hwnd();
console.log("Window Handle:", handle);
# Get window handle
handle = model.getWindow("Window").hwnd()
print(f"Window Handle: {handle}")

height()

Height of the control, returns number type, unit is pixels.

Returns:

  • Asynchronously returns control height (pixels).

Example

JavaScript
Python
// Get control height
let height = await model.getButton("Button").height();
console.log("Control Height:", height, "pixels");
# Get control height
height = model.getButton("Button").height()
print(f"Control Height: {height} pixels")

width()

Width of the control, returns number type, unit is pixels.

Returns:

  • Asynchronously returns control width (pixels).

Example

JavaScript
Python
// Get control width
let width = await model.getButton("Button").width();
console.log("Control Width:", width, "pixels");
# Get control width
width = model.getButton("Button").width()
print(f"Control Width: {width} pixels")

enabled()

Whether the control is enabled.

Returns:

  • Asynchronously returns boolean value of whether control is enabled.

Example

JavaScript
Python
// Check if button is enabled
let isEnabled = await model.getButton("Button").enabled();
if (isEnabled) {
    console.log("Button is enabled, can be clicked");
}
# Check if button is enabled
is_enabled = model.getButton("Button").enabled()
if is_enabled:
    print("Button is enabled, can be clicked")

focused()

Whether the control is focused/selected. When control is selected, it returns true, usually used to verify if control is operated.

Returns:

  • Asynchronously returns boolean value of whether control is focused.

Example

JavaScript
Python
// Check if input box is focused
let isFocused = await model.getEdit("Edit").focused();
if (isFocused) {
    console.log("Input box is focused, can input text");
}
# Check if input box is focused
is_focused = model.getEdit("Edit").focused()
if is_focused:
    print("Input box is focused, can input text")

visible()

Whether the control is visible and not finding. When control is selected, it returns true. Usually used to verify if control can be operated. For example, in the following scenarios, this method returns false:

  • Control is covered by other controls or windows/dialogs;
  • Control is outside visible area;
  • Control is off-screen;

If the control does not exist, this method will throw "Object not found" error. If you wish not to throw error, can combine with exists() method like:

JavaScript
Python
if (await control.exists() && await control.visible()) {
  // Execute operation
}
if control.exists() and control.visible():
  # Execute operation

helpText()

Help text of the control, i.e., the content of the tooltip message that appears when mouse hovers over the control, usually encountered in WPF, WinForm framework applications.

value()

Value of the control, for example, Slider control Slider, ScrollBar control ScrollBar will return corresponding numerical value. If you wish to get the displayed name or tooltip text of the control, you can try text() or name() property methods.

Returns:

  • Asynchronously returns value of the control, can be string or number.

Example

Verify control value:

JavaScript
Python
// Get input box value and verify
let actual = await model.getEdit("Edit").value();
let expected = 'Hello World!';
assert.equal(actual, expected);
# Get input box value and verify
actual = model.getEdit("Edit").value()
expected = 'Hello World!'
assert actual == expected

processId()

Process Id of the application the control belongs to.

Returns:

  • Asynchronously returns process ID.

Example

JavaScript
Python
// Get process ID of the control
let pid = await model.getWindow("Window").processId();
console.log("Process ID:", pid);
# Get process ID of the control
pid = model.getWindow("Window").processId()
print(f"Process ID: {pid}")

rect()

Bounding rectangle of the control, returns Rect type, containing x, y, height and width info of the control, defined as Rect Type.

Returns:

  • Asynchronously returns Rect object containing control position and size info.

Example

JavaScript
Python
// Get control position and size info
let rect = await model.getButton("Button").rect();
console.log(`Pos: (${rect.x}, ${rect.y}), Size: ${rect.width}x${rect.height}`);
# Get control position and size info
rect = model.getButton("Button").rect()
print(f"Pos: ({rect['x']}, {rect['y']}), Size: {rect['width']}x{rect['height']}")

allProperties()

Gets all runtime properties of the target control, returned as an object. If you wish to directly return value of a specific property, refer to property(propertyIds) method.

Returns:

  • Asynchronously returns object composed of properties of target model object.

Example

JavaScript
Python
// Get all runtime properties of button
let properties = await model.getButton("Button").allProperties();
console.log(properties);
// Get just one property, e.g. objectName
console.log('objectName=' + properties['objectName']);
# Get all runtime properties of button
properties = model.getButton("Button").allProperties()
print(properties)
# Get just one property, e.g. objectName
print('objectName=' + properties['objectName'])

It will get all properties of the button and print:

{
  "name": "Normal",
  "className": "CheckBox",
  "automationId": "",
  "accessKey": "",
  "enabled": true,
  "hasKeyboardFocus": false,
  ...
  "interfaces": [
    "Toggle",
    "LegacyIAccessible"
  ],
  "Toggle.toggleState": 0,
  "LegacyIAccessible.defaultAction": "Select",
  "LegacyIAccessible.description": "",
  "LegacyIAccessible.help": "",
  "LegacyIAccessible.keyboardShortcut": "",
  "LegacyIAccessible.name": "Normal",
  "LegacyIAccessible.role": 44,
  "LegacyIAccessible.state": 1048576,
  "LegacyIAccessible.value": ""
}

Among them, interfaces field is used to return pattern information (UIA Pattern Names) of the control, helping users confirm the operation behaviors supported by the control. LegacyIAccessible.defaultAction is the default action of this control. If not empty, user can execute this default action by calling doDefaultAction.

modelImage(options?)

Screenshot snapshot of the control cached in the model. Default returns base64 string of the snapshot.

Parameters:

  • options: object type, optional parameter, containing following fields:
    • encoding: "buffer" or "base64" string parameter, controls encoding of returned image, default is "base64".

Returns:

  • string type or Buffer type. Asynchronously returns image data according to specified options.encoding option, default is string type.

Example

JavaScript
Python
// Get screenshot in model (base64 format)
let imageBase64 = await model.getButton("Button").modelImage();
# Get screenshot in model (base64 format)
image_base64 = model.getButton("Button").modelImage()

modelProperties(all?)

Properties of the control cached in the model. Default returns only identification properties. Pass true parameter to also get other properties not used for identification.

Parameters:

  • all: boolean type, optional parameter. Whether to get all properties. Default is false, only get identification properties.

Returns:

  • Property object.

Example

JavaScript
Python
// Get model properties of window
let modelProperties = await model.getWindow("Standard_Dialogs").modelProperties();
console.log(modelProperties);
assert.equal('Window', modelProperties.type);
# Get model properties of window
modelProperties = model.getWindow("Standard_Dialogs").modelProperties()
print(modelProperties)
assert modelProperties['type'] == 'Window'

Output modelProperties is:

{ type: 'Window', className: 'Dialog', text: 'Standard Dialogs' }

CukeTest provides a series of control navigation methods, allowing users to retrieve parent, child, and sibling controls of the target control using navigation methods. These methods enable indexing into the entire control tree via an anchor control, commonly used in scenarios like input box positioning and control traversal.

Navigation methods are asynchronous, meaning they require some time to retrieve the navigated control within the application and return. They do not navigate directly within the Model Manager's tree, so please distinguish this difference.

For usage of control navigation, you can refer to "File Explorer Traversal" in Appendix H: CukeTest Samples.

firstChild(controlType?)

Gets the first child control of the control in the application. You can specify child control type by passing controlType parameter to achieve filtering effect, i.e., get the first child control of controlType type in the application. controlType is string, optional values can see ControlType. Returns null if no matching child control is found.

At the same time, child only represents direct children, will not search grandchildren. If no matching control is found among the children, it returns null immediately instead of continuing to search in grandchildren. If you wish to get all controls under a certain control, you can use the findControls method.

Note that invisible or not-yet-loaded controls are not counted. Strictly speaking, firstChild() retrieves the first of the accessible child objects, and the same applies to the lastChild() method below.

Parameters:

  • controlType: (Optional) string type, optional parameter, see ControlType.

Returns:

  • Asynchronously returns any control type, depending on the type of control navigated to. Returns null if no control is found.

Example

JavaScript
Python
// Get the first child of the Pane control
let firstChild = await model.getPane("Container").firstChild();
if (firstChild) {
    console.log("Found first child control");
}
# Get the first child of the Pane control
first_child = model.getPane("Container").firstChild()
if first_child:
    print("Found first child control")

lastChild(controlType?)

Gets the last child control of the control in the application. You can specify child control type by passing controlType parameter to achieve filtering effect. controlType is string, see ControlType. Returns null if no matching child control is found.

Note: lastChild() only retrieves the last of the accessible child objects.

Parameters:

  • controlType: (Optional) string type, optional parameter, see ControlType.

Returns:

  • Asynchronously returns any control type, depending on the type of control navigated to. Returns null if no control is found.

Example

JavaScript
Python
// Get the last child of the Pane control
let lastChild = await model.getPane("Container").lastChild();
if (lastChild) {
    console.log("Found last child control");
}
# Get the last child of the Pane control
last_child = model.getPane("Container").lastChild()
if last_child:
    print("Found last child control")

next(controlType?)

Gets the next sibling control of the control in the application, usually the adjacent node on the right or below, depending on the container's layout direction. You can specify sibling control type by passing controlType parameter. controlType is string, see ControlType. Returns null if no matching sibling control is found, for example when the control is the lastChild of its parent.

Parameters:

  • controlType: (Optional) string type, optional parameter, see ControlType.

Returns:

  • Asynchronously returns any control type, depending on the type of control navigated to. Returns null if no control is found.

Example

JavaScript
Python
// Get the next sibling of the current button
let nextControl = await model.getButton("Button1").next();
if (nextControl) {
    await nextControl.click();
}
# Get the next sibling of the current button
next_control = model.getButton("Button1").next()
if next_control:
    next_control.click()

previous(controlType?)

Opposite to next(), gets the previous sibling control of the control in the application, usually the adjacent node on the left or above, depending on the container's layout direction. You can specify sibling control type by passing controlType parameter. controlType is string, see ControlType. Returns null if no matching sibling control is found, for example when the control is the firstChild of its parent.

Parameters:

  • controlType: (Optional) string type, optional parameter, see ControlType.

Returns:

  • Asynchronously returns any control type, depending on the type of control navigated to. Returns null if no control is found.

Example

JavaScript
Python
// Get the previous sibling of the current button
let prevControl = await model.getButton("Button2").previous();
if (prevControl) {
    await prevControl.click();
}
# Get the previous sibling of the current button
prev_control = model.getButton("Button2").previous()
if prev_control:
    prev_control.click()

parent()

Opposite to firstChild() and lastChild(), gets the parent control of the control. Returns null if the control is a top-level control.

Returns:

  • Asynchronously returns any control type, depending on the type of control navigated to. Returns null if no control is found.

Example

JavaScript
Python
// Get the parent of the button
let parentControl = await model.getButton("Button").parent();
if (parentControl) {
    console.log("Found parent control");
}
# Get the parent of the button
parent_control = model.getButton("Button").parent()
if parent_control:
    print("Found parent control")

all()

The all() method returns an array of all sibling controls that match the "identification properties" of the current control without specifying any filtering conditions. This method is suitable for batch operations on multiple controls at the same level in testing, such as tables, lists, or a group of buttons. See Get Object API.

Returns:

  • Asynchronously returns control array containing all sibling control objects. Returns empty array if no controls found.

Example

JavaScript
Python
// Get all sibling button controls
let controls = await model.getButton("Normal").all();
console.log('Number of controls:', controls.length);
// Iterate through all controls
for (let control of controls) {
    console.log(await control.name());
}
# Get all sibling button controls
controls = model.getButton("Normal").all()
print(f"Number of controls: {len(controls)}")
# Iterate through all controls
for control in controls:
    print(control.name())

findControls(...conditions)

The findControls() method is a powerful query tool used to filter a collection of controls that meet specified conditions. It accepts one or more ConditionFilter objects as parameters, which define the filtering conditions.

This method is suitable for scenarios where you need to retrieve controls from the application based on specific conditions. For example, on an interface with dynamic content, you may need to find all controls with specific properties or states. findControls() method can dynamically identify and return these controls based on provided conditions. See Get Object API.

Parameters:

  • conditions: ConditionFilter[] type, one or more filtering conditions.

Returns:

  • Asynchronously returns an IWinControl array containing all controls satisfying the provided filtering conditions. Returns empty array if no controls found.

Example

JavaScript
Python
// Find all controls of Button type
let buttons = await model.getPane("MainPane").findControls({type: "Button"});
console.log(`Found ${buttons.length} buttons`);
// Iterate and operate all found buttons
for (let button of buttons) {
    await button.click();
}
# Find all controls of Button type
buttons = model.getPane("MainPane").findControls({"type": "Button"})
print(f"Found {len(buttons)} buttons")
# Iterate and operate all found buttons
for button in buttons:
    button.click()

Control Navigation Scenarios

Case 1: Input Box Positioning

In some applications, there are forms to be filled, i.e.:

Form:
    [Label1]: [Input1]
    [Label2]: [Input2]
    [Label3]: [Input3]
    [Label4]: [Input4]

For some application input boxes that may lack sufficient properties for identification, and all labels and input boxes belong to the same container (form) without isolation, CukeTest might treat Input1-4 as the same input box. In this case, you can add label objects, then use navigation methods to get the input box control on its right side to get the target input box:

JavaScript
Python
let labels = ["Label1", "Label2", "Label3", "Label4"]
for (let label of labels) {
    let input = await model.getText(label).next();
    await input.set("Value to input");
}
labels = ["Label1", "Label2", "Label3", "Label4"]
for label in labels:
    input = model.getText(label).next()
    input.set("Value to input")

Case 2: Control Traversal

You can traverse all controls in the entire application by recursively calling navigation methods.