LoginSignup
16
8

More than 1 year has passed since last update.

Playwrightで遠隔からAndroidデバイスをぐりぐり動かす。

Last updated at Posted at 2022-12-14

この記事は、ソフトウェアテスト Advent Calendar 2022の11日目の記事となります。
前日11日の記事は、@gremito さんによる「Appium on Azure Pipelines」でした。本日の記事もアプリの自動操作関連です。

概要

ChromeやWebKitを自動操作できるPlaywrightはもう皆さんご存知ですよね?

PlaywrightにはAndroidを自動操作する機能が実は備わっていて、AndroidネイティブアプリケーションもChromeブラウザも自動操作することができます。

ただ、これまではPCに直接ADB接続されているAndroidデバイスしか自動操作することができませんでした。
ところが、割と最近リリースされたv1.28では launchServer (ADB接続したAndroidデバイスをWebSocket経由で自動操作する機能)が追加されました。これにより、デバイスファームのような使い方もできるようになりました。

image.png

「これはAppium以外の選択肢がもう一つできたのでは?」と思い、実際に触ってみました。

インストール&準備

$ npm install playwright-core

するだけです。(ブラウザをダウンロードする必要がないのでplaywrightではなくplaywright-coreを選択しています。)

https://playwright.dev/docs/api/class-android の冒頭に書かれているように

image.png

まずはAndroidはエミュレータでも実機でもいいのでADB接続できる状態にしておきます。

% adb devices
List of devices attached
emulator-5554	device

そして、AndroidのChrome上で chrome:flags を打ち、コマンドラインアクセスを有効化します。

image.png

まずは単体で自動操作してみる

standalone.js
const playwright = require('playwright-core')

playwright._android.devices().then(async ([device]) => {
    const browserContext = await device.launchBrowser()
    const page = await browserContext.newPage()

    await page.goto('https://playwright.dev/')
    console.log('Taking browser screenshot')
    await page.screenshot({ path: 'playwright.dev.png' })
    console.log('Taking device screenshot')
    await device.screenshot({ path: 'device.png' })
    await browserContext.close()

    await device.close()
})
% node standalone.js      
Taking browser screenshot
Taking device screenshot
playwright.dev.png device.png
playwright.dev.png device.png

page.screenshotはブラウザのキャプチャなのに対し、device.screenshotはADBのスクリーンショット機能を使っているようですね。

サーバーを起動する

いよいよネットワーク越しに自動操作するためのサーバーを立てます。
とはいえ、全然大したコードではありません。

server.js
const playwright = require('playwright-core')

playwright._android.launchServer({ port: 12345, wsPath: 'my-emulator' }).then(server => {
    console.log(`Android server is now available! -> ${server.wsEndpoint()}`)
})
% node server.js 
Android server is now available! -> ws://127.0.0.1:12345/my-emulator

ちなみに、portもwsPathも省略できますが、省略すると以下のようにランダムなポート、ランダムなパス文字列になります。

% node server.js
Android server is now available! -> ws://127.0.0.1:60633/159d66315e21098a73ce0f0142c12fc7

ランダムでは、クライアント側のコードをいちいち変えないといけないので、デバイスファームのような使い方をするにはちょっと面倒です。なので(Playwright公式のグリッド機能を使わないなら)portとwsPathオプションは付けておくと良さそうです。

クライアントから接続する

まずは、さっきの単体実行のコードをベースに、WebSocket接続で同じことをやってみます。

client.js
const playwright = require('playwright-core')

playwright._android.connect('ws://localhost:12345/my-emulator').then(async (device) => {
    const browserContext = await device.launchBrowser()
    const page = await browserContext.newPage()
    await page.goto('https://playwright.dev/')
    console.log('Taking browser screenshot')
    await page.screenshot({ path: 'playwright.dev.png' })
    console.log('Taking device screenshot')
    await device.screenshot({ path: 'device.png' })
    await browserContext.close()

    await device.close()
})
% node client.js
Taking browser screenshot
Taking device screenshot
playwright.dev.png device.png
playwright.dev.png device.png

まぁ当然同じ結果です。何の面白みもありません。

Dockerコンテナでサーバーに接続してみる

どうせならADBの入っていない環境で違うクライアントから接続してみましょう。

Playwright公式のDockerイメージを取ってきます。

% docker pull mcr.microsoft.com/playwright:v1.28.0-focal
% docker run -it --rm -v $(pwd):/app -w /app mcr.microsoft.com/playwright:v1.28.0-focal bash
root@8313fa40b980:/app# npm install playwright-core

接続先だけ、Dockerから見たサーバーの場所に変えます。

client.js
const playwright = require('playwright-core')

playwright._android.connect('ws://host.docker.internal:12345/my-emulator').then(async (device) => {

あとは、実行してみると...

root@8313fa40b980:/app# adb
bash: adb: command not found
root@8313fa40b980:/app# node client.js 
Taking browser screenshot
Taking device screenshot

ADBのない環境でも無事、自動操作でスクリーンショットがとれました。

playwright.dev.png device.png
playwright.dev.png device.png

まとめ

Playwrightを使うと、SeleniumやAppiumを使うのにに比べて、とてもかんたんにAndroidのアプリ/ブラウザを操作することができます。

また、Playwright 1.28以降ではWebSocket接続でサーバー/クライアント接続ができるようになり、クライアント側にはADB不要で、サーバーをデバイスファームのようにして使うことができるようになりました。

まだ知らなかった方は一度ためしてみてはいかがでしょうか。

16
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
8