Page Object Load Interception

For a page to be ready for further interaction after loading, we often must wait for an event, such as DOM is ready, or for the presence of an element indicating that loading is complete.

By default, the load method finds a root element inside its parent. For a root page object (located directly in the driver or browser root), the default behavior is to wait for the root element to become present. You can override the default method that is invoked when a page object is loaded.

The load method is __beforeLoad__() in JavaScript or load() in Java. It's invoked every time a page object is created:

Now, let's look at some examples of overriding the default loading by using beforeLoad in a page object. The beforeLoad array sets the criteria to be satisfied before the load method completes.

Important: Statements inside the beforeLoad array can reference only root or document elements because other elements aren’t loaded yet.

Wait for DOM readyState

Set the apply method as waitForDocumentReady to exit from the method only when the DOM is "ready" (document.readyState === 'complete').

{
    "beforeLoad": [
        {
            "element": "document",
            "apply": "waitForDocumentReady"
        }
    ]
}

Tip: Functionality related to browser interactions like navigation, entering and exiting frames, or waiting for DOM state is a part of the Document object and is described in the JSON grammar reference.

Wait for Navigation to a URL

This example is relevant if the page we're loading is associated with a URL.

{
    "beforeLoad": [
        {
            "element": "document",
            "apply": "waitFor",
            "args": [
                {
                    "type": "function",
                    "predicate": [
                        {
                            "element": "document",
                            "apply": "getUrl",
                            "matcher": {
                                "type": "stringContains",
                                "args": [
                                    {
                                        "value": "my/homePage"
                                    }
                                ]
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

Wait for a Spinner to Disappear

Consider the use case of a user creating a record and clicking a save button. While the transaction completes and the next page loads, a spinning wheel is displayed.

This example waits for the spinning element to no longer be present directly in the driver root.

{
    "beforeLoad": [
        {
            "element": "document",
            "apply": "waitFor",
            "args": [
                {
                    "type": "function",
                    "predicate": [
                        {
                            "element": "document",
                            "apply": "containsElement",
                            "args": [
                                {
                                    "value": { "css": "my-spinner" },
                                    "type": "locator"
                                }
                            ],
                            "matcher": {
                                "type": "isFalse"
                            }
                        }
                    ]
                }
            ]
        }
    ]
}

The predicate in the waitFor statement has to return a truthy value (not null, not false and doesn’t throw) for the method to complete without an error.

Wait for a Page Object to Contain an Element

This example waits for the root element to contain an element with the given selector inside its shadowRoot.

{
    "beforeLoad": [
        {
            "apply": "waitFor",
            "args": [
                {
                    "type": "function",
                    "predicate": [
                        {
                            "element": "root",
                            "apply": "containsElement",
                            "args": [
                                // first arg - selector to search for
                                {
                                    "value": { "css": "i-am-slow" },
                                    "type": "locator"
                                },
                                // second arg - expand the shadow root of the parent
                                { "value": true }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}