PBA
PBA

Reputation: 415

HtmlUnit wait for ajax response

I have this project where I need to use one site to get data from it. So the thing is: using htmlunit I fill textbox with my data, then I press on anchor which is using ajax do download content I need and dynamically change HTML page, showing content in modal window. But after i use .click() on anchor I get the same page, without been updated, and after looking around for solution I found this on web:

HtmlUnit will execute the Ajax call and will update the page. Just observe that, unlike a regular page loading, the click() call will not wait for the completion of the Ajax request. It will proceed to the next line of code right away.

Here is my code:

final HtmlPage page = webClient.getPage("myUrl");
System.out.println(page.asXml());
final HtmlForm form =    page.getFirstByXPath("//form[@action='myFormAction']");
final HtmlTextInput input = form.getInputByName("url");
input.setText(vacancyURL);

List<HtmlAnchor> anchors = page.getAnchors();
HtmlAnchor link = null;

    for (HtmlAnchor anchor : anchors) {
        String str = anchor.asText();
        if (anchor.asText().equals("Start"))
            link = anchor;
    }

    HtmlPage page2 = link.click(); //I think this is a problem

Any ideas how can I click on anchor and wait for ajax to receive response back, and fill page with data(on browser everything works great)? I really need help, any ideas?

Upvotes: 2

Views: 6833

Answers (3)

qfrank
qfrank

Reputation: 272

oh, this is an old question..i want to share my solution.. i think page.wait is disgusting...because u won't get notified immediately when ajax request finished,there will be a delay.. my answer is using method

com.gargoylesoftware.htmlunit.javascript.background.JavaScriptJobManager#waitForJobs

invoke example: page.getEnclosingWindow().getJobManager().waitForJobs(1000);

page is a type of com.gargoylesoftware.htmlunit.html.HtmlPage

1000 is timeoutMillis which means the max time in millis u want to wait

Upvotes: 4

maxmax
maxmax

Reputation: 778

I agree with Tasawer, relying upon a state / element is usually a good thing.

Depending the javascript on the remote website, you can also ask the webclient how many javscripts threads are still in progress. For eg:

int wait = 0;
int nbProcess = 1;
while (nbProcess > 0 && wait < 10) {
   nbProcess = client.waitForBackgroundJavaScript(1000);
      if (wait == 9) {
         System.err.println("** needs more time ** ");
      }
   wait++;
}

Warning : some sites can have one or more scripts perpetually running so the minimal nbProcess could be 1, 2 ...

Link to javadoc

Upvotes: 1

Tasawer Nawaz
Tasawer Nawaz

Reputation: 925

yes you have to wait for execution, best is to retrying for some time until page is not updated (using any condition) here is example of code

    int input_length = page.getByXPath("//input").size();
    int tries = 5; 
    while (tries > 0 && input_length < 12) { //you can change number of tries and condition according to your need
        tries--;
        synchronized (page) {
            page.wait(2000); //wait
        }
        input_length = page.getByXPath("//input").size(); //input length is example of condtion
    }

Upvotes: 1

Related Questions