Aaron Digulla
Aaron Digulla

Reputation: 328556

How do I locate ZK DOM nodes with Selenium 3?

When using ZK, I have development IDs (id="foo"). How can I get the DOM node for it using Selenium 3?

Upvotes: 0

Views: 115

Answers (1)

Aaron Digulla
Aaron Digulla

Reputation: 328556

This involves several steps. First, you need to locate the DOM node using client side JavaScript. ZK offers the function window.jq() for that. This function gives you access to a jQuery instance (see https://www.zkoss.org/wiki/ZK_Client-side_Reference/General_Control/Client-side_selection_of_elements_and_widgets).

To differentiate between DOM and ZK IDs, use # and $ respectively.

So the final JavaScript should look like so:

jq('$foo')

To run this JavaScript, use driver.executeScript(). You probably also want to use a context (development IDs are often only unique within a ZK parent element).

The result is a jQuery set which for example ChromeDriver can't handle (you will get javascript error: circular reference errors). So you need to call toArray() on the result to convert the jQuery object into an array with plain DOM nodes. ChromeDriver knows how to convert those to Java. All that is left is to return this array from JavaScript. You will then get a List<WebElement> on the Java side.

I have created a By locator for this:

public class ByZKId extends By {

    private String id;
    private WebElement context;

    public ByZKId(String id) {
        this.id = "$" + id;
    }

    public ByZKId(String id, WebElement context) {
        this.id = "$" + id;
        this.context = context;
    }

    @Override
    public List<WebElement> findElements(SearchContext context) {
        if (context == null) {
            return executeJavaScript("return jq(arguments[0]).toArray();", id);
        }

        return executeJavaScript("return jq(arguments[0], arguments[1]).toArray();", id, this.context);
    }

    @Override
    public String toString() {
        return "ByZKId: [" + id + "]";
    }
}

Upvotes: 1

Related Questions