Java Automation APIs

Generating automation code for Java controls is similar to that of Windows controls.

Java Container API

The container API is the API used to fetch objects, as follows:

JavaScript
interface IJContainer {
    parent: IJContainer;
    getJWindow(...conditions: ConditionFilter[]): IJWindow;
    getJButton(...conditions: ConditionFilter[]): IJButton;
    getJCheckBox(...conditions: ConditionFilter[]): IJCheckBox;
    getRadioButton(...conditions: ConditionFilter[]): IJRadioButton;
    getJEdit(...conditions: ConditionFilter[]): IJEdit;
    getJCustom(...conditions: ConditionFilter[]): IJControl;
    getJList(...conditions: ConditionFilter[]): IJList;
    getJMenu(...conditions: ConditionFilter[]): IJMenu;
    getJLabel(...conditions: ConditionFilter[]): IJLabel;
    // You can refer to the next section - "The method of dynamically obtaining controls: findControls" introduction
    findControls(...conditions:ConditionFilter[]):IJControl[];
}

Java object members

Default Controls: JControl

All Java objects inherit from the IJControl class, which in turn inherits from the IJContainer class mentioned above, which is the Java container class:

JavaScript
interface IJControl extends IJContainer {
    click(x?: number, y?: number, mousekey?: number): Promise<void>;
    dblClick(x?: number, y?: number, mousekey?: number): Promise<void>;
    moveMouse(x?: number, y?: number): Promise<void>;
    pressKeys(keys: string, options?: PressKeysOptions | number): Promise<void>;
    takeScreenshot(filePath?:string):Promise<string>;

    name():Promise<string>;
}

And each particular object may have its own control methods and properties, For example:

RadioButton

JavaScript
interface IJRadioButton extends IJControl {
    check(): Promise<void>;

    // Get selected status
    checked(): Promise<boolean>
}

JCheckBox

JavaScript
interface IJCheckBox extends IJControl {
    checkState(): Promise<boolean>
    toggleCheck(checkState: boolean): Promise<void>
}

JEdit

JavaScript
interface IJEdit extends IJControl {
    set(value: string): Promise<void>;
    value(): Promise<string>;
}

JList

JavaScript
interface IJList extends IJControl {
    getItem(itemIndex:number):Promise<string>;
    itemCount():Promise<itemCount>;
}

JMenu

JavaScript
interface IJMenu extends IJControl {
}
Special attention needs to be paid to the JMenu control above, i.e. the menu control. Usually the menu that is expanded in the toolbar belongs to the JMenu control. Since menus usually pop up only after clicking or hovering, we need to pay attention to two techniques when detecting such controls:

  1. hold down the Ctrl key to resume normal clicking: clicking on the control during detection will automatically add the control to the model manager, and holding down the Ctrl key on the keyboard during recognition will restore it to normal clicking, at which point clicking will expand the menu.
  2. Wait a little while detecting: When detecting menu controls, it occasionally happens that the detected control is incorrect, usually in scenarios where the menu option the mouse points to jumps to a new interface, closes a window, and other scenarios that change the structure of the application model. For this, the current solution is to hold down the left button while detecting the menu control to identify the control and don't release it until the detector pops up, so that the target menu control can be correctly identified.

JTable

JavaScript
interface IJTable extends IJControl {
    clickCell(rowIndex: number, columnToFind: string | number);
    cellValue(rowIndex: number, columnNameOrIndex: number | string): Promise<string>;
    data(): Promise<string[][]>;
    setCellValue(rowIndex: number, columnToFind: string | number, value: string);
    
    columnCount(): Promise<number>;
    columnHeaders(): Promise<string[]>;
    rowCount(): Promise<number>;
}

clickCell method will perform double-click the target cell, if the cell can be edited will enter the editing state, you can use the pressKeys method to enter the specified content (or directly use setCellValue to set the contents of the target cell, if the cell can not be edited, it is invalid).

findControls

Provides a way to directly match multiple controls that match the filter criteria without relying on the model manager.The findControls method is used in the same way as in Windows Automation, see findControls in Windows. The findControls method takes parameters similar to the other get[ControlType] methods, for example:

Runtime identification properties

At code runtime, you can not only match objects in the model manager by object name, but also dynamically match controls from the application that meet the identified properties by using the identified properties. The advantage of this is that for dynamically changing, but predictable controls, adding the recognition property increases the accuracy of the match and allows you to perform the operation in the automation script without adding it to the model manager in advance. Here are a few examples of code that use the recognition property:

JavaScript
await model.getJButton("button1").name(); // Suppose button1 is a button control and the name property is "Press Me"

// The following two lines of code can match the same control as the previous line
await model.getJButton({name: "Press Me"}); // Only one matching JButton control will be returned, and only the first one will be returned if multiple matches are made.
await model.findControls({name: "Press Me", type:"JButton"}); // Returns an array of all eligible control objects

Introduction of identification properties

At code runtime, controls are matched from the application based on the properties of the action object. And since the matching direction is from the topmost control down one layer of controls, that is, when matching a control, all its parent controls are matched with increased accuracy. This poses a problem, as window controls usually act as the topmost node, which results in the lowest recognition accuracy. The search indicator property search provides a way to specify the matching direction indication, such as indicating the matching direction upward, so that you can in turn use a control as a starting point and match the window, container, or panel where the control is located upward. Assuming that there are multiple windows in the runtime environment at this point, the following script can be used if trying to close the login window:

JavaScript
let button = model.getJButton("Login");  // Login button unique to the login window
await button.getJWindow("JWindow",{search:"up"}).close();  // The window where the Login button is located is the login window

Simple Java automation sample code

The following is an example of a call to a Java object:

Sample 1:

JavaScript
const { JavaAuto } = require('leanpro.java');
    const model = JavaAuto.loadModel(__dirname + '/java_model.tmodel');

    (async function () {
        try {
            await model.getJEdit("text1").set('some content');
        } catch(err) {
            console.log('err', err)
        }
    })();

In order to get Java controls from the model, you should start calling from model, which will return the root IJContainer"` object, which in turn can get other Java objects from the model.

When you call a member on a Java object and the Java object cannot find the matching control, it will raise a "object not found" exception.

If the "text1" object can find the edit box control, it sets its content to "some content".

Sample 2:

The following is a sample snippet that gets the checkbox's checked or unchecked state and toggles its state to checked.

JavaScript
(async function () {
        let checkbox = model.getJCheckBox('checkbox-0');  // Assume False is unchecked at this point
        console.log('checked state', await checkbox.checkState());
        await checkbox.toggleCheck(true);
        let checkbox = model.getJCheckBox('checkbox-0');  // Then True is selected at this time
   })();

results matching ""

    No results matching ""