Javascript 在带有C的Selenium页面对象模型中不可能鼠标悬停#

Javascript 在带有C的Selenium页面对象模型中不可能鼠标悬停#,javascript,c#,selenium,selenium-webdriver,pageobjects,Javascript,C#,Selenium,Selenium Webdriver,Pageobjects,我需要将鼠标悬停在网站的菜单选项上,以便出现上下文菜单。因此,我尝试了两种方法:使用Actions类和JavaScriptExecutor,并在我的页面对象模型Selenium项目中使用Pagefactory的专用脚本。但事实证明,它们都在POM中抛出异常,而在非POM Selenium项目中则没有。我提供了两个快速示例,以便您可以自己比较这些行为 以下是没有POM的版本,它可以工作: using System; using Microsoft.VisualStudio.TestTools.Un

我需要将鼠标悬停在网站的菜单选项上,以便出现上下文菜单。因此,我尝试了两种方法:使用Actions类和JavaScriptExecutor,并在我的页面对象模型Selenium项目中使用Pagefactory的专用脚本。但事实证明,它们都在POM中抛出异常,而在非POM Selenium项目中则没有。我提供了两个快速示例,以便您可以自己比较这些行为

以下是没有POM的版本,它可以工作:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Support.Events;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace UnitTestProject1
{
[TestClass]
public class SimpleTest
{
    public static EventFiringWebDriver Driver { get; set; }

    [TestMethod]
    public void TestMethod1()
    {
        var caps = new DesiredCapabilities();
        caps.SetCapability("browserName", "internet explorer");
        SimpleTest.Driver = new EventFiringWebDriver(new RemoteWebDriver(new Uri("http://127.0.0.1:4444/wd/hub"), caps, TimeSpan.FromSeconds(120)));
        SimpleTest.Driver.Navigate().GoToUrl("https://www.stackoverflow.com");
        var element = SimpleTest.Driver.FindElement(By.Id("nav-questions"));

        // using Actions
        // does not throw an exception
        new Actions(SimpleTest.Driver).MoveToElement(element).Perform();

        // using JavaScript
        // does not throw an exception
        var mouseOverScript = @"if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj); } else if(document.createEventObject) { arguments[0].fireEvent('onmouseover'); }";
        ((IJavaScriptExecutor)SimpleTest.Driver).ExecuteScript(mouseOverScript, element);
    }

    [TestCleanup]
    public void Cleanup()
    {
        SimpleTest.Driver.Quit();
    }
}
}
下面是POM版本,它只抛出异常,尽管其他所有内容与另一个示例中的相同:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Support.Events;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Support.PageObjects;

namespace UnitTestProject1
{
[TestClass]
public class PomTest
{
    public PomTest()
    {
        var caps = new DesiredCapabilities();
        caps.SetCapability("browserName", "chrome");
        PomTest.Driver = new EventFiringWebDriver(new RemoteWebDriver(new Uri("http://127.0.0.1:4444/wd/hub"), caps, TimeSpan.FromSeconds(120)));
        PomTest.Driver.Navigate().GoToUrl("https://www.stackoverflow.com");
    }

    public static EventFiringWebDriver Driver { get; set; }

    [TestMethod]
    public void TestMethod1()
    {
        var page = new SoPage();
        page.HoverWithActions();
        page.HoverWithJS();
    }

    [TestCleanup]
    public void Cleanup()
    {
        PomTest.Driver.Quit();
    }
}

public class SoPage
{
    public SoPage()
    {
        PageFactory.InitElements(PomTest.Driver, this);
    }

    public void HoverWithActions()
    {
        // using Actions
        // throws System.Reflection.TargetException;
        new Actions(PomTest.Driver).MoveToElement(this.Element).Perform();
    }

    public void HoverWithJS()
    {
        // using JavaScript
        // throws System.ArgumentException
        var mouseOverScript = @"if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj); } else if(document.createEventObject) { arguments[0].fireEvent('onmouseover'); }";
        ((IJavaScriptExecutor)PomTest.Driver).ExecuteScript(mouseOverScript, this.Element);
    }

    [FindsBy(How = How.Id, Using = "nav-questions")]
    public IWebElement Element { get; set; }
}
}
例外情况如下:

"System.Reflection.TargetException: Das Objekt stimmt mit dem Zieltyp nicht überein.
   bei System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
   bei System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   bei System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   bei OpenQA.Selenium.Support.PageObjects.WebDriverObjectProxy.InvokeMethod(IMethodCallMessage msg, Object representedValue)
   bei OpenQA.Selenium.Support.PageObjects.WebElementProxy.Invoke(IMessage msg)
   bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   bei OpenQA.Selenium.ILocatable.get_Coordinates()
   bei OpenQA.Selenium.Interactions.Internal.MouseAction.get_ActionLocation()
   bei OpenQA.Selenium.Interactions.MoveMouseAction.Perform()
   bei OpenQA.Selenium.Interactions.CompositeAction.Perform()
   bei OpenQA.Selenium.Interactions.Actions.Perform()
   bei UnitTestProject1.SoPage.HoverWithActions() in c:\\users\\lwa\\documents\\visual studio 2015\\Projects\\UnitTestProject1\\UnitTestProject1\\PomTest.cs:Zeile 50.
   bei UnitTestProject1.PomTest.TestMethod1() in c:\\users\\lwa\\documents\\visual studio 2015\\Projects\\UnitTestProject1\\UnitTestProject1\\PomTest.cs:Zeile 28."
这对于JavaScriptExecutor来说是:

System.ArgumentException: Argument is of an illegal typeOpenQA.Selenium.Support.Events.EventFiringWebDriver+EventFiringWebElement
Parametername: arg
   bei OpenQA.Selenium.Remote.RemoteWebDriver.ConvertObjectToJavaScriptObject(Object arg)
   bei OpenQA.Selenium.Remote.RemoteWebDriver.ConvertArgumentsToJavaScriptObjects(Object[] args)
   bei OpenQA.Selenium.Remote.RemoteWebDriver.ExecuteScriptCommand(String script, String commandName, Object[] args)
   bei OpenQA.Selenium.Remote.RemoteWebDriver.ExecuteScript(String script, Object[] args)
   bei OpenQA.Selenium.Support.Events.EventFiringWebDriver.ExecuteScript(String script, Object[] args)
   bei UnitTestProject1.SoPage.HoverWithJS() in c:\\users\\lwa\\documents\\visual studio 2015\\Projects\\UnitTestProject1\\UnitTestProject1\\PomTest.cs:Zeile 58.
   bei UnitTestProject1.PomTest.TestMethod1() in c:\\users\\lwa\\documents\\visual studio 2015\\Projects\\UnitTestProject1\\UnitTestProject1\\PomTest.cs:Zeile 29."
我正在Visual Studio 2015中使用C#,并附带Selenium.WebDriver和Selenium包。在版本3.3中支持这两个版本,但有一个bug阻止我使用3.4(请参阅)。我的Selenium服务器单机版是3.4.0。Chrome、Firefox和Internet Explorer的行为相同


有人知道如何在C#中的POM项目中实现悬停吗?

我找到了两种解决方法。您可以放弃FindsByAttribute,自己定义一个属性getter

public IWebElement Element => PomTest.Driver.FindElement(By.Id("nav-questions"));
或者,您可以使用IWebElement的IList来代替IWebElement,然后引用列表中的第一个元素,该选项的贷方为。 这将是我正在使用的变体,它看起来如下所示:

public void HoverWithActions()
{
    // using actions
    // now it works :)
    new Actions(PomTest.Driver).MoveToElement(this.Elements.First()).Perform();
}

public void HoverWithJS()
{
    // using Javascript
    // now it works :)
    var mouseOverScript = @"if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj); } else if(document.createEventObject) { arguments[0].fireEvent('onmouseover'); }";
    ((IJavaScriptExecutor)PomTest.Driver).ExecuteScript(mouseOverScript, this.Elements.First());
}

[FindsBy(How = How.Id, Using = "nav-questions")]
public IList<IWebElement> Elements { get; set; }
public void HoverWithActions()
{
//使用动作
//现在它起作用了:)
新操作(PomTest.Driver).MoveToElement(this.Elements.First()).Perform();
}
public void HoverWithJS()
{
//使用Javascript
//现在它起作用了:)
var mouseOverScript=@“if(document.createEvent){var evObj=document.createEvent('MouseEvents');evObj.initEvent('mouseover',true,false);参数[0]。dispatchEvent(evObj);}else if(document.createEventObject){arguments[0]。fireEvent('onmouseover');}”;
((IJavaScriptExecutor)PomTest.Driver).ExecuteScript(mouseOverScript,this.Elements.First());
}
[FindsBy(How=How.Id,使用=“导航问题”)]
公共IList元素{get;set;}

您能在debug中检查此.Element在传递给脚本/操作时是否已正确初始化吗?在第一个示例中,我可以毫无问题地查看debug中的元素,而在POM示例中,此.Element显示错误“此上下文中不支持获取透明代理的运行时类型”,在调试中查看时。所以我猜它没有正确初始化,我该如何更改它?