views:

408

answers:

1

Hi all,

I am kinda new to HtmlUnit and am having some trouble getting a form to submit with HtmlImageInput.click(). When I call the method, nothing seems to happen, no form submission, no round trip to the server, or anything, as far as I can tell. The method returns immediately, returning the current page.

There's no Javascript event handler attached to the image input. It's just a plain old vanilla image input, nothing special going on. The input is initially set to disabled when the page is loaded, and then gets enabled as the user interacts with certain AJAXy elements within the page. But by the time I click on the input, it has already been enabled, so I don't think it's an AJAX issue.

Anybody have an idea of what is going on? Runnable source code pasted below.

Thanks, Matthew

import java.io.*;
import java.util.*;
import com.gargoylesoftware.htmlunit.*;
import com.gargoylesoftware.htmlunit.html.*;
import org.w3c.dom.*;

public class Test {

public static void main(String args[]) {

    try {
        WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_7);
        webClient.setThrowExceptionOnScriptError(false);
        HtmlPage page = webClient.getPage("http://us.megabus.com");
        System.out.println("got the page");
        HtmlForm form = page.getFormByName("ctl01");
        System.out.println("got the form");
        HtmlSelect select = form.getSelectByName("SearchAndBuy1$ddlLeavingFrom");
        select.click();
        System.out.println("clicked the select");
        HtmlOption option = select.getOptionByValue("13");
        option.click();
        System.out.println("clicked the option...going to sleep");
        try { Thread.sleep(15000); } catch(InterruptedException e) {}
        select = form.getSelectByName("SearchAndBuy1$ddlTravellingTo");
        select.click();
        System.out.println("clicked the select 2");
        option = select.getOptionByValue("37");
        option.click();
        System.out.println("clicked the option 2...going to sleep");
        try { Thread.sleep(15000); } catch(InterruptedException e) {}
        HtmlImage image = (HtmlImage)page.getElementById("SearchAndBuy1_imgOutboundDate");
        image.click();
        System.out.println("clicked the image");
        String month = "April";
        String date = "09";
        HtmlTable table = (HtmlTable)page.getElementById("SearchAndBuy1_calendarOutboundDate");
        HtmlTableRow row = ((HtmlTable)table.getCellAt(0, 0).getChildElements().iterator().next()).getRow(0);
        String monthString = row.getCell(1).getTextContent();
        monthString = monthString.substring(0, monthString.indexOf(' '));
        while(!monthString.equals(month)) {
            row.getCell(2).getChildElements().iterator().next().click();
            System.out.println("clicked to go to the next month");
            try { Thread.sleep(15000); } catch(InterruptedException e) {}
            table = (HtmlTable)page.getElementById("SearchAndBuy1_calendarOutboundDate");
            row = ((HtmlTable)table.getCellAt(0, 0).getChildElements().iterator().next()).getRow(0);
            monthString = row.getCell(1).getTextContent();
            monthString = monthString.substring(0, monthString.indexOf(' '));
        }
        DomNodeList<HtmlElement> aList = table.getElementsByTagName("a");
        for (int i = 0; i < aList.size(); i++) {
            HtmlAnchor anchor = (HtmlAnchor)aList.get(i);
            if (anchor.getAttribute("title").equals(DomElement.ATTRIBUTE_NOT_DEFINED) || anchor.getAttribute("title").equals(DomElement.ATTRIBUTE_VALUE_EMPTY))
                throw new RuntimeException("DomElement ATTRIBUTE_NOT_DEFINED or ATTRIBUTE_VALUE_EMPTY");
            if (anchor.getAttribute("title").equals(month + " " + date)) {
                anchor.click();
                try { Thread.sleep(15000); } catch(InterruptedException e) {}
                break;
            }
        }
        HtmlImageInput imageInput = (HtmlImageInput)page.getElementByName("SearchAndBuy1$btnSearch");
        page = (HtmlPage)imageInput.click();
        System.out.println("clicked search button");

    } catch(FailingHttpStatusCodeException e) {
        e.printStackTrace();
    } catch(IOException e) {
        e.printStackTrace();
    } catch(ElementNotFoundException e) {
        e.printStackTrace();
    } catch(IndexOutOfBoundsException e) {
        e.printStackTrace();
    }
}
}
A: 

That image is not an input field, it's just a plain old image:

<img id="SearchAndBuy1_imgOutboundDate" disabled="disabled" alt="calendar"
    CausesValidation="False" src="images/icon_calendar.gif" style="border-width:0px;" />

There are no JS handlers specified there, so they must be attached elsewhere, and seems it's at the bottom of the page:

Sys.Application.add_init(function() {
    $create(AjaxControlToolkit.PopupControlBehavior,
       {"PopupControlID":"SearchAndBuy1_panelOutboundDate","Position":3,"dynamicServicePath":"/default.aspx","id":"SearchAndBuy1_pceImageOutboundDate"}, null, null, $get("SearchAndBuy1_imgOutboundDate"));

});

When your program clicks on the image, there is no form submit, just an AJAX call (presumably), so you're right, you don't get a new page back. But as your code proves (I just ran it with a debugger), the content of the HtmlPage has changed, since it now contains the calendar widget, which you were able to pull details from.

It can be a bit confusing knowing when you will get a net new HtmlPage back, but usually it's only when you would see a whole new page in the browser. I've never tried HtmlUnit against something like Gmail, but I suspect you might only ever deal with the one HtmlPage object, and everything takes places within it.

Rodney Gitzel