Chromium Chronicle #21: ChromeOS のエンドツーエンドの UI 自動化

エピソード 21: Brendan Hansknecht、カリフォルニア州マウンテンビュー(2021 年 5 月)
以前のエピソード

これまで、一連のデバイス全体でのエンドツーエンド(E2E)テストで ChromeOS UI を自動化することは困難でした。Tast では、Chrome の a11y(ユーザー補助)ツリーを使用して ChromeOS UI を制御する新しい UI ライブラリが作成されました。このライブラリを使用すると、デベロッパーは表示されている UI サーフェス(ChromeOS デスクトップ UI、ネイティブ アプリ、ウェブアプリ、Chrome ブラウザの UI)に対する E2E テストを簡単に作成できます。

このライブラリには、UI 要素を見つける方法を記述するためのシンプルで連鎖可能な方法が用意されています。 たとえば、ファイルアプリの [ダウンロード] フォルダは次のように定義できます。

filesWindow := nodewith.NameStartingWith("Files")
  .ClassName("RootView").Role(role.Window)
downloadsButton := nodewith.Name("Downloads")
  .Role(role.TreeItem).Ancestor(filesWindow)

ノード ファインダーを定義したら、さまざまな方法でノードを操作できます。シンプルなクリックからフォーカスの待機まで、UI ライブラリにより多くのオペレーションに安定してアクセスできます。たとえば、[Downloads] フォルダを右クリックし、コピーボタンを左クリックすると、次のように記述します。

ui := uiauto.New(tconn)
if err := uiauto.Combine("copy downloads",
  ui.RightClick(downloadsButton),
  ui.LeftClick(nodewith.Name("Copy").Role(role.MenuItem)),
)(ctx); err != nil { /* do error handling */ }

共通 UI 領域のラッパー(設定、ランチャー、ファイルアプリなど)には既存のラッパーがあります。

上記で使用した uiauto.Run 関数は、アクションのリストを受け取ります。このコンテキストでは、アクションは単なる func(context.Context) error です。このようなシンプルな API を使用すると、他の種類のアクションを UI アクションに混在させることができます。たとえば、キーボードは以下のように簡単に操作できます。

if err := uiauto.Combine("do some random stuff",
  ui.FocusAndWait( /* some text field */ ),
  kb.TypeAction("Hello, world!"),
  kb.AccelAction("Enter"),
  func(ctx context.Context) error {
    // My custom action!
  },
)(ctx); err != nil { /* do error handling */ }

より詳細なガイドについては、Tast Codelab: Chrome UI Automation をご覧ください。

このようなテストを作成するときは、デバッグのために Chrome の a11y ツリーをダンプすると非常に便利です。次のコードを追加します。

defer faillog.DumpUITreeOnError(ctx, s.OutDir(), s.HasError, tconn)
s.Fatal("I would like to see the ui tree here")

a11y ツリーは、他の tast ログとともに faillog/ui_tree.txt として保存されるようになりました。

ご不明な点がございましたら、tast-users グループまでお問い合わせください。