Wait For Load State -- possible to wait until 'finish'?

Hello, I regularly encounter the following problem while testing an application at work: let’s say I need the test to click a certain button and then the next keyword follows, like checking if an error message pops up. The test waits for the element (button) to be visible and clicks the button, but the GUI has not registered or responded to it. So the test goes to the next keyword and fails, since the next step is not visible yet on the screen. I could use a sleep keyword, but I don’t want that. So far I have had succes with using Wait For Load State (alternating between ‘‘domcontentloaded’’ and ‘load’), but it’s not enough every time. I still have instances in which a test fails because the test clicks the button but the application or GUI doesn’t register. It seems there is still information being loaded after the ‘load’ event. The last possible event for loading a webpage should be ‘finish’, but there’s no way to wait for that. Does anyone know a way to make sure the tests waits until the ‘finish’ state? I know I could use something like ‘wait until keyword succeeds’ and retry a few times, but then I would need to rewrite all kinds of keywords and group them together to form specific ‘loops’ to retry, so that doesn’t work for me. What I need is to be able to make my ‘click’-keyword wait until everything is loaded. Would it be possible to request this feature as an addition to ‘Wait for load state’? Any other ideas? Thank you.

This was a solution for Selenium Library for a similar issue:

You should be able to do something similar with Browser Library using either Evaluate JavaScript or Wait For Function, never tried this in Browser Library though.

Hope that helps,

Dave.

@JST81 If the click on the button triggers a network response you could use Wait For Response (you can check this in the network tab of your browser). In the documentation for this keyword you see examples how to deal with synchronous and asynchronous situations. Most likely you need the asynchronous example something like:

${promise}= Promise To Wait For Response matcher=**/api/ get/text
Click \#button_submit
${body}= Wait For ${promise}

1 Like

Hi there, there is possibility that you have some things that are happening between your actions like:

  1. Loading element overlay
  2. Buttons that you click are enabled and visible state but may have –inactive class, still ther are clicked and no action happening - I encountered this many times.

First can be handled with e.g.:

Wait For Elements State css=${LOADING_ELEMENT} hidden

Second with something like

Click button:has-text(“Button“):not(.button–inactive):visible

The key is to see what is happening with your actions, try to debug, for example slowering your browser with dev tools or pausing on scripts execution. Maybe this helps.

Thanks all! For now, it seems like the page loads normally but APEX is still doing ‘things’’ afterwards which sometimes causes the test seeing and clicking a button but nothing happens in the GUI. The request timeline of the browser shows ‘‘XHR’’-objects are still being loaded after ‘load’'-state of the page is completed. So I have used ChatGPT to write some Javascript that ‘‘polls’’ the request timeline and only continues when there’s no activity there.

First it waits for ‘‘complete’’ readystate which is basically the same as using ‘‘Wait For Load State’’. Second it polls the request timeline for XHR-objects and only continues if it is quiet. ChatGPT also suggested to wait for ‘spinners’’ or other busy-indicators but my application doesn’t have these.

I am still tweaking this script, since it slows down the tests a bit. But in most cases there will be no activity on the request timeline after load state so the test can continue immediately. It is also possible to wait for other things like fetch or beacon types, but I don’t need these.

It seems to help making my tests more robust and not fail on clicks so much.

Wait Until Page Finished
[Arguments] ${timeout}=60 s ${quiet_window_ms}=400

# 1) Wait for page 'load' first
Wait For Function    () => document.readyState === 'complete'    timeout=${timeout}

# 2) Quiet window: only XHRs to APEX endpoints matter
${QUIET_FUNC}=    Catenate    SEPARATOR=\n
...    () => {
...      const quiet = ${quiet_window_ms};
...      const now = performance.now();
...      const entries = performance.getEntriesByType('resource');
...      for (const e of entries) {
...        const type = String(e.initiatorType || '').toLowerCase();
...        if (type !== 'xmlhttprequest') continue;
...        if (!(e.name.includes('/wwv_flow.ajax') || e.name.includes('/ords/'))) continue;
...        const t = e.responseEnd || e.fetchStart || e.startTime || 0;
...        if ((now - t) < quiet) return false;   // still busy
...      }
...      return true;    // quiet window achieved
...    }
Wait For Function    ${QUIET_FUNC}    timeout=${timeout}

In such case I would raise the white flag and go with WUKS … 3x timeout=5s :smiley:

What do you mean? I can’t use WUKS for the click-keyword since the test sees and clicks the button but nothing happens (or I should add something like retry until the button is not visible anymore). I also can’t use WUKS for the next keyword (e.g. check error message) since it won’t be there. So I would have to wrap these 2 keywords into 1 to be able to use WUKS, but that would mean I would have to do that for dozens of different click actions and their follow-ups throughout the whole suite. So I figured the best way for me is to wait clicking until everything is loaded. But I’ll have to see when & where to use this since it does seem to slow the tests down a bit, still testing :slight_smile:

I don’t know what flow you are testing, but for me if you say that you are making Click upon enabled active element and it does nothing, when supposed to fire onClick this is kinda faulty beahvior and thing to look into with devs of the app. Async functions/actions should and could be handled by Promises –> @falcon030 reply.

BTW, if you just click your app as normal user, I guess you’d expect action-reaction flow. If it works ok with manual and you have no option to straighten things up for your tests maybe experiment with slowMo param in New Browser.