2

I am implementing selenium automated web tests on salesforce lightning page. Between different test steps, the test need wait until the web page is completely loaded, so that the web element is visible or clickable, e.g. Click a dropdown menu will open a new saleforce lightning component, then enter some value in a text field in the new opened component.

In the normal web page, we can use javascript to check if the webpage is loaded by checking document.readyState == complete. For the page using jQuery framework, we can also use javascript to check if ajax in page is complete by checking jQuery.active==0.

Saleforce lightning use the aura framework. How can we check if the page (all components) is loaded? How can we check the ajax in salesforce lightning page is done?

2
  • 1
    You might be able to use aura:doneRendering, but I don't have time to validate that.
    – sfdcfox
    Apr 16, 2018 at 22:08
  • hi Sebastian, aura:doneRendering is a system event, is there any method in aura return a boolean value to check if the components are finished with rendering?
    – Juewei Jin
    Apr 17, 2018 at 6:55

4 Answers 4

2

Sorry for a late reply, but we literally just investigated this exact problem and found what seems to be a workable solution over the last few weeks.

We didn't find any available way of telling when a component is done rendering as Aura doesn't seem to provide a way to do so. However, we did discover that there is an inFlightXHRs method that returns a count of pending XMLHttpRequests. We've modified our selenium framework to wait until there are no in flight XHRs before continuing.

It's not a perfect solution, but it has allowed us to stabilize tests and reduce artificial sleep times.

Here's the javascript we're using for the check: https://github.com/SalesforceFoundation/CumulusCI/blob/master/cumulusci/robotframework/Salesforce.py#L24-L45

And here's the section from our docs about it: http://cumulusci.readthedocs.io/en/latest/robotframework.html#waiting-for-lightning-ui

1

Slightly late for answering the question, but here's the updated code based on above answers:

public void waitForPagetoLoad() throws InterruptedException {
        // reference https://www.toolsqa.com/selenium-webdriver/advance-webdriver-waits/
        Thread.sleep(3000);
        try {
            WebDriverWait wait1 = new WebDriverWait(driver, 50);

            ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
                @Override
                public Boolean apply(WebDriver driver) {
                    return ((JavascriptExecutor) driver).executeScript("return document.readyState").toString()
                            .equals("complete");
                }
            };

            ExpectedCondition<Boolean> aurascriptLoad = new ExpectedCondition<Boolean>() {
                @Override
                public Boolean apply(WebDriver driver) {
                    String WAIT_FOR_AURA_SCRIPT = "return (typeof $A !== 'undefined' && $A && $A.metricsService.getCurrentPageTransaction().config.context.ept > 0)";
                    String EPT_COUNTER_SCRIPT = "return ($A.metricsService.getCurrentPageTransaction().config.context.ept)";
                    Boolean result = (Boolean) ((JavascriptExecutor) driver).executeScript((WAIT_FOR_AURA_SCRIPT));

                    if (result.equals(true)) {
                        System.out.println("EPT on the current page is : "
                                + ((JavascriptExecutor) driver).executeScript(EPT_COUNTER_SCRIPT));
                        return true;
                    } else {
                        return false;
                    }

                }
            };
            if (wait1.until(jsLoad) && wait1.until(aurascriptLoad)) {
                System.out.println("Page load complete");
            } else {
                Thread.sleep(2000);
            }
        }

        catch (Exception e) {
            System.out.println("Exception happened in waiting for page to load , so sleeping for 5 seconds");
            System.out.println("Exception is " + e.getMessage());
            Thread.sleep(5000);

        }
    }

Also the code above doesn't guarantee defence against javaScript modifications to the page after the page has loaded and EPT is finalized.

0

You should try to define a custom renderer on your parent component (the page or the app).
You can then use the afterRender() function to perform actions after the DOM is updated.

0

Salesforce seems to be actively against automated UI testing... Anyhow, I've managed to find internal JS that tracks how quickly page loads (you can see it when you enable Lightning debug mode, but internally it's always on). Anyhow here's the script:

return driver.wait(function () {
            return driver.executeScript(
                `return (document.readyState === "interactive"
                    || document.readyState === "complete")
                    && typeof $A !== 'undefined' && $A && $A.metricsService.getCurrentPageTransaction()
                    && $A.metricsService.getCurrentPageTransaction().config.context.ept > 0)
        }, 60 * 1000, 'TIMEOUT_EXCEPTION')

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .