FrameworkDemoiselle.gov.brCommunity Documentation

Capítulo 3. Mapeamento de Classes

3.1. Capturando os objetos da tela a serem utilizados
3.2. Classe de Mapeamento
3.3. Mapeamento Parametrizável
3.4. Composição de Telas (Embedded Screens)
3.5. Sistemas com AJAX (Componente Loading)

Esta seção apresenta um roteiro para criação de scripts visuais.

O primeiro passo na criação de um script no Demoiselle-Behave é a escolha dos objetos visuais que serão utilizados. Os objetos poderão ser identificados de diversas formas como Id, XPath ou CSS. Estas diferentes formas de encontrar um objeto na tela são denominadas localizadores. Neste tutorial serão utilizadas algumas ferramentas de apoio para a escolha dos objetos. De forma exemplificativa o tutorial apresentará um exemplo onde o usuário buscará uma informação na página do SERPRO(www.serpro.gov.br).

O próximo passo é utilizar uma ferramenta de apoio para escolher os objetos. O XPath Checker e o FirePath são ferramentas que permitem obter o Xpath de objetos na tela (https://addons.mozilla.org/pt-br/firefox/addon/xpath-checker/)(https://addons.mozilla.org/en-US/firefox/addon/firepath/).

Após instalação das ferramentas de apoio devem ser escolhidos os objetos que devem interagir com a tela. De forma a exemplificar o processo será realizada uma pesquisa na página do SERPRO (www.serpro.gov.br). Será selecionado o campo de busca e o botão de pesquisa. Utilizando o firepath será identificado o id do campo de pesquisa.

Uma vez utilizado o firepath descobre-se que o xpath do campo de busca possui o valor .//*[@id='searchGadget'] e o xpath do botão de busca possui o valor .//*[@id='livesearch0']/div/input[1] .

O próximo passo será implementar uma classe com o mapeamento dos objetos a serem testados e seus identificadores.

package packageName;

import br.gov.frameworkdemoiselle.behave.annotation.ElementLocatorType;
import br.gov.frameworkdemoiselle.behave.annotation.ElementMap;
import br.gov.frameworkdemoiselle.behave.annotation.ScreenMap;
import br.gov.frameworkdemoiselle.behave.runner.ui.Button;
import br.gov.frameworkdemoiselle.behave.runner.ui.TextField;

@ScreenMap(name = "Tela Inicial", location = "https://www.serpro.gov.br")
public class MyPage {

	@ElementMap(name = "Campo de Busca", locatorType = ElementLocatorType.XPath, locator = ".//*[@id='searchGadget']")
	private TextField searchField;

	@ElementMap(name = "Estou com sorte", locatorType = ElementLocatorType.XPath, locator = ".//*[@id='livesearch0']/div/input[1]")
	private Button button;

}

O motor do framework escolhe automaticamente que ação será realizada dependendo do tipo de objeto aplicado ao elemento da interface gráfica. No exemplo acima o tipo Button indica que a ação de clique deve ser realizada.

Outros tipos de elementos são CheckBox, Link, Radio, Screen, Select e TextField. Para cada elemento visual foi criada uma interface que é implementada por uma classe que define como a ação deve ser realizada.

package br.gov.frameworkdemoiselle.behave.runner.ui;

import br.gov.frameworkdemoiselle.behave.runner.ui.base.BaseUI;

public interface Radio extends BaseUI {

	public void click();
	
}

A seguir segue implementação da classe Radio para Web utilizando Selenium.

package br.gov.frameworkdemoiselle.behave.runner.webdriver.ui;

import br.gov.frameworkdemoiselle.behave.runner.ui.Radio;

public class WebRadio extends WebBase implements Radio {

	public void click() {
		waitElement(0);

		getElements().get(0).click();
	}

}

A implementação da classe para a interface visual é configurada utilizando o conceito de SPI no framework. Para cada interface existe um arquivo que indica qual implementação será escolhida para cada interface.

É possível por meio de frases pré definidas parametrizar o locator.

Em uma determinada situação será necessário que seja selecionado um botão que está presente em uma linha que possui na sua primeira coluna a palavra "Brasil", para facilitar esta tarefa foram criados os locators parametrizáveis. O primeiro passo será criar o mapeamento na classe como mostra o exemplo abaixo.

@ElementMap(name = "Excluir", locatorType = ElementLocatorType.XPath, locator = "(//tr[contains(@id, 'tr-identification')][.//text()='%param1%']//button)[1]")
private Button botao;

Perceba que no locator existe o trecho %param1%, esse é o identificador para que na história seja passado algum texto para ser inserido neste local, como por exemplo:

Quando clico em "Excluir" referente a "Brasil"

Também é possível passar mais de um parâmetro para a frase como no exemplo abaixo (os valores devem ser separados por vírgula):

// Mapeamento do Campo
@ElementMap(name = "Excluir", locatorType = ElementLocatorType.XPath, locator = "(//tr[contains(@id, '%param1%')][.//text()='%param2%']//button)[1]")
private Button botao;

// Frase na história
Quando clico em "Excluir" referente a "obra, valor"

As seguintes frases permitem a parametrização do texto do locator:

O framework fornece uma anotação (@Embedded) que permite que sejam reutilizadas telas dentro de outras telas. Como exemplo vamos utilizar uma tela de login abaixo:

@ScreenMap(name = "Tela de Login", location = "/")
public class LoginPage {

	@ElementMap(name = "Campo Usuário", locatorType = ElementLocatorType.XPath, locator = "(//input[contains(@id, 'formLogin')][contains(@type, 'text')])[1]")
	private TextField campoUsuario;

	@ElementMap(name = "Campo Senha", locatorType = ElementLocatorType.XPath, locator = "(//input[contains(@id, 'formLogin')][contains(@type, 'password')])[1]")
	private TextField campoSenha;

	@ElementMap(name = "Entrar", locatorType = ElementLocatorType.XPath, locator = "(//button[contains(@id, 'formLogin')][contains(@type, 'submit')])[1]")
	private Button botaoEnviar;

}

Para que a tela de login seja utilizada em várias partes públicas do sistema basta que em qualquer ScreenMap seja criado um atributo da seguinte maneira:

@Embedded
private LoginPage loginPage;

Isso fará com que a tela de login seja incorporada na tela que possuir o atributo com a anotação.

O framework fornece um componente de tela chamado Loading, que auxilia no tratamento das ações AJAX que normalmente têm como comportamento padrão abrir um elemento em cima do conteúdo com uma imagem/texto de "Carregando...", impedindo o acesso aos outros elementos de tela, enquanto a imagem/texto é exibida. O componente tem como objetivo aguardar que a imagem desapareça para ir para o próximo passo. Para utilizar o componente, adicione em qualquer ScreenMap um ElementeMap com tipo Loading como mostra abaixo:

@ElementMap(name = "Carregando", locatorType = ElementLocatorType.XPath, locator = "/HTML/BODY/DIV[2]/DIV[1]/SPAN[@id='ui-dialog-title-j_idt9']")
private Loading loading;

Basta adicionar o Loading em um ScreenMap para que funcione para todas as telas.

A partir da versão 1.4.3 a anotação @ElementMap possui um atributo forceWaitLoading que por padrão é false. Em casos muito específicos ele tem como objetivo forçar a espera do elemento de loading mapeado aparacer, ou seja, quando o elemento estiver com esta propriedade forceWaitLoading = true o dbehave irá aguardar pelo maxWait o loading aparecer e em seguinda desaparecer antes de executar a próxima ação. Abaixo esta um exemplo de utilização:

@ElementMap(name = "NOME DO ELEMENTO NA HISTÓRIA", forceWaitLoading = true, locatorType = ElementLocatorType.Id, locator = "ID DO ELEMENTO")
private TextField field;