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関連

    Windows 8 Release PreviewにClassic Shellをインストールしてみま…

    2012/8/22 追記:Windows 8 RTMにインストール…

  2. Office関連

    【2017年1月版】Microsoft Edgeを操作するVBAマクロ(DOM編)(2)

    昨日の記事で、Microsoft Edgeを操作するVBAコードを改め…

  3. Windows 10

    起動中のMicrosoft EdgeからタイトルとURLを取得するC#コード(UI Automati…

    2017/8/18 追記:当記事のコードは現在動作しなくなっている…

  4. Windows 10

    Windows Insider Meetup in Japan 2019 東京に参加しました。

    Windows Insider向けのミートアップイベント「Window…

  5. Windows 10

    Windows 10をクリーンインストールする。

    各種メディアでも話題になっていますが、先日ついにWindows 10が…

  6. Windows 10

    [Windows 10]アップグレードせずにクリーンインストールしたらどうなるの?

    「Windows 10をクリーンインストールする。」で、MediaCr…

コメント

  • コメント (0)

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

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

Time limit is exhausted. Please reload CAPTCHA.

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

Translate

最近の記事

アーカイブ

PAGE TOP