Manipulando Janelas Ativas Inesperadas

Um problema comum nos testes de GUI é a aparência de uma janela ativa inesperada -- por exemplo, uma caixa de mensagens de aviso em um navegador de HTML. Este tópico descreve como lidar com este problema.

Imagine que você grave um clique em uma página segura e que esse link o leve para uma página que não é segura. Suponha que a configuração de segurança do navegador esteja ajustada para que apareça uma caixa de mensagem avisando que a página seguinte não será segura. Você clica em OK para descartar a mensagem de aviso e, em seguida, clica em uma caixa de opções na página não segura. O script gravado do Functional Tester seria semelhante ao seguinte:

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

Quando você reproduz o script em um navegador com uma configuração de segurança diferente, o script não é reproduzido porque o Dialog_HtmlDialogButtonOK() não pode ser localizado. É possível colocar a instrução Dialog_HtmlDialogButtonOK().click(); como comentário, mas haverá falhas quando o diálogo realmente for exibido.

Uma solução é aguardar que a mensagem apareça. Se não aparecer, você pode continuar. A solução é possível com o seguinte código:

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

Esse código realiza seu objetivo principal. Se a mensagem de aviso aparecer, descarte-a. Se não aparecer, pare de aguardar e então continue. Entretanto, é provável que você não queira aguardar o período de tempo padrão pela exibição da mensagem de aviso. Se tiver certeza que, quando a mensagem de aviso for exibida ela chegará em 5 segundos, poderá acelerar esse tempo codificando da seguinte forma:

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

Uma objeção aceitável para essa abordagem é que esse código especial precisará ser incluído onde quer que um link em um navegador possa alternar páginas e causar alteração na segurança. A manipulação dessa situação em um lugar comum sem alterar muitos scripts de teste seria mais eficiente. A implementação da exceção onObjectNotFound permite manipular o evento sempre que ocorrer. Colocando a implementação em um superscript auxiliar, você pode manipular o evento para qualquer script do Functional Tester que estender essa superclasse auxiliar.

O código no exemplo a seguir implementa uma classe base para scripts que testam aplicativos HTML. Essa classe base implementa onObjectNotFound. O método onObjectNotFound examina todos os domínios HTML e procura todas as caixas de diálogo HTML. Todas as caixas de diálogo HTML são descartadas pressionando Enter. Se alguma delas for descartada, o método TestObject será reiniciado. Se nenhuma for descartada, o método não agirá e a exceção ObjectNotFoundException será lançada normalmente.

import com.rational.test.ft.script.*;
import com.rational.test.ft.object.interfaces.*;
/**
* Essa classe fornece alguns recursos básicos para trabalhar
* com HTML.
*/
public abstract class HtmlScript extends RationalTestScript
{
/**
* Substitui a implementação base de onObjectNotFound. Sempre
 * que esse evento ocorrer, examine todos os domínios ativos (locais
 * em que os objetos podem ser localizados). Para domínios HTML (Java
 * e outros domínios são ignorados) localiza todos os objetos superiores.
 * Se o objeto superior for um Html Dialog,
 * digita uma tecla Enter para descartar o diálogo.
 * Registra um aviso quando isso acontece.
 */
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"))
       {
           // O domínio HTML foi localizado.
           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"))
                       {
                           // Um HtmlDialog de nível superior foi localizado.
                            logWarning("HtmlScript.onObjectNotFound - dismissing dialog.");
                           try
                           {
                               dismissedAWindow = true;
                                ((TopLevelTestObject)topObjects[j]).inputKeys("{enter}");
                           }
                           catch(RuntimeException e) {}
                        }
                   }
               }
                     finally
               {
                   //cancelar o registro de todas as referências a objetos superiores
                    unregister(topObjects);
                }
           }
                       
       }
   }
   if (dismissedAWindow)
    {
       //  tentar novamente
       testObjectMethodState.findObjectAgain();
    }
   else
   {
       logWarning("HtmlScript.onObjectNotFound; no Html Dialog to dismiss");
   }
}
}

Observe que a implementação anterior de HtmlScript serve apenas para teste de HTML. Talvez você queira utilizar esta classe-base para qualquer script, incluindo scripts que testem Java. Nesse caso, é necessário certificar-se de que TestObject seja um HTMLobject do Functional Testes antes de descartar as caixas de diálogo HTML. Você pode incluir o seguinte código no início do método onObjectNotFound:

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

Feedback