

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Pruebas de Appium en AWS Device Farm
<a name="appium-endpoint"></a>

Durante una sesión de acceso remoto, puede ejecutar pruebas de Appium desde su entorno local y dirigirlas al dispositivo de la sesión mediante un punto de conexión de Appium administrado. Con un punto final de Appium, puedes desarrollar, probar y ejecutar el código de Appium con una respuesta rápida y una iteración rápidas. Este enfoque de pruebas **del lado del cliente** ofrece la flexibilidad de conectarse a un dispositivo Device Farm desde cualquier entorno de cliente de Appium que elija.

Para complementar las pruebas del lado del cliente, Device Farm también admite la ejecución de pruebas en la infraestructura administrada por el servicio, lo que se denomina ejecución del lado **del servidor**. [Con este enfoque, puedes cargar la aplicación y las pruebas en el servicio y, a continuación, ejecutar las pruebas en paralelo en varios dispositivos mediante hosts de prueba gestionados por el servicio.](custom-test-environments-hosts.md) Este enfoque se adapta bien para realizar pruebas en muchos dispositivos de forma independiente, así como para realizar pruebas desde el contexto de una canalización. CI/CD 

Para obtener más información sobre la ejecución en el servidor, consulta. [Marcos de pruebas y pruebas integradas en AWS Device Farm](test-types.md)

**Topics**
+ [¿Qué es un punto final de Appium?](#appium-endpoint-what-is)
+ [Cómo empezar con las pruebas de Appium](appium-endpoint-getting-started.md)
+ [Interactuar con el dispositivo mediante Appium](appium-endpoint-interaction.md)
+ [Revisión de los registros del servidor de Appium](appium-endpoint-server-logs.md)
+ [Capacidades y comandos de Appium compatibles](appium-endpoint-supported-caps-and-commands.md)

## ¿Qué es un punto final de Appium?
<a name="appium-endpoint-what-is"></a>

[Appium](https://appium.io/) es un popular marco de pruebas de software de código abierto para probar aplicaciones web nativas, híbridas y móviles en diferentes dispositivos, incluidos teléfonos móviles y tabletas, tanto para iOS como para Android. Permite a los desarrolladores e ingenieros de control de calidad (control de calidad) escribir scripts que pueden controlar un dispositivo de forma remota, simular las interacciones de los usuarios y verificar que la aplicación objeto de prueba se comporta como se espera. Appium interactúa con las aplicaciones desde la perspectiva del usuario final, lo que permite a los evaluadores desarrollar pruebas que simulan la forma en que los usuarios reales utilizarán la aplicación para sus pruebas.

Appium se basa en el modelo cliente-servidor, en el que un cliente local solicita a un servidor Appium (local o remoto) que controle un dispositivo en su nombre. El servidor Appium administra un controlador para comunicarse con el dispositivo, como el [UIAutomator2 controlador](https://github.com/appium/appium-uiautomator2-driver/) para Android o el [XCUITest controlador](https://appium.github.io/appium-xcuitest-driver/9.10/) para iOS. Todos los comandos siguen los WebDriver estándares del [W3C](https://www.w3.org/TR/webdriver2/) sobre cómo controlar un dispositivo.

El terminal Appium de Device Farm muestra la URL del servidor Appium del dispositivo en tu sesión de acceso remoto. La URL del punto de conexión de Appium será específica de ese dispositivo en esa sesión y seguirá siendo válida durante toda la sesión, lo que le permitirá realizar iteraciones en el mismo dispositivo sin necesidad de tiempo de configuración adicional. Para obtener más información sobre el acceso remoto, consulte. [Acceso remoto en AWS Device Farm](remote-access.md)

# Cómo empezar con las pruebas de Appium
<a name="appium-endpoint-getting-started"></a>

Para la mayoría de los usuarios de Appium, el uso de Device Farm para las pruebas de Appium solo requiere cambios menores en la configuración de prueba existente.

En términos generales, hay tres pasos para usar Device Farm para las pruebas de Appium del lado del cliente:

1. En primer lugar, debe [crear una sesión de acceso remoto](how-to-create-session.md) para probar un dispositivo Device Farm. Puedes incluir tus aplicaciones como parte de tu solicitud de acceso remoto o instalarlas una vez iniciada la sesión.

1. Una vez que se ejecute la sesión, puede [copiar la URL del punto final de Appium](appium-endpoint-interaction.md) y utilizarla a través de una herramienta independiente (como el [Inspector](https://github.com/appium/appium-inspector) de Appium) o desde el código de prueba de Appium en su IDE. La URL será válida durante toda la sesión de acceso remoto.

1. Por último, una vez que la prueba de Appium haya comenzado, podrás [revisar los registros del servidor de Appium en tiempo real durante la ejecución de la prueba junto con la transmisión de vídeo de tu](appium-endpoint-server-logs.md) dispositivo.

# Interactuar con el dispositivo mediante Appium
<a name="appium-endpoint-interaction"></a>

Una vez que haya [creado una sesión de acceso remoto](how-to-create-session.md), el dispositivo estará disponible para las pruebas de Appium. Durante toda la sesión de acceso remoto, puedes ejecutar tantas sesiones de Appium como desees en el dispositivo, sin límites en cuanto a los clientes que utilices. Por ejemplo, puede empezar por ejecutar una prueba con el código Appium local de su IDE y, a continuación, pasar a utilizar el Inspector de Appium para solucionar cualquier problema que encuentre. La sesión puede durar hasta [150 minutos](limits.md#service-limits); sin embargo, si no hay actividad durante más de 5 minutos (ya sea a través de la consola interactiva o del terminal de Appium), se agotará el tiempo de espera de la sesión.

## Uso de aplicaciones para realizar pruebas con tu sesión de Appium
<a name="appium-endpoint-using-apps"></a>

Device Farm te permite usar tus aplicaciones como parte de tu solicitud de creación de sesión de acceso remoto o instalar aplicaciones durante la propia sesión de acceso remoto. Estas aplicaciones se instalan automáticamente en el dispositivo que se está probando y se incorporan como funciones predeterminadas para cualquier solicitud de sesión de Appium. Al crear una sesión de acceso remoto, tiene la opción de transferir un ARN de aplicación, que se utilizará de forma predeterminada como `appium:app` capacidad para todas las sesiones de Appium posteriores, así como una aplicación auxiliar ARNs, que se utilizará como capacidad. `appium:otherApps`

Por ejemplo, si crea una sesión de acceso remoto con una aplicación `com.aws.devicefarm.sample` como aplicación y `com.aws.devicefarm.other.sample` como una de sus aplicaciones auxiliares, cuando vaya a crear una sesión de Appium, tendrá capacidades similares a las siguientes:

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

Durante la sesión, puedes instalar aplicaciones adicionales (ya sea dentro de la consola o mediante la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_InstallToRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_InstallToRemoteAccessSession.html)API). Estas anularán cualquier aplicación existente que se haya utilizado anteriormente como `appium:app` capacidad. Si esas aplicaciones utilizadas anteriormente tienen un nombre de paquete distinto, permanecerán en el dispositivo y se utilizarán como parte de la `appium:otherApps` capacidad.

Por ejemplo, si inicialmente usas una aplicación `com.aws.devicefarm.sample` al crear tu sesión de acceso remoto, pero luego instalas una nueva aplicación con el nombre `com.aws.devicefarm.other.sample` durante la sesión, tus sesiones de Appium tendrán capacidades similares a las siguientes:

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

Si lo prefieres, puedes especificar de forma explícita las capacidades de tu aplicación mediante el nombre de la aplicación (utilizando las `appium:bundleId` capacidades `appium:appPackage` o las capacidades para Android e iOS, respectivamente).

Si estás probando una aplicación web, especifica la `browserName` capacidad de tu solicitud de creación de sesión de Appium. El `Chrome` navegador está disponible en todos los dispositivos Android y en todos los dispositivos iOS. `Safari`

Device Farm no admite el paso de una URL remota o una ruta del sistema de archivos local `appium:app` durante una sesión de acceso remoto. Cargue aplicaciones a Device Farm e inclúyalas en la sesión.

**nota**  
Para obtener más información sobre la carga automática de aplicaciones como parte de tu sesión de acceso remoto, consulta cómo [automatizar la carga de aplicaciones](api-ref.md#upload-example).

## ¿Cómo usar el terminal de Appium?
<a name="appium-endpoint-how-to-use"></a>

Estos son los pasos para acceder al punto final de Appium de la sesión desde la consola, el y el AWS CLI. AWS SDKs Estos pasos incluyen cómo empezar a ejecutar pruebas utilizando varios marcos de pruebas de clientes de Appium:

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

1. Abre la página de sesión de acceso remoto en tu navegador web:  
![\[\]](http://docs.aws.amazon.com/es_es/devicefarm/latest/developerguide/images/aws-device-farm-appium-endpoint.png)

1. Para ejecutar una sesión con Appium Inspector, haga lo siguiente:

   1. Haga clic en el botón **Configurar** sesión de Appium

   1. Siga las instrucciones de la página sobre cómo iniciar una sesión con Appium Inspector.

1. Para ejecutar una prueba de Appium desde tu IDE local, haz lo siguiente:

   1. Haga clic en el icono de «copiar» situado junto al texto de la URL del punto de conexión de **Appium**

   1. Pegue esta URL en su código local de Appium donde especifique actualmente su dirección remota o ejecutor de comandos. Para ver ejemplos de idiomas específicos, haga clic en una de las pestañas de esta ventana de ejemplo para el idioma que prefiera.

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

En primer lugar, compruebe que su versión de AWS CLI esté up-to-date disponible [descargando e instalando la versión más reciente](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

**importante**  
El campo de punto final de Appium no está disponible en las versiones anteriores de la AWS CLI.

Una vez que la sesión esté activa, la URL del punto de conexión de Appium estará disponible en un campo cuyo nombre aparece `remoteDriverEndpoint` en la respuesta a una llamada a la 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"
```

Esto mostrará un resultado como el siguiente:

```
{
    "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...",
        ...
}
```

Puedes usar esta URL en tu código local de Appium siempre que especifiques actualmente tu dirección remota o tu ejecutor de comandos. Para ver ejemplos de idiomas específicos, haga clic en una de las pestañas de esta ventana de ejemplo para seleccionar el idioma que prefiera.

Para ver un ejemplo de cómo interactuar con el punto final directamente desde la línea de comandos, puedes usar la [herramienta de línea de comandos curl para llamar](https://curl.se/) directamente al punto final: WebDriver 

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

Esto mostrará un resultado como el siguiente:

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

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

Una vez que la sesión esté en marcha, la URL del punto final de Appium estará disponible en un campo denominado `remoteDriverEndpoint` en la respuesta a una llamada a la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_GetRemoteAccessSession.html)API:

```
# 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 ]

*Nota: este ejemplo usa el AWS SDK para Java v2 y es compatible con las versiones 11 y superiores de JDK.*

Una vez que la sesión esté en marcha, la URL del punto final de Appium estará disponible en un campo denominado `remoteDriverEndpoint` en la respuesta a una llamada a la 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 ]

*Nota: en este ejemplo se usa el AWS SDK para la versión JavaScript 3 y WebDriverIO para la versión 8\$1 con Node 18\$1.*

Una vez que la sesión esté en marcha, la URL del punto final de Appium estará disponible en un campo denominado `remoteDriverEndpoint` en la respuesta a una llamada a la 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 ]

Una vez que la sesión esté activa, la URL del punto de conexión de Appium estará disponible en un campo denominado `remoteDriverEndpoint` en la respuesta a una llamada a la 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 ]

Una vez que la sesión esté activa, la URL del punto de conexión de Appium estará disponible en un campo denominado `remoteDriverEndpoint` en la respuesta a una llamada a la 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
```

------

# Revisión de los registros del servidor de Appium
<a name="appium-endpoint-server-logs"></a>

Una vez que haya [iniciado una sesión de Appium](appium-endpoint-interaction.md), podrá ver los registros del servidor de Appium en directo en la consola Device Farm o descargarlos cuando finalice la sesión de acceso remoto. Estas son las instrucciones para hacerlo:

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

1. En la consola de Device Farm, abra la sesión de acceso remoto del dispositivo.

1. Inicie una sesión de punto final de Appium con el dispositivo desde su IDE local o el Inspector de Appium

1. Luego, el registro del servidor de Appium aparecerá junto al dispositivo en la página de la sesión de acceso remoto, con la «información de la sesión» disponible en la parte inferior de la página, debajo del dispositivo:  
![\[\]](http://docs.aws.amazon.com/es_es/devicefarm/latest/developerguide/images/aws-device-farm-appium-endpoint-logs.gif)

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

*Nota: en este ejemplo se utiliza la [herramienta de línea de comandos `curl`](https://curl.se/) para extraer el registro de Device Farm.*

Durante o después de la sesión, puedes usar la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API de Device Farm para descargar el registro del servidor de 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
```

Esto mostrará resultados como los siguientes durante la sesión:

```
{
    "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..."
        }
    ]
}
```

Y lo siguiente una vez finalizada la sesión:

```
{
    "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..."
```

Esto mostrará un resultado como el siguiente:

```
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 ]

*Nota: en este ejemplo se utiliza el `requests` paquete de terceros para descargar el registro, así como el AWS SDK para Python`boto3`.*

Durante o después de la sesión, puedes usar la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API de Device Farm para recuperar la URL del registro del servidor de Appium y, a continuación, descargarla.

```
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()
```

Esto mostrará un resultado como el siguiente:

```
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 ]

*Nota: en este ejemplo se utiliza el AWS SDK para Java v2 y `HttpClient` para descargar el registro, y es compatible con las versiones 11 y superiores de JDK.*

Durante la sesión o después de ella, puedes usar la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API de Device Farm para recuperar la URL del registro del servidor Appium y, a continuación, descargarla.

```
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());
        }
    }
}
```

Esto mostrará un resultado como el siguiente:

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

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

*Nota: en este ejemplo se utiliza el AWS SDK para JavaScript la versión 3 y el nodo 18\$1 `fetch` para descargar el registro.*

Durante o después de la sesión, puedes usar la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API de Device Farm para recuperar la URL del registro del servidor de Appium y, a continuación, descargarla.

```
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);
```

Esto mostrará un resultado como el siguiente:

```
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 ]

*Nota: en este ejemplo se utiliza el AWS SDK para .NET y `HttpClient` para descargar el registro.*

Durante o después de la sesión, puedes usar la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API de Device Farm para recuperar la URL del registro del servidor de Appium y, a continuación, descargarla.

```
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)}");
    }
}
```

Esto mostrará un resultado como el siguiente:

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

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

*Nota: en este ejemplo se usa el AWS SDK for Ruby y `Net::HTTP` se descarga el registro.*

Durante o después de la sesión, puedes usar la [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API de Device Farm para recuperar la URL del registro del servidor de Appium y, a continuación, descargarla.

```
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)}"
```

Esto mostrará un resultado como el siguiente:

```
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 y comandos de Appium compatibles
<a name="appium-endpoint-supported-caps-and-commands"></a>

El punto de conexión Appium de Device Farm admite la mayoría de los mismos comandos y capacidades deseadas que se utilizan en los dispositivos locales, con algunas excepciones. Las siguientes listas muestran qué funciones y comandos no se admiten actualmente. Si las pruebas no se pueden ejecutar según lo esperado debido a una capacidad restringida, abra un caso de soporte para obtener más información.

## Capacidades compatibles
<a name="appium-endpoint-unsupported-capabilities"></a>

Al crear una sesión de Appium en Device Farm, recomendamos tener un conjunto distinto de capacidades que excluya las capacidades específicas de su dispositivo local. En Device Farm, la creación de sesiones puede fallar si se configuran determinadas capacidades no compatibles. Esto incluye capacidades específicas del dispositivo, como y. `udid` `platformVersion` Además, no se admiten determinadas funciones relacionadas ChromeDriver con WebDriverAgent Android y iOS, así como funciones que solo se admiten en emuladores y simuladores.

## Comandos admitidos
<a name="appium-endpoint-unsupported-commands"></a>

La mayoría de los comandos de Appium que se ejecutan correctamente en dispositivos Android e iOS reales se ejecutarán según lo esperado en Device Farm, con las siguientes exclusiones: 

### Comandos de 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`

### Appium ejecuta métodos y scripts () `/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`