2017-05-23 1 views
1

J'ai besoin de survoler une option de menu d'un site Web, afin qu'un menu contextuel s'affiche. J'ai donc essayé les deux: utiliser la classe Actions et utiliser JavaScriptExecutor avec un script dédié dans mon projet Page-Object-Model-Selenium avec Pagefactory. Mais il s'avère que tous les deux jettent des exceptions dans POM, alors qu'ils ne le font pas dans un projet non-POM Selenium. J'ai fourni deux exemples rapides, afin que vous puissiez comparer les comportements vous-même.Le déplacement de la souris n'est pas possible dans Selenium Page Modèle d'objet avec C#

Ci-dessous est la version sans POM, cela fonctionne:

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(); 
    } 
} 
} 

Et voici la version avec POM, qui jette seulement des exceptions, même si tout le reste est le même que dans l'autre exemple:

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; } 
} 
} 

les exceptions sont ce pour les 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." 

Et cela pour la Javascri ptExecutor:

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." 

J'utilise C# dans Visual Studio 2015 avec les paquets Selenium.WebDriver et Selenium.Support aussi bien dans la version 3.3, il y a un bug qui me empêche d'utiliser 3.4 (voir this question). Mon Selenium Server Standalone est 3.4.0. Les comportements sont les mêmes pour Chrome, Firefox et Internet Explorer.

Quelqu'un a-t-il une idée de la façon de faire du vol stationnaire dans un projet POM en C#?

+1

Pouvez-vous vérifier dans le débogage que this.Element a été correctement initialisé quand il est passé au script/action? – FDM

+0

Dans le premier exemple je peux regarder les éléments dans debug sans problème, alors que dans l'exemple POM this.Element montre une erreur "Obtenir le type d'exécution d'un proxy transparent n'est pas supporté dans ce contexte.", Vu dans debug. Donc, je suppose qu'il n'est pas initialisé correctement, comment puis-je changer cela? – Waldi

Répondre

1

J'ai trouvé deux solutions de contournement pour cela. Vous pouvez jeter le FindsByAttribute et définir une propriété vous getter

public IWebElement Element => PomTest.Driver.FindElement(By.Id("nav-questions")); 

ou au lieu d'un IWebElement vous pouvez utiliser un IList de IWebElements puis reportez-vous au premier élément de la liste, le crédit pour cette option va à this question. Ce sera la variante que je me sers, et il ressemble à ceci:

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; }