为YUI表单提交编写HTMLUnit脚本的问题

时间:2011-09-03 13:07:16

标签: forms button yui jenkins htmlunit

我想为Jenkins(前Hudson)编写一个简单的HTMLUnit测试脚本。信息:Jenkins使用YUI Javascript库。 YUI库使用自定义按钮替换表单提交。该脚本只是在Jenkins中创建了一个新工作。

启动詹金斯: java -jar jenkins.war

当前版本的HTMLUnit不再支持form.submit,并要求您使用button.click()进行表单提交。不幸的是,这对Jenkins不起作用(下面的示例不会使页面前进并创建作业,但会保留在新的作业页面上)

我现在试了几个小时才找到解决方案或解决方法但到目前为止我无法提交表单。希望有人找到解决方案并让我知道。

以下是我的示例代码:

package example;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlButton;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlInput;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;

public class jenkins3 {
     public static void main(String args[]) {
        // create a new job in jenkins
        // home
        final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3_6);
        try {
            final HtmlPage page1 = webClient.getPage("http://localhost:8080");
            //assertEquals("Dashboard [Jenkins]", page1.getTitleText());

            // new job
            final HtmlAnchor new_job = page1.getAnchorByText("New Job");
            final HtmlPage page2 = new_job.click();

            // job name
            HtmlTextInput name_field = (HtmlTextInput) page2.getElementById("name");
            name_field.type("new job by htmlunit");

            // radio button
            final HtmlInput radio_freestyle = (HtmlInput) page2.getByXPath("//input[@value='hudson.model.FreeStyleProject']").get(0);
            radio_freestyle.click();
            Thread.sleep(10000);

            // OK button (submit form)
            final HtmlForm form = page2.getFormByName("createItem");
            //final HtmlSubmitInput button = (HtmlSubmitInput) form.getByXPath("//button").get(0);
            final HtmlButton button = (HtmlButton) form.getByXPath("//button").get(0);

            final HtmlPage page3 = button.click(); // !!!!! Form submit does not workstacko
            //assertEquals("Dashboard [Jenkins]", page3.getTitleText());
        }

        catch( Exception e ) {
            System.out.println( "General exception thrown:" + e.getMessage() );
            e.printStackTrace();
        }

        webClient.closeAllWindows();
    }
}

4 个答案:

答案 0 :(得分:2)

虽然在你的senerio中这可能是完全不可能的:我建议放弃HTMLUnit。我有bug之后的bug,主要是因为我一直在自动化测试的页面并不总是100%有效的html(第三方搭载请求)。我终于去了别的地方,发现PhantomJS(js绑定到WebKit引擎)更适合。 对我来说,优势显而易见: - 不需要其他应用服务器 - 比Java更简单,更快速地编写JS脚本 - 一个“真正的” - 世界引擎比一个错误的模拟器更真实 那是我的建议, 干杯

答案 1 :(得分:1)

HTMLUnit不包括对测试javascript操作的支持。您可能不想在此时切换测试框架,但我建议使用Selenium进行此类测试。它运行一个模拟浏览器并执行javascript,这样就可以做到这一点。

答案 2 :(得分:1)

我发现了这个小技巧。使用HtmlUnit导航到Jenkins登录页面。在登录表单中添加“提交”按钮。为Submit元素设置适当的属性,包括“onclick”值。点击这个新按钮和中提琴!你已经登录了。

注意,如果您不关心安全性,也可以这样做:

webClient.getPage("https://yourdomain:8443/jenkins/j_acegi_security_check?j_username=yourUsername&j_password=yourPassword");

请参阅下面的第一种方法。

享受, 尼克。

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlForm;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class JenkinsLogin {

  final String urlValue = "https://<yourdomain>:8443/jenkins";
  private final String userName = "yourUsername";
  private final String password = "yourPassword";
  protected static final BrowserVersion BROWSER_VERSION_FIREFOX = new BrowserVersion(
          "Netscape", "5.0 (Windows)",
          "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0) Gecko/20100101 Firefox/8.0",
          (float) 1.2);
  private final WebClient webClient = new WebClient(BROWSER_VERSION_FIREFOX);

  public static void main(final String[] args) throws Exception {
    final JenkinsLogin jenkinsLogin = new JenkinsLogin();
    jenkinsLogin.login();
  }

  private void login() throws Exception {

    this.webClient.setThrowExceptionOnScriptError(false);

    HtmlPage page = this.webClient.getPage(this.urlValue + "/login");

    final HtmlForm form = page.getFormByName("login");
    form.getInputByName("j_username").setValueAttribute(this.userName);
    form.getInputByName("j_password").setValueAttribute(this.password);

    final HtmlElement createdElement = page.createElement("input");
    createdElement.setAttribute("type", "submit");
    createdElement.setAttribute("name", "submitIt");
    createdElement.setAttribute("onclick", "login.submit();");
    form.appendChild(createdElement);

    final HtmlElement submitButton = form.getInputByName("submitIt");
    page = submitButton.click();

    final HtmlElement loginField = page.getFirstByXPath("id('login-field')");
    if (loginField == null || !loginField.getTextContent().contains(this.userName))
      throw new RuntimeException("Unable to log on to Jenkins. ");
    System.out.println("Logged in! ");
  }
}

答案 3 :(得分:0)

替换

final HtmlButton button = (HtmlButton) form.getByXPath("//button").get(0);
final HtmlPage page3 = button.click()

form.submit((HtmlButton)last(form.getHtmlElementsByTagName("button")));

工作?