I need to hover over a menu option of a website, so that a context menu appears. So I tried both: using the Actions-Class and using the JavaScriptExecutor with a dedicated script in my Page-Object-Model-Selenium project with Pagefactory. But it turns out both of them throw exceptions in POM, while they don't in a non-POM Selenium project. I provided two quick examples, so you can compare the behaviors yourself.
Below is the version without POM, it works:
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();
}
}
}
And here is the version with POM, which only throws exceptions, even though everything else is the same as in the other example:
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; }
}
}
The exceptions are this for Actions:
"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."
And this for the 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."
I am using C# in Visual Studio 2015 with the packages Selenium.WebDriver and Selenium.Support both in version 3.3, there is a bug that prevents me from using 3.4 (see this question). My Selenium Server Standalone is 3.4.0. The behaviors is the same for Chrome, Firefox and Internet Explorer.
Does anyone have an idea of how to make hovering possible in a POM-Project in C#?