在我的 PageObject 类中,IWebElement 定义如下:
[FindsBy(How = How.XPath, Using = "//input[contains(@ng-model,'model.BrancheName')]/following-sibling::span")]
private IWebElement TooltipBrancheName;
以下方法获取此工具提示的文本:
public string GetTooltiptekstDatabaseBranche()
{
string text = TooltipBrancheName.GetAttribute("class");
Actions actions = new Actions(driver);
actions.MoveToElement(TooltipBrancheName).Perform();
//actions.MoveToElement(driver.FindElement(By.XPath("//input[contains(@ng-model,'model.BrancheName')]/following-sibling::span"))).Perform();
return TooltipBrancheName.GetAttribute("title");
}
当我从测试类中调用此方法时,出现 System.Refelection.TargetException: Object does not match target type. 使用 MoveToElement 方法在线路上抛出异常。
该方法中的第一行代码仅用于检查 ToolTipBrancheName IWebElement 属性是否存在且不为 Null,之所以如此,是因为它为我提供了类属性的正确值。
当我取消注释注释行并注释给出异常的行时,该方法工作正常。两条线使用的定位器是相同的。我很好奇是什么导致了这个异常,字段 ToolTipBrancheName 存在,不为 Null 并且类型正确 IWebElement。
在第二行尝试这个,也许有效:
private IWebElement TooltipBrancheName {get; set;}
一点历史:
昨天,我在测试使用反射比较两个 DTO 的方法时,实际上偶然发现了同样的异常。我的例子中的问题是,我不小心使用了两个不同的 DTO 类(例如
ServerDTO, AccountDTO
),当反射从第一个 DTO 获取属性时,它在第二个 DTO 中找不到它。
疯狂的猜测:
我要在这里进行长距离猜测,并猜测您的
FindsBy
返回的内容与 WebDriver
返回的内容不同。如果您的驱动程序是(例如)ChromeDriver
,它会返回 ChromeWebElement
,但 FindsBy(因为该属性独立于 webdriver)可能会返回 IWebElement(它使用 WebElement
接口)。
但是
当您使用
Actions actions = new Actions(driver);
时,它可能必须使用WebDriver的对象(ChromeWebElement
,FireFoxWebElement
,取决于您使用的驱动程序)。当 Perform()
运行时,它使用反射来获取 WebElement 的属性(例外是一个死的赠品)。此时,也许它假设该元素是 ChromeWebElement
而不是 IWebElement
,(因此例外,它尝试获取 ChromeWebElement
具有但不是 IWebElement
的东西,就像我偶然发现的那样与 DTO)。
附注我上面所说的只是纯粹的假设,但也许它可能会有助于进一步调查。