Home > OS >  Find element via "findElementsBy", check innerText, refresh page, download or loop
Find element via "findElementsBy", check innerText, refresh page, download or loop

Time:05-11

I have a page where a process gets kicked off, and then the page needs to be refreshed until "Status" on a table goes to "Processed", at which point a report can be downloaded.

...
              String processing="NotFinished";
              WebElement table = driver.findElement(By.id("TableID")); 
              List<WebElement> allRows = table.findElements(By.tagName("tr")); 
              while(processing.equals("NotFinished")) {
              for (WebElement row : allRows) {
                    List<WebElement> cells = row.findElements(By.tagName("td")); 
                    for (WebElement cell : cells) {
                        if(cell.getText().equals("ReportName")) {
                            String[] ColData = row.getText().split(" ");                    
                    if(ColData[5].equals("Processed")) {
                        //click download
                        wait.until(ExpectedConditions.elementToBeClickable(By.id("DownloadButtonID")));
                    Thread.sleep(250);
                    driver.findElement(By.id("DownloadButtonID")).click();
                        processing = "Finished";
                        System.out.println("DownloadClicked");
                    } else {
                            System.out.println("Refreshing");
                            wait.until(ExpectedConditions.elementToBeClickable(By.id("RefreshButtonID")));
                            Thread.sleep(250);
                            driver.findElement(By.id("RefreshButtonID")).click();
                            Thread.sleep(5000);       
                        }
                    }
                }    
            }
...

At this point I have been able to confirm that "ColData[5]" is pulling in the correct value. I have been trying to move the "while" statement to different areas in this chunk of code to see if I can get it to work, but I am seeing 2 main behaviors.

If I locate the where below the second for, then it will simply loop forever. The value for "ColData[5]" is getting updated on the page, but Java isn't seeing that.

When I locate the where like it is here, it will loop a few times between the for statements and then will seemingly spontaneously pop out of the while statement without hitting the "processing = "Finished";" statement.

I was thinking that I may need to break out of the for statements so that Java correctly backs up to redefining the table at the start of the loop after clicking the refresh button, but doing a break seemed to make it skip all of the above.

Can anyone point me in the direction of getting this code to: Get the table data, get the value of the cell a few columns over from the Report Name I am targeting, determine if it says "Processed", If yes, click download and move on. If no, wait 5 seconds, click refresh, and check again.

I know this is pretty ungodly bad code, but at this point the name of the game is anything that works, and in the future I can work on being better at the language.

CodePudding user response:

Try moving the lines

WebElement table = driver.findElement(By.id("TableID")); 
List<WebElement> allRows = table.findElements(By.tagName("tr")); 

inside the while block.

CodePudding user response:

So, I went back at it fresh this morning, deleted everything, and proceeded to rebuild it piece by piece and I figured out what my issue was.

  ...
  String fileDownloaded="No";
  do {String needsRefresh="No";
  wait.until(ExpectedConditions.elementToBeClickable(By.id("TableID")));
  WebElement table = driver.findElement(By.id("TableID"));
  List<WebElement> allRows = table.findElements(By.tagName("tr")); 
    for (WebElement row : allRows) {
        List<WebElement> cells = row.findElements(By.tagName("td"));
        for (WebElement cell : cells) {
            if(cell.getText().equals("ReportName")) {
                String[] ColData = row.getText().split(" ");
                if(ColData[5].equals("Processed")) {
                    
                } else {
                    needsRefresh="Yes";
                }//close second if
            }//close first if
        }//close second for
    }//close first for
  if (needsRefresh.equals("Yes")) {
      wait.until(ExpectedConditions.elementToBeClickable(By.id("RefreshButtonID")));
      Thread.sleep(250);
      System.out.println("Refreshing");
      driver.findElement(By.id("RefreshButtonID")).click();
      Thread.sleep(5000);
      } else {
          System.out.println("Downloading");
          wait.until(ExpectedConditions.elementToBeClickable(By.id("DownloadButtonID")));
          Thread.sleep(250);
      driver.findElement(By.id("DownloadButtonID")).click();
          Thread.sleep(250);
              fileDownloaded="Yes";
      }
  } while (fileDownloaded.equals("No"));//close first do
      ...

Basically, putting the page refresh inside the 2 for statements was causing stale element errors. I dont believe Java has an "Exit For" statement (which I have a bad habit of using in VBA). In VBA, 2 well placed "Exit For" statements would create the cascade I was going for.

Instead of appraising through the table until the target element is found and then immediately trying to perform the action, I had to work in a flag that allowed the 2 for statements to appraise the entire table and run their full natural course, then, OUTSIDE of the loops, the flag is appraised, and the proper action is taken, then the code successfully falls back to the top level loop, which grabs the table element fresh or terminates.

The shortfall I need to anticipate with this chunk of code is that it isnt going to be happy if the report I am looking for is not found in the table, which may be a consideration in the future, but is not one today, so this gets my job done.

  • Related