Neste documento, fornecemos 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 de controle de qualidade manual de apps para dispositivos móveis e permitem estratégias de teste de pré-lançamento e integração contínua (CI). Um script Robo é um arquivo JSON que descreve uma sequência da interface do usuário (IU) e outras ações.
Um script Robo pode ser criado das seguintes maneiras:
Use o recurso de gravação de script Robo. (Somente Android)
Crie o script Robo manualmente. (Android e iOS+)
Grave e edite o script Robo 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 com outras entradas, como o pacote de aplicativo Android (APK) em teste no app.
Confira a seguir um exemplo de script Robo que faz a conexão de um usuário a um app e que é acionado quando o app 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 apenas um script Robo em um arquivo e ele tiver a condição de acionamento
app_under_test_shown
padrão, como no exemplo acima, vai ser possível
especificar o script Robo em um arquivo usando um formato mais simples, como
consequência das ações realizadas:
[
{
"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 do iOS+ para scripts Robo
O 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 compatíveis do iOS+ se comportam de maneira semelhante aos equivalentes do Android.
As ações a seguir têm suporte ao iOS+:
- Declaração
- Clique
- Clique longo
- Deslizar
- Ignorar todos os elementos
- Espera
- Fazer uma captura de tela
- Encerrar rastreamento
Os seguintes atributos de identificação em descritores de elementos oferecem suporte ao iOS+:
- Nome da classe
- Nome da classe ancestral
- Descrição do conteúdo (e regex)
- Texto (e regex)
As condições de acionamento nos descritores de contexto são compatíveis com o iOS+:
- App em fase de teste exibido
- Elemento presente
- Ação de script não Robo realizada
Estrutura
Um script Robo tem vários atributos que descrevem como ele é executado. A maioria desses atributos é opcional e tem valores padrão definidos previamente:
Atributo | Descrição |
id
|
Um número inteiro que ajuda a rastrear o script Robo nas saídas de rastreamento.
O Robo tem scripts integrados com id s próprios. Embora
o mesmo id em scripts Robo diferentes não afete o
comportamento deles, distinguir as ações desses scripts Robo nas saídas de rastreamento
pode ser desafiador. Recomendamos atribuir um id exclusivo de
1000 ou superior para seus scripts Robo, a fim de evitar conflitos.
|
description
|
Semelhante a id , porém mais descritivo.
|
crawlStage
|
O estágio de rastreamento em que o Robo aplica este script Robo. Por padrão, é o estágio de rastreamento principal. |
priority
|
A prioridade deste script Robo em comparação com outros.
Por padrão, todos os scripts Robo têm prioridade 1 .
|
maxNumberOfRuns
|
Especifica quantas vezes durante um rastreamento o Robo pode executar este script Robo. Por padrão, o Robo pode executar um script Robo uma vez. |
contextDescriptor
|
Descreve o contexto ou condição que aciona o script Robo. Se omitido, a condição de acionamento do script Robo vai ser considerada sempre atendida, ou seja, o script Robo é incondicional. |
actions
|
Todas as ações deste script Robo. |
Um único arquivo possui um conjunto de um ou mais scripts Robo.
Confira a seguir o exemplo de um arquivo com dois scripts Robo não condicionais, cada um com uma só ação, que é 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 a condição que aciona um script Robo usando um atributo ou uma combinação deles:
Atributo | Descrição |
---|---|
"condition": "always"
|
Sempre aciona um script Robo. |
"condition": "element_present"
|
Verifica se um widget de IU correspondente a elementDescriptors ou
um texto especificado por visionText é exibido na tela.
|
"condition": "element_disabled"
|
Verifica se um widget de IU correspondente a elementDescriptors está
presente na tela e não pode ser usado para interagir.
|
"condition": "element_checked"
|
Verifica se um widget de IU correspondente a elementDescriptors está
presente na tela e marcado.
|
"condition": "app_under_test_shown"
|
Verifica se o app em teste está em execução em primeiro plano. |
"condition": "default_launcher_shown"
|
Verifica se a tela de início de um dispositivo está sendo exibida, isto é, nenhum app está sendo executado em primeiro plano. |
"condition": "non_roboscript_action_performed"
|
Verifica se as últimas nonRoboscriptActionCount ações consecutivas executadas pelo teste Robo não são ações de script Robo.
|
negateCondition
|
Se definido como true , o condition é negado. Por
exemplo, você pode usar esse atributo para verificar se um widget de IU NÃO está
em exibição na tela ou se o app em teste NÃO está em execução em
primeiro plano.
|
elementDescriptors
|
Um ou mais descritores de elementos que identificam um widget de interface na tela.
É usado em combinação com as condições element_present ,
element_disabled e
element_checked . Mutuamente exclusivo com visionText . Para mais
informações, consulte Descritores de elementos.
|
visionText
|
O texto na tela é detectado usando a API OCR (de reconhecimento
óptico de caracteres). 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 realizadas anteriormente. Ele é
usado em combinação com a condição
non_roboscript_action_performed para acionar um script Robo após cada
nonRoboscriptActionCount ação do Robo. Por padrão, ele é
1 .
|
Confira a seguir o exemplo de um script Robo que é acionado por um widget de IU
com um ID de recurso "my.app.package:id/page_header"
na
tela:
{
"id": 1000,
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/page_header"
}
]
},
"actions": [
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"text": "Settings"
}
]
}
]
}
Confira a seguir o exemplo de um script Robo que é acionado pelo
"Privacy Policy"
detectado por 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"
}
]
}
Confira a seguir o exemplo de um script Robo que aguarda cinco segundos após cada ação que não seja de um script Robo:
{
"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 por um pacote de um ou mais pares de valor e atributo, descritos na tabela a seguir:
Atributo | Descrição |
eventType
|
Especifica o tipo da ação, por exemplo, clique, edição de texto etc. Obrigatório para cada ação. |
elementDescriptors
|
Descritores que identificam um widget de IU. Obrigatório para todas as ações que têm um widget de IU de destino, como clicar em um botão específico. |
optional
|
Se for definida como true , a ação será ignorada quando não puder ser
realizada. Por exemplo, essa ação é ignorada quando não é possível encontrar o
widget da IU de destino em uma tela sem falhar no script em que o Robo
está. Por padrão, o valor é false .
|
replacementText
|
O texto a ser inserido no widget da IU de destino. Obrigatório para ações de edição de texto. |
swipeDirection
|
Especifica em que direção deslizar. Obrigatório para ações de deslizar. |
delayTime
|
Especifica o tempo de espera, em milissegundos. Obrigatório para ações de espera. |
pointTapXCoordinate e pointTapYCoordinate
|
As coordenadas de pixel X e Y do ponto de toque. Mutuamente exclusivo
com pointTapXPercent e pointTapYPercent .
Obrigatório para ações de toque no ponto.
|
pointTapXPercent e pointTapYPercent
|
É a porcentagem de coordenadas X e Y do ponto de toque. Ele
é mutuamente exclusivo com pointTapXCoordinate e
pointTapYCoordinate . Obrigatório para ações de toque no ponto.
|
Veja a seguir o exemplo de script Robo com duas ações sem widgets de IU de destino. Isso significa que essas ações não operam em um widget de IU específico:
[
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
},
{
"eventType": "PRESSED_BACK"
}
]
Descritores de elemento
Um descritor de elemento identifica um widget de IU usando um ou mais dos seguintes atributos de identificação:
Atributo | Descrição |
className
|
– |
ancestorClassName
|
Nome da classe do ancestral da hierarquia de IU do elemento. Um ancestral é qualquer um dos nós pais na hierarquia de IU do elemento, incluindo o próprio elemento. |
resourceId
|
– |
resourceIdRegex
|
Expressão regular Java correspondente a resourceId .
|
contentDescription
|
– |
contentDescriptionRegex
|
Expressão regular Java correspondente a contentDescription .
|
text (que aparece na tela)
|
– |
textRegex
|
Expressão regular Java correspondente a text .
|
groupViewChildPosition ,
recyclerViewChildPosition ou
adapterViewChildPosition
|
Representa a posição filha de um widget de IU, dependendo do tipo de widget pai. |
Muitas vezes, esses atributos são indefinidos. Por exemplo, um botão pode não
ter descrição de texto e conteúdo. Mesmo que alguns valores de atributos estejam presentes,
eles podem não ser exclusivos em uma determinada tela do app (incluindo resourceId
).
Por exemplo, a diferenciação entre itens de uma lista geralmente só é possível
quando são usadas as diferentes posições filhas no widget pai. Isto é,
usar apenas um descritor de elemento para identificar um widget de IU geralmente é
insuficiente. Portanto, o atributo elementDescriptors
de uma ação contém uma
sequência de descritores de elementos ordenados de maneira que o primeiro
corresponda ao widget da IU de destino. O segundo corresponde ao widget pai
do widget da IU de destino e assim por diante. O widget de IU de destino de uma ação é correspondido
quando todos os descritores de elemento correspondem à sub-hierarquia de widget
de IU correspondente.
Veja a seguir o exemplo de script Robo com alteração de texto e ações de clique. Ambos exigem a identificação do widget da IU 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
Como opção, é possível prefixar a lista de ações em um script Robo com um objeto JSON
que especifica as opções de execução para esse script Robo. Esse
cabeçalho de configuração começa com a palavra-chave roboscript
, seguida por uma
representação JSON das opções de execução pretendidas.
Os scripts Robo são compatíveis com as seguintes opções de execução:
executionMode
: opções de execução aplicadas quando um script Robo está em execução:strict
: se configurado 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 tão logo não seja possível executar qualquer uma das ações dele. Por padrão, ela equivale afalse
.dismiss_popups
: se definido comotrue
, o teste Robo dispensará todas as caixas de diálogo inesperadas ao executar o script Robo, mesmo no modostrict
. Essa opção não tem efeito quando não está no modostrict
. Por padrão, ela equivale afalse
.notify
: se definido comofalse
, o script Robo não vai mostrar notificações na tela no início e no fim da execução. Por padrão, ele étrue
.
postscript
: opções de execução aplicadas após a conclusão de um script Robo:terminate
: se for definido comotrue
, o teste Robo deixará de rastrear depois que o script Robo for concluído. Por padrão, ele éfalse
.
Confira a seguir o exemplo de script Robo executado no modo strict
sem
notificações na tela. Ele fica suspenso por três segundos. Depois disso, 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 do modelo é um marcador de posição em um script Robo que é substituído pelo valor real quando o teste Robo carrega esse script para execução. Os parâmetros do modelo são prefixados com um sublinhado duplo seguido por um sinal de porcentagem e são sufixados com um sinal de porcentagem seguido por um sublinhado duplo.
Os scripts Robo são compatíveis com o seguinte parâmetro de modelo:
__%APP_PACKAGE_NAME%__
: nome do pacote do app em teste.
Veja a seguir o exemplo de script Robo que interrompe o processo do app em teste:
[
{
"eventType": "ADB_SHELL_COMMAND",
"command": "am force-stop __%APP_PACKAGE_NAME%__"
}
]
Comentários
Um script Robo pode conter linhas de comentários, iniciadas com
#
ou //
.
Veja a seguir o 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"
}
]
}
]
Recursos
Por padrão, até que todas as ações de um script Robo sejam concluídas (ou pelo menos tentadas), ele permanece ativo. O teste Robo continua tentando fazer a correspondência com uma ação de script Robo sempre que está escolhendo uma ação a ser executada. 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 afrouxados e a correspondência será repetida. A correspondência parcial
não considera o descritor de elemento mais externo ao corresponder ao
widget de IU de destino de uma ação do script Robo.
Se a correspondência parcial for bem-sucedida, a ação correspondente do script Robo é executada normalmente. Essa técnica é compatível com cenários em que a estrutura do app muda, por exemplo, entre versões do app, quando os elementos da tela são reorganizados. |
Pular a ação atual | Se a ação atual do script Robo não for total ou parcialmente correspondida,
o Robo tentará fazer a correspondência com a ação seguinte do script Robo. Se a ação subsequente
corresponder total ou parcialmente, o teste Robo ignora permanentemente
a ação atual do script Robo e executa a ação seguinte.
Essa técnica é compatível com cenários em que o comportamento do app muda entre versões ou é inconsistente. Por exemplo, quando uma caixa de diálogo intermitente pode aparecer em telas diferentes durante a gravação ou a repetição de um script Robo. |
Suspender | Quando as ações de script Robo atuais ou subsequentes não correspondem total ou parcialmente,
elas são suspensas temporariamente, e o teste Robo
escolhe uma ação a ser executada usando as outras estratégias. Depois que essa ação
é concluída, o teste Robo retoma a execução do script Robo.
Desde que as ações atuais ou subsequentes do script Robo não sejam correspondentes, o script Robo permanece suspenso, independentemente da quantidade de ações. Assim, os scripts Robo não precisam ser um prólogo para um teste Robo. Você pode intercalar as ações de script Robo com as ações de teste Robo padrão. Essa técnica suporta casos em que o comportamento do app é instável ou quando as alterações nas versões do app são grandes o suficiente para que o teste Robo precise "preencher as lacunas" com as ações padrão. |
Prioridades
Depois que um script Robo atingir maxNumberOfRuns
, ele não vai poder mais ser acionado
em um determinado rastreamento. Se mais de um script Robo puder ser acionado pelo contexto
atual, a prioridade vai ser dada, na ordem a seguir, ao script que:
- Tiver um atributo
contextDescriptor
. - Tiver o
priority
mais alto. Por padrão, todos os scripts Robo têm a mesma execuçãopriority
de1
. - For o primeiro deles na lista de scripts Robo, se as prioridades forem as mesmas.
Confira a seguir o exemplo de um arquivo com três scripts Robo que executam a mesma ação e são acionados pela mesma condição: o app em teste estar 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 app em teste está em primeiro plano, o Robo aciona o seguinte nesta ordem:
"Robo script 2"
por ter a prioridade mais alta."Robo script 1"
por estar listado antes dos scripts Robo restantes e 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 pelo atributo maxNumberOfRuns
.
Confira a seguir um exemplo de script Robo que coloca o app 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 rastreamento do Robo:
Estágio de rastreamento | Descrição |
pre_crawl
|
Antes do Robo iniciar e rastrear o app em teste. |
post_crawl
|
Depois que o Robo concluir o rastreamento do app em teste. Um
script Robo post_crawl não pode ter duração superior a 15 segundos,
caso contrário, o rastreamento pode ser encerrado com um tempo limite.
|
crawl
|
O estágio de rastreamento principal, quando o Robo rastreia o app em teste. |
close_screen
|
Quando o Robo tenta retornar (recuar) de uma determinada tela, quando todas as ações possíveis nessa tela forem analisadas. Por padrão, o Robo pressiona de volta, o que é indesejável em alguns casos. |
Se o atributo crawlStage
de um script Robo não for especificado, ele vai ser considerado como
crawl
.
Confira a seguir o exemplo de um script Robo que limpa os dados do usuário do app em teste antes que o Robo comece o rastreamento:
{
"id": 1000,
"crawlStage": "pre_crawl",
"actions": [
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
]
}
Este é um exemplo de script Robo que instrui o Robo a clicar em
"Cancel"
sempre que ele tentar retornar (recuar) 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 possuem três atributos adicionais que descrevem como o Robo as realiza:
Atributo | Descrição |
priority
|
A prioridade dessa ação condicional em comparação com as outras
no script Robo onde elas estão. Por padrão, todas
as ações condicionais têm prioridade 1 .
|
maxNumberOfRuns
|
Quantas vezes a ação condicional pode ser realizada durante uma execução do script Robo onde ela está. Por padrão, todas as ações condicionais podem ser realizadas no máximo uma vez em uma única execução do script Robo onde elas estão. |
contextDescriptor
|
O contexto ou a condição que aciona essa ação condicional. Tem a mesma estrutura e oferece recursos semelhantes ao contextDescriptor do script Robo. |
Quando acionado, um script Robo realiza as ações não condicionais uma a uma, na ordem em que aparecem. Se um script Robo contiver ações condicionais, elas sempre vão ser consideradas antes que uma ação não condicional seja escolhida para execução. Se qualquer ação condicional for acionada e selecionada com base na prioridade e no número restante de execuções, o script Robo vai executar essa ação condicional. Caso contrário, o script Robo vai executar a ação não condicional seguinte. Para um script Robo ser válido, ele precisa conter pelo menos uma ação não condicional.
Confira a seguir o 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
}
}
Ações de ignorar
Um script Robo pode conter instruções para que o Robo ignore widgets
da IU específicos ou todos em uma tela específica. Essas instruções são
representadas como "ações" de ignorar com eventType
ELEMENT_IGNORED
e
ALL_ELEMENTS_IGNORED
correspondentes.
Sempre que o atributo contextDescriptor
de um script Robo com ações de ignorar
corresponder a uma determinada tela, o Robo não vai interagir com os widgets de IU
segmentados pelas ações de ignorar, a menos que outra ação do script Robo
faça com que o Robo realize uma ação em um dos widgets de IU ignorados.
Um script Robo pode conter uma combinação de ações condicionais, não condicionais e de ignorar. Ao contrário de outras ações do script Robo, as ações de ignorar são aplicadas se o contextDescriptor
dele corresponder a uma tela durante um
rastreamento Robo, independentemente dos atributos priority
e maxNumberOfRuns
.
Confira a seguir um exemplo de arquivo com dois scripts Robo. O primeiro script Robo
faz com que ele ignore todos os widgets de IU em uma tela que tenha um widget de IU com
um ID de recurso "my.app.package:id/ignored_screen"
. O segundo faz com que ele
ignore widgets de IU com IDs de recurso que correspondam ao regex Java ".*:id/done"
em uma
tela que tenha um widget de IU 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 a RecyclerView e AdapterView
Os filhos dos widgets RecyclerView e AdapterView são carregados dinamicamente e podem ser exibidos com muitas ações de deslizar para fora da tela atual. Como o tamanho de uma tela e o número de ações de deslizar necessários para chegar a esse filho são diferentes para formatos de dispositivos que também diferem, é muito mais seguro confiar na posição de dados do filho, que é absoluta. É uma abordagem menos segura confiar no número de ações de deslizar, necessárias para levar esse filho à tela e usar a posição dele.
Portanto, o script Robo captura as posições absolutas dos dados dos filhos RecyclerView
que são destinos de ações do script Robo, como
recyclerViewChildPosition
. O script Robo também captura as posições absolutas
dos dados dos filhos do AdapterView, que são destinos das ações do script Robo,
como adapterViewChildPosition
.
As ações nos filhos do RecyclerView e AdapterView são realizadas nas seguintes etapas:
O teste Robo garante que o filho correspondente seja exibido na tela com uma ação de posicionamento no respectivo RecyclerView ou AdapterView.
O teste Robo executa a ação gravada diretamente no elemento filho, uma vez que ele já é exibido na tela.
Este exemplo é da ação de clique em um filho (android.widget.GridView
) do
AdapterView:
{
"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
}
]
}
Veja a seguir o exemplo de uma ação de clique em um filho (android.support.v7.widget.RecyclerView
) do
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
}
]
}
Gravar um script Robo no Android Studio e executá-lo no Test Lab
Você pode criar um script Robo no Android Studio, que o salva como um arquivo JSON. Em seguida, é possível fazer o upload do arquivo JSON para Firebase Test Lab com o aplicativo e executar o teste conforme esperado.
Ao executar um teste Robo com um script anexado, primeiro o Robo lê as ações programadas para depois analisar o app 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 do script Robo
O atributo opcional comum a seguir se aplica a todas as ações:
description
: ajuda a monitorar a execução dessa ação do script Robo nas saídas do teste Robo.
Declaração
Se a condição declarada for verdadeira, o script Robo segue para a ação seguinte, que pode ser outra declaração. Caso contrário, a execução do script Robo vai ser interrompida devido a uma declaração com falha.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ASSERTION"
|
-- |
contextDescriptor
|
Descreve o contexto ou a condição declarados. Tem a mesma estrutura e oferece recursos semelhantes ao contextDescriptor do script Robo. |
Veja a seguir o exemplo de uma declaração de script Robo que verifica se o app em teste está no primeiro plano:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "app_under_test_shown"
}
}
Veja a seguir o exemplo de uma declaração de script Robo que verifica se um widget de IU
com o ID do recurso "com.google.samples.apps.topeka:id/done"
é
exibido em uma tela:
{
"eventType": "ASSERTION",
"contextDescriptor": {
"condition": "element_present",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
}
Veja a seguir o exemplo de uma declaração de script Robo que verifica
se "Settings"
NÃO é detectado 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 app em teste. |
"eventType": "SOFT_KEYBOARD_CLICK"
|
Clica no elemento de destino do teclado de virtual. |
"eventType": "SOFT_KEYBOARD_RANDOM_CLICK"
|
Clica em elementos aleatórios do teclado de virtual até
maxNumberOfRuns vezes.
|
"eventType": "LIST_ITEM_CLICKED"
|
Usado pelo gravador de script Robo no Android Studio para clicar em itens de 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 o OCR. Mutuamente exclusivo com
elementDescriptors .
|
matchIndex
|
Especifica o índice da ocorrência do elemento de destino correspondente, quando
o elemento de destino é identificado usando visionText . Se for
0 , a ação do script Robo vai escolher o primeiro elemento correspondente. Se for
1 , a ação do script Robo vai escolher o segundo elemento correspondente,
e assim por diante. A ordem é determinada da esquerda para a direita, de cima para baixo. O
valor padrão é 0 (a primeira correspondência é escolhida).
|
maxNumberOfRuns
|
Especifica quantas vezes clicar em um elemento aleatório do teclado de virtual,
quando eventType for SOFT_KEYBOARD_RANDOM_CLICK .
O valor padrão é 1 .
|
Veja a seguir o exemplo de uma ação de script Robo que clica em um botão com
o ID do recurso "com.google.samples.apps.topeka:id/done"
:
{
"eventType": "VIEW_CLICKED",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/done"
}
]
}
Confira a seguir o exemplo de uma ação de script Robo que clica na segunda
ocorrência da palavra "Search"
detectada em uma tela usando o OCR:
{
"eventType": "VIEW_CLICKED",
"visionText": "Search",
"matchIndex": 1
}
Veja a seguir o 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"
}
]
}
Veja a seguir o 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 o teclado virtual
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "DISABLE_KEYBOARD"
|
-- |
Veja a seguir o exemplo de uma ação de script Robo que desativa o teclado de virtual:
{
"eventType": "DISABLE_KEYBOARD"
}
Executar o comando adb shell
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) para executar. |
O atributo a seguir é opcional:
expectedOutputRegex
: a saída esperada do comando como uma expressão regular Java. Se a saída não for correspondente, a ação do script Robo falhará. Por padrão, é uma string vazia, o que significa que a saída não está marcada.
Veja a seguir o exemplo de ação de script Robo que limpa os dados do usuário do app em teste:
{
"eventType": "ADB_SHELL_COMMAND",
"command": "pm clear __%APP_PACKAGE_NAME%__"
}
Conceder permissões
Esta ação é gravada pelo gravador de scripts Robo no Android Studio para compatibilidade com versões anteriores com o Espresso Test Recorder. O teste Robo concede todas as permissões para o app em teste no início de cada rastreamento, portanto, esta ação é não é operacional. NÃO use esta ação nos scripts Robo.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "PERMISSIONS_REQUEST"
|
-- |
Ignorar todos os elementos em uma tela
Essa ação faz com que o Robo ignore todos os elementos em qualquer tela que acione o script Robo onde ela está.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ALL_ELEMENTS_IGNORED"
|
-- |
Confira a seguir o exemplo de uma ação de script Robo que faz com que ele ignore todos os elementos em uma tela:
{
"eventType": "ALL_ELEMENTS_IGNORED"
}
Ignorar um elemento
Esta ação faz com que o Robo ignore um ou mais elementos correspondentes ao
elementDescriptors
especificado.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "ELEMENT_IGNORED"
|
-- |
elementDescriptors
|
Identifica widget(s) de interface ignorado(s) usando a hierarquia de interface do Android. |
O atributo a seguir é opcional:
ignoreChildren
: se definido comotrue
, o Robo também ignorará todos os descendentes dos widgets de interface ignorados. Por padrão, ele éfalse
.
Confira a seguir o exemplo de uma ação de script Robo que faz com que ele ignore todos
os elementos com descrições de conteúdo que comecem 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 da IU de destino e, em seguida,
envia um evento KEYCODE_ENTER para esse widget de IU.
|
elementDescriptors
|
Identifica o widget da IU de destino usando a hierarquia de IU do Android. |
replacementText
|
O texto a ser inserido no widget da IU de destino. |
Veja a seguir o exemplo de uma ação de script Robo que insere "John"
em
um widget de IU com o ID do 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 da IU de destino usando a hierarquia de IU do Android. Mutuamente
exclusivo com visionText .
|
visionText
|
Identifica o elemento selecionado com clique longo usando o OCR. Mutuamente exclusivo com
elementDescriptors .
|
matchIndex
|
Especifica o índice da ocorrência do elemento de destino correspondente, quando
o elemento de destino é identificado usando visionText . Se for
0 , a ação do script Robo vai escolher o primeiro elemento correspondente. Se for
1 , a ação do script Robo vai escolher o segundo elemento correspondente,
e assim por diante. A ordem é determinada da esquerda para a direita, de cima para baixo. O
valor padrão é 0 (a primeira correspondência é escolhida).
|
O atributo a seguir é opcional:
delayTime
: especifica a duração de um clique longo em milissegundos.
Confira a seguir o exemplo de uma ação de script Robo que executa um clique de cinco
segundos em um widget de IU com descrição de conteúdo "Avatar 8"
:
{
"eventType": "VIEW_LONG_CLICKED",
"elementDescriptors": [
{
"contentDescription": "Avatar 8"
}
],
"delayTime": 5000
}
Executar 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 atributo a seguir é opcional:
dragAndDrop
: se definido comotrue
, o gesto de um ponto vai realizar uma ação de arrastar e soltar. Por padrão, ele éfalse
.
Veja a seguir o exemplo de uma ação de gesto de um ponto do script Robo que executa a ação de deslizar para baixo:
{
"eventType": "ONE_POINT_GESTURE",
"coordinates": "(50%,25%)->(50%,75%)"
}
Executar 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. |
Veja a seguir o exemplo de uma ação de script Robo que executa um gesto de pinça:
{
"eventType": "TWO_POINT_GESTURE",
"coordinates": "(50%,50%)->(25%,50%),(50%,50%)->(75%,50%)"
}
Executar uma ação do IME
Esta ação pressiona o botão de ação atual, como "próximo", "concluído" e "pesquisar", no Editor de método de entrada (IME, na sigla em inglês) do widget de IU de destino especificado.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "PRESSED_EDITOR_ACTION"
|
-- |
elementDescriptors
|
Identifica o widget da IU de destino usando a hierarquia de IU do Android. |
Veja a seguir o exemplo de uma ação de script Robo que executa uma ação do IME
em um widget de IU com o ID do recurso
"com.google.samples.apps.topeka:id/first_name"
:
{
"eventType": "PRESSED_EDITOR_ACTION",
"elementDescriptors": [
{
"resourceId": "com.google.samples.apps.topeka:id/first_name"
}
]
}
Pressionar "Voltar"
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 de volta no nível de API 28 dos emuladores. |
Veja a seguir o exemplo de ação de script Robo que pressiona de volta:
{
"eventType": "PRESSED_BACK"
}
Pressionar "Início"
Esta ação envia um evento KEYCODE_HOME
para o dispositivo.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "GO_HOME"
|
-- |
Veja a seguir o exemplo de ação de script Robo que pressiona "Início":
{
"eventType": "GO_HOME"
}
Rolar um elemento para visualização
Esta ação faz o teste Robo avançar o widget da IU correspondente ao
elementDescriptors
especificado até que o widget da IU correspondente aos childElementDescriptors
especificados
esteja na tela ou que 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 a ser rolado usando a hierarquia de IU do Android. |
Este exemplo é de uma ação de script Robo que faz a rolagem do widget da IU
com o ID do recurso "my.app.package:id/scrollable_card_container"
até que o widget da IU
com texto "Orange"
seja exibido na tela ou que não seja mais possível realizar nenhuma rolagem
ou que o número máximo de 50 rolagens seja 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 em que direção deslizar:
|
elementDescriptors
|
Identifica o widget da IU de destino usando a hierarquia de IU do Android. |
Veja a seguir o exemplo de uma ação de script Robo que desliza para cima um widget de IU
com o ID do recurso "my.app.package:id/custom_content"
:
{
"eventType": "VIEW_SWIPED",
"swipeDirection": "Up",
"elementDescriptors": [
{
"resourceId": "my.app.package:id/custom_content"
}
]
}
Fazer uma 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 o exemplo de uma ação de script Robo que faz uma captura de tela:
{
"eventType": "TAKE_SCREENSHOT",
"screenshotName": "my_screenshot"
}
Tocar em um ponto na tela
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "POINT_TAP"
|
-- |
pointTapXCoordinate
|
A coordenada do pixel X do ponto de toque. Mutuamente exclusivo com
pointTapXPercent e pointTapYPercent .
|
pointTapYCoordinate
|
A coordenada do pixel Y do ponto de toque. Mutuamente exclusivo com
pointTapXPercent e pointTapYPercent .
|
pointTapXPercent
|
É a coordenada X percentual do ponto de toque. Mutuamente exclusivo com
pointTapXCoordinate e pointTapYCoordinate .
|
pointTapYPercent
|
É a coordenada Y percentual do ponto de toque. Mutuamente exclusivo com
pointTapXCoordinate e pointTapYCoordinate .
|
Veja a seguir o exemplo de uma ação de script Robo que toca no meio de uma tela:
{
"eventType": "POINT_TAP",
"pointTapXPercent": 50,
"pointTapYPercent": 50
}
Tocar em um ponto em um elemento
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "POINT_TAP_ELEMENT"
|
-- |
pointTapXPercent
|
É a coordenada X percentual no elemento de destino. |
pointTapYPercent
|
É a coordenada Y percentual no elemento de destino. |
elementDescriptors
|
Identifica o widget da IU de destino usando a hierarquia de IU do Android. |
Veja a seguir o exemplo de uma ação de script Robo que move o controle deslizante de uma 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 Robo.
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
---|---|
"eventType": "TERMINATE_CRAWL"
|
-- |
Veja a seguir o exemplo de uma ação de script Robo que interrompe um teste Robo:
{
"eventType": "TERMINATE_CRAWL"
}
Espera
A tabela a seguir lista os atributos obrigatórios:
Atributo | Descrição |
"eventType": "DELAYED_MESSAGE_POSTED"
|
-- |
delayTime
|
Especifica o tempo de espera, em milissegundos. |
Veja a seguir o exemplo de uma ação de script Robo que aguarda três segundos:
{
"eventType": "DELAYED_MESSAGE_POSTED",
"delayTime": 3000
}
Aguardar um elemento
Esta ação faz o teste Robo aguardar a exibição de um elemento 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. |
Veja a seguir o exemplo de uma ação de script Robo que aguarda até 30
segundos para que um widget de IU com o ID do recurso
"my.app.package:id/confirmation_button"
seja exibido na tela:
{
"eventType": "WAIT_FOR_ELEMENT",
"delayTime": 30000,
"elementDescriptors": [
{
"resourceId": "my.app.package:id/confirmation_button"
}
]
}