【问题标题】:What is wrong with the below selenuim 2/webdriver test?下面的 selenium 2/webdriver 测试有什么问题?
【发布时间】:2011-05-02 02:27:01
【问题描述】:

我无法自动化一个简单的 JSF 登录页面,该页面需要 4 个输入(客户端代码、系统代码、用户和密码)并进入管理页面。下面的测试对每个驱动程序的行为都不同,并且所有驱动程序都不成功。我查看了浏览器中的 html 代码(查看源代码),我看到所有输入类型元素都具有正确的 id。

更新

通过以下更改,我能够使代码在 Firefox 上正常工作(通过显式单击按钮而不是提交表单来提交表单)。但其他驱动程序显示出与所述相同的错误行为。

driver.findElement(By.className("af_commandButton")).click();

代码

import junit.framework.Assert;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class LoginPage
{
    public static void main(final String[] args)
    {
        // WebDriver driver = new InternetExplorerDriver();
        // WebDriver driver = new HtmlUnitDriver();
        WebDriver driver = new ChromeDriver();
        // WebDriver driver = new FirefoxDriver();

        try
        {
            driver.get("http://domain:port/coco/webapp/login/login.faces");

            driver.findElement(By.id("clientCode")).sendKeys("coco");
            driver.findElement(By.id("systemCode")).sendKeys("consumer");
            driver.findElement(By.id("userId")).sendKeys("ffadmin");
            driver.findElement(By.id("password")).sendKeys("password1");

            driver.findElement(By.id("LoginloginForm")).submit();
            // driver.findElement(By.id("login")).click();

            Assert.assertTrue(driver.getPageSource().contains("Administration"));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            driver.quit();
        }
    }
}

铬

信息填写错误如下图

Internet Explorer

org.openqa.selenium.NoSuchElementException: Unable to find element with id == clientCode (WARNING: The server did not pr
ovide any stacktrace information)
System info: os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1', java.version: '1.6.0_24'
Driver info: driver.version: RemoteWebDriver
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:131)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:105)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:409)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:192)
    at org.openqa.selenium.remote.RemoteWebDriver.findElementById(RemoteWebDriver.java:209)
    at org.openqa.selenium.By$1.findElement(By.java:66)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:184)
    at LoginPage.main(LoginPage.java:22)

火狐

如下所示正确填写信息,但是当使用发布的代码提交表单时没有任何反应,我得到了显示的异常

Exception in thread "main" junit.framework.AssertionFailedError: null
    at junit.framework.Assert.fail(Assert.java:47)
    at junit.framework.Assert.assertTrue(Assert.java:20)
    at junit.framework.Assert.assertTrue(Assert.java:27)
    at LoginPage.main(LoginPage.java:30)

HtmlUnitDriver

org.openqa.selenium.WebDriverException: Cannot locate element used to submit form
System info: os.name: 'Windows 7', os.arch: 'x86', os.version: '6.1', java.version: '1.6.0_24'
Driver info: driver.version: unknown
    at org.openqa.selenium.htmlunit.HtmlUnitWebElement.submitForm(HtmlUnitWebElement.java:155)
    at org.openqa.selenium.htmlunit.HtmlUnitWebElement.submit(HtmlUnitWebElement.java:108)
    at LoginPage.main(LoginPage.java:27)

HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html dir="ltr" lang="en-US">
  <head>
    <meta name="generator" content=
    "HTML Tidy for Windows (vers 14 February 2006), see www.w3.org">
    <meta name="generator" content="Apache Trinidad">
    <link rel="stylesheet" charset="UTF-8" type="text/css" href=
    "/coco/webapp/adf/styles/cache/interconnect-zcl0st-en-ltr-webkit.css">
    <script type="text/javascript">
var _AdfWindowOpenError='A popup window blocker has been detected in your browser. Popup blockers interfere with the operation of this application. Please disable your popup blocker or allow popups from this site.';
    </script>
    <script type="text/javascript" src=
    "/coco/webapp/adf/jsLibs/Common1_0_8.js">
</script>
    <script type="text/javascript">
_defaultTZ()
    </script>
    <link rel="stylesheet" href="../skins/interconnect/trinidad-components.css"
    type="text/css">
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <script language="JavaScript" src="../Assets/jquery-1.3.2.min.js" type=
    "text/javascript">
</script>
    <script language="JavaScript" src="../Assets/vsFunctions.js" type=
    "text/javascript">
</script>
    <script language="JavaScript" src="../Assets/ic-script.js" type=
    "text/javascript">
</script>
    <script language="JavaScript" src="../Assets/timezone.js" type=
    "text/javascript">
</script><!--[if lte IE 6]>     

                        <link rel="stylesheet" type="text/css" href="../Assets/ie6fixes.css" />   

                        <script language="JavaScript" src="../Assets/ie6-script.js"></script>   

                <![endif]--><!--[if IE 7]>     

                        <link rel="stylesheet" type="text/css" href="../Assets/ie7fixes.css" />  

                        <script language="JavaScript" src="../Assets/ie7-script.js"></script>

                <![endif]-->

    <script type="text/javascript" language="JavaScript">

                        function disableButton(inputButton)

                        {

                                inputButton.disabled=true;              

                        }

    </script>
    <title></title>
  </head><!-- this is a placehold for application version-->
  <body onload=
  "return _chain('_checkLoad()','readTimeZoneOffset()',this,event)" onunload=
  "_checkUnload(event)">
    <a name="top" id="top"></a><noscript>This page uses JavaScript and requires
    a JavaScript enabled browser.Your browser is not JavaScript
    enabled.</noscript>
    <div class="main-header">
      <div id="header:header-branding" class="header-branding">
        <div id="header:clientbrand" class="client-brand">
          <img id="header:client-image" name="header:client-image" src=
          "/coco/webapp/skins/interconnect/client-logo.gif">
        </div>
      </div>
      <form id="header:_id5" name="header:_id5" style="margin:0px" method=
      "post" onkeypress="return _submitOnEnter(event,'header:_id5');" action=
      "/coco/webapp/login/login.faces">
        <div id="header:basebar" class="basebar">
          <div id="header:finish-right-bar" class="finish-right-bar">
            <ul class="navbar navBarHelp"></ul>
          </div>
        </div><input type="hidden" name=
        "org.apache.myfaces.trinidad.faces.FORM" value="header:_id5"><span id=
        "tr_header:_id5_Postscript"><input type="hidden" name=
        "org.apache.myfaces.trinidad.faces.STATE" value=
        "!24835796"><script type="text/javascript">
function _header__id5Validator(f,s){return true;}
        </script></span><script type="text/javascript">
_submitFormCheck();
        </script>
      </form>
      <div class="rule"></div>
    </div>
    <div class="main-menu">
      <div class="rule"></div>
    </div>
    <div id="content" class="compact content split-lines">
      <div class="content">
        <div class="locale">
          <form id="localeChanger" name="localeChanger" class="spacingDisplay"
          style="margin:0px" method="post" onkeypress=
          "return _submitOnEnter(event,'localeChanger');" action=
          "/coco/webapp/login/login.faces">
            <div class="locale-links">
              <a href="#" onclick=
              "submitForm('localeChanger',1,{source:'changeLocale_en'});return false;"
              id="changeLocale_en" title="English version" name=
              "changeLocale_en"><img id="flagUSA" src=
              "/coco/webapp/Images/upgrade/flag_english.jpg" alt=
              "English version" border="0" name="flagUSA"></a><a href="#"
              onclick=
              "submitForm('localeChanger',1,{source:'changeLocale_es'});return false;"
              id="changeLocale_es" title="Spanish version" name=
              "changeLocale_es"><img id="flagSPAIN" src=
              "/coco/webapp/Images/upgrade/flag_spanish.jpg" alt=
              "Spanish version" border="0" name="flagSPAIN"></a><a href="#"
              onclick=
              "submitForm('localeChanger',1,{source:'changeLocale_fr'});return false;"
              id="changeLocale_fr" title="French version" name=
              "changeLocale_fr"><img id="flagFRANCE" src=
              "/coco/webapp/Images/upgrade/flag_french.jpg" alt=
              "French version" border="0" name="flagFRANCE"></a><a href="#"
              onclick=
              "submitForm('localeChanger',1,{source:'changeLocale_pt'});return false;"
              id="changeLocale_pt" title="Portuguese version" name=
              "changeLocale_pt"><img id="flagBRASIL" src=
              "/coco/webapp/Images/upgrade/flag_portuguese.jpg" alt=
              "Portuguese version" border="0" name="flagBRASIL"></a>
            </div><input type="hidden" name=
            "org.apache.myfaces.trinidad.faces.FORM" value=
            "localeChanger"><span id="tr_localeChanger_Postscript"><input type=
            "hidden" name="org.apache.myfaces.trinidad.faces.STATE" value=
            "!24835796"><script type="text/javascript">
function _localeChangerValidator(f,s){return true;}
            </script></span><script type="text/javascript">
_submitFormCheck();
            </script>
          </form>
        </div>
        <form id="LoginloginForm" name="LoginloginForm" class="spacingDisplay"
        style="margin:0px" method="post" onkeypress=
        "return _submitOnEnter(event,'LoginloginForm','login');" action=
        "/coco/webapp/login/login.faces">
          <h1 class="pageTitle">
            User Authentication
          </h1>
          <div class="wizard">
            <div class="section">
              <div class="content">
                <div class="input">
                  <div class="field">
                    <span class="label"><label for="clientCode">Client
                    Code</label></span>
                    <div class="content">
                      <script type="text/javascript">
var _locale='en-US';var _tLocale='en-US';
                      </script><script type="text/javascript" src=
                      "/coco/webapp/adf/jsLibs/resources/LocaleElements_en_US1_0_8.js?loc=en_US">
</script><span class="af_inputText p_AFRequired"><input id="clientCode"
                      name="clientCode" class="af_inputText_content" size="30"
                      maxlength="20" type="text"></span>
                    </div>
                  </div>
                  <div class="field">
                    <span class="label"><label for="systemCode">System
                    Code</label></span>
                    <div class="content">
                      <span class="af_inputText p_AFRequired"><input id=
                      "systemCode" name="systemCode" class=
                      "af_inputText_content" size="30" maxlength="20" type=
                      "text"></span>
                    </div>
                  </div>
                  <div class="field">
                    <span class="label"><label for="userId">User
                    Id</label></span>
                    <div class="content">
                      <span class="af_inputText p_AFRequired"><input id=
                      "userId" name="userId" class="af_inputText_content" size=
                      "30" maxlength="20" type="text"></span>
                    </div>
                  </div>
                  <div class="field">
                    <span class="label"><label for=
                    "password">Password</label></span>
                    <div class="content">
                      <span class="af_inputText p_AFRequired"><input id=
                      "password" name="password" onkeydown=
                      "return _clearPassword(this, event);" class=
                      "af_inputText_content" size="30" maxlength="20" type=
                      "password"></span>
                    </div>
                  </div>
                </div><img class="wizard-graphic" src=
                "../Images/upgrade/safe_box.jpg">
                <div class="section">
                  <button id="login" name="login" type="button" onclick=
                  "submitForm('LoginloginForm',1,{source:'login'});return false;"
                  class="action af_commandButton">Log In</button><button id=
                  "forgotPassword" name="forgotPassword" type="button" class=
                  "action af_goButton" onclick=
                  "document.location='../forgotpassword/ForgotPassword.faces'">Password
                  Help</button>
                </div>
              </div>
            </div>
          </div>
          <div class="legalNoticeLogin">
            <div class="section">
              <div class="content">
                <div id="legalCopy" class="copy">
                  <div class="xcopy af_outputDocument">
                    <p class="af_outputDocument_paragraph">
                      <b>IMPORTANT - READ CAREFULLY</b>
                    </p>
                    <p class="af_outputDocument_paragraph">
                      The private Web site you are about to enter
                    </p>
                  </div>
                </div>
              </div>
            </div>
          </div><input type="hidden" name=
          "org.apache.myfaces.trinidad.faces.FORM" value=
          "LoginloginForm"><span id="tr_LoginloginForm_Postscript"><input type=
          "hidden" name="org.apache.myfaces.trinidad.faces.STATE" value=
          "!24835796"><script type="text/javascript">
function _LoginloginFormValidator(f,s){return true;}
          </script></span><script type="text/javascript">
_submitFormCheck();
          </script>
        </form>
      </div>
    </div>
  </body>
</html>

【问题讨论】:

  • 您能否向我们展示它试图与之对抗的完整 html
  • 您的页面上可能有多个具有相同 id 的元素?
  • @Tim Koopmans - 添加了生成的 html
  • @Carlosz - 不,ID 不重复...我现在已将 html 添加到问题中

标签: java testing selenium webdriver selenium-webdriver


【解决方案1】:

正确的做法是以下之一:

selenium.click("//button[@id='login']");
driver.findElement(By.Xpath("//button[@id='login']")).click();

我会避免使用提交表单功能,因为看起来登录按钮单击正在触发一些自定义 JavaScript,如果您使用 webDriver 表单提交功能,您将不会触发此功能。

通过尝试单击具有特定类的按钮,您会给自己带来以下问题:

多个元素可以合法地具有相同的类,因此您可能点击了错误的元素。 可以将多个类分配给一个元素,如果应用了多个类并且您正在搜索单个类,它不会总是识别您的元素,您可以使用 XPath 使用 contains 函数来解决这个问题,但如果您有一个完全可服务的 ID 使用此策略是疯狂的,因为使用 contains 可能会再次匹配多个元素,因此您可能不会点击您希望点击的那个。

XPath 包含示例:

selenium.click("//button[contains(@class,'af_commandButton')]");
driver.findElement(By.Xpath("//button[contains(@class,'af_commandButton')]")).click();

【讨论】:

  • " 登录按钮点击正在触发一些自定义的 JavaScript,如果您使用 webDriver 表单提交功能,您将不会触发它。"你能告诉我这是记录在哪里吗?
  • 这不是 Selenium 问题,而是了解浏览器如何工作的问题。提交表单是一个 HTTP 函数,而不是 JavaScript 函数。您不需要启用 JavaScript 来执行 POST/GET。要在 JavaScript 中触发 onClick 事件,您需要单击按钮或编写代码来触发 onClick 事件,它不会通过 HTTP Post 自行发生。
  • 您能否解释一下为什么不同的浏览器驱动程序在填写表单时表现不同?为什么 chrome 或 IE 无法识别文本字段,即使它们都有唯一的 id 并且我使用这些 id 在 selenium 中引用它们?交易
  • 由于该页面不是有效的 W3C 兼容 HTML,因此缺少 。现代浏览器可以很好地猜测丢失的标签应该去哪里并渲染页面,但是每个浏览器都会对 DOM 的结构做出不同的猜测。导致您出现问题的是不同版本的 DOM,它的某些版本可能缺少您尝试填充的元素。向您的开发团队提出错误以使页面符合要求,然后他们再试一次(在具有非 W3C 兼容 HTML 的跨浏览器环境中,自动测试最终总是会失败)
  • 谢谢小费。我没有看到任何丢失的 UL 标签。此外,我正在尝试通过 id 查找 tan 输入元素,我认为这是跨浏览器工作的基本内容。 Firefox 识别所有这些,Chrome 错误识别输入元素和 IE 抱怨它找不到“clientCode”..这打败了我......
【解决方案2】:

对于火狐,

如果您有任何提交表单的 UI 元素,请使用它

说selenium.click("link=submit")

我认为它在提交表单后会立即检查断言(也失败了),但是页面加载需要一些时间。尝试在表单提交后延迟一些时间。您可以使用 waitForPageToLoad() 或 Thread.sleep()。

另外如果页面出现“Administration”文本,先用xpath/css定位器检索文本,再比较,比读取整个页面源要快。

我只在 Selenium 1 上工作过,但我相信您在 Selenium 2 驱动程序中也会有类似的功能。

更新

selenium.click("//div[@class=\'section\']/button[@id=\'login\']") //this will click on login button. Java code for selenium 1

我希望这可行,否则使用 firebug 复制登录按钮的 xpath/css 定位器并将其用作 selenium click 函数的参数。

【讨论】:

  • 感谢您的回复。我已经发布了 html...你能看看它并建议提交响应的最佳方式
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多