处理非预期活动窗口

在 GUI 测试中,出现非预期活动窗口是一个常见问题 -- 例如,HTML 浏览器中的警告消息框。本主题描述如何处理该问题。

假定记录安全页面上的点击,而此链接会链接到不安全的页面。假定已调整您的浏览器安全设置来使消息框出现,以警告您下一页面将不是安全页面。单击确定以关闭警告消息,然后单击非安全页面上的复选框。记录的 Functional Tester 脚本将如下所示:

linkThatLeavesSecurePage().click(); 
Dialog_HtmlDialogButtonOK().click(); 
CheckboxOnTheUnsecurePage().click(); 

当使用安全设置不同的浏览器来回放脚本时,该脚本不会回放,因为找不到 Dialog_HtmlDialogButtonOK()。您可以注释掉 Dialog_HtmlDialogButtonOK().click(); 语句,但是,当对话框确实出现时,将遇到故障。

等待消息出现是一个解决方案。如果它不出现,那么可以继续。可以使用以下代码来实现该解决方案:

linkThatLeavesSecurePage().click();
try 
{
    Dialog_HtmlDialogButtonOK().click();
}
catch(ObjectNotFoundException e) {} 
CheckboxOnTheUnsecurePage().click();

该代码可实现您的主要目标。如果警告消息出现,请将其关闭。如果它不出现,最后请停止等待并继续。然而,您可能不想花费缺省时间量来等待警告消息的出现。如果您确定,只要警告消息确实会出现,它将在 5 秒钟之内出现,那么可以进行编码来加速此操作,如下所示:

linkThatLeavesSecurePage().click();
try
{
    Dialog_HtmlDialogButtonOK().waitForExistence(5,1);
    Dialog_HtmlDialogButtonOK().click();
}
catch(ObjectNotFoundException e) {}
CheckboxOnTheUnsecurePage().click();

此方法的一个现实弊端是:无论浏览器上何处有链接可能切换页面并引起安全性更改,您都需要添加此特别代码。在公共位置处理此情况,而不必更改许多测试脚本将更加有效率。通过实施 onObjectNotFound 异常,无论此事件何时发生,您都能进行处理。通过将该实施置于 helper 超级脚本中,您可以为任何扩展该 helper 超类的 Functional Tester 脚本处理此事件。

以下示例中的代码为测试 HTML 应用程序的脚本实施基类。该基类实施 onObjectNotFoundonObjectNotFound 方法会浏览所有 HTML 域,并查找任何 HTML 对话框。每个 HTML 对话框都通过按 Enter 键来关闭。如果关闭了任何对话框,都会重新启动 TestObject 方法。如果未关闭任何对话框,那么该方法不会执行任何操作,并且会像往常一样抛出 ObjectNotFoundException

import com.rational.test.ft.script.*;
import com.rational.test.ft.object.interfaces.*;
/**
* This class provides some base capabilities for working
* with HTML.
*/
public abstract class HtmlScript extends RationalTestScript
{
/**
* Overrides the base implementation of onObjectNotFound. Whenever
* this event occurs, look through all the active domains (places
* where objects might be found). For HTML domains (Java
* and other domains are skipped) finds all the top objects.
* If the top object is an Html Dialog,
* types an Enter key to dismiss the dialog.
* Logs a warning when this happens.
*/
public void onObjectNotFound(ITestObjectMethodState testObjectMethodState)
{
   boolean dismissedAWindow = false;
   DomainTestObject domains[] = getDomains();
   for (int i = 0; i < domains.length; ++i)
   {
       if (domains[i].getName().equals("Html"))
       {
           // HTML domain is found.
           TestObject[] topObjects = domains[i].getTopObjects();
           if (topObjects != null)
           {
               try
               {
                   for (int j = 0; j < topObjects.length; ++j)
                   {
                       if (topObjects[j].getProperty(".class").equals("Html.Dialog"))
                       {
                           // A top-level HtmlDialog is found.
                           logWarning("HtmlScript.onObjectNotFound - dismissing dialog.");
                           try
                           {
                               dismissedAWindow = true;
                               ((TopLevelTestObject)topObjects[j]).inputKeys("{enter}");
                           }
                           catch(RuntimeException e) {}
                       }
                   }
               }
               finally
               {
                   //unregister all references to top objects
                   unregister(topObjects);
               }
           }
                       
       }
   }
   if (dismissedAWindow)
   {
       //  try again
       testObjectMethodState.findObjectAgain();
   }
   else
   {
       logWarning("HtmlScript.onObjectNotFound; no Html Dialog to dismiss");
   }
}
}

请注意,以上对 HtmlScript 的实施仅适用于测试 HTML。您可能想要能够将此基类用于任何脚本,包括测试 Java™ 的脚本。在此情况下,必须确保在关闭 HTML 对话框前,TestObject 是 Functional Tester HTMLobject。您可以将以下代码添加到 onObjectNotFound 方法的开头:

if (!testObjectMethodState.getTestObject().
          getPropertyFromMap(IMapPropertyName.DOMAIN).equals("Html"))
{
    return;
}

反馈