

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Pengujian appium di AWS Device Farm
<a name="appium-endpoint"></a>

Selama sesi akses jarak jauh, Anda dapat menjalankan pengujian Appium dari lingkungan lokal Anda, menargetkan perangkat sesi menggunakan titik akhir Appium yang dikelola. Dengan titik akhir Appium, Anda dapat mengembangkan, menguji, dan mengeksekusi kode Appium dengan umpan balik cepat dan iterasi cepat. Pendekatan **sisi klien** untuk pengujian ini menawarkan fleksibilitas untuk terhubung ke perangkat Device Farm dari lingkungan klien Appium pilihan Anda.

Untuk melengkapi pengujian sisi klien, Device Farm juga mendukung menjalankan pengujian pada infrastruktur yang dikelola oleh layanan, yang disebut eksekusi sisi **server**. [Dalam pendekatan ini, Anda dapat mengunggah aplikasi dan pengujian ke layanan, lalu menjalankan pengujian secara paralel di beberapa perangkat menggunakan host pengujian yang dikelola layanan.](custom-test-environments-hosts.md) Pendekatan ini berskala baik untuk pengujian pada banyak perangkat secara independen, serta pengujian dari konteks CI/CD pipa.

Untuk mempelajari lebih lanjut tentang eksekusi sisi server, silakan lihat. [Uji kerangka kerja dan pengujian bawaan di AWS Device Farm](test-types.md)

**Topics**
+ [Apa itu titik akhir Appium?](#appium-endpoint-what-is)
+ [Memulai dengan pengujian Appium](appium-endpoint-getting-started.md)
+ [Berinteraksi dengan perangkat menggunakan Appium](appium-endpoint-interaction.md)
+ [Meninjau log server Appium Anda](appium-endpoint-server-logs.md)
+ [Kemampuan dan perintah Appium yang didukung](appium-endpoint-supported-caps-and-commands.md)

## Apa itu titik akhir Appium?
<a name="appium-endpoint-what-is"></a>

[Appium](https://appium.io/) adalah kerangka pengujian perangkat lunak open-source yang populer untuk menguji aplikasi web asli, hibrida, dan seluler pada perangkat yang berbeda, termasuk ponsel dan tablet, untuk iOS dan Android. Ini memungkinkan pengembang dan insinyur QA (Quality Assurance) untuk menulis skrip yang dapat mengontrol perangkat dari jarak jauh, mensimulasikan interaksi pengguna, dan memverifikasi bahwa aplikasi yang diuji berperilaku seperti yang diharapkan. Appium berinteraksi dengan aplikasi dari perspektif pengguna akhir, memungkinkan penguji untuk mengembangkan pengujian yang mensimulasikan bagaimana pengguna nyata akan menggunakan aplikasi untuk pengujian mereka.

Appium dibangun pada model client-server, di mana klien lokal meminta server Appium (lokal atau jarak jauh) untuk memerintahkan perangkat atas nama mereka. [Server Appium mengelola driver untuk berkomunikasi dengan perangkat, seperti [UIAutomator2 driver untuk Android atau driver](https://github.com/appium/appium-uiautomator2-driver/) untuk iOSXCUITest .](https://appium.github.io/appium-xcuitest-driver/9.10/) Semua perintah mengikuti WebDriver standar [W3C](https://www.w3.org/TR/webdriver2/) untuk cara mengontrol perangkat.

Titik akhir Appium Device Farm memperlihatkan URL server Appium untuk perangkat dalam sesi akses jarak jauh Anda. URL titik akhir Appium akan spesifik untuk perangkat tersebut dalam sesi tersebut, dan tetap valid selama durasi sesi, memungkinkan Anda untuk melakukan iterasi pada perangkat yang sama tanpa waktu penyiapan tambahan. Untuk informasi lebih lanjut tentang Remote Access, silakan lihat[Akses jarak jauh di AWS Device Farm](remote-access.md).

# Memulai dengan pengujian Appium
<a name="appium-endpoint-getting-started"></a>

Untuk sebagian besar pengguna Appium, menggunakan Device Farm untuk pengujian Appium hanya memerlukan sedikit perubahan pada konfigurasi pengujian yang ada.

Pada tingkat tinggi, ada tiga langkah untuk menggunakan Device Farm untuk pengujian Appium sisi klien:

1. Pertama, Anda perlu [membuat sesi akses jarak jauh](how-to-create-session.md) untuk menguji perangkat Device Farm. Anda dapat menyertakan aplikasi sebagai bagian dari permintaan akses jarak jauh, atau menginstal aplikasi setelah sesi dimulai.

1. Setelah sesi berjalan, Anda dapat [menyalin URL titik akhir Appium](appium-endpoint-interaction.md), dan menggunakannya baik melalui alat yang berdiri sendiri (seperti Appium [Inspector](https://github.com/appium/appium-inspector)) atau dari kode pengujian Appium di IDE Anda. URL akan berlaku selama sesi akses jarak jauh.

1. Dan akhirnya, setelah pengujian Appium Anda dimulai, Anda dapat [meninjau log server Appium Anda](appium-endpoint-server-logs.md) secara langsung selama eksekusi pengujian di samping aliran video perangkat Anda.

# Berinteraksi dengan perangkat menggunakan Appium
<a name="appium-endpoint-interaction"></a>

Setelah Anda [membuat sesi akses jarak jauh](how-to-create-session.md), perangkat akan tersedia untuk pengujian Appium. Untuk seluruh durasi sesi akses jarak jauh, Anda dapat menjalankan sesi Appium sebanyak yang Anda inginkan di perangkat, tanpa batasan pada klien yang Anda gunakan. Misalnya, Anda dapat memulai dengan menjalankan pengujian menggunakan kode Appium lokal dari IDE, lalu beralih menggunakan Appium Inspector untuk memecahkan masalah apa pun yang Anda temui. Sesi dapat berlangsung hingga [150 menit](limits.md#service-limits), namun, jika tidak ada aktivitas selama lebih dari 5 menit (baik melalui konsol interaktif atau melalui titik akhir Appium), sesi akan habis waktu.

## Menggunakan Aplikasi untuk pengujian dengan sesi Appium Anda
<a name="appium-endpoint-using-apps"></a>

Device Farm memungkinkan Anda menggunakan aplikasi sebagai bagian dari permintaan pembuatan sesi akses jarak jauh, atau untuk menginstal aplikasi selama sesi akses jarak jauh itu sendiri. Aplikasi ini secara otomatis diinstal ke perangkat yang sedang diuji dan disuntikkan sebagai kemampuan default untuk permintaan sesi Appium apa pun. Saat Anda membuat sesi akses jarak jauh, Anda memiliki opsi untuk meneruskan ARN aplikasi, yang akan digunakan secara default sebagai `appium:app` kemampuan untuk semua sesi Appium berikutnya, serta aplikasi tambahan ARNs, yang akan digunakan sebagai kemampuan. `appium:otherApps`

Misalnya, jika Anda membuat sesi akses jarak jauh menggunakan aplikasi `com.aws.devicefarm.sample` sebagai aplikasi Anda, dan `com.aws.devicefarm.other.sample` sebagai salah satu aplikasi tambahan, maka ketika Anda pergi untuk membuat sesi Appium, itu akan memiliki kemampuan yang mirip dengan yang berikut:

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

Selama sesi, Anda dapat menginstal aplikasi tambahan (baik di dalam konsol, atau menggunakan [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_InstallToRemoteAccessSession.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_InstallToRemoteAccessSession.html)API). Ini akan menggantikan aplikasi yang ada yang sebelumnya digunakan sebagai `appium:app` kemampuan. Jika aplikasi yang sebelumnya digunakan memiliki nama paket yang berbeda, mereka akan tetap berada di perangkat dan digunakan sebagai bagian dari `appium:otherApps` kemampuan.

Misalnya, jika Anda awalnya menggunakan aplikasi `com.aws.devicefarm.sample` saat membuat sesi akses jarak jauh, tetapi kemudian menginstal aplikasi baru yang diberi nama `com.aws.devicefarm.other.sample` selama sesi, maka sesi Appium Anda akan memiliki kemampuan yang mirip dengan yang berikut ini:

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

Jika mau, Anda dapat secara eksplisit menentukan kemampuan untuk aplikasi menggunakan nama aplikasi (masing-masing menggunakan `appium:bundleId` kemampuan `appium:appPackage` atau untuk Android dan iOS).

Jika Anda menguji aplikasi web, tentukan `browserName` kemampuan untuk permintaan pembuatan sesi Appium Anda. `Chrome`Browser tersedia di semua perangkat Android, dan `Safari` browser tersedia di semua perangkat iOS.

Device Farm tidak mendukung penerusan URL jarak jauh atau jalur sistem file lokal `appium:app` selama sesi akses jarak jauh. Unggah aplikasi ke Device Farm dan sertakan dalam sesi sebagai gantinya.

**catatan**  
Untuk informasi selengkapnya tentang mengunggah aplikasi secara otomatis sebagai bagian dari sesi akses jarak jauh Anda, lihat [mengotomatiskan unggahan aplikasi](api-ref.md#upload-example).

## Cara menggunakan titik akhir Appium
<a name="appium-endpoint-how-to-use"></a>

Berikut adalah langkah-langkah untuk mengakses titik akhir Appium sesi dari konsol, konsol AWS CLI, dan. AWS SDKs Langkah-langkah ini mencakup cara memulai menjalankan pengujian menggunakan berbagai kerangka kerja pengujian klien Appium:

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

1. Buka halaman sesi akses jarak jauh Anda di browser web Anda:  
![\[\]](http://docs.aws.amazon.com/id_id/devicefarm/latest/developerguide/images/aws-device-farm-appium-endpoint.png)

1. Untuk menjalankan sesi menggunakan Appium Inspector, lakukan hal berikut:

   1. Klik tombolnya **Pengaturan sesi Appium**

   1. Ikuti petunjuk di halaman untuk cara memulai sesi menggunakan Appium Inspector.

1. Untuk menjalankan pengujian Appium dari IDE lokal Anda, lakukan hal berikut:

   1. Klik ikon “salin” di sebelah teks URL titik akhir **Appium**

   1. Tempel URL ini ke kode Appium lokal Anda di mana pun Anda saat ini menentukan alamat jarak jauh atau pelaksana perintah Anda. Untuk contoh khusus bahasa, silakan klik salah satu tab di jendela contoh ini untuk bahasa pilihan Anda.

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

Pertama, verifikasi bahwa versi AWS CLI Anda adalah up-to-date dengan [mengunduh dan menginstal versi terbaru](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

**penting**  
Bidang titik akhir Appium tidak tersedia di AWS CLI versi lama.

Setelah sesi Anda aktif dan berjalan, URL titik akhir Appium akan tersedia melalui `remoteDriverEndpoint` bidang bernama sebagai respons terhadap panggilan ke 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"
```

Ini akan menampilkan output seperti berikut:

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

Anda dapat menggunakan URL ini dalam kode Appium lokal Anda di mana pun Anda saat ini menentukan alamat jarak jauh atau pelaksana perintah Anda. Untuk contoh khusus bahasa, silakan klik salah satu tab di jendela contoh ini untuk bahasa pilihan Anda.

Untuk contoh cara berinteraksi dengan titik akhir langsung dari baris perintah, Anda dapat menggunakan [alat baris perintah curl](https://curl.se/) untuk memanggil titik akhir secara langsung: WebDriver 

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

Ini akan menampilkan output seperti berikut:

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

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

Setelah sesi Anda aktif dan berjalan, URL titik akhir Appium akan tersedia melalui `remoteDriverEndpoint` bidang bernama sebagai respons terhadap panggilan ke 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 ]

*Catatan: contoh ini menggunakan AWS SDK for Java v2, dan kompatibel dengan JDK versi 11 dan yang lebih tinggi.*

Setelah sesi Anda aktif dan berjalan, URL titik akhir Appium akan tersedia melalui `remoteDriverEndpoint` bidang bernama sebagai respons terhadap panggilan ke 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 ]

*Catatan: contoh ini menggunakan AWS SDK untuk JavaScript v3 dan WebDriverIO v8\$1 menggunakan Node 18\$1.*

Setelah sesi Anda aktif dan berjalan, URL titik akhir Appium akan tersedia melalui `remoteDriverEndpoint` bidang bernama sebagai respons terhadap panggilan ke 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 ]

Setelah sesi Anda aktif dan berjalan, URL titik akhir Appium akan tersedia melalui `remoteDriverEndpoint` bidang bernama sebagai respons terhadap panggilan ke 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 ]

Setelah sesi Anda aktif dan berjalan, URL titik akhir Appium akan tersedia melalui `remoteDriverEndpoint` bidang bernama sebagai respons terhadap panggilan ke 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
```

------

# Meninjau log server Appium Anda
<a name="appium-endpoint-server-logs"></a>

Setelah [memulai sesi Appium](appium-endpoint-interaction.md), Anda dapat melihat log server Appium secara langsung di konsol Device Farm, atau mengunduhnya setelah sesi akses jarak jauh berakhir. Berikut adalah instruksi untuk melakukannya:

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

1. Di konsol Device Farm, buka sesi akses jarak jauh untuk perangkat Anda.

1. Memulai sesi titik akhir Appium dengan perangkat dari IDE lokal atau Appium Inspector

1. Kemudian, log server Appium akan muncul di samping perangkat di halaman sesi akses jarak jauh, dengan “informasi sesi” tersedia di bagian bawah halaman di bawah perangkat:  
![\[\]](http://docs.aws.amazon.com/id_id/devicefarm/latest/developerguide/images/aws-device-farm-appium-endpoint-logs.gif)

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

*Catatan: contoh ini menggunakan [alat baris perintah `curl`](https://curl.se/) untuk menarik log dari Device Farm.*

Selama atau setelah sesi, Anda dapat menggunakan [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API Device Farm untuk mengunduh log server 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
```

Ini akan menampilkan output seperti berikut selama sesi:

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

Dan berikut ini setelah sesi selesai:

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

Ini akan menampilkan output seperti berikut:

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

*Catatan: contoh ini menggunakan `requests` paket pihak ketiga untuk mengunduh log, serta AWS SDK untuk Python`boto3`.*

Selama atau setelah sesi, Anda dapat menggunakan [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API Device Farm untuk mengambil URL log server Appium, lalu mengunduhnya.

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

Ini akan menampilkan output seperti berikut:

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

*Catatan: contoh ini menggunakan AWS SDK for Java v2 `HttpClient` dan untuk mengunduh log, dan kompatibel dengan JDK versi 11 dan yang lebih tinggi.*

Selama atau setelah sesi, Anda dapat menggunakan [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API Device Farm untuk mengambil URL log server Appium, lalu mengunduhnya.

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

Ini akan menampilkan output seperti berikut:

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

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

*Catatan: contoh ini menggunakan AWS SDK for JavaScript (v3) dan Node 18\$1 `fetch` untuk mengunduh log.*

Selama atau setelah sesi, Anda dapat menggunakan [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API Device Farm untuk mengambil URL log server Appium, lalu mengunduhnya.

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

Ini akan menampilkan output seperti berikut:

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

*Catatan: contoh ini menggunakan AWS SDK for .NET `HttpClient` dan untuk men-download log.*

Selama atau setelah sesi, Anda dapat menggunakan [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API Device Farm untuk mengambil URL log server Appium, lalu mengunduhnya.

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

Ini akan menampilkan output seperti berikut:

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

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

*Catatan: contoh ini menggunakan AWS SDK for `Net::HTTP` Ruby dan mengunduh log.*

Selama atau setelah sesi, Anda dapat menggunakan [https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html](https://docs.aws.amazon.com/devicefarm/latest/APIReference/API_ListArtifacts.html)API Device Farm untuk mengambil URL log server Appium, lalu mengunduhnya.

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

Ini akan menampilkan output seperti berikut:

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

------

# Kemampuan dan perintah Appium yang didukung
<a name="appium-endpoint-supported-caps-and-commands"></a>

Titik akhir Appium Device Farm mendukung sebagian besar perintah yang sama dan kemampuan yang diinginkan yang Anda gunakan di perangkat lokal, dengan beberapa pengecualian. Daftar berikut menunjukkan kemampuan dan perintah mana yang saat ini tidak didukung. Jika pengujian Anda tidak dapat berjalan seperti yang diharapkan karena kemampuan terbatas, silakan buka kasus dukungan untuk panduan tambahan.

## Kemampuan yang didukung
<a name="appium-endpoint-unsupported-capabilities"></a>

Saat membuat sesi Appium di Device Farm, sebaiknya Anda memiliki serangkaian kemampuan berbeda yang mengecualikan kemampuan apa pun yang spesifik untuk perangkat lokal Anda. Di Device Farm, pembuatan sesi mungkin gagal jika kemampuan tertentu yang tidak didukung disetel. Ini termasuk kemampuan khusus perangkat seperti dan. `udid` `platformVersion` Selain itu, kemampuan tertentu yang terkait dengan ChromeDriver WebDriverAgent Android dan iOS tidak didukung, serta kemampuan yang hanya didukung pada emulator dan simulator.

## Perintah yang Didukung
<a name="appium-endpoint-unsupported-commands"></a>

Sebagian besar perintah Appium yang berjalan dengan benar di perangkat Android dan iOS nyata akan berjalan seperti yang diharapkan di Device Farm, dengan pengecualian berikut: 

### Perintah perangkat 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 mengeksekusi metode dan skrip () `/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`