

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Teste do Appium no AWS Device Farm
<a name="appium-endpoint"></a>

Durante uma sessão de acesso remoto, você pode executar testes Appium em seu ambiente local, visando o dispositivo da sessão usando um endpoint Appium gerenciado. Com um endpoint Appium, você pode desenvolver, testar e executar o código Appium com feedback rápido e iteração rápida. Essa abordagem de teste **do lado do cliente** oferece a flexibilidade de se conectar a um dispositivo Device Farm a partir de qualquer ambiente cliente Appium de sua escolha.

Para complementar os testes do lado do cliente, o Device Farm também oferece suporte à execução de testes na infraestrutura gerenciada pelo serviço, chamada de execução do lado do **servidor**. [Nessa abordagem, você pode fazer upload do aplicativo e dos testes para o serviço e, em seguida, executá-los paralelamente em vários dispositivos usando hosts de teste gerenciados pelo serviço.](custom-test-environments-hosts.md) Essa abordagem se adapta bem para testes em vários dispositivos de forma independente, bem como para testes a partir do contexto de um CI/CD pipeline.

Para saber mais sobre a execução no lado do servidor, consulte. [Frameworks de teste e testes integrados no AWS Device Farm](test-types.md)

**Topics**
+ [O que é um endpoint Appium?](#appium-endpoint-what-is)
+ [Começando com os testes do Appium](appium-endpoint-getting-started.md)
+ [Interagindo com o dispositivo usando o Appium](appium-endpoint-interaction.md)
+ [Revisando os registros do servidor Appium](appium-endpoint-server-logs.md)
+ [Capacidades e comandos compatíveis do Appium](appium-endpoint-supported-caps-and-commands.md)

## O que é um endpoint Appium?
<a name="appium-endpoint-what-is"></a>

O [Appium](https://appium.io/) é uma popular estrutura de teste de software de código aberto para testar aplicativos web nativos, híbridos e móveis em diferentes dispositivos, incluindo telefones celulares e tablets, para iOS e Android. Ele permite que desenvolvedores e engenheiros de QA (Garantia de Qualidade) escrevam scripts que possam controlar remotamente um dispositivo, simular interações com o usuário e verificar se o aplicativo em teste está se comportando conforme o esperado. O Appium interage com os aplicativos da perspectiva de um usuário final, permitindo que os testadores desenvolvam testes que simulem como usuários reais usarão o aplicativo para seus testes.

O Appium é construído no modelo cliente-servidor, em que um cliente local solicita que um servidor Appium (local ou remoto) comande um dispositivo em seu nome. O servidor Appium gerencia um driver para comunicação com o dispositivo, como o [UIAutomator2 driver para Android ou o driver XCUITest ](https://github.com/appium/appium-uiautomator2-driver/) [para](https://appium.github.io/appium-xcuitest-driver/9.10/) iOS. Todos os comandos seguem os WebDriver padrões do [W3C](https://www.w3.org/TR/webdriver2/) sobre como controlar um dispositivo.

O endpoint Appium do Device Farm expõe uma URL do servidor Appium para o dispositivo em sua sessão de acesso remoto. O URL do endpoint Appium será específico para esse dispositivo nessa sessão e permanecerá válido durante a sessão, permitindo que você itere no mesmo dispositivo sem tempo adicional de configuração. Para obter mais informações sobre o acesso remoto, consulte[Acesso remoto no AWS Device Farm](remote-access.md).

# Começando com os testes do Appium
<a name="appium-endpoint-getting-started"></a>

Para a maioria dos usuários do Appium, o uso do Device Farm para testes do Appium requer apenas pequenas alterações na configuração de teste existente.

Em um alto nível, há três etapas para usar o Device Farm para testes Appium do lado do cliente:

1. Primeiro, você precisa [criar uma sessão de acesso remoto](how-to-create-session.md) para testar um dispositivo Device Farm. Você pode incluir seus aplicativos como parte de sua solicitação de acesso remoto ou instalar aplicativos após o início da sessão.

1. Quando a sessão estiver em execução, você pode [copiar o URL do endpoint Appium](appium-endpoint-interaction.md) e usá-lo por meio de uma ferramenta independente (como o Appium [Inspector](https://github.com/appium/appium-inspector)) ou do código de teste do Appium em seu IDE. O URL será válido durante a sessão de acesso remoto.

1. E, finalmente, depois que o teste do Appium for iniciado, você poderá [revisar os registros do servidor Appium ao vivo durante a execução do teste junto com o stream de vídeo do seu](appium-endpoint-server-logs.md) dispositivo.

# Interagindo com o dispositivo usando o Appium
<a name="appium-endpoint-interaction"></a>

Depois de [criar uma sessão de acesso remoto](how-to-create-session.md), o dispositivo estará disponível para testes do Appium. Durante toda a sessão de acesso remoto, você pode executar quantas sessões do Appium quiser no dispositivo, sem limites de quais clientes você usa. Por exemplo, você pode começar executando um teste usando o código Appium local do seu IDE e, em seguida, passar a usar o Appium Inspector para solucionar quaisquer problemas encontrados. A sessão pode durar até [150 minutos](limits.md#service-limits), no entanto, se não houver atividade por mais de 5 minutos (por meio do console interativo ou do endpoint Appium), a sessão expirará.

## Usando aplicativos para testar com sua sessão do Appium
<a name="appium-endpoint-using-apps"></a>

O Device Farm permite que você use seus aplicativos como parte da solicitação de criação da sessão de acesso remoto ou instale aplicativos durante a própria sessão de acesso remoto. Esses aplicativos são instalados automaticamente no dispositivo em teste e são injetados como recursos padrão para qualquer solicitação de sessão do Appium. Ao criar uma sessão de acesso remoto, você tem a opção de passar um ARN do aplicativo, que será usado por padrão como o `appium:app` recurso para todas as sessões subsequentes do Appium, bem como o aplicativo auxiliar ARNs, que será usado como o recurso. `appium:otherApps`

Por exemplo, se você criar uma sessão de acesso remoto usando um aplicativo `com.aws.devicefarm.sample` como seu aplicativo e `com.aws.devicefarm.other.sample` como um de seus aplicativos auxiliares, ao criar uma sessão do Appium, ela terá recursos semelhantes aos seguintes:

```
{
    "value":
    {
        "sessionId": "abcdef123456-1234-5678-abcd-abcdef123456",
        "capabilities":
        {
            "app": "/tmp/com.aws.devicefarm.sample.apk",
            "otherApps": "[\"/tmp/com.aws.devicefarm.other.sample.apk\"]",
            ...
        }
    }
}
```

Durante sua sessão, você pode instalar aplicativos adicionais (no console ou usando a [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_InstallToRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_InstallToRemoteAccessSession.html)API). Eles substituirão todos os aplicativos existentes usados anteriormente como `appium:app` recurso. Se esses aplicativos usados anteriormente tiverem um nome de pacote distinto, eles permanecerão no dispositivo e serão usados como parte do `appium:otherApps` recurso.

Por exemplo, se você usar inicialmente um aplicativo `com.aws.devicefarm.sample` ao criar sua sessão de acesso remoto, mas depois instalar um novo aplicativo chamado `com.aws.devicefarm.other.sample` durante a sessão, suas sessões do Appium terão recursos semelhantes aos seguintes:

```
{
    "value":
    {
        "sessionId": "abcdef123456-1234-5678-abcd-abcdef123456",
        "capabilities":
        {
            "app": "/tmp/com.aws.devicefarm.other.sample.apk",
            "otherApps": "[\"/tmp/com.aws.devicefarm.sample.apk\"]",
            ...
        }
    }
}
```

Se preferir, você pode especificar explicitamente os recursos do seu aplicativo usando o nome do aplicativo (usando os `appium:bundleId` recursos `appium:appPackage` ou para Android e iOS, respectivamente).

Se você estiver testando um aplicativo web, especifique a `browserName` capacidade da sua solicitação de criação de sessão do Appium. O `Chrome` navegador está disponível em todos os dispositivos Android e o `Safari` navegador está disponível em todos os dispositivos iOS.

O Device Farm não suporta a transmissão de uma URL remota ou um caminho do sistema de arquivos local `appium:app` durante uma sessão de acesso remoto. Faça upload de aplicativos para o Device Farm e, em vez disso, inclua-os na sessão.

**nota**  
Para obter mais informações sobre o upload automático de aplicativos como parte de sua sessão de acesso remoto, consulte Como [automatizar](api-ref.md#upload-example) o upload de aplicativos.

## Como usar o endpoint Appium
<a name="appium-endpoint-how-to-use"></a>

Aqui estão as etapas para acessar o endpoint Appium da sessão a partir do console AWS CLI, do e. AWS SDKs Essas etapas incluem como começar a executar testes usando várias estruturas de teste de clientes da Appium:

------
#### [ Console ]

1. Abra sua página de sessão de acesso remoto em seu navegador da web:  
![\[\]](http://docs.aws.amazon.com/pt_br/devicefarm/latest/developerguide/images/aws-device-farm-appium-endpoint.png)

1. Para executar uma sessão usando o Appium Inspector, faça o seguinte:

   1. Clique no botão **Configurar sessão do Appium**

   1. Siga as instruções na página sobre como iniciar uma sessão usando o Appium Inspector.

1. Para executar um teste Appium a partir do seu IDE local, faça o seguinte:

   1. Clique no ícone “copiar” ao lado do texto URL do **endpoint Appium**

   1. Cole esse URL em seu código Appium local onde quer que você especifique atualmente seu endereço remoto ou executor de comando. Para exemplos específicos do idioma, clique em uma das guias nesta janela de exemplo para o idioma de sua escolha.

------
#### [ AWS CLI ]

Primeiro, verifique se sua versão da AWS CLI é [baixando e up-to-date instalando a versão mais recente](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

**Importante**  
O campo de endpoint do Appium não está disponível em versões mais antigas da AWS CLI.

Quando sua sessão estiver em execução, o URL do endpoint do Appium estará disponível por meio de um campo nomeado `remoteDriverEndpoint` na resposta a uma chamada para a API: [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html)

```
$ aws devicefarm get-remote-access-session \
    --arn "arn:aws:devicefarm:us-west-2:123456789876:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000"
```

Isso mostrará uma saída como a seguinte:

```
{
    "remoteAccessSession": {
        "arn": "arn:aws:devicefarm:us-west-2:111122223333:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000",
        "name": "Google Pixel 8",
        "status": "RUNNING",
        "endpoints": {
            "remoteDriverEndpoint": "https://devicefarm-interactive-global.us-west-2.api.aws/remote-endpoint/ABCD1234...",
        ...
}
```

Você pode usar essa URL em seu código Appium local onde quer que você especifique atualmente seu endereço remoto ou executor de comando. Para exemplos específicos do idioma, clique em uma das guias nesta janela de exemplo para o idioma de sua escolha.

Para ver um exemplo de como interagir com o endpoint diretamente da linha de comando, você pode usar a [ferramenta de linha de comando curl](https://curl.se/) para chamar um endpoint diretamente: WebDriver 

```
$ curl "https://devicefarm-interactive-global.us-west-2.api.aws/remote-endpoint/ABCD1234.../status"
```

Isso mostrará uma saída como a seguinte:

```
{
    "value":
    {
        "ready": true,
        "message": "The server is ready to accept new connections",
        "build":
        {
            "version": "2.5.1"
        }
    }
}
```

------
#### [ Python ]

Quando sua sessão estiver em execução, o URL do endpoint do Appium estará disponível por meio de um campo nomeado `remoteDriverEndpoint` na resposta a uma chamada para a API: [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html)

```
# To get the URL
import sys
import boto3
from botocore.exceptions import ClientError

def get_appium_endpoint() -> str:
    session_arn = "arn:aws:devicefarm:us-west-2:111122223333:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000"
    device_farm_client = boto3.client("devicefarm", region_name="us-west-2")

    try:
        resp = device_farm_client.get_remote_access_session(arn=session_arn)
    except ClientError as exc:
        sys.exit(f"Failed to call Device Farm: {exc}")

    remote_access_session = resp.get("remoteAccessSession", {})
    endpoints = remote_access_session.get("endpoints", {})
    endpoint = endpoints.get("remoteDriverEndpoint")

    if not endpoint:
        sys.exit("Device Farm response did not include endpoints.remoteDriverEndpoint")

    return endpoint

# To use the URL
from appium import webdriver
from appium.options.android import UiAutomator2Options

opts = UiAutomator2Options()
driver = webdriver.Remote(get_appium_endpoint(), options=opts)
# ...
driver.quit()
```

------
#### [ Java ]

*Observação: este exemplo usa o AWS SDK for Java v2 e é compatível com as versões 11 e superiores do JDK.*

Quando sua sessão estiver em execução, o URL do endpoint do Appium estará disponível por meio de um campo nomeado `remoteDriverEndpoint` na resposta a uma chamada para a API: [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html)

```
// To get the URL
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.devicefarm.DeviceFarmClient;
import software.amazon.awssdk.services.devicefarm.model.GetRemoteAccessSessionRequest;
import software.amazon.awssdk.services.devicefarm.model.GetRemoteAccessSessionResponse;

public class AppiumEndpointBuilder {
    public static String getAppiumEndpoint() throws Exception {
        String session_arn = "arn:aws:devicefarm:us-west-2:111122223333:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000";

        try (DeviceFarmClient client = DeviceFarmClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build()) {

            GetRemoteAccessSessionResponse resp = client.getRemoteAccessSession(
                    GetRemoteAccessSessionRequest.builder().arn(session_arn).build()
            );

            String endpoint = resp.remoteAccessSession().endpoints().remoteDriverEndpoint();
            if (endpoint == null || endpoint.isEmpty()) {
                throw new IllegalStateException("remoteDriverEndpoint missing from response");
            }
            return endpoint;
        }
    }
}

// To use the URL
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.options.UiAutomator2Options;

import java.net.URL;

public class ExampleTest {
    public static void main(String[] args) throws Exception {
        String endpoint = AppiumEndpointBuilder.getAppiumEndpoint();
        UiAutomator2Options options = new UiAutomator2Options();
        AndroidDriver driver = new AndroidDriver(new URL(endpoint), options);

        try {
            // ... your test ...
        } finally {
            driver.quit();
        }
    }
}
```

------
#### [ JavaScript ]

*Observação: este exemplo usa AWS SDK para JavaScript v3 e WebDriverIO v8\$1 usando o Node 18\$1.*

Quando sua sessão estiver em execução, o URL do endpoint do Appium estará disponível por meio de um campo nomeado `remoteDriverEndpoint` na resposta a uma chamada para a API: [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html)

```
// To get the URL
import { DeviceFarmClient, GetRemoteAccessSessionCommand } from "@aws-sdk/client-device-farm";

export async function getAppiumEndpoint() {
  const sessionArn = "arn:aws:devicefarm:us-west-2:111122223333:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000";

  const client = new DeviceFarmClient({ region: "us-west-2" });
  const resp = await client.send(new GetRemoteAccessSessionCommand({ arn: sessionArn }));

  const endpoint = resp?.remoteAccessSession?.endpoints?.remoteDriverEndpoint;
  if (!endpoint) throw new Error("remoteDriverEndpoint missing from response");
  return endpoint;
}

// To use the URL with WebdriverIO
import { remote } from "webdriverio";

(async () => {
  const endpoint = await getAppiumEndpoint();
  const u = new URL(endpoint);

  const driver = await remote({
    protocol: u.protocol.replace(":", ""),
    hostname: u.hostname,
    port: u.port ? Number(u.port) : (u.protocol === "https:" ? 443 : 80),
    path: u.pathname + u.search,
    capabilities: {
      platformName: "Android",
      "appium:automationName": "UiAutomator2",
      // ...other caps...
    },
  });

  try {
    // ... your test ...
  } finally {
    await driver.deleteSession();
  }
})();
```

------
#### [ C\$1 ]

Quando sua sessão estiver em execução, o URL do endpoint do Appium estará disponível por meio de um campo nomeado `remoteDriverEndpoint` na resposta a uma chamada para a API: [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html)

```
// To get the URL
using System;
using System.Threading.Tasks;
using Amazon;
using Amazon.DeviceFarm;
using Amazon.DeviceFarm.Model;

public static class AppiumEndpointBuilder
{
    public static async Task<string> GetAppiumEndpointAsync()
    {
        var sessionArn = "arn:aws:devicefarm:us-west-2:111122223333:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000";

        var config = new AmazonDeviceFarmConfig
        {
            RegionEndpoint = RegionEndpoint.USWest2
        };
        using var client = new AmazonDeviceFarmClient(config);

        var resp = await client.GetRemoteAccessSessionAsync(new GetRemoteAccessSessionRequest { Arn = sessionArn });
        var endpoint = resp?.RemoteAccessSession?.Endpoints?.RemoteDriverEndpoint;

        if (string.IsNullOrWhiteSpace(endpoint))
            throw new InvalidOperationException("RemoteDriverEndpoint missing from response");

        return endpoint;
    }
}

// To use the URL
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Android;

class Example
{
    static async Task Main()
    {
        var endpoint = await AppiumEndpointBuilder.GetAppiumEndpointAsync();

        var options = new AppiumOptions();
        options.PlatformName = "Android";
        options.AutomationName = "UiAutomator2";

        using var driver = new AndroidDriver(new Uri(endpoint), options);
        try
        {
            // ... your test ...
        }
        finally
        {
            driver.Quit();
        }
    }
}
```

------
#### [ Ruby ]

Quando sua sessão estiver em execução, o URL do endpoint do Appium estará disponível por meio de um campo nomeado `remoteDriverEndpoint` na resposta a uma chamada para a API: [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html)

```
# To get the URL
require 'aws-sdk-devicefarm'

def get_appium_endpoint
  session_arn = "arn:aws:devicefarm:us-west-2:111122223333:session:abcdef123456-1234-5678-abcd-abcdef123456/abcdef123456-1234-5678-abcd-abcdef123456/00000"

  client = Aws::DeviceFarm::Client.new(region: 'us-west-2')
  resp = client.get_remote_access_session(arn: session_arn)
  endpoint = resp.remote_access_session.endpoints.remote_driver_endpoint
  raise "remote_driver_endpoint missing from response" if endpoint.nil? || endpoint.empty?
  endpoint
end

# To use the URL
require 'appium_lib_core'

endpoint = get_appium_endpoint
opts = {
  server_url: endpoint,
  capabilities: {
    'platformName' => 'Android',
    'appium:automationName' => 'UiAutomator2'
  }
}

driver = Appium::Core.for(opts).start_driver
begin
  # ... your test ...
ensure
  driver.quit
end
```

------

# Revisando os registros do servidor Appium
<a name="appium-endpoint-server-logs"></a>

Depois de [iniciar uma sessão do Appium](appium-endpoint-interaction.md), você pode ver os registros do servidor Appium ao vivo no console do Device Farm ou baixá-los após o término da sessão de acesso remoto. Aqui estão as instruções para fazer isso:

------
#### [ Console ]

1. No console do Device Farm, abra a sessão de acesso remoto do seu dispositivo.

1. Inicie uma sessão de endpoint Appium com o dispositivo a partir do seu IDE local ou do Appium Inspector

1. Em seguida, o log do servidor Appium aparecerá ao lado do dispositivo na página da sessão de acesso remoto, com as “informações da sessão” disponíveis na parte inferior da página abaixo do dispositivo:  
![\[\]](http://docs.aws.amazon.com/pt_br/devicefarm/latest/developerguide/images/aws-device-farm-appium-endpoint-logs.gif)

------
#### [ AWS CLI ]

*Observação: este exemplo usa a [ferramenta de linha de comando `curl`](https://curl.se/) para extrair o log do Device Farm.*

Durante ou após a sessão, você pode usar a [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API do Device Farm para baixar o log do servidor Appium.

```
$ aws devicefarm list-artifacts \
  --type FILE \
  --arn arn:aws:devicefarm:us-west-2:111122223333:session:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000
```

Isso mostrará uma saída como a seguinte durante a sessão:

```
{
    "artifacts": [
        {
            "arn": "arn:aws:devicefarm:us-west-2:111122223333:artifact:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000",
            "name": "AppiumServerLogOutput",
            "type": "APPIUM_SERVER_LOG_OUTPUT",
            "extension": "",
            "url": "https://prod-us-west-2-results.s3.dualstack.us-west-2.amazonaws.com/111122223333/12345678..."
        }
    ]
}
```

E o seguinte após o término da sessão:

```
{
    "artifacts": [
        {
            "arn": "arn:aws:devicefarm:us-west-2:111122223333:artifact:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000",
            "name": "Appium Server Output",
            "type": "APPIUM_SERVER_OUTPUT",
            "extension": "log",
            "url": "https://prod-us-west-2-results.s3.dualstack.us-west-2.amazonaws.com/111122223333/12345678..."
        }
    ]
}
```

```
$ curl "https://prod-us-west-2-results.s3.dualstack.us-west-2.amazonaws.com/111122223333/12345678..."
```

Isso mostrará uma saída como a seguinte:

```
info Appium Welcome to Appium v2.5.4
info Appium Non-default server args:
info Appium { address: '127.0.0.1',
info Appium   allowInsecure:
info Appium    [ 'execute_driver_script',
info Appium      'session_discovery',
info Appium      'perf_record',
info Appium      'adb_shell',
info Appium      'chromedriver_autodownload',
info Appium      'get_server_logs' ],
info Appium   keepAliveTimeout: 0,
info Appium   logNoColors: true,
info Appium   logTimestamp: true,
info Appium   longStacktrace: true,
info Appium   sessionOverride: true,
info Appium   strictCaps: true,
info Appium   useDrivers: [ 'uiautomator' ] }
```

------
#### [ Python ]

*Observação: este exemplo usa o `requests` pacote de terceiros para baixar o log, bem como o AWS SDK para Python`boto3`.*

Durante ou após a sessão, você pode usar a [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API do Device Farm para recuperar a URL de log do servidor Appium e, em seguida, baixá-la.

```
import pathlib
import requests
import boto3

def download_appium_log():
    session_arn = "arn:aws:devicefarm:us-west-2:111122223333:session:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000"
    client = boto3.client("devicefarm", region_name="us-west-2")

    # 1) List artifacts for the session (FILE artifacts), handling pagination
    artifacts = []
    token = None
    while True:
        kwargs = {"arn": session_arn, "type": "FILE"}
        if token:
            kwargs["nextToken"] = token
        resp = client.list_artifacts(**kwargs)
        artifacts.extend(resp.get("artifacts", []))
        token = resp.get("nextToken")
        if not token:
            break

    if not artifacts:
        raise RuntimeError("No artifacts found in this session")

    # Filter strictly to Appium server logs
    allowed = {"APPIUM_SERVER_OUTPUT", "APPIUM_SERVER_LOG_OUTPUT"}
    filtered = [a for a in artifacts if a.get("type") in allowed]
    if not filtered:
        raise RuntimeError("No Appium server log artifacts found (expected APPIUM_SERVER_OUTPUT or APPIUM_SERVER_LOG_OUTPUT)")

    # Prefer the final 'OUTPUT' log, else the live 'LOG_OUTPUT'
    chosen = (next((a for a in filtered if a.get("type") == "APPIUM_SERVER_OUTPUT"), None)
              or next((a for a in filtered if a.get("type") == "APPIUM_SERVER_LOG_OUTPUT"), None))

    url = chosen["url"]
    ext = chosen.get("extension") or "log"
    out = pathlib.Path(f"./appium_server_log.{ext}")

    # 2) Download the artifact
    with requests.get(url, stream=True) as r:
        r.raise_for_status()
        with open(out, "wb") as fh:
            for chunk in r.iter_content(chunk_size=1024 * 1024):
                if chunk:
                    fh.write(chunk)

    print(f"Saved Appium server log to: {out.resolve()}")

download_appium_log()
```

Isso mostrará uma saída como a seguinte:

```
info Appium Welcome to Appium v2.5.4
info Appium Non-default server args:
info Appium { address: '127.0.0.1', allowInsecure: [ 'execute_driver_script', ... ], useDrivers: [ 'uiautomator' ] }
```

------
#### [ Java ]

*Observação: este exemplo usa o AWS SDK for Java v2 `HttpClient` e para baixar o log, e é compatível com as versões 11 e superiores do JDK.*

Durante ou após a sessão, você pode usar a [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API do Device Farm para recuperar a URL de log do servidor Appium e, em seguida, baixá-la.

```
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.devicefarm.DeviceFarmClient;
import software.amazon.awssdk.services.devicefarm.model.Artifact;
import software.amazon.awssdk.services.devicefarm.model.ArtifactCategory;
import software.amazon.awssdk.services.devicefarm.model.ListArtifactsRequest;
import software.amazon.awssdk.services.devicefarm.model.ListArtifactsResponse;

public class AppiumLogDownloader {

    public static void main(String[] args) throws Exception {
        String sessionArn = "arn:aws:devicefarm:us-west-2:111122223333:session:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000";

        try (DeviceFarmClient client = DeviceFarmClient.builder()
                .region(Region.US_WEST_2)
                .build()) {

            // 1) List artifacts for the session (FILE artifacts) with pagination
            List<Artifact> all = new ArrayList<>();
            String token = null;
            do {
                ListArtifactsRequest.Builder b = ListArtifactsRequest.builder()
                        .arn(sessionArn)
                        .type(ArtifactCategory.FILE);
                if (token != null) b.nextToken(token);
                ListArtifactsResponse page = client.listArtifacts(b.build());
                all.addAll(page.artifacts());
                token = page.nextToken();
            } while (token != null && !token.isBlank());

            // Filter strictly to Appium logs
            List<Artifact> filtered = all.stream()
                    .filter(a -> {
                        String t = a.typeAsString();
                        return "APPIUM_SERVER_OUTPUT".equals(t) || "APPIUM_SERVER_LOG_OUTPUT".equals(t);
                    })
                    .toList();

            if (filtered.isEmpty()) {
                throw new RuntimeException("No Appium server log artifacts found (expected APPIUM_SERVER_OUTPUT or APPIUM_SERVER_LOG_OUTPUT).");
            }

            // Prefer OUTPUT; else LOG_OUTPUT
            Artifact chosen = filtered.stream()
                    .filter(a -> "APPIUM_SERVER_OUTPUT".equals(a.typeAsString()))
                    .findFirst()
                    .orElseGet(() -> filtered.stream()
                            .filter(a -> "APPIUM_SERVER_LOG_OUTPUT".equals(a.typeAsString()))
                            .findFirst()
                            .get());

            String url = chosen.url();
            String ext = (chosen.extension() == null || chosen.extension().isBlank()) ? "log" : chosen.extension();
            Path out = Path.of("appium_server_log." + ext);

            // 2) Download the artifact with HttpClient
            HttpClient http = HttpClient.newBuilder()
                    .connectTimeout(Duration.ofSeconds(10))
                    .build();

            HttpRequest get = HttpRequest.newBuilder(URI.create(url))
                    .timeout(Duration.ofMinutes(5))
                    .GET()
                    .build();

            HttpResponse<Path> resp = http.send(get, HttpResponse.BodyHandlers.ofFile(out));
            if (resp.statusCode() / 100 != 2) {
                throw new IOException("Failed to download log, HTTP " + resp.statusCode());
            }
            System.out.println("Saved Appium server log to: " + out.toAbsolutePath());
        }
    }
}
```

Isso mostrará uma saída como a seguinte:

```
info Appium Welcome to Appium v2.5.4
info Appium Non-default server args:
info Appium { address: '127.0.0.1', ..., useDrivers: [ 'uiautomator' ] }
```

------
#### [ JavaScript ]

*Observação: este exemplo usa o AWS SDK para JavaScript (v3) e o Node 18\$1 `fetch` para baixar o log.*

Durante ou após a sessão, você pode usar a [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API do Device Farm para recuperar a URL de log do servidor Appium e, em seguida, baixá-la.

```
import { DeviceFarmClient, ListArtifactsCommand } from "@aws-sdk/client-device-farm";
import { createWriteStream } from "fs";
import { pipeline } from "stream";
import { promisify } from "util";

const pipe = promisify(pipeline);
const client = new DeviceFarmClient({ region: "us-west-2" });

const sessionArn = "arn:aws:devicefarm:us-west-2:111122223333:session:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000";

// 1) List artifacts for the session (FILE artifacts), handling pagination
const artifacts = [];
let nextToken;
do {
  const page = await client.send(new ListArtifactsCommand({
    arn: sessionArn,
    type: "FILE",
    nextToken
  }));
  artifacts.push(...(page.artifacts ?? []));
  nextToken = page.nextToken;
} while (nextToken);

if (!artifacts.length) throw new Error("No artifacts found");

// Strict filter to Appium logs
const filtered = (artifacts ?? []).filter(a =>
  a.type === "APPIUM_SERVER_OUTPUT" || a.type === "APPIUM_SERVER_LOG_OUTPUT"
);
if (!filtered.length) {
  throw new Error("No Appium server log artifacts found (expected APPIUM_SERVER_OUTPUT or APPIUM_SERVER_LOG_OUTPUT).");
}

// Prefer OUTPUT; else LOG_OUTPUT
const chosen =
  filtered.find(a => a.type === "APPIUM_SERVER_OUTPUT") ??
  filtered.find(a => a.type === "APPIUM_SERVER_LOG_OUTPUT");

const url = chosen.url;
const ext = chosen.extension || "log";
const outPath = `./appium_server_log.${ext}`;

// 2) Download the artifact
const resp = await fetch(url);
if (!resp.ok) {
  throw new Error(`Failed to download log: ${resp.status} ${await resp.text().catch(()=>"")}`);
}
await pipe(resp.body, createWriteStream(outPath));
console.log("Saved Appium server log to:", outPath);
```

Isso mostrará uma saída como a seguinte:

```
info Appium Welcome to Appium v2.5.4
info Appium Non-default server args:
info Appium { address: '127.0.0.1', allowInsecure: [ 'execute_driver_script', ... ], useDrivers: [ 'uiautomator' ] }
```

------
#### [ C\$1 ]

*Observação: este exemplo usa o AWS SDK for .NET `HttpClient` e para baixar o log.*

Durante ou após a sessão, você pode usar a [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API do Device Farm para recuperar a URL de log do servidor Appium e, em seguida, baixá-la.

```
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Linq;
using Amazon;
using Amazon.DeviceFarm;
using Amazon.DeviceFarm.Model;

class AppiumLogDownloader
{
    static async Task Main()
    {
        var sessionArn = "arn:aws:devicefarm:us-west-2:111122223333:session:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000";

        using var client = new AmazonDeviceFarmClient(RegionEndpoint.USWest2);

        // 1) List artifacts for the session (FILE artifacts), handling pagination
        var all = new List<Artifact>();
        string? token = null;
        do
        {
            var page = await client.ListArtifactsAsync(new ListArtifactsRequest
            {
                Arn = sessionArn,
                Type = ArtifactCategory.FILE,
                NextToken = token
            });
            if (page.Artifacts != null) all.AddRange(page.Artifacts);
            token = page.NextToken;
        } while (!string.IsNullOrEmpty(token));

        if (all.Count == 0)
            throw new Exception("No artifacts found");

        // Strict filter to Appium logs
        var filtered = all.Where(a =>
            a.Type == "APPIUM_SERVER_OUTPUT" || a.Type == "APPIUM_SERVER_LOG_OUTPUT").ToList();

        if (filtered.Count == 0)
            throw new Exception("No Appium server log artifacts found (expected APPIUM_SERVER_OUTPUT or APPIUM_SERVER_LOG_OUTPUT).");

        // Prefer OUTPUT; else LOG_OUTPUT
        var chosen = filtered.FirstOrDefault(a => a.Type == "APPIUM_SERVER_OUTPUT")
                    ?? filtered.First(a => a.Type == "APPIUM_SERVER_LOG_OUTPUT");
        
        var url = chosen.Url;
        var ext = string.IsNullOrWhiteSpace(chosen.Extension) ? "log" : chosen.Extension;
        var outPath = $"./appium_server_log.{ext}";

        // 2) Download the artifact
        using var http = new HttpClient();
        using var resp = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
        resp.EnsureSuccessStatusCode();
        await using (var fs = File.Create(outPath))
        {
            await resp.Content.CopyToAsync(fs);
        }
        Console.WriteLine($"Saved Appium server log to: {Path.GetFullPath(outPath)}");
    }
}
```

Isso mostrará uma saída como a seguinte:

```
info Appium Welcome to Appium v2.5.4
info Appium Non-default server args:
info Appium { address: '127.0.0.1', ..., useDrivers: [ 'uiautomator' ] }
```

------
#### [ Ruby ]

*Observação: este exemplo usa o AWS SDK for `Net::HTTP` Ruby e para baixar o log.*

Durante ou após a sessão, você pode usar a [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API do Device Farm para recuperar a URL de log do servidor Appium e, em seguida, baixá-la.

```
require "aws-sdk-devicefarm"
require "net/http"
require "uri"

client = Aws::DeviceFarm::Client.new(region: "us-west-2")
session_arn = "arn:aws:devicefarm:us-west-2:111122223333:session:12345678-1111-2222-333-456789abcdef/12345678-1111-2222-333-456789abcdef/00000"

# 1) List artifacts for the session (FILE artifacts), handling pagination
artifacts = []
token = nil
loop do
  page = client.list_artifacts(arn: session_arn, type: "FILE", next_token: token)
  artifacts.concat(page.artifacts || [])
  token = page.next_token
  break if token.nil? || token.empty?
end

raise "No artifacts found" if artifacts.empty?

# Strict filter to Appium logs
filtered = (artifacts || []).select { |a| ["APPIUM_SERVER_OUTPUT", "APPIUM_SERVER_LOG_OUTPUT"].include?(a.type) }
raise "No Appium server log artifacts found (expected APPIUM_SERVER_OUTPUT or APPIUM_SERVER_LOG_OUTPUT)." if filtered.empty?

# Prefer OUTPUT; else LOG_OUTPUT
chosen = filtered.find { |a| a.type == "APPIUM_SERVER_OUTPUT" } ||
         filtered.find { |a| a.type == "APPIUM_SERVER_LOG_OUTPUT" }

url = chosen.url
ext = (chosen.extension && !chosen.extension.empty?) ? chosen.extension : "log"
out_path = "./appium_server_log.#{ext}"

# 2) Download the artifact
uri = URI.parse(url)
Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == "https")) do |http|
  req = Net::HTTP::Get.new(uri)
  http.request(req) do |resp|
    raise "Failed GET: #{resp.code} #{resp.body}" unless resp.code.to_i / 100 == 2
    File.open(out_path, "wb") { |f| resp.read_body { |chunk| f.write(chunk) } }
  end
end
puts "Saved Appium server log to: #{File.expand_path(out_path)}"
```

Isso mostrará uma saída como a seguinte:

```
info Appium Welcome to Appium v2.5.4
info Appium Non-default server args:
info Appium { address: '127.0.0.1', allowInsecure: [ 'execute_driver_script', ... ], useDrivers: [ 'uiautomator' ] }
```

------

# Capacidades e comandos compatíveis do Appium
<a name="appium-endpoint-supported-caps-and-commands"></a>

O endpoint Appium do Device Farm suporta a maioria dos mesmos comandos e recursos desejados que você usa em dispositivos locais, com algumas exceções. As listas a seguir mostram quais recursos e comandos não são suportados atualmente. Se seus testes não puderem ser executados conforme o esperado devido a uma capacidade restrita, abra um caso de suporte para obter orientação adicional.

## Recursos com suporte
<a name="appium-endpoint-unsupported-capabilities"></a>

Ao criar uma sessão do Appium no Device Farm, recomendamos ter um conjunto distinto de recursos que exclua quaisquer recursos específicos do seu dispositivo local. No Device Farm, a criação da sessão pode falhar se determinados recursos não suportados forem definidos. Isso inclui recursos específicos do dispositivo, como e. `udid` `platformVersion` Além disso, alguns recursos relacionados ao ChromeDriver WebDriverAgent Android e ao iOS não são compatíveis, bem como recursos que só são compatíveis com emuladores e simuladores.

## Comandos compatíveis
<a name="appium-endpoint-unsupported-commands"></a>

A maioria dos comandos do Appium que são executados corretamente em dispositivos Android e iOS reais serão executados conforme o esperado no Device Farm, com as seguintes exclusões: 

### Comandos do dispositivo Appium () `/appium/device`
<a name="appium-endpoint-unsupported-device-commands"></a>
+ `install_app`
+ `finger_print`
+ `send_sms`
+ `gsm_call`
+ `gsm_signal`
+ `gsm_voice`
+ `power_ac`
+ `power_capacity`
+ `network_speed`
+ `shake`

### Métodos e scripts de execução do Appium () `/execute`
<a name="appium-endpoint-unsupported-execute-methods"></a>
+ `installApp`
+ `execEmuConsoleCommand`
+ `fingerprint`
+ `gsmCall`
+ `gsmSignal`
+ `sendSms`
+ `gsmVoice`
+ `powerAC`
+ `powerCapacity`
+ `networkSpeed`
+ `sensorSet`
+ `injectEmulatorCameraImage`
+ `isGpsEnabled`
+ `shake`
+ `clearApp`
+ `clearKeychains`
+ `configureLocalization`
+ `enrollBiometric`
+ `getPasteboard`
+ `installXCTestBundle`
+ `listXCTestBundles`
+ `listXCTestsInTestBundle`
+ `runXCTest`
+ `sendBiometricMatch`
+ `setPasteboard`
+ `setPermission`
+ `startAudioRecording`
+ `startLogsBroadcast`
+ `startRecordingScreen`
+ `startScreenStreaming`
+ `startXCTestScreenRecording`
+ `stopAudioRecording`
+ `stopLogsBroadcast`
+ `stopRecordingScreen`
+ `stopScreenStreaming`
+ `stopXCTestScreenRecording`
+ `updateSafariPreferences`