Autify を使ってみた所感と Puppeteer と Playwright

sekitats です。

さて、back check では E2Eテストツール Autify が導入されました。

f:id:sekilberg:20210613194119p:plain

1日触ってみたので所感を書きたいと思います。

よかった点

まず、海外発サービスかと思いきや、日本人が作った感のある馴染みやすいUIが良い。

シナリオ作成では、ブラウザでの操作をそのままレコーディングしてテストシナリオとして保存できるのが画期的だ。すぐに使い方を覚えることができた。 これであれば誰でもテストシナリオを書くことができるだろう。

そして、何よりクロスブラウザテストをサポートしているところが嬉しい。これだけで導入するだけの価値はある。

また、AI技術を使って変更の差分を検出するなど、きめ細かなサポートが素晴らしい。

ダミーのメールアドレスを生成してそれを使いまわせるのが便利だし、開発者にとっては JavaScript でコードを実行できるのも柔軟さがあっていい。

気になった点

使い心地で不便を感じたのは、シナリオ作成途中で修正が発生した場合、基本的にブラウザでレコーディングをする以外の方法がないことだ。

それから、例えば、コードであれば当然あるシナリオをコメントアウトやスキップするなりして一部のシナリオを実行させないことができる。一部シナリオを無効化するなどできると嬉しいと感じた。

細かくシナリオを区切ってパーツ化したとしても、最終的に一つのテストプランに書き出すマスタリングのような工程が必要なため、つぎはぎのままではテストを実行できない。

それから、ローカルでの設定、ステージングでの設定など、設定を簡単に切り替えられるのもコードなら簡単にできる。

テストが異常終了した場合もコンソール上であれば分かりやすい。

それなら Autify である必要がないのはもっともだ。

結局、細かいところの制御はコードには勝てない。

要は用途によって使い分けるべきということでしょうか。

しかし、E2Eテストをここまで進化させた Autify を応援したい気持ちでいっぱいです。Autify の更なる進化に期待せざるを得ません。

Master of Puppeteer

f:id:sekilberg:20210613203131p:plain

私は Puppeteer でテストシナリオを書き始めた。Puppeteer は E2E テストフレームワークではないが、Autify で不便に感じたところを解消できそうな気がしたのである。

Puppeteer と聞くと、Metallica“Master of Puppets” が思い浮かぶ。 Metallica の代表的な曲であり海外では有名な曲なので聞いたことない人は一度聞いてみて損はない。(ギターリフを全て異常な速さのダウンピッキングで弾いていることでも有名)

話が脱線しましたが Puppeteer の tips を共有。

iframe 内の要素にアクセス

const frame = await page.frame().find(f => f.name() === 'preview-html')
const button = await frame.$('.button')

タブの切り替え

const pages = await browser.pages() // 全タブを取得
const newTab = pages[pages.length - 1] // 開いたタブを取得

新規タブが開いたあと画面がローディング中のまま進まないことがあった。 一度他のタブに切り替え、新規タブに切り替え直すとローディングから先に進むようになった。

const pages = await browser.pages() // 全タブを取得
...
const prevTab = pages[pages.length - 2] // 一個前のタブ
await prevTab.bringToFront() // 一個前のタブを前面に
await prevTab.waitForTimeout(2000) // 2秒待機
await newTab.bringToFront() // 開いたタブをもう一度選択する

クリップボードにコピー

const documentHandle = await page.evaluateHandle('document');
await page.evaluate((document) => {
    // documentHandle を渡すと evaluate 内でdocumentにアクセスできる
    const oneTimePass = document.getElementById('password').innerText
    navigator.clipboard.writeText(password)
}, documentHandle)
await documentHandle.dispose() // 使い終わったら破棄

クリップボードの中身を取得

const password = await page.evaluate(async () => {
    return await navigator.clipboard.readText()
})

ちなみにクリップボードのアクセスを許可しておかなければならない。

const browser = await puppeteer.launch()
await browser
  .defaultBrowserContext()
  .overridePermissions(' host名 ', ['clipboard-read'])

おまけ playwright も触ってみた

f:id:sekilberg:20210614131150p:plain

playwright とは

Playwrightとは、Microsoftが提供しているWebDriverやpuppeterと同じ種類の自動テスト用のライブラリです。2020年2月1日に、オープンソースで公開されました。ChromiumFirefoxWebKitといったブラウザの動作をプログラムで再現し、自動的にテストをすることができます。

ざっくりいうと puppeteer の制作チームが Microsoft に行って Chromium だけでなく Firefox, WebKit にも対応した新しいライブラリを作ろうってことで puppeteer の改良版 playwright を作ることになったてな感じでしょうか。

今回、最初から playwright で書けば良いのではと聞こえてきそうだが、“Master of Puppeteer” ってどうしても言いたかったのでよいのである。

puppeteer と Playwright との詳細な違いは他の記事に任せるとして、puppeteer とのざっくり変更点。browser インスタンス生成のところだけ変えただけでだいたい動いた。

const { chromium, webkit } = require('playwright');

const browser = await chromium.launch({ ...config })
const context = await this.browser.newContext()
await context.grantPermissions(['clipboard-read'], ' host名 ')

playwright になってタブの操作方法が変わった(以前の書き方でもできそうだが、context ってのを使うっぽい)

const [newPage] = await Promise.all([
  context.waitForEvent('page'),
  page.click('a[target="_blank"]') // Opens a new tab
])
await newPage.waitForLoadState();
console.log(await newPage.title());

(新規タブが開いたあと画面がローディング中のまま進まないところは以前として解決できない。これは他の原因がありそう。)

playwright について言えば、なんとユーザー操作からコードを生成するなんてことができるようだ。機会があれば使ってみて記事を書いてみたい。

まとめ

Autify は素晴らしいツールだ。人力でやっている非効率な作業から解放され、プロダクトの価値向上のためによりリソースを使える。こういったサービスがさらに進化し続け、世の中の負の解消になれば良いと思う。

他のE2Eテストフレームワークもどんどんと進化を続けている。 Karma によるブラウザの自動操作を初めて見たときは衝撃を受けた。もちろん Selenium もあったし、ヘッドレスブラウザに関しては、PhantomJS, CasperJS, Nightwatch.jsNightmare もあった。IEやレガシーEdge がなくなった世界になれば、E2Eテストはさらに楽になる。願ってやまない。

それから今回同じく E2Eテストフレームワークcypress も触ってみた。しかし、cypress は別タブ遷移ができないので痒いところに手が届かなそう、ということで断念。

結局何が言いたかったかというと、Metallica も E2Eテストでも何でも進化を止めてはいけない。という雑なまとめで締めたいと思う。