2012-01-17 82 views
1

下面我正在调试并抛出一个异常,以便找出来自WebDriver的JavaScript调用的值。我怎样才能投出jQuery调用,以便在我的异常消息中打印一个字符串(基于表中ID为“viewtable”的表中tr标签的数量)?我想这与C#代码完全没有关系。我敢打赌,驱动程序不能正确执行jQuery调用,但我不知道正确的语法。无法转换为Selenium 2.0中的System.String Webdriver NUnit测试用例

异常由NUnit的抛出:

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

环境:

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

测试案例的C#代码:
(! “BAD” 寻找下文)

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 = "[email protected]"; 
      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; 
      } 
     } 
    } 
} 
+1

您遇到的问题有所有**都与您的C#代码有关。 Ints不能直接转换为字符串,并且'IJavaScriptExecutor.ExecuteScript()'返回被强制转换为正确类型的'object'。在这种情况下,jQuery选择器中的'.length'属性返回一个JavaScript数字类型,所以C#语言绑定从'ExecuteScript()'调用中返回一个int。 – JimEvans 2012-01-18 11:31:58

回答

2

刚刚从异常我假设ExecuteScript正在恢复为$("query").lengthint64$("query").html()一个string。如果你喜欢数

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

或:

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

不知道的第二个,但第一个应该工作

所以,你可能想试试这个。

+0

这完全正确。您不能直接将数字值转换为字符串。 – JimEvans 2012-01-18 11:33:45

+0

谢谢! .ToString()与cast(string)有什么不同? – MacGyver 2012-01-18 15:18:39

+0

第二个工作顺便说一句,这是我想要的类型,所以我可以在循环中使用它 – MacGyver 2012-01-18 16:24:11

0

似乎这是一个错误,否则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);