Windows 10

WinAppDriver UI Recorderを試してみました。

下記記事にある通り、「WinAppDriver UI Recorder」が公開されたので、さっそく試してみました。

米Microsoftは20日(現地時間)、新しいオープンソースツール「WinAppDriver UI Recorder」を「Windows Application Driver」の一部としてリリースした。自動UIテストを作成するのに役立つ。

https://forest.watch.impress.co.jp/docs/news/1128952.html より

Microsoftは2018年6月20日(米国時間)、「Windows Application Driver」(WinAppDriver)コミュニティー向けの新しいオープンソースツール「WinAppDriver UI Recorder」(以下、UI Recorder)の公開を発表した。UI Recorderは、自動化されたUI(ユーザーインタフェース)テストのスクリプトを簡単に作成できるツールだ。

http://www.atmarkit.co.jp/ait/articles/1806/22/news036.html

WinAppDriver UI Recorderの使い方

GitHubReleasesページにZip形式で圧縮されたバイナリファイルがありますが、今回はVisual Studio Community 2017でビルドしたものを使用しました。

WinAppDriver UI Recorderを使うとUI要素のXPathクエリを生成でき、上図の通り「Record」ボタンをクリックすると、操作を記録することができます。

生成されたコード

電卓を操作した際に生成されたコードが下記になります。

// LeftClick on "One" at (75,20)
Console.WriteLine("LeftClick on \"One\" at (75,20)");
string xp1 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num1Button\"][@Name=\"One\"]";
var winElem1 = MyDesktopSession.FindElementByXPath(xp1);
if (winElem1 != null)
{
    winElem1.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp1}");
    return;
}


// LeftClick on "Two" at (44,20)
Console.WriteLine("LeftClick on \"Two\" at (44,20)");
string xp2 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num2Button\"][@Name=\"Two\"]";
var winElem2 = MyDesktopSession.FindElementByXPath(xp2);
if (winElem2 != null)
{
    winElem2.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp2}");
    return;
}


// LeftClick on "Three" at (36,20)
Console.WriteLine("LeftClick on \"Three\" at (36,20)");
string xp3 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num3Button\"][@Name=\"Three\"]";
var winElem3 = MyDesktopSession.FindElementByXPath(xp3);
if (winElem3 != null)
{
    winElem3.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp3}");
    return;
}


// LeftClick on "Plus" at (19,18)
Console.WriteLine("LeftClick on \"Plus\" at (19,18)");
string xp4 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"StandardOperators\"][@Name=\"Standard operators\"]/Button[@AutomationId=\"plusButton\"][@Name=\"Plus\"]";
var winElem4 = MyDesktopSession.FindElementByXPath(xp4);
if (winElem4 != null)
{
    winElem4.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp4}");
    return;
}


// LeftClick on "Four" at (57,18)
Console.WriteLine("LeftClick on \"Four\" at (57,18)");
string xp5 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num4Button\"][@Name=\"Four\"]";
var winElem5 = MyDesktopSession.FindElementByXPath(xp5);
if (winElem5 != null)
{
    winElem5.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp5}");
    return;
}


// LeftClick on "Five" at (80,19)
Console.WriteLine("LeftClick on \"Five\" at (80,19)");
string xp6 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num5Button\"][@Name=\"Five\"]";
var winElem6 = MyDesktopSession.FindElementByXPath(xp6);
if (winElem6 != null)
{
    winElem6.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp6}");
    return;
}


// LeftClick on "Six" at (34,18)
Console.WriteLine("LeftClick on \"Six\" at (34,18)");
string xp7 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num6Button\"][@Name=\"Six\"]";
var winElem7 = MyDesktopSession.FindElementByXPath(xp7);
if (winElem7 != null)
{
    winElem7.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp7}");
    return;
}


// LeftClick on "Equals" at (59,29)
Console.WriteLine("LeftClick on \"Equals\" at (59,29)");
string xp8 = "/Pane[@Name=\"デスクトップ 1\"][@ClassName=\"#32769\"]/Window[@Name=\"Calculator ‎- Calculator\"][@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"StandardOperators\"][@Name=\"Standard operators\"]/Button[@AutomationId=\"equalButton\"][@Name=\"Equals\"]";
var winElem8 = MyDesktopSession.FindElementByXPath(xp8);
if (winElem8 != null)
{
    winElem8.Click();
}
else
{
    Console.WriteLine($"Failed to find element {xp8}");
    return;
}

これをこのままコピー&ペーストしても動作しないので、一部コードを書き足して実行したところ、要素の取得で躓きました。

仕方が無いので、XPathの一部を編集したのが下記のコードです。
(「Windows Application Driverを試してみました。」記事に書いている通り、コードを実行する際はNuGetで「Appium.WebDriver」を追加してください。)

using System;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Remote;

namespace WinAppDriverTest
{
    class Program
    {
        private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
        private const string CalculatorAppId = "Microsoft.WindowsCalculator_8wekyb3d8bbwe!App";
        protected static WindowsDriver<WindowsElement> session;

        static void Main(string[] args)
        {
            string serverPath = System.IO.Path.Combine(
                System.Environment.GetFolderPath(
                    System.Environment.SpecialFolder.ProgramFilesX86
                ), @"Windows Application Driver", "WinAppDriver.exe"
            );
            System.Diagnostics.Process.Start(serverPath);

            DesiredCapabilities appCapabilities = new DesiredCapabilities();
            appCapabilities.SetCapability("app", CalculatorAppId);
            session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
            session.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(1.5));

            // LeftClick on "One" at (75,20)
            Console.WriteLine("LeftClick on \"One\" at (75,20)");
            string xp1 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num1Button\"][@Name=\"One\"]";
            var winElem1 = session.FindElementByXPath(xp1);
            if (winElem1 != null)
            {
                winElem1.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp1}");
                return;
            }

            // LeftClick on "Two" at (44,20)
            Console.WriteLine("LeftClick on \"Two\" at (44,20)");
            string xp2 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num2Button\"][@Name=\"Two\"]";
            var winElem2 = session.FindElementByXPath(xp2);
            if (winElem2 != null)
            {
                winElem2.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp2}");
                return;
            }

            // LeftClick on "Three" at (36,20)
            Console.WriteLine("LeftClick on \"Three\" at (36,20)");
            string xp3 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num3Button\"][@Name=\"Three\"]";
            var winElem3 = session.FindElementByXPath(xp3);
            if (winElem3 != null)
            {
                winElem3.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp3}");
                return;
            }

            // LeftClick on "Plus" at (19,18)
            Console.WriteLine("LeftClick on \"Plus\" at (19,18)");
            string xp4 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"StandardOperators\"][@Name=\"Standard operators\"]/Button[@AutomationId=\"plusButton\"][@Name=\"Plus\"]";
            var winElem4 = session.FindElementByXPath(xp4);
            if (winElem4 != null)
            {
                winElem4.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp4}");
                return;
            }

            // LeftClick on "Four" at (57,18)
            Console.WriteLine("LeftClick on \"Four\" at (57,18)");
            string xp5 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num4Button\"][@Name=\"Four\"]";
            var winElem5 = session.FindElementByXPath(xp5);
            if (winElem5 != null)
            {
                winElem5.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp5}");
                return;
            }

            // LeftClick on "Five" at (80,19)
            Console.WriteLine("LeftClick on \"Five\" at (80,19)");
            string xp6 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num5Button\"][@Name=\"Five\"]";
            var winElem6 = session.FindElementByXPath(xp6);
            if (winElem6 != null)
            {
                winElem6.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp6}");
                return;
            }

            // LeftClick on "Six" at (34,18)
            Console.WriteLine("LeftClick on \"Six\" at (34,18)");
            string xp7 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"NumberPad\"][@Name=\"Number pad\"]/Button[@AutomationId=\"num6Button\"][@Name=\"Six\"]";
            var winElem7 = session.FindElementByXPath(xp7);
            if (winElem7 != null)
            {
                winElem7.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp7}");
                return;
            }

            // LeftClick on "Equals" at (59,29)
            Console.WriteLine("LeftClick on \"Equals\" at (59,29)");
            string xp8 = "//*[@ClassName=\"ApplicationFrameWindow\"]/Window[@Name=\"Calculator\"][@ClassName=\"Windows.UI.Core.CoreWindow\"]/Group[@ClassName=\"LandmarkTarget\"]/Group[@AutomationId=\"StandardOperators\"][@Name=\"Standard operators\"]/Button[@AutomationId=\"equalButton\"][@Name=\"Equals\"]";
            var winElem8 = session.FindElementByXPath(xp8);
            if (winElem8 != null)
            {
                winElem8.Click();
            }
            else
            {
                Console.WriteLine($"Failed to find element {xp8}");
                return;
            }

            /*
            if (session != null)
            {
                session.Quit();
                session = null;
            }
            */

            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}

実行画面

下図の通り、WinAppDriverを使って問題なく電卓の操作ができました。

感想

軽く触ってみた感じ、要素のXPathを取得できる点は便利でしたが、生成されるコードは冗長で、Excelのマクロ記録機能のような印象を受けました。

UI要素を調べるツールとして、現時点(2018年6月)ではInspectの代わりになるものではなく、Inspectと併用することで、WinAppDriverを使ったコードが書きやすくなるツールなのだと思います。

まだ、出始めのツールなので、今後に期待ですね!

【アイカツフレンズ!】フレンズスカウト(蝶乃舞花)に参加しました。前のページ

[Windows 10]大型アップデートをサイレントインストールする方法次のページ

関連記事

  1. Windows 10

    Windows 10に昔のソフトを入れてみました。

    「Windows 10 Technical PreviewにOffic…

  2. Windows 10

    Windows Application Driverを試してみました。

    Build 2016のセッション「UI Test Automation…

  3. Windows 11

    Windows 11をクリーンインストールしてみました。

    下記記事にもあるように、10月5日(日本時間)にWindows 11が…

  4. Windows 10

    [Windows 10]切り取り&スケッチを起動するショートカット

    Windows 10の「切り取り&スケッチ」機能、皆さん使ってますでし…

  5. Windows 10

    Chromium版のMicrosoft Edgeをインストールしてみました。

    下記記事の通り、今月の15日(米国時間)付でChromiumベースのM…

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

Time limit is exhausted. Please reload CAPTCHA.

※本ページはプロモーションが含まれています。

Translate

最近の記事

アーカイブ

PAGE TOP