Este documento fornece informações de referência sobre scripts Robo, incluindo estrutura, recursos, uso, gravação e ações. Os scripts Robo são testes que automatizam tarefas manuais de garantia de qualidade (QA) para aplicativos móveis e permitem integração contínua (CI) e estratégias de teste de pré-lançamento. Um script Robo é um arquivo JSON que descreve uma sequência de interface do usuário (IU) e outras ações.
Você pode criar um script Robo das seguintes maneiras:
Use o recurso de gravação de script Robo. (somente Android)
Crie o script Robo manualmente. (Android e iOS+)
Grave o script Robo e edite-o manualmente. (somente Android)
Para saber mais sobre como usar scripts Robo, consulte Executar um script Robo .
Introdução
O script Robo é fornecido para o teste Robo junto com outras entradas, como o pacote de aplicativos Android (APK) do aplicativo em teste.
Veja a seguir um exemplo de script Robo que conecta um usuário a um aplicativo, que é acionado quando o aplicativo em teste é iniciado:
[
{
"crawlStage": "crawl",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "user123",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/username"
}
]
},
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "12345",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/password"
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/login"
}
]
}
]
}
]
Se houver um único script Robo em um arquivo e ele tiver a condição de acionamento padrão app_under_test_shown
, como no exemplo acima, você poderá especificar o script Robo em um arquivo usando um formato mais simples - apenas como uma sequência de suas ações:
[
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "user123",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/username"
}
]
},
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "12345",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/password"
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/login"
}
]
}
]
Suporte iOS+ para scripts Robo
Robo para iOS+ (Beta) tem suporte limitado para scripts Robo. A sintaxe do script Robo para iOS+ é idêntica à sintaxe do Android, e os recursos suportados do iOS+ se comportam de maneira semelhante aos seus equivalentes do Android.
As seguintes ações são suportadas no iOS+:
- Afirmação
- Clique
- Clique longo
- Deslizar
- Ignorar todos os elementos
- Espere
- Tirar captura de tela
- Encerrar rastreamento
Os seguintes atributos de identificação em descritores de elementos são suportados no iOS+:
- Nome da classe
- Nome da classe ancestral
- Descrição do conteúdo (e regex)
- Texto (e regex)
As seguintes condições de acionamento em descritores de contexto são suportadas no iOS+:
- Aplicativo em teste mostrado
- Elemento presente
- Ação de script não Robo executada
Estrutura
Um script Robo possui vários atributos que descrevem como o Robo o executa. A maioria desses atributos é opcional com valores padrão predefinidos:
Atributo | Descrição |
id | Um número inteiro que ajuda a rastrear esse script Robo nas saídas de rastreamento. Robo possui scripts Robo integrados com seus próprios id s. Embora o mesmo id em scripts Robo diferentes não afete seu comportamento, distinguir ações desses scripts Robo nas saídas de rastreamento pode ser um desafio. Recomendamos atribuir um id exclusivo de 1000 ou superior para seus scripts Robo para evitar conflitos. |
description | Semelhante ao id mas mais descritivo. |
crawlStage | O estágio de rastreamento do Robo aplica este script do Robo em. Por padrão, é o estágio principal de rastreamento. |
priority | A prioridade deste script Robo em comparação com outros scripts Robo. Por padrão, todos os scripts Robo têm prioridade 1 . |
maxNumberOfRuns | Especifica quantas vezes durante um rastreamento o Robo pode executar esse script Robo. Por padrão, o Robo pode executar um script Robo uma vez. |
contextDescriptor | Descreve o contexto ou a condição que aciona esse script Robo. Se omitido, a condição de acionamento deste script Robo é considerada sempre atendida; em outras palavras, o script Robo é incondicional. |
actions | Todas as ações deste script Robo. |
Um único arquivo contém uma coleção de um ou mais scripts Robo.
Veja a seguir um exemplo de arquivo com dois scripts Robo incondicionais, cada um com uma única ação executada uma vez no início de um rastreamento:
[
{
"id": 1000,
"description": "My first Robo script",
"actions": [
{
"eventType": "DISABLE_KEYBOARD"
}
]
},
{
"id": 1001,
"description": "My second Robo script",
"actions": [
{
"eventType": "PRESSED_BACK"
}
]
}
]
Descritor de contexto
Um descritor de contexto define o contexto ou condição que aciona um script Robo usando um ou uma combinação de vários atributos:
Atributo | Descrição |
---|---|
"condition": "always" | Sempre aciona um script Robo. |
"condition": "element_present" | Verifica se um widget de UI que corresponde a elementDescriptors ou ao texto especificado por visionText está presente na tela. |
"condition": "element_disabled" | Verifica se um widget de UI que corresponde elementDescriptors está presente na tela e não pode interagir com ele. |
"condition": "element_checked" | Verifica se um widget de UI que corresponde a elementDescriptors está presente na tela e é verificado. |
"condition": "app_under_test_shown" | Verifica se o aplicativo em teste está sendo executado em primeiro plano. |
"condition": "default_launcher_shown" | Verifica se a tela inicial de um dispositivo é exibida, o que significa que nenhum aplicativo está sendo executado em primeiro plano. |
"condition": "non_roboscript_action_performed" | Verifica se as últimas ações consecutivas nonRoboscriptActionCount executadas pelo teste Robo não são ações de script Robo. |
negateCondition | Se definido como true , nega a condition . Por exemplo, você pode usar este atributo para verificar se um widget de UI NÃO está presente na tela ou se o aplicativo em teste NÃO está sendo executado em primeiro plano. |
elementDescriptors | Um ou mais descritores de elementos que identificam um widget de UI na tela. É usado em combinação com as condições element_present , element_disabled e element_checked . Mutuamente exclusivo com visionText . Para obter mais informações, consulte Descritores de elementos . |
visionText | O texto na tela é detectado usando a API de reconhecimento óptico de caracteres (OCR). visionText é usado em combinação com a condição element_present . Mutuamente exclusivo com elementDescriptors . |
nonRoboscriptActionCount | O número de ações consecutivas de script não Robo executadas anteriormente. Ele é usado em combinação com a condição non_roboscript_action_performed para acionar um script Robo após cada ação nonRoboscriptActionCount Robo. Por padrão, é 1 . |
A seguir está um exemplo de um script Robo que é acionado por um widget de UI com um ID de recurso "my.app.package:id/page_header"
presente na tela:
{
"id": 1000,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/page_header"
}
]
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"text": "Settings"
}
]
}
]
}
A seguir está um exemplo de um script Robo que é acionado pela "Privacy Policy"
detectada pelo Reconhecimento Óptico de Caracteres (OCR):
{
"id": 1000,
"description": "Vision text Robo script",
"contextDescriptor": {
"condition": "element_present",
"visionText": "Privacy Policy"
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
]
}
A seguir está um exemplo de um script Robo que aguarda 5 segundos após cada ação Robo sem script:
{
"contextDescriptor": {
"condition": "non_roboscript_action_performed"
},
"maxNumberOfRuns" : 1000,
"actions" : [
{
"eventType" : "DELAYED_MESSAGE_POSTED",
"delayTime" : 5000
}]
}
Ações
Cada ação em um script Robo é representada como um pacote de um ou mais pares de atributo-valor, descritos na tabela a seguir:
Atributo | Descrição |
eventType | Especifica o tipo de ação, por exemplo, clique, edição de texto, etc. Obrigatório para cada ação. |
elementDescriptors | Descritores que identificam um widget de UI. Obrigatório para todas as ações que possuem um widget de UI de destino, como clicar em um botão específico. |
optional | Se definida como true , esta ação será ignorada quando não puder ser executada. Por exemplo, esta ação é ignorada quando não consegue encontrar seu widget de UI de destino em uma tela – sem falhar no script Robo que a contém. Por padrão, o valor é false . |
replacementText | O texto a ser inserido no widget da UI de destino. Necessário para ações de edição de texto. |
swipeDirection | Especifica a direção do deslizamento. Obrigatório para ações de deslizar. |
delayTime | Especifica quanto tempo esperar, em milissegundos. Obrigatório para ações de espera. |
pointTapXCoordinate e pointTapYCoordinate | As coordenadas X e Y do pixel do ponto tocado. Mutuamente exclusivo com pointTapXPercent e pointTapYPercent . Necessário para ações de toque pontual. |
pointTapXPercent e pointTapYPercent | As coordenadas percentuais X e Y do ponto tocado. Mutuamente exclusivo com pointTapXCoordinate e pointTapYCoordinate . Necessário para ações de toque pontual. |
Veja a seguir um exemplo de script Robo com duas ações sem widgets de UI de destino, o que significa que essas ações não operam em um widget de UI específico:
[
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
},
{
"eventType": "PRESSED_BACK"
}
]
Descritores de elementos
Um descritor de elemento identifica um widget de UI usando um ou mais dos seguintes atributos de identificação:
Atributo | Descrição |
className | – |
ancestorClassName | Nome da classe do ancestral da hierarquia da interface do usuário do elemento. Um ancestral é qualquer um dos nós pais na hierarquia da UI do elemento, incluindo o próprio elemento. |
resourceId | – |
resourceIdRegex | Expressão regular Java para corresponder resourceId . |
contentDescription | – |
contentDescriptionRegex | Expressão regular Java para corresponder a contentDescription . |
text (que aparece na tela) | – |
textRegex | Expressão regular Java para corresponder text . |
groupViewChildPosition , recyclerViewChildPosition ou adapterViewChildPosition | Representa a posição filho de um widget de UI dependendo do tipo de widget pai. |
Freqüentemente, esses atributos são indefinidos, por exemplo, um botão pode não ter texto e descrição de conteúdo. Mesmo que alguns valores de atributos estejam presentes, eles podem não ser exclusivos em uma determinada tela do aplicativo (incluindo resourceId
).
Por exemplo, a diferenciação entre itens de uma lista normalmente só é possível usando suas diferentes posições filhas no widget pai. Isso significa que usar apenas um descritor de elemento para identificar um widget de UI geralmente é insuficiente. Portanto, o atributo elementDescriptors
de uma ação contém uma sequência de descritores de elementos ordenados de forma que o primeiro corresponda ao widget de UI de destino, o segundo corresponda ao widget pai do widget de UI de destino e assim por diante. O widget de UI de destino de uma ação é correspondido quando todos os seus descritores de elemento correspondem à subhierarquia do widget de UI correspondente.
A seguir está um exemplo de um script Robo com uma alteração de texto e ações de clique, ambas exigindo que você identifique o widget de UI de destino usando os descritores de elemento fornecidos:
[
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "John",
"elementDescriptors": [
{
"className": "android.support.v7.widget.AppCompatEditText",
"groupViewChildPosition": 0,
"resourceId": "com.google.samples.apps.topeka:id/first_name"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 0
},
{
"className": "android.support.design.widget.TextInputLayout",
"groupViewChildPosition": 1
}
]
},
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "android.support.design.widget.FloatingActionButton",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/done"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/content"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 0,
"resourceId": "com.google.samples.apps.topeka:id/sign_in_content"
}
]
}
]
Opções de execução
Opcionalmente, você pode prefixar a lista de ações em um script Robo com um objeto JSON que especifica as opções de execução desse script Robo. Este cabeçalho de configuração começa com a palavra-chave roboscript
seguida por uma representação JSON das opções de execução desejadas.
Os scripts Robo suportam as seguintes opções de execução:
-
executionMode
- opções de execução aplicadas quando um script Robo está em execução:-
strict
- se definido comotrue
, o script Robo não emprega correspondência parcial, ignorando a ação atual e suspensão . Ou seja, o script Robo é executado como um teste de instrumentação regular e falha assim que alguma de suas ações não puder ser executada. Por padrão, éfalse
. -
notify
- se definido comofalse
, o script Robo não mostra notificações na tela no início e no final de sua execução. Por padrão, étrue
.
-
-
postscript
- opções de execução aplicadas após a conclusão de um script Robo:-
terminate
- se definido comotrue
, o teste Robo para de rastrear após a conclusão do script Robo. Por padrão, éfalse
.
-
A seguir está um exemplo de um script Robo executado em modo strict
, sem notificações na tela, que fica suspenso por três segundos, após os quais o rastreamento é interrompido:
"roboscript": {
"executionMode": {
"strict": true,
"notify": false
},
"postscript": {
"terminate": true
}
}
[
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
Parâmetros do modelo
Um parâmetro de modelo é um espaço reservado em um script Robo que é substituído pelo valor real quando o teste do Robo carrega esse script Robo para execução. Os parâmetros do modelo são prefixados com um sublinhado duplo seguido por um sinal de porcentagem e são pós-fixados com um sinal de porcentagem seguido por um sublinhado duplo.
Os scripts Robo suportam o seguinte parâmetro de modelo:
-
__%APP_PACKAGE_NAME%__
- o nome do pacote do aplicativo em teste.
Veja a seguir um exemplo de script Robo que interrompe o processo do aplicativo em teste:
[
{
"eventType": "ADB_SHELL_COMMAND",
"command": "am force-stop __%APP_PACKAGE_NAME%__"
}
]
Comentários
Um script Robo pode conter linhas de comentários, que começam com #
ou //
.
A seguir está um exemplo de script Robo com alguns comentários:
# Confirm a user account.
[
{
// Click the DONE button.
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
]
Capacidades
Por padrão, até que todas as ações de um script Robo sejam concluídas (ou pelo menos tentadas), o script Robo permanece ativo. O teste Robo continua tentando corresponder a uma ação de script Robo sempre que escolhe uma ação para executar. O script Robo emprega as seguintes técnicas para aumentar a robustez:
Técnica | Descrição |
Correspondência parcial | Se a ação atual do script Robo não puder ser totalmente correspondida, os critérios de correspondência serão relaxados e a correspondência será repetida. A correspondência parcial não considera o descritor do elemento mais externo ao corresponder ao widget de UI de destino de uma ação de script Robo. Se a correspondência parcial for bem-sucedida, a ação de script Robo correspondente será executada normalmente. Essa técnica oferece suporte a cenários em que a estrutura do aplicativo muda, por exemplo, entre versões do aplicativo, quando os elementos da tela são reorganizados. |
Pular ação atual | Se a ação de script Robo atual não puder ser correspondida total ou parcialmente, o Robo tentará corresponder à ação de script Robo subsequente. Se a ação subsequente corresponder total ou parcialmente, o teste Robo ignora (e nunca retorna) a ação de script Robo atual e executa a ação subsequente. Essa técnica oferece suporte a cenários em que o comportamento do aplicativo muda entre versões ou é instável, por exemplo, quando uma caixa de diálogo intermitente pode aparecer em telas diferentes durante a gravação ou a reprodução de um script Robo. |
Suspender | Se nem as ações atuais nem as subsequentes do script Robo puderem ser total ou parcialmente correspondidas, o script Robo será temporariamente suspenso e o teste Robo escolherá uma ação para executar usando suas outras estratégias. Após a conclusão desta ação, o teste Robo retoma a execução do script Robo. Enquanto as ações atuais ou subsequentes do script Robo não puderem ser correspondidas, o script Robo permanecerá suspenso para qualquer número de ações. Assim, os scripts Robo não precisam necessariamente ser um prólogo para um teste Robo, e você pode intercalar ações de script Robo com ações de teste Robo padrão. Essa técnica oferece suporte a cenários em que o comportamento do aplicativo é instável ou quando as alterações entre as versões do aplicativo são grandes o suficiente para que o teste Robo precise "preencher as lacunas" com suas ações padrão. |
Prioridades
Se um script Robo atingir seu maxNumberOfRuns
, ele não poderá mais ser acionado em um determinado rastreamento. Se mais de um script Robo puder ser acionado pelo contexto atual, a prioridade será dada escolhendo, na seguinte ordem, o script Robo que:
- Possui um atributo
contextDescriptor
. - Tem a
priority
mais alta (por padrão, todos os scripts Robo têm a mesmapriority
de execução1
). - Aparece primeiro na lista de scripts Robo, se as prioridades dos scripts Robo forem as mesmas.
A seguir está um exemplo de arquivo com três scripts Robo que executam a mesma ação e são acionados pela mesma condição - o aplicativo em teste está em primeiro plano:
[
{
"id": 1000,
"description": "Robo script 1",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
},
{
"id": 1001,
"description": "Robo script 2",
"priority": "2",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
},
{
"id": 1002,
"description": "Robo script 3",
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
]
}
]
Quando o aplicativo em teste está em primeiro plano, o Robo aciona o seguinte, em ordem:
-
"Robo script 2"
porque tem a prioridade mais alta. -
"Robo script 1"
porque aparece mais cedo entre os restantes scripts Robo aplicáveis com a mesma prioridade. -
"Robo script 3"
como o último script Robo aplicável.
Execuções repetidas
Por padrão, o Robo aciona um script Robo no máximo uma vez durante um rastreamento. Isso pode ser ajustado por meio do atributo maxNumberOfRuns
.
A seguir está um exemplo de script Robo que coloca o aplicativo em teste em segundo plano até 10 vezes:
{
"id": 1000,
"maxNumberOfRuns": 10,
"contextDescriptor": {
"condition": "app_under_test_shown"
},
"actions": [
{
"eventType": "GO_HOME"
}
]
}
Estágio de rastreamento
Os scripts Robo são aplicáveis em diferentes estágios de um determinado rastreamento Robo:
Estágio de rastreamento | Descrição |
pre_crawl | Antes que o Robo seja iniciado e comece a rastrear o aplicativo em teste. |
post_crawl | Depois que Robo terminar de rastrear o aplicativo em teste. |
crawl | O estágio principal de rastreamento, quando o Robo rastreia o aplicativo em teste. |
close_screen | Quando Robo tenta retornar (retroceder) de uma determinada tela, quando todas as ações possíveis nesta tela são exploradas. Por padrão, Robo pressiona de volta, o que é indesejável em alguns cenários. |
Se o atributo crawlStage
de um script Robo não for especificado, ele estará implícito como crawl
.
Veja a seguir um exemplo de script Robo que limpa os dados do usuário do aplicativo em teste antes que o Robo comece a rastreá-los:
{
"id": 1000,
"crawlStage": "pre_crawl",
"actions": [
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
]
}
A seguir está um exemplo de um script Robo que instrui o Robo a clicar em "Cancel"
sempre que tentar retornar (retroceder) de uma caixa de diálogo de confirmação:
{
"id": 1000,
"crawlStage": "close_screen",
"maxNumberOfRuns": 999,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_dialog"
}
]
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"text": "Cancel"
}
]
}
]
}
Ações condicionais
Um script Robo pode conter ações condicionais. As ações condicionais têm três atributos adicionais que descrevem como o Robo as executa:
Atributo | Descrição |
priority | A prioridade desta ação condicional em comparação com outras ações condicionais dentro do script Robo que a contém. Por padrão, todas as ações condicionais têm prioridade 1 . |
maxNumberOfRuns | Quantas vezes esta ação condicional pode ser executada durante uma execução do script Robo que a contém. Por padrão, todas as ações condicionais podem ser executadas no máximo uma vez em uma única execução do script Robo que as contém. |
contextDescriptor | O contexto/condição que aciona esta ação condicional. Ele tem a mesma estrutura e oferece recursos semelhantes ao [contextDescriptor do script Robo](#context-descriptor). |
Quando acionado, um script Robo executa suas ações não condicionais, uma por uma, em ordem de aparecimento. Se um script Robo contiver ações condicionais, elas serão consideradas sempre antes de escolher uma ação não condicional para executar. Se qualquer ação condicional for acionada e escolhida com base em sua prioridade e no número restante de execuções, o script Robo executará essa ação condicional. Caso contrário, o script Robo executará a seguinte ação não condicional. Para ser válido, um script Robo deve conter pelo menos uma ação não condicional.
A seguir está um exemplo de um script Robo incondicional com uma ação condicional que dispensa caixas de diálogo pop-up se elas aparecerem em qualquer ponto durante a execução do script Robo:
{
"id": 1000,
"actions": [
{
"description": "Dismiss popup",
"maxNumberOfRuns": 100,
"contextDescriptor": {
"condition": "default_launcher_shown",
"negateCondition": true
},
"eventType": "GO_HOME"
},
{
"description": "Screen off",
"eventType": "ADB_SHELL_COMMAND",
"command": "input keyevent 26"
},
{
"description": "Wait for 10 seconds",
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 10000
},
{
"description": "Screen on",
"eventType": "ADB_SHELL_COMMAND",
"command": "input keyevent 82"
},
{
"description": "Wait for 10 seconds",
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 10000
}
}
Ignorando ações
Um script Robo pode conter instruções para o Robo ignorar widgets de UI específicos ou todos os widgets de UI em uma tela específica. Estas instruções são representadas como ignorando "ações" com eventType
ELEMENT_IGNORED
e ALL_ELEMENTS_IGNORED
correspondentemente.
Sempre que o atributo contextDescriptor
de um script Robo contendo ações de ignorar corresponder a uma determinada tela, o Robo não interage com nenhum widget de UI alvo de suas ações de ignorar (a menos que alguma outra ação de script do Robo faça o Robo executar uma ação em um dos widgets de UI ignorados).
Um script Robo pode conter uma mistura de ações ignoradas, condicionais e não condicionais. Ao contrário de outras ações de script Robo, as ações de ignorar são aplicadas desde que contextDescriptor
que contém o script Robo corresponda a uma tela durante um rastreamento Robo, independentemente dos valores dos atributos priority
e maxNumberOfRuns
.
A seguir está um exemplo de arquivo com dois scripts Robo. O primeiro script Robo faz com que Robo ignore todos os widgets de UI em uma tela contendo um widget de UI com um ID de recurso "my.app.package:id/ignored_screen"
. O segundo script Robo faz com que Robo ignore widgets de UI cujos IDs de recurso correspondem ao Java regex ".*:id/done"
em uma tela contendo um widget de UI com um ID de recurso "my.app.package:id/main_screen"
:
[
{
"id": 1000,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/ignored_screen"
}
]
},
"actions": [
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
]
},
{
"id": 1001,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/main_screen"
}
]
},
"actions": [
{
"eventType": "ELEMENT_IGNORED",
"elementDescriptors": [
{
"resourceIdRegex": ".*:id/done"
}
]
}
]
}
]
Suporte para RecyclerView e AdapterView
Os widgets filhos dos RecyclerView e AdapterView são carregados dinamicamente e podem ser exibidos a muitos movimentos de distância da tela atual. Como o tamanho da tela e o número de movimentos necessários para chegar até essa criança são diferentes para diferentes formatos de dispositivo, é muito mais robusto confiar na posição dos dados da criança, que é absoluta. É uma abordagem menos robusta confiar no número de movimentos necessários para trazer a criança até a tela e depois usar sua posição na tela.
Portanto, o script Robo captura as posições absolutas dos dados dos filhos do RecyclerView que são alvos das ações do script Robo como recyclerViewChildPosition
. O script Robo também captura as posições de dados absolutas dos filhos do AdapterView que são alvos de ações do script Robo como adapterViewChildPosition
.
As ações nos filhos RecyclerView e AdapterView são executadas nas seguintes etapas:
O teste Robo garante que o filho correspondente seja exibido na tela por meio de uma ação de posicionamento no RecyclerView ou AdapterView que contém.
O teste Robo realiza a ação gravada diretamente no elemento filho, uma vez que já está exibido na tela.
A seguir está um exemplo de uma ação de clique em um filho do AdapterView ( android.widget.GridView
):
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "com.google.samples.apps.topeka.widget.AvatarView",
"adapterViewChildPosition": 5,
"resourceId": "com.google.samples.apps.topeka:id/avatar",
"contentDescription": "Avatar 6"
},
{
"className": "android.widget.GridView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/avatars"
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 1
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 0
}
]
}
A seguir está um exemplo de uma ação de clique em um filho RecyclerView ( android.support.v7.widget.RecyclerView
):
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"className": "android.support.v7.widget.AppCompatTextView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/category_title"
},
{
"className": "android.widget.FrameLayout",
"recyclerViewChildPosition": 8,
"resourceId": "com.google.samples.apps.topeka:id/category_item"
},
{
"className": "android.support.v7.widget.RecyclerView",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/categories"
},
{
"className": "android.widget.FrameLayout",
"groupViewChildPosition": 1,
"resourceId": "com.google.samples.apps.topeka:id/category_container"
},
{
"className": "android.widget.LinearLayout",
"groupViewChildPosition": 0
}
]
}
Grave um script Robo no Android Studio e execute-o no Test Lab
Você pode criar um script Robo no Android Studio, que salva o script como um arquivo JSON. Você pode então fazer upload do arquivo JSON para o Firebase Test Lab com o aplicativo e executar o teste de acordo.
Quando você executa um teste Robo com um script anexado, o teste Robo primeiro percorre suas ações predefinidas e depois explora o aplicativo normalmente.
Para criar um arquivo JSON de script Robo no Android Studio, siga as etapas em Gravar um script Robo usando o Test Lab no Android Studio .
Ações de script Robo
O seguinte atributo opcional comum se aplica a todas as ações:
-
description
- ajuda a rastrear a execução desta ação de script Robo nas saídas de teste do Robo.
Afirmação
Se a condição declarada for verdadeira, o script Robo continua para a próxima ação, que pode ser outra afirmação. Caso contrário, a execução do script Robo será interrompida devido a uma falha na asserção.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ASSERTION" | -- |
contextDescriptor | Descreve o contexto ou condição afirmada. Ele tem a mesma estrutura e oferece recursos semelhantes ao contextDescriptor do script Robo . |
A seguir está um exemplo de uma declaração de script Robo que verifica se o aplicativo em teste está em primeiro plano:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "app_under_test_shown"
}
}
Veja a seguir um exemplo de uma declaração de script Robo que verifica se um widget de IU com o ID de recurso "com.google.samples.apps.topeka:id/done"
está presente em uma tela:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
}
A seguir está um exemplo de uma declaração de script Robo que verifica se "Settings"
NÃO é detectada em uma tela usando OCR:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"negateCondition": true,
"visionText": "Settings"
}
}
Clique
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
eventType | Especifica o tipo de ação do script Robo. |
"eventType": "VIEW_CLICKED" | Clica no elemento de destino do aplicativo em teste. |
"eventType": "SOFT_KEYBOARD_CLICK" | Clica no elemento de destino do teclado virtual. |
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK" | Clica em elementos aleatórios do teclado virtual até maxNumberOfRuns vezes. |
"eventType": "LIST_ITEM_CLICKED" | Usado pelo gravador de script Robo no Android Studio para clicar em itens da lista. |
elementDescriptors | Identifica o widget de IU clicado usando a hierarquia de IU do Android. Mutuamente exclusivo com visionText . |
visionText | Identifica o elemento clicado usando OCR. Mutuamente exclusivo com elementDescriptors . |
maxNumberOfRuns | Especifica quantas vezes clicar em um elemento aleatório do teclado virtual, quando eventType for SOFT_KEYBOARD_RANDOM_CLICK . O valor padrão é 1 . |
Veja a seguir um exemplo de uma ação de script Robo que clica em um botão com o ID de recurso "com.google.samples.apps.topeka:id/done"
:
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
A seguir está um exemplo de uma ação de script Robo que clica em "Privacy Policy"
detectada em uma tela usando OCR:
{
"eventType": "VIEW_CLICKED",
"visionText": "Privacy Policy"
}
A seguir está um exemplo de uma ação de script Robo que clica em um elemento de teclado virtual com uma descrição de conteúdo "Emoji button"
:
{
"eventType": "SOFT_KEYBOARD_CLICK",
"elementDescriptors": [
{
"contentDescription": "Emoji button"
}
]
}
A seguir está um exemplo de uma ação de script Robo que clica em elementos aleatórios do teclado virtual até cinco vezes:
{
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK",
"maxNumberOfRuns": 5
}
Desativar teclado virtual
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "DISABLE_KEYBOARD" | -- |
A seguir está um exemplo de uma ação de script Robo que desativa o teclado virtual:
{
"eventType": "DISABLE_KEYBOARD"
}
Execute o comando shell adb
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ADB_SHELL_COMMAND" | -- |
command | O comando shell do Android Debug Bridge (adb) a ser executado. |
O seguinte atributo é opcional:
-
expectedOutputRegex
- a saída esperada do comando como uma expressão regular Java. Se a saída não corresponder, a ação do script Robo falhará. Por padrão, é uma string vazia, o que significa que a saída não é verificada.
Veja a seguir um exemplo de uma ação de script Robo que limpa os dados do usuário do aplicativo em teste:
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
Conceder permissões
Esta ação é gravada pelo gravador de script Robo no Android Studio para compatibilidade com versões anteriores do Espresso Test Recorder . O teste Robo concede todas as permissões ao aplicativo em teste no início de cada rastreamento e, portanto, esta ação é autônoma. NÃO use esta ação em seus scripts Robo.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "PERMISSIONS_REQUEST" | -- |
Ignore todos os elementos em uma tela
Esta ação faz com que o Robo ignore todos os elementos em qualquer tela que acione o script do Robo que o contém.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ALL_ELEMENTS_IGNORED" | -- |
A seguir está um exemplo de uma ação de script do Robo que faz o Robo ignorar todos os elementos em uma tela:
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
Ignorar um elemento
Esta ação faz com que o Robo ignore um elemento (ou elementos) que corresponda ao elementDescriptors
especificado.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ELEMENT_IGNORED" | -- |
elementDescriptors | Identifica os widgets de IU ignorados usando a hierarquia de IU do Android. |
O seguinte atributo é opcional:
-
ignoreChildren
- se definido comotrue
, Robo também ignora todos os descendentes dos widgets de UI ignorados. Por padrão, éfalse
.
A seguir está um exemplo de ação de script do Robo que faz o Robo ignorar todos os elementos, cujas descrições de conteúdo começam com "Avatar"
:
{
"eventType": "ELEMENT_IGNORED",
"elementDescriptors": [
{
"contentDescriptionRegex": "Avatar.*"
}
]
}
Entrada de texto
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
eventType | Especifica o tipo de ação do script Robo. |
"eventType": "VIEW_TEXT_CHANGED" | Insere o texto fornecido no widget da IU de destino. |
"eventType": "ENTER_TEXT" | insere o texto fornecido no widget de UI de destino e, em seguida, envia um evento KEYCODE_ENTER para este widget de UI. |
elementDescriptors | Identifica o widget de IU de destino usando a hierarquia de IU do Android. |
replacementText | O texto a ser inserido no widget da UI de destino. |
Veja a seguir um exemplo de uma ação de script Robo que insere "John"
em um widget de IU com o ID de recurso "com.google.samples.apps.topeka:id/first_name"
:
{
"eventType": "VIEW_TEXT_CHANGED",
"replacementText": "John",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Clique longo
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "VIEW_LONG_CLICKED" | -- |
elementDescriptors | Identifica o widget de IU de destino usando a hierarquia de IU do Android. Mutuamente exclusivo com visionText . |
visionText | Identifica o elemento clicado longamente usando OCR. Mutuamente exclusivo com elementDescriptors . |
O seguinte atributo é opcional:
-
delayTime
- especifica quanto tempo dura o pressionamento de um clique longo, em milissegundos.
A seguir está um exemplo de uma ação de script Robo que executa um clique de cinco segundos em um widget de IU com a descrição de conteúdo "Avatar 8"
:
{
"eventType": "VIEW_LONG_CLICKED",
"elementDescriptors": [
{
"contentDescription": "Avatar 8"
}
],
"delayTime": 5000
}
Execute um gesto de um ponto
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "ONE_POINT_GESTURE" | -- |
coordinates | Duas coordenadas para um gesto de um ponto, formatado como "(x1,y1)->(x2,y2)" como porcentagens ou pixels. |
O seguinte atributo é opcional:
-
dragAndDrop
- se definido comotrue
, o gesto de um ponto executa uma ação de arrastar e soltar. Por padrão, éfalse
.
A seguir está um exemplo de ação de gesto de um ponto do script Robo que executa um deslizar para baixo:
{
"eventType": "ONE_POINT_GESTURE",
"coordinates": "(50%,25%)->(50%,75%)"
}
Execute um gesto de dois pontos
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "TWO_POINT_GESTURE" | -- |
coordinates | Quatro coordenadas para um gesto de dois pontos, formatado como "(x1,y1)->(x2,y2),(x3,y3)->(x4,y4)" como porcentagens ou pixels. |
A seguir está um exemplo de uma ação de script Robo que executa um gesto de pinçar:
{
"eventType": "TWO_POINT_GESTURE",
"coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}
Execute uma ação IME
Esta ação pressiona o botão de ação atual, por exemplo, próximo, concluído e pesquisar, no Input Method Editor (IME) para o widget de UI de destino especificado.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "PRESSED_EDITOR_ACTION" | -- |
elementDescriptors | Identifica o widget de IU de destino usando a hierarquia de IU do Android. |
Veja a seguir um exemplo de uma ação de script Robo que executa uma ação IME em um widget de IU com o ID de recurso "com.google.samples.apps.topeka:id/first_name"
:
{
"eventType": "PRESSED_EDITOR_ACTION",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Pressione de volta
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
eventType | Especifica o tipo de ação do script Robo. |
"eventType": "PRESSED_BACK" | Envia um evento KEYCODE_BACK para o dispositivo. |
"eventType": "PRESSED_BACK_EMULATOR_28" | Usado pelo gravador de script Robo no Android Studio para pressionar em emuladores API 28. |
A seguir está um exemplo de uma ação de script Robo que pressiona de volta:
{
"eventType": "PRESSED_BACK"
}
Pressione casa
Esta ação envia um evento KEYCODE_HOME
ao dispositivo.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "GO_HOME" | -- |
A seguir está um exemplo de uma ação de script Robo que pressiona home:
{
"eventType": "GO_HOME"
}
Rolar um elemento para visualização
Esta ação faz o teste Robo rolar para frente o widget de UI que corresponde aos elementDescriptors
especificados até que o widget de UI que corresponde aos childElementDescriptors
especificados esteja presente na tela, ou o widget rolado não possa mais ser rolado, ou o número máximo de 50 rolagens seja atingido.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ELEMENT_SCROLL_INTO_VIEW" | -- |
elementDescriptors | Identifica o widget de IU rolado usando a hierarquia de IU do Android. |
childElementDescriptors | Identifica o widget de IU para rolar usando a hierarquia de IU do Android. |
A seguir está um exemplo de uma ação de script Robo que rola o widget de UI com o ID de recurso "my.app.package:id/scrollable_card_container"
até que o widget de UI com o texto "Orange"
esteja presente na tela (ou nenhuma rolagem mais possa ser feita). ser executado ou o número máximo de 50 pergaminhos for atingido):
{
"eventType": "ELEMENT_SCROLL_INTO_VIEW",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/scrollable_card_container"
}
],
"childElementDescriptors": [
{
"text": "Orange"
}
]
}
Deslizar
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "VIEW_SWIPED" | -- |
swipeDirection | Especifica a direção do deslizamento:
|
elementDescriptors | Identifica o widget de IU de destino usando a hierarquia de IU do Android. |
A seguir está um exemplo de uma ação de script Robo que desliza para cima um widget de IU com o ID de recurso "my.app.package:id/custom_content"
:
{
"eventType": "VIEW_SWIPED",
"swipeDirection": "Up",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/custom_content"
}
]
}
Tirar captura de tela
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "TAKE_SCREENSHOT" | -- |
screenshotName | Especifica o nome do arquivo de captura de tela. |
Veja a seguir um exemplo de ação de script Robo que faz uma captura de tela:
{
"eventType": "TAKE_SCREENSHOT",
"screenshotName": "my_screenshot"
}
Toque em um ponto na tela
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "POINT_TAP" | -- |
pointTapXCoordinate | A coordenada X do pixel do ponto tocado. Mutuamente exclusivo com pointTapXPercent e pointTapYPercent . |
pointTapYCoordinate | A coordenada Y do pixel do ponto tocado. Mutuamente exclusivo com pointTapXPercent e pointTapYPercent . |
pointTapXPercent | A porcentagem da coordenada X do ponto tocado. Mutuamente exclusivo com pointTapXCoordinate e pointTapYCoordinate . |
pointTapYPercent | A coordenada percentual Y do ponto tocado. Mutuamente exclusivo com pointTapXCoordinate e pointTapYCoordinate . |
A seguir está um exemplo de uma ação de script Robo que toca no meio de uma tela:
{
"eventType": "POINT_TAP",
"pointTapXPercent": 50,
"pointTapYPercent": 50
}
Toque em um ponto dentro de um elemento
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "POINT_TAP_ELEMENT" | -- |
pointTapXPercent | A porcentagem da coordenada X no elemento de destino. |
pointTapYPercent | A coordenada percentual Y dentro do elemento de destino. |
elementDescriptors | Identifica o widget de IU de destino usando a hierarquia de IU do Android. |
A seguir está um exemplo de uma ação de script Robo que move o controle deslizante da barra de busca para a direita:
{
"eventType": "POINT_TAP_ELEMENT",
"pointTapXPercent": 80,
"pointTapYPercent": 50,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/my_seekbar"
}
]
}
Encerrar rastreamento
Esta ação interrompe o teste do Robo.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "TERMINATE_CRAWL" | -- |
Veja a seguir um exemplo de uma ação de script Robo que interrompe um teste Robo:
{
"eventType": "TERMINATE_CRAWL"
}
Espere
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "DELAYED_MESSAGE_POSTED" | -- |
delayTime | Especifica quanto tempo esperar, em milissegundos. |
A seguir está um exemplo de uma ação de script Robo que aguarda três segundos:
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
Espere por um elemento
Esta ação faz com que o Robo test espere que um elemento apareça na tela até o tempo limite especificado.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "WAIT_FOR_ELEMENT" | -- |
delayTime | Especifica o tempo limite de espera, em milissegundos. |
elementDescriptors | Identifica o widget de IU esperado usando a hierarquia de IU do Android. |
A seguir está um exemplo de uma ação de script Robo que aguarda até 30 segundos para que um widget de UI com o ID de recurso "my.app.package:id/confirmation_button"
apareça na tela:
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}