java 下面的 selenuim 2/webdriver 测试有什么问题?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5853009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 13:07:45  来源:igfitidea点击:

What is wrong with the below selenuim 2/webdriver test?

javatestingseleniumwebdriverselenium-webdriver

提问by Aravind Yarram

I have trouble automating a simple JSF login page that takes 4 inputs (client code, system code, user and password) and takes to the administration page. The below test is behaving differently with each of the drivers and all of them are unsuccessful. I have looked at the html code from the browser (view source) and I see all the input type elements are present with proper id's.

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

UPDATE

更新

I was able to make the code work correctly with Firefox with the below change (submitting the form by explicitly clicking on the button rather than submitting he form). But other drivers are showing the same erroneous behavior as described.

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

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


Code

代码

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();
        }
    }
}

Chrome

铬合金

Incorrectly filling in the information as shown below

信息填写错误如下图

enter image description here

在此处输入图片说明

Internet Explorer

IE浏览器

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.findElement(By.java:66)
    at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:184)
    at LoginPage.main(LoginPage.java:22)

FireFox

火狐

Fills in the information properly as shown below but nothing happens when the form is submitted with the posted code and I get the shown exception

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

enter image description here

在此处输入图片说明

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

Html 单元驱动程序

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

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>

回答by Ardesco

The correct way to do it would be one of the following:

正确的做法是以下之一:

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

I would avoid using the submit form functionality because it looks like the Log In button click is firing some customised JavaScript, you won't fire this if you use the webDriver form submit functionality.

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

By trying to click on a button with a specific class you are causing yourself the following problems:

通过尝试单击具有特定类的按钮,您会导致以下问题:

More than 1 element can legally have the same class so you may be clicking on the wrong element. Multiple classes can be assigned to an element, if more than one class is applied and you are searching for a single class it will not always recognise your element, you can get arouns this with XPath by using the contains function, but if you have a perfectly servicable ID it is madness to use this strategy as using contains will again potentially match multiple elements so you may not click on the one you are expecting to click on.

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

Example of contains with XPath:

包含 XPath 的示例:

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

回答by 9ikhan

For firefox,

对于火狐,

If you have any UI element that submits the form, please use that

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

say selenium.click("link=submit")

selenium.click("link=submit")

I think It immediately checks for assertion after submitting the form(which also has failed), but it would take some time for page to load. Try putting some delay after form submit. You can use waitForPageToLoad() or Thread.sleep().

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

Also if the Text "Administration" appears on page, first retrieve the text using xpath/css locator first and then compare it, it will be faster than reading the whole page source.

此外,如果页面上出现文本“管理”,首先使用 xpath/css 定位器检索文本然后进行比较,它会比读取整个页面源更快。

I've worked only on Selenium 1, but I'm sure you'll have similar functions in Selenium 2 driver.

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

UPDATE

更新

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

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

I hope this works, otherwise use firebug to copy the xpath/css locator of the login button and use that as argument for selenium click function.

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