Sélénium Driver pour les applications WinForms
Toutes les contributions sont les bienvenues :)
Ce projet utilise
Pourquoi un autre pilote, alors qu'il y a déjà https://github.com/microsoft/winappdriver? L'application que je teste est assez grande avec de nombreux éléments, et ce conducteur a chronométré après 60 secondes sur certaines requêtes XPath (voir ce problème), et après avoir tout assemblé, la requête a terminé moins de 2 secondes.
Ce projet repose sur l'automatisation de l'interface utilisateur MS qui fait partie de l'API d'accessibilité Windows.
La documentation officielle mentionne le soutien de diverses plateformes:
L'automatisation de l'interface utilisateur est prise en charge sur les systèmes d'exploitation suivants: Windows XP, Windows Server 2003, Windows Server 2003 R2, Windows Vista, Windows 7, Windows 10, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2, Windows Server 2016 et Windows Server 2019.
Je ne peux pas confirmer que cela fonctionnera sur ces plates-formes car je n'ai gagné que 10 Enterprise sur ma machine, mais toutes les bibliothèques requises font partie du projet.
Pour autant que je sache, le mode développeur n'est pas requis.
Actuellement, il n'y a pas d'installation. Clone le référentiel et construire l'exécutable à partir des sources. Utilisez l'exécutable trouvé sous WinAppDriver.ServerbinDebugWinAppDriver.Server.exe
Le dernier pilote client version 3.141.0.0 doit être utilisé lors de l'appel du serveur.
Ok et Yes , des sous-titres supplémentaires peuvent être ajoutés en définissant acceptAlertButtonCaptions Capabilitys avec une liste de valeurs séparées par semi-colon Cancel et No , des sous-titres supplémentaires peuvent être ajoutés en définissant la capacité de dismissAlertButtonCaptions avec une liste de valeurs séparées par semi-colon Commandes de sélénium non pris en charge
Support XPath:
//node[3] //node[@attribute = 'X'] Seule cette commande Appium est implémentée
Ajoutez une référence à Selenium.WebDriver v3.141.0 (https://www.nuget.org/packages/selenium.webdriver/3.141.0) et vous êtes prêt à partir.
Le pilote peut soit démarrer le système sous le processus de test, soit s'attacher à un processus en cours. Utilisez des capacités pour définir le processus auquel se fixer.
Lorsqu'aucun argument de ligne de commande n'est fourni, le serveur sera lancé à l'adresse IP par défaut http://127.0.0.1:4444 .
Les capacités suivantes sont prises en charge:
mode - start (valeur par défaut) ou attachprocessId - ID du processus pour attacherprocessName - Nom du processus à attacherexePath ou app - Chemin vers l'exécutable pour démarrer le processus (les arguments ne peuvent pas être fournis pour le moment)appWorkingDir - Définissez le répertoire de travail du nouveau processusmainWindowTitle - Expression régulière pour aider le winappdriver à réduire le processus pour se fixersendKeyStrategy ( oneByOne | grouped | setValue ) - Stratégie à utiliser pour taper du texte dans un champ de texte, la valeur par défaut est oneByOne , actuellement cette capacité ne peut pas être modifiée pendant la session public static RemoteWebDriver CreateSessionByStartingTheApplication()
{
DesiredCapabilities desktopCapabilities = new DesiredCapabilities();
desktopCapabilities.SetCapability("app", "<name of the program to start>");
// or "exePath" desktopCapabilities.SetCapability("exePath", "<path to the executable to start the process>");
// following capabilities should be provided for UWP applications like Calculator or Clocks & Alarms
// optional - to set the working directory
desktopCapabilities.SetCapability("appWorkingDir", "<path to run the process in>");
// optional - to identify the process
desktopCapabilities.SetCapability("processName", "<name of the process>");
// optional - to identify the main window
desktopCapabilities.SetCapability("mainWindowTitle", "<name of the process>");
return new RemoteWebDriver(
new CommandExec(new Uri("http://127.0.0.1:4444"),
TimeSpan.FromSeconds(60)),
desktopCapabilities);
}
public static RemoteWebDriver CreateSessionByAttachingToRunningProcess()
{
DesiredCapabilities desktopCapabilities = new DesiredCapabilities();
desktopCapabilities.SetCapability("mode", "attach");
// attach to process using process name
desktopCapabilities.SetCapability("processName", "<name of the process to attach to>");
// with (optional)
desktopCapabilities.SetCapability("windowTitle", "<regular expression to narrow down the list of matching processes>");
// or attach to process using process id
desktopCapabilities.SetCapability("processId", "<id of the process to attach to>");
return new RemoteWebDriver(
new CommandExec(new Uri("http://127.0.0.1:4444"),
TimeSpan.FromSeconds(60)),
desktopCapabilities);
}
L'emplacement de l'élément recommandé utilise l'expression XPATH (bien qu'avec un support d'expression limité)
var webBrowser = session.FindElement(By.XPath("//Pane[@AutomationId='webBrowser']"));
Mécanismes d'emplacement des éléments qui sont pris en charge
TextBox#id Les fenêtres de l'application Win ne sont pas comme Windows dans le navigateur. Les Windows ( ControlType.Window ) peuvent être imbriquées à l'intérieur de l'arborescence de commande, par exemple dans un élément Tab .
La fenêtre peut être située à l'aide de XPath Expression var window = session.FindElement(By.XPath("/Window/Pane/Window[@AutomationId='WindowName']")); ou en passant à informatique session.SwitchTo().Window("WindowName"); , dans le premier exemple, vous obtiendrez la référence de l'élément, dans l'autre, le contexte interne est passé à une nouvelle fenêtre et les éléments mis en cache pendant les opérations suivantes peuvent être éliminées lorsque la fenêtre est clodée session.Close() .
Notez que les emballages d'éléments comme OpenQA.Selenium.Support.UI.SelectElement ne fonctionnent pas car les éléments select et option sont attendus en interne.
Il y a un piratage assez laid qui contourne la nécessité de changer de fenêtre lors de la recherche d'une fenêtre enfant en utilisant l'expression XPATH. Par défaut, la recherche démarre à l'élément racine d'une fenêtre - la fenêtre principale ou la fenêtre vers laquelle l'utilisateur a basculé - et la recherche d'une fenêtre enfant échouait car il n'était pas un enfant direct de la racine actuelle. Le correctif démarre la recherche d'une fenêtre au niveau supérieur.