3

I have a test case that goes something like this:

  • open homepage
  • if there is no content present
  • refresh page
  • continue with other steps...

This is the relevant part of the code:

public JpoPO() {
        driver.get(Settings.JPO_TEST_URL);
        PageFactory.initElements(driver, this);
        System.out.println("[INFO] Homepage initialized.");
        zatvoriModal();
        refreshIfNeeded();
        zatvoriModal();
        (new WebDriverWait(driver, 30)).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("#loading")));
        System.out.println("[DEBUG] broj .ng-scope elemenata: " +driver.findElements(By.cssSelector(".ng-scope")).size());
        System.out.println("[OK] JpoPO() initialized.");
}

And this is the refreshIfNeeded() part:

public void refreshIfNeeded() {
    if(System.getProperty("os.name").equals("Linux")){
        System.out.println("### A"+now());
        int broj = driver.findElements(By.cssSelector(".ng-scope")).size();
        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("location.reload()");
        //driver.findElement(By.cssSelector("header")).sendKeys(Keys.F5);
        driver.get(driver.getCurrentUrl());
        waitForNoSpinner();
        System.out.println("[DEBUG] location reloaded, .ng-scope elements: "+broj);
        System.out.println("### B"+now());
    }else{
        System.out.println("[] Starting refreshIfNeeded()");
        Date ts1 = new Date();
        int count = 0;
        while (driver.findElements(By.cssSelector(".ng-scope")).size()==0 && count < 10){
            driver.navigate().refresh();
            zatvoriModal();
            try {
                (new WebDriverWait(driver, 10)).until(ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".ng-scope"), 0));
                Date ts2 = new Date();
                long trajanje = ts2.getTime() - ts1.getTime();
                System.out.println(String.format("[INFO] Učitavanje sadržaja: %s ms.", trajanje));
            } catch (Exception e){
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            System.out.println("[] Count: "+count);
            count++;
        }
    }
}

The thing is working when running locally on my Windows machine, but when it is running on the remote Jenkins linux machine the refresh doesn't seem to work.

This is the Jenkins console output:

16:18:48 [INFO] Homepage initialized.
16:18:48 ### A2019-10-30T16:18:48.904
16:18:49 [INFO] Spinner (ili uvjet čekanja) je trajao: 117 ms. (waitForNoSpinner-try)
16:18:49 [INFO] Spinner (ili uvjet čekanja) je trajao: 89 ms. (waitForNoSpinner-finally)
16:18:49 [DEBUG] location reloaded, .ng-scope elements: 0
16:18:49 ### B2019-10-30T16:18:49.417
16:18:49 [DEBUG] broj .ng-scope elemenata: 0
16:18:49 [OK] JpoPO() initialized.

The test fails in the following step when trying to find an element that is not there unless the page is refreshed. This is also confirmed by using screenshots that I'm unable to share.

There are multiple ways of refreshing a page with Selenium here, but none of them is working.

It just seems that neither js.executeScript("location.reload()") nor driver.navigate().refresh() are working.

I'm using the following Chromedriver options :

if(System.getProperty("os.name").equals("Linux")){
    options.addArguments("--headless");
    options.addArguments("--proxy-server='direct://'");
    options.addArguments("--proxy-bypass-list=*");
    options.addArguments("--window-size=1200,800");
    WebDriverManager.chromedriver().version("77.0.3865.40").setup();
}


EDIT:

When I tried refreshing using the Robot class, I would get a java.awt.AWTException: headless environment so I added System.setProperty("java.awt.headless", "false"); to my code.

Now I'm getting a

java.awt.AWTError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.

I know next to nothing about Linux, can that be the reason for this?

Mate Mrše
  • 7,997
  • 10
  • 40
  • 77
  • Which version of Chrome do you on the Jenkins server? – Greg Burghardt Oct 30 '19 at 17:24
  • It is the 77.0.3865.40. – Mate Mrše Oct 30 '19 at 18:42
  • Have you tried with all the ways mentioned in the link that you have given? sendKeys.Keys , navigate.to() , sendKeys() , get() – Durga Prasad Behera Nov 11 '19 at 04:14
  • Yes, I tried all of them. – Mate Mrše Nov 11 '19 at 07:44
  • can you try calling it ````int broj = driver.findElements(By.cssSelector(".ng-scope")).size();```` after ````driver.get(driver.getCurrentUrl()); waitForNoSpinner();```` – Durga Prasad Behera Nov 11 '19 at 09:10
  • I just did and it equals 0 at that point. – Mate Mrše Nov 11 '19 at 09:34
  • @MateMrše How you check if it's refreshed or not, by checking `broj`? – Sers Nov 11 '19 at 11:30
  • Exactly, that is the number of content elements of the page that appear after refresh. It should be greater than 0. – Mate Mrše Nov 11 '19 at 12:21
  • Just for debugging purpose can you try putting some explicit wait after refreshing the page and then probably print the broj. Another thing you can try is search for any other element, example any link or simply some text probably. @Mate Mrse – Durga Prasad Behera Nov 12 '19 at 03:47
  • I faced the same issue today. So i observed while the page was loading, i tried to refresh the page so instead of refreshing it was stopping the refresh. And i see the same in your code. Instead of JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("location.reload()"); //driver.findElement(By.cssSelector("header")).sendKeys(Keys.F5); driver.get(driver.getCurrentUrl()); Try adding sleep for like 8000 (just for debugging purpose) Thread.sleep(8000); Robot robot = new Robot(); robot.keyPress(KeyEvent.VK_F5); – Durga Prasad Behera Nov 14 '19 at 10:56
  • @DurgaPrasadBehera Robot doesn't work in headless. – Mate Mrše Nov 14 '19 at 12:40
  • @MateMrše The intention is to let the page load completely then do a refresh, if you refresh in between it cancels the refresh. You may refresh with robot or actions or anything. This worked in my case. – Durga Prasad Behera Nov 15 '19 at 04:59
  • I tried with very long waits. It is still not working. The problem is all the various ways of refreshing don't work. – Mate Mrše Nov 15 '19 at 08:03

1 Answers1

0

You store size of the .ng-scope elements before refreshing and do not get size after. This is the reason you get 0 in the logs. You should search for the elements after waitForNoSpinner to get update size value:

if(System.getProperty("os.name").equals("Linux")){
    System.out.println("### A"+now());
    int broj = driver.findElements(By.cssSelector(".ng-scope")).size();
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("location.reload()");
    //driver.findElement(By.cssSelector("header")).sendKeys(Keys.F5);
    driver.get(driver.getCurrentUrl());
    waitForNoSpinner();
    broj = wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(By.cssSelector(".ng-scope"), 0)).size();
    System.out.println("[DEBUG] location reloaded, .ng-scope elements: "+ broj);
    System.out.println("### B"+now());
}

Here is alternative refreshIfNeeded method, where waitForNoSpinner and zatvoriModal based on OS. If there's no difference between waitForNoSpinner and zatvoriModal replace if with one of them. Method will throw TimeoutException if .ng-scope will be not found after 20 seconds:

public void refreshIfNeeded() {
    WebDriverWait wait = new WebDriverWait(driver, 20, 1000);

    System.out.println("[DEBUG] check .ng-scope elements and refresh if not located");

    wait.until(d -> {
        if (d.findElements(By.cssSelector(".ng-scope")).isEmpty()) {
            System.out.println("[DEBUG] no .ng-scope elements, refresh..");
            driver.navigate().refresh();
            waitForNoSpinner();
            /*if (System.getProperty("os.name").equals("Linux")) {
                waitForNoSpinner();
            } else {
               zatvoriModal();
            }*/
        }
        return !d.findElements(By.cssSelector(".ng-scope")).isEmpty();
    });

    System.out.println("[DEBUG] .ng-scope elements: " + driver.findElements(By.cssSelector(".ng-scope")).size());
}

With loop:

public void refreshIfNeeded() throws InterruptedException {
    WebDriverWait wait = new WebDriverWait(driver, 20, 1000);

    System.out.println("[DEBUG] check .ng-scope elements and refresh if not located");

    for (int i=0; i < 10; i++) {
        try {
            wait.until(d -> {
                if (d.findElements(By.cssSelector(".ng-scope")).isEmpty()) {
                    System.out.println("[DEBUG] no .ng-scope elements, refresh..");
                    driver.navigate().refresh();
                    if (System.getProperty("os.name").equals("Linux")) {
                        waitForNoSpinner();
                    } else {
                        zatvoriModal();
                    }
                }
                return !d.findElements(By.cssSelector(".ng-scope")).isEmpty();
            });
            break;
        } catch (Exception e) {
            Thread.sleep(3000);
        }
    }
}
Sers
  • 12,047
  • 2
  • 12
  • 31
  • The problem is: `driver.navigate().refresh();` won't do anything. That is not based solely on `broj` value but on screenshots as well. – Mate Mrše Nov 11 '19 at 14:13
  • Can you share screenshots? Why you refresh is required? – Sers Nov 11 '19 at 14:17
  • Do you have access to the web page from Jenkins? – Sers Nov 11 '19 at 15:02
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/202156/discussion-between-sers-and-mate-mrse). – Sers Nov 11 '19 at 15:36