【问题标题】:Unable to cast to System.String in Selenium 2.0 Webdriver NUnit Test Case无法在 Selenium 2.0 Webdriver NUnit 测试用例中转换为 System.String
【发布时间】:2012-01-17 22:37:57
【问题描述】:

下面我正在调试并故意抛出异常以找出来自 WebDriver 的 JavaScript 调用的值。如何转换 jQuery 调用,以便在我的异常消息中打印一个字符串(基于我的表中 tr 标签的数量,id 为“viewtable”)?我想这与 C# 代码完全无关。我敢打赌驱动程序无法正确执行 jQuery 调用,但我不知道正确的语法。

NUnit 抛出异常:

Selenium.ProductPricing.TheUntitledTest:
System.InvalidCastException : Unable to cast object of type 'System.Int64' to type 'System.String'.

环境:

  • 类库项目名为 Selenium.sln/Selenium.csproj
  • 项目引用 NUnit dll 和 Selenium C# 客户端驱动程序,包括 WebDriver dll 文件
  • 项目有一个名为 ProductPricing.cs 的类
  • 在 NUnit 2.6 中运行类库 dll

测试用例 C# 代码:
(在下面搜索“糟糕!”)

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Chrome;
using Selenium;
using System.Text;
using System;

namespace Selenium
{
    [TestFixture]
    public class ProductPricing
    {
        private IWebDriver driver;
        private StringBuilder verificationErrors;
        private string baseURL;

        [SetUp]
        public void Setup()
        {
            driver = new FirefoxDriver();
            baseURL = "http://buyemp.qa.xxx.com/";

            ISelenium selenium = new WebDriverBackedSelenium(driver, baseURL);
            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]
        public void TeardownTest()
        {
            try
            {
                driver.Quit();
            }
            catch (Exception)
            {
                // Ignore errors if unable to close the browser
            }
            Assert.AreEqual("", verificationErrors.ToString());
        }

        [Test]
        public void TheUntitledTest()
        {
            //String var_skip_product = "false";
            String var_admin_user = "coders@xxx.com";
            String var_admin_pass = "notsure";
            driver.Navigate().GoToUrl(baseURL + "/admin");
            driver.FindElement(By.Id("email")).Clear();
            driver.FindElement(By.Id("email")).SendKeys(var_admin_user);
            driver.FindElement(By.Id("password")).Clear(); 
            driver.FindElement(By.Id("password")).SendKeys(var_admin_pass);
            driver.FindElement(By.CssSelector("input[type=\"submit\"]")).Click();            
            driver.WaitForElement(By.LinkText("Products"));
            driver.FindElement(By.LinkText("Products")).Click();
            String var_product_row = "24";  // force script to start on row 24/25

            //// ERROR: Caught exception [unknown command [getTableTrCount]]
            // Command: getTableTrCount | Target: viewtable | Value: var_table_row_count (user extensions don't work in WebDriver)
            IJavaScriptExecutor js = driver as IJavaScriptExecutor;

            // this one throws an exception with value 22 - GOOD!
            //int x = Convert.ToInt32((string)js.ExecuteScript("return '22'"));

            // this one throws an exception with the cast exception - BAD!
            int x = Convert.ToInt32((string)js.ExecuteScript("return $('#viewtable tr').length"));

            // explicitly throwing Selenium exception so we can debug this code in NUnit
            throw new SeleniumException(x.ToString());

            // Command: storeText | Target: //a[@title='last page']/text() | Value: var_page_total_text
            // Conversion: String var_page_total_text = driver.FindElement(By.XPath("//a[@title='last page']/text()")).Text;
            String var_page_total_text = driver.FindElement(By.XPath("//a[@title='last page']")).Text;

            //// ERROR: Caught exception [ERROR: Unsupported command [getEval]]
            // Command: eval | Target: javascript{storedVars['var_page_total_text'].substring(1,storedVars['var_page_total_text'].length-1)}
            //int var_page_total = Convert.ToInt32(var_page_total_text.Substring(1,var_page_total_text.Length-1));           

        }    

        private bool IsElementPresent(By by)
        {
            try
            {
                driver.FindElement(by);
                return true;
            }
            catch (NoSuchElementException)
            {
                return false;
            }
        }
    }
}

【问题讨论】:

  • 您遇到的问题与您的 C# 代码一切有关。 Ints 不能直接转换为字符串,IJavaScriptExecutor.ExecuteScript() 返回一个 object 强制转换为正确的类型。在这种情况下,来自 jQuery 选择器的 .length 属性返回一个 JavaScript 数字类型,因此 C# 语言绑定从 ExecuteScript() 调用返回一个 int。

标签: c# jquery .net webdriver selenium-webdriver


【解决方案1】:

除了例外,我假设ExecuteScript$("query").length 返回一个int64,为$("query").html() 返回一个string

所以你可能想试试这个:

string x = js.ExecuteScript("return $('#viewtable tr').length").ToString();

或者如果您更喜欢数字:

long x = (long)js.ExecuteScript("return $('#viewtable tr').length");

不确定第二个,但第一个应该可以工作。

【讨论】:

  • 这完全正确。您不能将数值直接转换为字符串。
  • 非常感谢! .ToString() 与强制转换为 (string) 有何不同?
  • 第二个工作顺便说一句,这就是我想要的类型,所以我可以循环使用它
  • 是的,(string) 只是将对象转换为字符串,如果对象不是字符串类型,则会失败。 ToString 告诉对象返回其自身的字符串版本
【解决方案2】:

似乎这是一个错误,否则 Selenium 不喜欢选择器的分配。如果你有想法,请告诉我。除非此站点上的 jQuery 版本不支持我用于选择器中附加 tr 的语法。

尽管情况并非如此,因为下面的 Selenium IDE 用户扩展自定义命令可以正常工作。

function jQuery(selector)
{
    return selenium.browserbot.getUserWindow().jQuery(selector);
}

Selenium.prototype.doGetTableTrCount = function(tableName, varStore) { 

    this.doStore(jQuery('#' + tableName + ' tr').length,varStore);
};

这行得通:

IWebElement webElement = (RemoteWebElement)js.ExecuteScript("return $('#viewtable').get(0);");
string jQuerySelector = "arguments[0]";
string x = (string)js.ExecuteScript("return $(" + jQuerySelector + ").html()", webElement);
throw new SeleniumException(x);

这行得通:

string x = (string)js.ExecuteScript("return $('#viewtable').html()");
throw new SeleniumException(x);

这不起作用:

IWebElement webElement = (RemoteWebElement)js.ExecuteScript("return $('#viewtable tr').get(0);");
string jQuerySelector = "arguments[0]";
string x = (string)js.ExecuteScript("return $(" + jQuerySelector + ").length", webElement);
throw new SeleniumException(x);

这不起作用:

string x = (string)js.ExecuteScript("return $('#viewtable tr').length");
throw new SeleniumException(x);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多