Blog de JP Gouigoux

15/08/2008

UI Automation : on touche au but !

Filed under: .NET,UIAutomation — jpgouigoux @ 9:51
Tags: , , ,

Miboboio a gagné le droit de me traiter d’andouille, et a eu la noblesse de ne pas le faire dans son commentaire de mon précédent post. Il a pourtant trouvé la solution à mon problème récurrent sur UIAutomation et je l’en remercie vivement !

Son approche est la suivante : puisque le TextPattern ne propose pas de SetValue, mais juste un GetValue, on va passer par le ValuePattern. J’avais essayé ce pattern ainsi que le InvokePattern, mais sans succès. Et c’est là que Miboboio a trouvé l’astuce : dans le cas où la zone de texte ne constitue pas un ValuePattern, il place le focus dessus (pas besoin de passer par un pattern pour ça, c’est appelable directement sur l’instance de AutomationElement), et ensuite fait un System.Windows.Forms.SendKeys.SendWait. Je précise bien le namespace sur le nom de classe, car il ne fait pas partie des espaces de nommages liés à l’UIAutomation.

Je me suis permis de raccourcir un peu le code de Miboboio, et de l’intégrer dans un code complet incluant le lancement du processus à contrôler, de façon que les personnes intéressées puissent simplement copier-coller dans VS.NET et lancer. Je vous laisse aller sur son commentaire pour voir l’original avec tous les commentaires. Et sinon, vous pouvez tester directement ceci :

Process notepad = Process.Start("notepad.exe");
Thread.Sleep(2000);
AutomationElement notepadForm = AutomationElement.FromHandle(notepad.MainWindowHandle);
AutomationElement zoneTexte = notepadForm.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, ""));
TextPattern txtPattern = zoneTexte.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
object valuePattern = null;
if (!zoneTexte.TryGetCurrentPattern(ValuePattern.Pattern, out valuePattern))
{
 zoneTexte.SetFocus();
 Thread.Sleep(500);
 SendKeys.SendWait("coucou");
}
else
{
 zoneTexte.SetFocus();
 ((ValuePattern)valuePattern).SetValue("coucou");
}

Vous aurez juste besoin de rajouter les using ci-dessous :

using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Automation; // inclure l'assembly UIAutomation
using System.Windows.Forms; // inclure l'assembly System.Windows.Forms

Moralité de l’histoire : quand la doc Microsoft dit que ce n’est pas possible de le faire pour des raisons de sécurité… trouvez une autre faille… pardon, une autre façon de faire.

Ah, juste un petit détail : n’essayez pas de faire fonctionner ce code en debug, ou en tout cas, ne passez pas par VS.NET entre le SetFocus et le SendKeys : en effet, dans ce cas-là, le focus repasse à VS.NET, au lieu du contrôle à piloter, et le SendKeys sur VS.NET pendant qu’il est en train de débugger ne se passe pas bien du tout (blocage du processus).

C’est d’ailleurs ça, la clé de l’astuce de Miboboio : quand vous faites un SetFocus sur un AutomationElement, le focus est vraiment passé à l’application piloté. L’UIAutomation ne fonctionne pas comme ManagedSpy++ avec des hooks Windows activés depuis le processus pilote : il envoie vraiment les messages Windows correspondants. Je vous encourage à voir l’article de Frédéric Queudret qui comprend un schéma très détaillé de comment ça fonctionne. J’avais d’ailleurs oublié de donner le lien dans mon post précédent. Désolé. Le voici.

Allez, un dernier lien pour la route : le forum de Microsoft dédié à l’accessibilité. Il y a pas mal de questions sur des cas précis : comment activer une combo, etc. Je pense que je vais trouver les réponses au reste de mes questions là-dedans, et j’espère dans quelques mois avoir mis en place un petit framework pour utiliser tout ça. Idéalement, une grammaire XML pour écrire des tests automatisés sur une application, avec un système de test unitaire embarqué. Bien évidemment, je vous tiendrai au courant.

En attendant, merci encore à Miboboio !

Publicités

Laisser un commentaire »

Aucun commentaire pour l’instant.

RSS feed for comments on this post. TrackBack URI

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Créez un site Web ou un blog gratuitement sur WordPress.com.

%d blogueurs aiment cette page :