WatiN框架学习二——对弹窗的处理

以IE为例,WatiN处理弹出窗口:

1             IE ie = new IE("string"); //打开指定web页
2             ie.Button(Find.ById("string")).Click(); //点击相应的按钮弹出需要测试的窗口TestSecondWindow
3             IE newIE = IE.AttachTo<IE>(Find.ByTitle("TestSecondWindow")); // 查找新窗口TestSecondWindow并赋给新的IE对象
4             //TODO: write the code you need to test in newIE  
View Code

WatiN处理confirm对话框:

1          IE ie = new IE(string); //打开指定web页
2          ConfirmDialogHandler cdh = new ConfirmDialogHandler();
3          ie.AddDialogHandler(cdh); //将ConfirmDialogHandler对象与IE建立关联
4          ie.Button(Find.ById(string)).ClickNoWait(); //记住这里要用ClickNoWait而不能用Click,否则在模式窗口关闭之前代码不会继续执行。
5          cdh.WaitUntilExists();
6          cdh.OKButton.Click(); 
7          ie.WaitForComplete();
8          ie.RemoveDialogHandler(cdh); // ConfirmDialogHandler对象与IE取消关联
View Code

这里需要注意的是Click()方法与ClickNoWait()方法的区别,先来看看Click()方法

1         /// <summary>
2         /// Clicks this element and waits till the event is completely finished (page is loaded 
3         /// and ready) .
4         /// </summary>
5         public virtual void Click()
6         {
7             ClickImpl(true);
8         }
View Code

接下来是ClickNoWait()方法:

1         /// <summary>
2         /// Clicks this instance and returns immediately. Use this method when you want to continue without waiting
3         /// for the click event to be finished. Mostly used when a 
4         /// HTMLDialog or javascript popup is displayed after clicking the element.
5         /// </summary>
6         public virtual void ClickNoWait()
7         {
8             ClickImpl(false);
9         }
View Code

从上面两段代码上看,可以发现,它们都调用了ClickImpl(bool xxx)方法,只是一个是true一个是false,那么被定义的bool值又是什么呢?找到ClickImpl()方法:

 1         /// <summary>
 2         /// Handles the implementation of Click and ClickNoWait
 3         /// </summary>
 4         protected virtual void ClickImpl(bool waitforComplete)
 5         {
 6             if (!Enabled)
 7             {
 8                 throw new ElementDisabledException(IdOrName, this);
 9             }
10 
11             Logger.LogAction((LogFunction log) => { log("Clicking (no wait) {0} '{1}', {2}", GetType().Name, IdOrName, Description); });
12 
13             Highlight(true);
14 
15             if (waitforComplete)
16             {
17                 FireEvent("onclick");
18             }
19             else
20             {
21                 FireEventNoWait("onclick");
22             }
23 
24             try
25             {
26                 if (waitforComplete) WaitForComplete();
27             }
28             finally
29             {
30                 Highlight(false);
31             }
32         }
View Code

原来bool值表示的是WaitForComplete, 撇开其他代码,先找到下面判断语句:

1             if (waitforComplete)
2             {
3                 FireEvent("onclick");
4             }
5             else
6             {
7                 FireEventNoWait("onclick");
8             }
View Code

问题转变成FireEvent()方法及FireEventNoWait()方法之间的区别,先找到FireEvent()方法:

1         /// <summary>
2         /// Fires the specified <paramref name="eventName"/> on this element
3         /// and waits for it to complete.
4         /// </summary>
5         /// <param name="eventName">Name of the event.</param>
6         public virtual void FireEvent(string eventName)
7         {
8             FireEvent(eventName, true, null);
9         }
View Code

看到这段代码,想来,和FireEventNoWait()方法之间的区别可能还会是其中某个bool值的区别,果不其然,看FireEventNoWait()方法:

1         /// <summary>
2         /// Only fires the specified <paramref name="eventName"/> on this element.
3         /// </summary>
4         public virtual void FireEventNoWait(string eventName)
5         {
6             FireEvent(eventName, false, null);
7         }
View Code

这两个方法都是调用FireEvent(string xxx, bool xxx, ?)方法,且区别仅在于bool值的设定,先不管,跳到这个方法看看先:

 1         private void FireEvent(string eventName, bool waitForComplete, NameValueCollection eventProperties)
 2         {
 3             if (!Enabled)
 4             {
 5                 throw new ElementDisabledException(IdOrName, this);
 6             }
 7 
 8             Highlight(true);
 9 
10             if (waitForComplete)
11             {
12                 NativeElement.FireEvent(eventName, eventProperties);
13                 WaitForComplete();
14             }
15             else
16             {
17                 NativeElement.FireEventNoWait(eventName, eventProperties);
18             }
19 
20             Highlight(false);
21         }
View Code

到这里会发现,重点在以下代码中:

1             if (waitForComplete)
2             {
3                 NativeElement.FireEvent(eventName, eventProperties);
4                 WaitForComplete();
5             }
6             else
7             {
8                 NativeElement.FireEventNoWait(eventName, eventProperties);
9             }
View Code

而最主要的在于WaitForComplete()方法的调用上,也就是在ClickNoWait()方法边上注释上所说的,如果用Click()方法,代码在往下走之前一定会等待模式窗口关闭,一旦关闭才是WaitForComplete()完成,因此,使用Click()方法的话,表面看起来整个程序会停着不动,从而达不到对对话框的处理效果。

作者:Ribbon 出处: http://www.cnblogs.com/Ribbon/ 本文版权归作者和博客园共有,欢迎转载。未经作者同意下,必须在文章页面明显标出原文链接及作者,否则保留追究法律责任的权利。 如果您认为这篇文章还不错或者有所收获,可以点击右下角的【推荐】按钮,因为你的支持是我继续写作,分享的最大动力!
原文地址:https://www.cnblogs.com/Ribbon/p/4332651.html