0

I'd like to ask how I could make my for loop work, all I want to do is count up every second if all 6 elements can't be found. I have 6 graphs and I want to see how long it takes for the 6 graphs to load, I don't care if 1 graph loads 2 seconds in, I want to see how long it takes until every single graph is present.

@Test
public void loadingTime(){
    for(int t = 0; t < 100; t++){
        WebElement first = driver.findElement(By.xpath("//*[@id=\"chart_mnic\"]/svg"));
        WebElement second = driver.findElement(By.xpath("//*[@id=\"chart_ci\"]/canvas[2]"));
        WebElement third = driver.findElement(By.xpath("//*[@id=\"//*[@id=\"chart_cnic\"]/canvas[2]"));
        WebElement fourth = driver.findElement(By.xpath("//*[@id=\"chart_cac\"]/canvas[2]"));
        WebElement fifth = driver.findElement(By.xpath("//*[@id=\"chart_mq\"]/svg"));
        WebElement sixth = driver.findElement(By.xpath("//*[@id=\"chart_cq\"]/canvas[2]"));
        break;
    }
}

So I was wondering whether I do this with an implicit wait or something? I'm fairly new to programming so I can't seem to be able to find a solution.

Any help would be appreciated, even if the solution suggested is entirely different, I'm open to ideas.

GRAPHS IN QUESTION are clickable, if that helps.

Michael Parker
  • 12,724
  • 5
  • 37
  • 58
MG97
  • 87
  • 1
  • 11

3 Answers3

1

The problem with your test is - it is too simple: yes, you dont care which of your six runs takes one second or two seconds. But: you are calling them in sequence. So you always get the time that all of them together take.

You need a more sophisticated solution; basically there are two options:

You take the "timewise" hit; and you just keep that code as it is. But you go as the other answers suggests: and you "measure" the time for each of your requests on its own; like:

for each X in requests
  now = fetch timestamp
  run request X
  then = fetch timestamp
  delta = (then - now)

Of course, when you really want to see what happens when all of these things run in parallel, you have to look into using Thread/Runnables.

EDIT:

First, you should look into ways to measure the execution time for a request; one starting point would be this SO question.

When you are happy with that part, you then look at examples such as this to understand how you use Threads in order to run things in parallel.

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Right, I'd like to look into perhaps making a more complex but solid solution, could you please elaborate on what I'd need to do research on in order to gain the skills to be able to make it all work? – MG97 Aug 26 '16 at 15:15
  • See my updates. Hope that is good enough to get you going; as A) providing more guidance would blow the "scope" of a reasonable answer and B) (honestly) I spent 12 hours today in order to hit the daily-200-limit; and just hit that limit; and I am tired, and close to calling it a day. Anyway, if my input helps you to get going, please accept my answer ;-) – GhostCat Aug 26 '16 at 15:24
0

Get System.currentTimeMillis at the start and end of each iteration. The difference between the two will be how long it took.

0

I would change your function to

@Test
public void loadingTime() {
    String[] xPathToWait = new String[] {
        "//*[@id=\"chart_mnic\"]/svg", "//*[@id=\"chart_ci\"]/canvas[2]", "//*[@id=\"//*[@id=\"chart_cnic\"]/canvas[2]", "//*[@id=\"chart_cac\"]/canvas[2]", "//*[@id=\"chart_mq\"]/svg", "//*[@id=\"chart_cq\"]/canvas[2]"
    };

    WebDriverWait wait = new WebDriverWait(driver, 10); // could be changed to appropriate value

    long startedAt = System.nanoTime();
    for(String xPath : xPathToWait) {
        wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(xPath)));
    }
    long endedAt = System.nanoTime();

    long durationNano = endedAt - startedAt;
    long durationMs = durationNano / 1000000; //if you wish, you can divide the result by 1 million to get duration in milliseconds
}

Explanation

First of all: there's no reason to duplicate the same line (which only differs by xpath) 6 times, so lets rather save all xpaths in one array and access them in loop.

Second: looping for 100 times in hopes something will be found is unreliable. Instead, you can utilize Selenium's explicit wait to find each item exactly once. The timeout (which I set to 10 sec.) should be set to maximal number of seconds you are ready to wait for graph to show up.

Finally System.nanoTime() gives you start and end time, which you can subtract to get the duration in nanoseconds or milliseconds, whichever you prefer.

Why this would work:

  • Test waits for the first graph. Let's say it appeared after X seconds (where X < timeout you specified for the WebDriverWait).
  • It goes to the next graph then. Say, that one already showed up by that time, so the test won't wait
  • Goes to graph 3. Lets (as example) say graph 3 is not yet shown. So it will wait there for Y sec. Thus now total time you get is X + Y which is equal to the time it took for all 3 graphs to load
  • And so on

So in the end you get a duration which is equal to the time it took for all graphs to load. And in this case it takes all graphs to load as long as longest of them.

Alternative option could be to develop a custom ExpectedCondition, which waits for all graphs to load.

timbre timbre
  • 12,648
  • 10
  • 46
  • 77