WinAppDriverを使ってUITestする

こんばんは。

Azure DevOpsでUITestをやっているのですが、詰まってしまってどうしようもないので、ひとまずアウトプットしようと思って記事を書いています。

2021/12/2追記。バグは解消しました。詳細を追記します。

# 概要

Visual Studio EnterpriseでなくてもUITestができると聞いたので、[boiler's Graphics](https://github.com/dhq-boiler/boiler-s-Graphics)にUITestを導入してみました。C#テストプロジェクトでUITestを実現するにはWinAppDriverというソフトウェアをインストールする必要があるとのことなのです。

# WinAppDriver のインストール

![2021-11-24 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/0a2f7003-9769-eccc-cb4b-3c67964637bb.png)

今回はWinAppDriverのReleaseページのv1.3 Release Candidate 1 (1.2.99)を選択しました。
インストーラーはWindowsApplicationDriver-1.2.99-win-x64.exeです。

# WinAppDriverの実行

WinAppDriverをインストールしたら、C:\Program Files\Windows Application Driver\WinAppDriver.exeをダブルクリックして起動します。

![2021-11-24 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/def736e6-f507-298c-cb51-b20f5d79d8cc.png)

↑この状態になったら放置します。

# テストプロジェクトに(NuGetで)ライブラリをインストールする

![2021-11-24 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/3a567496-e929-cbb6-b6ad-edf2b27e3cc3.png)

またC#テストプロジェクトにNuGetパッケージマネージャーで、"Microsoft.WinAppDriver.Appium.WebDriver"のバージョン1.0.1-Previewをインストールします。プレビュー版なので、☑プレリリースを含めるにチェックを入れて下さい。

# UITestを書く

そして、C#テストプロジェクトにUITestを書きますが、手始めにAppSession.csというUITest共通の基本クラスを作成します。ここでsessionなどを準備します。

```csharp:UITest/AppSession.cs
using NUnit.Framework;
using OpenQA.Selenium.Appium.Windows;
using OpenQA.Selenium.Remote;
using System;
using System.IO;
using System.Reflection;

namespace boilersGraphics.Test.UITests
{
    public class AppSession
    {
        // Note: append /wd/hub to the URL if you're directing the test at Appium
        private const string WindowsApplicationDriverUrl = "http://127.0.0.1:4723";
        private static readonly string AppPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "boilersGraphics.exe");//"Microsoft.WindowsCalculator_8wekyb3d8bbwe!App";

        protected static WindowsDriver<WindowsElement> session;

        [SetUp]
        public static void Setup()
        {
            // Launch Calculator application if it is not yet launched
            if (session == null)
            {
                // Create a new session to bring up an instance of the Calculator application
                // Note: Multiple calculator windows (instances) share the same process Id
                DesiredCapabilities appCapabilities = new DesiredCapabilities();
                appCapabilities.SetCapability("app", AppPath);
                appCapabilities.SetCapability("deviceName", "WindowsPC");
                session = new WindowsDriver<WindowsElement>(new Uri(WindowsApplicationDriverUrl), appCapabilities);
                Assert.That(session, Is.Not.Null);

                // Set implicit timeout to 1.5 seconds to make element search to retry every 500 ms for at most three times

                session.Manage().Timeouts().ImplicitWait = TimeSpan.FromMinutes(1);

                session.Manage().Window.Maximize();
            }
        }

        [TearDown]
        public static void TearDown()
        {
            // Close the application and delete the session
            if (session != null)
            {
                session.Quit();
                session = null;
            }
        }
    }
}

```

※テスト安定化を図るために、WindowsDriverSessionでMaximize()して、テスト対象アプリのウィンドウを最大化しています。これをすることで、テスト対象アプリのウィンドウが最も手前に来てテストが安定します。

あとは、思う存分にUITestのコードを書くだけです。今回は(1)チェッカーパターンの出来損ないが収録されているxmlファイルを読み込んで、jpgファイルにエクスポートするのと、(2)単なる白背景のキャンパスをそのままjpgファイルにエクスポートする２つを実装してみます...。

下記ではライブラリとして、ログ出力のためにNLog等を使用しています。（なくてもおｋ！）

```csharp:UITests/ExportTest.cs
using NLog;
using NUnit.Framework;
using OpenQA.Selenium;
using System.IO;
using System.Reflection;
using System.Threading;

namespace boilersGraphics.Test.UITests
{
    [TestFixture]
    public class ExportTest : AppSession
    {
        [Test]
        public void 真っ白なキャンパスをエクスポートする()
        {
            var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var exportFilePath = $"{dir}\\ExportTest.jpg";

            try
            {
                session.FindElementByAccessibilityId("Export").Click();
                session.FindElementByAccessibilityId("ExportFileName").SendKeys(exportFilePath);
                session.FindElementByAccessibilityId("PerformExport").Click();
                Thread.Sleep(1000);
                LogManager.GetCurrentClassLogger().Info(exportFilePath);
                Assert.That(File.Exists(exportFilePath), Is.EqualTo(true));
            }
            finally
            {
                File.Delete(exportFilePath);
            }
        }

        [Test]
        public void チェッカーパターンを読み込んでエクスポートする()
        {
            LogManager.GetCurrentClassLogger().Info("A");
            var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var loadFilePath = $"{dir}\\XmlFiles\\checker_pattern.xml";
            var exportFilePath = $"{dir}\\ExportTest2.jpg";

            try
            {
                LogManager.GetCurrentClassLogger().Info("B");
                session.FindElementByAccessibilityId("Load").Click();
                LogManager.GetCurrentClassLogger().Info("C");
                session.FindElementByAccessibilityId("1").Click();
                LogManager.GetCurrentClassLogger().Info("D");
                session.Keyboard.SendKeys(Keys.Alt + "N" + Keys.Alt);
                LogManager.GetCurrentClassLogger().Info("E");
                session.Keyboard.SendKeys(Keys.Alt + "N" + Keys.Alt);
                LogManager.GetCurrentClassLogger().Info("F");
                session.FindElementByAccessibilityId("1148").SendKeys(loadFilePath);
                LogManager.GetCurrentClassLogger().Info("G");
                session.FindElementByAccessibilityId("1").Click();

                LogManager.GetCurrentClassLogger().Info("H");
                Thread.Sleep(1000);


                session.FindElementByAccessibilityId("Export").Click();
                LogManager.GetCurrentClassLogger().Info("I");
                Thread.Sleep(1000);
                session.FindElementByAccessibilityId("ExportFileName").SendKeys(exportFilePath);
                LogManager.GetCurrentClassLogger().Info("J");
                session.FindElementByAccessibilityId("PerformExport").Click();
                LogManager.GetCurrentClassLogger().Info("K");
                Thread.Sleep(1000);
                LogManager.GetCurrentClassLogger().Info("L");
                Assert.That(File.Exists(exportFilePath), Is.EqualTo(true));
                LogManager.GetCurrentClassLogger().Info("M");
            }
            finally
            {
                LogManager.GetCurrentClassLogger().Info("N");
                File.Delete(exportFilePath);
                LogManager.GetCurrentClassLogger().Info("O");
            }
        }
    }
}

```

# ローカル環境でテスト実行

あと注意点なのですが、Windowsの設定で英語キーボードじゃないと"\"が文字化けして"]"になってしまう問題があります。これは、テストを実行する前にWindowsキー+Spaceキーでキーボードレイアウトを英語（米国）にする必要があります。この辺将来のアップデートで日本語キーボードも使えるようにして欲しぃ...。

テストを書いたら、ローカルでテストしてみます。ローカルではテストはすんなり通ると思います。

![UITest_demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/4c0d9e34-9605-8897-7281-e3460936e694.gif)

↑ちょっと画面端が切れてますがご了承下さい。ScreenToGifだとフルスクリーンで録画できないんです...。
でも、こうして自動でUITestが動いていることがわかると思います。

# Azure DevOps(CIサーバー）でテスト実行

さて、出来上がったUITestはローカル環境で検証しましたが、これをクラウドのCI環境で自動で検証させたいという要望が上がってきました。試しにAzure DevOpsでUITestを実行させてみましょう。

## アドオンインストール

Azure DevOpsでWinAppDriverを実行するにはアドオンをインストールする必要があります。

https://marketplace.visualstudio.com/items?itemName=WinAppDriver.winappdriver-pipelines-task

## azure-pipelines.ymlに追記

次に、azure-pipelines.ymlにWinAppDriverの起動タスクと終了タスクを追記する必要があります。

```yml:azure-pipelines_develop.yml
# .NET Desktop
# Build and run tests for .NET Desktop or Windows classic desktop solutions.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net

trigger:
- develop

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
  disable.coverage.autogenerate: 'true'

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
    
- task: Windows Application Driver@0
  inputs:
    OperationType: 'Start'
    AgentResolution: '1080p'

- task: CmdLine@2
  displayName: "NUnit & OpenCover"
  inputs:
    script: >
      packages\OpenCover.4.7.1221\tools\OpenCover.Console.exe
      -register:Path64
      -target:"packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe"
      -targetargs:"boilersGraphics.Test.dll"
      -targetdir:"boilersGraphics.Test\bin\$(buildConfiguration)"
      -returntargetcode
      -output:"coverage.xml"
      -filter:"+[boilersGraphics]* +[TsOperationHistory]* -[*]XamlGeneratedNamespace*"

- task: Windows Application Driver@0
  condition: always()
  inputs:
    OperationType: 'Stop'

- task: PublishTestResults@2
  displayName: "Publish unit test result"
  condition: always()
  inputs:
    testResultsFormat: 'NUnit'
    testResultsFiles: '**/TestResult.xml'
    failTaskOnFailedTests: false

- task: reportgenerator@4
  condition: always()
  inputs:
    reports: '**\coverage.xml'
    targetdir: 'coveragereport'

- task: PublishCodeCoverageResults@1
  condition: always()
  inputs:
    codeCoverageTool: 'Cobertura'
    summaryFileLocation: 'coveragereport\Cobertura.xml'
    reportDirectory: 'coveragereport\'

# Archive files
# Compress files into .7z, .tar.gz, or .zip
- task: ArchiveFiles@2
  condition: always()
  inputs:
    rootFolderOrFile: '$(System.DefaultWorkingDirectory)\boilersGraphics\bin\Release' 
    includeRootFolder: false
    archiveType: 'zip' # Options: zip, 7z, tar, wim
    tarCompression: 'gz' # Optional. Options: gz, bz2, xz, none
    archiveFile: '$(Build.ArtifactStagingDirectory)/boilersGraphics_$(Build.BuildId).zip' 
    replaceExistingArchive: true 
    #verbose: # Optional
    #quiet: # Optional

# GitHub Release
# Create, edit, or delete a GitHub release
- task: GitHubRelease@0
  condition: always()
  inputs:
    gitHubConnection: dhq-boiler-azure-devops
    repositoryName: '$(Build.Repository.Name)' 
    action: 'create' # Options: create, edit, delete
    target: '$(Build.SourceVersion)' # Required when action == Create || Action == Edit
    tagSource: manual # Required when action == Create# Options: auto, manual
    #tagPattern: # Optional
    tag: unstable-$(Build.BuildNumber) # Required when action == Edit || Action == Delete || TagSource == Manual
    #title: # Optional
    #releaseNotesSource: 'file' # Optional. Options: file, input
    #releaseNotesFile: # Optional
    #releaseNotes: # Optional
    assets: '$(Build.ArtifactStagingDirectory)\boilersGraphics_$(Build.BuildId).zip'
    assetUploadMode: 'delete' # Optional. Options: delete, replace
    isDraft: false # Optional
    isPreRelease: true # Optional
    addChangeLog: true # Optional
    compareWith: 'lastFullRelease' # Required when addChangeLog == True. Options: lastFullRelease, lastRelease, lastReleaseByTag
    #releaseTag: # Required when compareWith == LastReleaseByTag

- task: CmdLine@2
  displayName: "pip install python-oauth2"
  inputs:
    script: >
      pip install twitter

# Python script
# Run a Python file or inline script
- task: PythonScript@0
  inputs:
    scriptSource: 'inline' # Options: filePath, inline
    #scriptPath: azure_devops/python_script/tweet.py # Required when scriptSource == filePath
    script: >
        from twitter import Twitter, OAuth

        access_token = '$(AccessToken)'

        access_token_secret = '$(AccessTokenSecret)'

        api_key = '$(APIKey)'

        api_secret = '$(APIKeySecret)'
        
        t = Twitter(auth = OAuth(access_token, access_token_secret, api_key, api_secret))

        text = 'https://github.com/dhq-boiler/boiler-s-Graphics/releases/tag/unstable-$(Build.BuildNumber)'

        statusUpdate = t.statuses.update(status=text)
    #arguments: # Optional
    #pythonInterpreter: # Optional
    #workingDirectory: # Optional
    #failOnStderr: false # Optional
```

ここで重要なのはTestを実行しているタスクの前後にWinAppDriverの開始タスクと終了タスクを挿入する必要があるということです。

WinAppDriverの開始タスクではAgentResolutionとして'1080p'を指定します。（これ重要らしい）

```yml
- task: Windows Application Driver@0
  inputs:
    OperationType: 'Start'
    AgentResolution: '1080p'

- task: CmdLine@2
  displayName: "NUnit & OpenCover"
  inputs:
    script: >
      packages\OpenCover.4.7.1221\tools\OpenCover.Console.exe
      -register:Path64
      -target:"packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe"
      -targetargs:"boilersGraphics.Test.dll"
      -targetdir:"boilersGraphics.Test\bin\$(buildConfiguration)"
      -returntargetcode
      -output:"coverage.xml"
      -filter:"+[boilersGraphics]* +[TsOperationHistory]* -[*]XamlGeneratedNamespace*"

- task: Windows Application Driver@0
  condition: always()
  inputs:
    OperationType: 'Stop'
```

## パイプライン実行

さて、これで舞台は整いました。
パイプラインを実行させてみましょう。

↓パイプラインを実行させた結果がこちら。

https://dev.azure.com/dhq-boiler/boiler_s%20Graphics/_build/results?buildId=207&view=logs&j=12f1170f-54f2-53f3-20dd-22fc7dff55f9&t=f8ed7bd8-2a7f-56f6-9385-7fc29a8b5b7b

```
2021-11-24T11:48:55.9989796Z ##[section]Starting: NUnit & OpenCover
2021-11-24T11:48:56.0729655Z ==============================================================================
2021-11-24T11:48:56.0730435Z Task         : Command line
2021-11-24T11:48:56.0730929Z Description  : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
2021-11-24T11:48:56.0731430Z Version      : 2.182.0
2021-11-24T11:48:56.0731805Z Author       : Microsoft Corporation
2021-11-24T11:48:56.0732276Z Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
2021-11-24T11:48:56.0732806Z ==============================================================================
2021-11-24T11:48:57.1787288Z Generating script.
2021-11-24T11:48:57.1888785Z Script contents:
2021-11-24T11:48:57.1893206Z packages\OpenCover.4.7.1221\tools\OpenCover.Console.exe -register:Path64 -target:"packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe" -targetargs:"boilersGraphics.Test.dll" -targetdir:"boilersGraphics.Test\bin\Release" -returntargetcode -output:"coverage.xml" -filter:"+[boilersGraphics]* +[TsOperationHistory]* -[*]XamlGeneratedNamespace*"
2021-11-24T11:48:57.2258869Z ========================== Starting Command Output ===========================
2021-11-24T11:48:57.2537767Z ##[command]"C:\Windows\system32\cmd.exe" /D /E:ON /V:OFF /S /C "CALL "D:\a\_temp\7e2a093a-25f1-4ff7-abf1-566cc75afe9c.cmd""
2021-11-24T11:48:57.5155667Z ﻿Launching OpenCover 4.7.1221.0
2021-11-24T11:48:58.9759009Z Executing: D:\a\1\s\packages\NUnit.ConsoleRunner.3.12.0\tools\nunit3-console.exe
2021-11-24T11:49:03.2922180Z NUnit Console Runner 3.12.0 (.NET 2.0)
2021-11-24T11:49:03.2923727Z Copyright (c) 2021 Charlie Poole, Rob Prouse
2021-11-24T11:49:03.3188109Z Wednesday, November 24, 2021 11:49:03 AM
2021-11-24T11:49:03.3195344Z 
2021-11-24T11:49:09.3746263Z Runtime Environment
2021-11-24T11:49:09.3762571Z    OS Version: Microsoft Windows NT 6.2.9200.0
2021-11-24T11:49:09.3763546Z    Runtime: .NET Framework CLR v4.0.30319.42000
2021-11-24T11:49:09.3764423Z 
2021-11-24T11:49:09.3766967Z Test Files
2021-11-24T11:49:09.3767678Z     boilersGraphics.Test.dll
2021-11-24T11:49:09.3768279Z 
2021-11-24T11:49:28.7292577Z 2021-11-24 11:49:27.3166|INFO|Homura.ORM.Migration.ChangePlanByVersion`1|Begin to upgrade to VersionOrigin.
2021-11-24T11:49:28.7294808Z 2021-11-24 11:49:27.6259|INFO|Homura.ORM.Migration.ChangePlanByVersion`1|Finish to upgrade to VersionOrigin.
2021-11-24T11:49:28.7308447Z 2021-11-24 11:49:27.6259|INFO|boilersGraphics.ViewModels.MainWindowViewModel|Heavy Modifying AppDB Count : 2
2021-11-24T11:49:28.7311356Z 2021-11-24 11:49:27.6259|INFO|boilersGraphics.Dao.SQLiteBaseDao`1|SQLite VACUUM Operation will start as soon.
2021-11-24T11:49:28.7324172Z 2021-11-24 11:49:27.6412|INFO|boilersGraphics.Dao.SQLiteBaseDao`1|SQLite VACUUM Operation finnished.
2021-11-24T11:49:29.0061038Z 2021-11-24 11:49:28.8550|INFO|boilersGraphics.ViewModels.MainWindowViewModel|Heavy Modifying AppDB Count : 0

（中略）

2021-11-24T11:50:59.6247511Z 2021-11-24 11:49:45.4339|INFO|boilersGraphics.Test.UITests.ExportTest|A
2021-11-24T11:50:59.6251058Z 2021-11-24 11:49:45.4339|INFO|boilersGraphics.Test.UITests.ExportTest|B
2021-11-24T11:50:59.6254031Z 2021-11-24 11:49:46.3341|INFO|boilersGraphics.Test.UITests.ExportTest|C
2021-11-24T11:50:59.6258212Z 2021-11-24 11:49:47.3152|INFO|boilersGraphics.Test.UITests.ExportTest|D
2021-11-24T11:50:59.6262441Z 2021-11-24 11:49:48.4392|INFO|boilersGraphics.Test.UITests.ExportTest|E
2021-11-24T11:50:59.6264755Z 2021-11-24 11:49:48.6446|INFO|boilersGraphics.Test.UITests.ExportTest|F
2021-11-24T11:50:59.6266893Z 2021-11-24 11:49:51.5246|INFO|boilersGraphics.Test.UITests.ExportTest|G
2021-11-24T11:50:59.6269610Z 2021-11-24 11:49:51.8636|INFO|boilersGraphics.Test.UITests.ExportTest|H
2021-11-24T11:50:59.6272604Z 2021-11-24 11:49:53.5064|INFO|boilersGraphics.Test.UITests.ExportTest|I
2021-11-24T11:50:59.6282263Z 2021-11-24 11:50:54.5629|INFO|boilersGraphics.Test.UITests.ExportTest|N
2021-11-24T11:50:59.6283830Z 2021-11-24 11:50:54.5629|INFO|boilersGraphics.Test.UITests.ExportTest|O
2021-11-24T11:51:08.3846661Z 2021-11-24 11:51:08.3303|INFO|boilersGraphics.Test.UITests.ExportTest|D:\a\1\s\boilersGraphics.Test\bin\Release\ExportTest.jpg

（中略）

2021-11-24T11:51:12.3651621Z 
2021-11-24T11:51:12.3669894Z Errors, Failures and Warnings
2021-11-24T11:51:12.3685461Z 
2021-11-24T11:51:12.3734296Z 1) Error : boilersGraphics.Test.UITests.ExportTest.チェッカーパターンを読み込んでエクスポートする
2021-11-24T11:51:12.3746425Z OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://127.0.0.1:4723/session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element timed out after 60 seconds.
2021-11-24T11:51:12.3757425Z   ----> System.Net.WebException : The operation has timed out
2021-11-24T11:51:12.3769726Z    at OpenQA.Selenium.Appium.Service.AppiumCommandExecutor.Execute(Command commandToExecute)
2021-11-24T11:51:12.3781949Z    at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
2021-11-24T11:51:12.4721838Z    at OpenQA.Selenium.Appium.AppiumDriver`1.Execute(String driverCommandToExecute, Dictionary`2 parameters)
2021-11-24T11:51:12.4914311Z    at OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(String mechanism, String value)
2021-11-24T11:51:12.4925116Z    at OpenQA.Selenium.Appium.AppiumDriver`1.FindElement(String by, String value)
2021-11-24T11:51:12.4958725Z    at OpenQA.Selenium.Appium.AppiumDriver`1.FindElementByAccessibilityId(String selector)
2021-11-24T11:51:12.5004117Z    at boilersGraphics.Test.UITests.ExportTest.チェッカーパターンを読み込んでエクスポートする() in D:\a\1\s\boilersGraphics.Test\UITests\ExportTest.cs:line 64
2021-11-24T11:51:12.5021425Z --WebException
2021-11-24T11:51:12.5030030Z    at System.Net.HttpWebRequest.GetResponse()
2021-11-24T11:51:12.5101834Z    at OpenQA.Selenium.Remote.HttpCommandExecutor.MakeHttpRequest(HttpRequestInfo requestInfo)
2021-11-24T11:51:12.5102789Z 
2021-11-24T11:51:12.5103905Z Run Settings
2021-11-24T11:51:12.5104752Z     DisposeRunners: True
2021-11-24T11:51:12.5105614Z     WorkDirectory: D:\a\1\s\boilersGraphics.Test\bin\Release
2021-11-24T11:51:12.5106484Z     ImageRuntimeVersion: 4.0.30319
2021-11-24T11:51:12.5107345Z     ImageTargetFrameworkName: .NETFramework,Version=v4.8
2021-11-24T11:51:12.5108254Z     ImageRequiresX86: False
2021-11-24T11:51:12.5109122Z     ImageRequiresDefaultAppDomainAssemblyResolver: False
2021-11-24T11:51:12.5109993Z     TargetRuntimeFramework: net-4.0
2021-11-24T11:51:12.5110804Z     NumberOfTestWorkers: 2
2021-11-24T11:51:12.5111509Z 
2021-11-24T11:51:12.5112247Z Test Run Summary
2021-11-24T11:51:12.5113219Z   Overall result: Failed
2021-11-24T11:51:12.5114161Z   Test Count: 124, Passed: 123, Failed: 1, Warnings: 0, Inconclusive: 0, Skipped: 0
2021-11-24T11:51:12.5115134Z     Failed Tests - Failures: 0, Errors: 1, Invalid: 0
2021-11-24T11:51:12.5115994Z   Start time: 2021-11-24 11:49:09Z
2021-11-24T11:51:12.5116819Z     End time: 2021-11-24 11:51:12Z
2021-11-24T11:51:12.5117916Z     Duration: 122.680 seconds
2021-11-24T11:51:12.5118585Z 
2021-11-24T11:51:12.5119861Z Results (nunit3) saved as TestResult.xml
2021-11-24T11:51:12.6175191Z Committing...
2021-11-24T11:51:12.8990731Z Visited Classes 130 of 418 (31.1)
2021-11-24T11:51:12.8992408Z Visited Methods 953 of 3041 (31.34)
2021-11-24T11:51:12.8993394Z Visited Points 2723 of 11774 (23.13)
2021-11-24T11:51:12.8994213Z Visited Branches 1234 of 5860 (21.06)
2021-11-24T11:51:12.8994783Z 
2021-11-24T11:51:12.8995591Z ==== Alternative Results (includes all methods including those without corresponding source) ====
2021-11-24T11:51:12.8996481Z Alternative Visited Classes 130 of 441 (29.48)
2021-11-24T11:51:12.8997281Z Alternative Visited Methods 953 of 3530 (27)
2021-11-24T11:51:13.0756701Z ##[error]Cmd.exe exited with code '1'.
2021-11-24T11:51:13.1410544Z ##[section]Finishing: NUnit & OpenCover
```

テストが失敗してしまいました。
ログには以下のように出力されています。

```
A
B
C
D
E
F
G
H
I
N
O
```
処理ABCDEFGHIまでは順調に実行できているようです。
処理JKLMが実行できていない。Jで例外が飛んだか？
処理NOはfinally句なので実行されてますね。

ちなみにCloseの方のWinAppDriverタスクを見てみると、WinAppDriverのログが出力されています。

```
2021-11-24T11:51:13.1518574Z ##[section]Starting: WindowsApplicationDriver
2021-11-24T11:51:13.1864748Z ==============================================================================
2021-11-24T11:51:13.1866690Z Task         : WinAppDriver
2021-11-24T11:51:13.1867990Z Description  : Use this extention to integrate Windows Application Driver (WinAppDriver) into your Azure Pipeline.
2021-11-24T11:51:13.1870055Z Version      : 0.0.2
2021-11-24T11:51:13.1871000Z Author       : Microsoft
2021-11-24T11:51:13.1871980Z Help         : Checkout the WinAppDriver GitHub Repo to learn more - https://github.com/Microsoft/WinAppDriver
2021-11-24T11:51:13.1873744Z ==============================================================================
2021-11-24T11:51:14.5302212Z Attempting to close WinAppDriver on Agent
2021-11-24T11:51:24.5349173Z 
2021-11-24T11:51:24.5359197Z Printing WinAppDriver Console logs:
2021-11-24T11:51:24.5363875Z 
2021-11-24T11:51:24.5442258Z Windows Application Driver listening for requests at: http://127.0.0.1:4723/
2021-11-24T11:51:24.5447996Z Press ENTER to exit.
2021-11-24T11:51:24.5449264Z 
2021-11-24T11:51:24.5449720Z 
2021-11-24T11:51:24.5451412Z ==========================================
2021-11-24T11:51:24.5452118Z POST /session HTTP/1.1
2021-11-24T11:51:24.5452847Z 
2021-11-24T11:51:24.5453768Z Accept: application/json, image/png
2021-11-24T11:51:24.5454281Z 
2021-11-24T11:51:24.5455037Z Connection: Keep-Alive
2021-11-24T11:51:24.5455334Z 
2021-11-24T11:51:24.5456373Z Content-Length: 152
2021-11-24T11:51:24.5457095Z 
2021-11-24T11:51:24.5457864Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5458492Z 
2021-11-24T11:51:24.5460144Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5461243Z 
2021-11-24T11:51:24.5462525Z 
2021-11-24T11:51:24.5463621Z 
2021-11-24T11:51:24.5465046Z {"desiredCapabilities":{"app":"D:\\a\\1\\s\\boilersGraphics.Test\\bin\\Release\\boilersGraphics.exe","deviceName":"WindowsPC","platformName":"Windows"}}
2021-11-24T11:51:24.5466254Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5466857Z 
2021-11-24T11:51:24.5467789Z Content-Length: 175
2021-11-24T11:51:24.5468617Z 
2021-11-24T11:51:24.5469832Z Content-Type: application/json
2021-11-24T11:51:24.5470574Z 
2021-11-24T11:51:24.5471535Z 
2021-11-24T11:51:24.5472467Z 
2021-11-24T11:51:24.5474195Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0,"value":{"app":"D:\\a\\1\\s\\boilersGraphics.Test\\bin\\Release\\boilersGraphics.exe","platformName":"Windows"}}
2021-11-24T11:51:24.5475069Z 
2021-11-24T11:51:24.5475892Z 
2021-11-24T11:51:24.5479349Z ==========================================
2021-11-24T11:51:24.5663526Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/timeouts HTTP/1.1
2021-11-24T11:51:24.5667106Z 
2021-11-24T11:51:24.5795302Z Accept: application/json, image/png
2021-11-24T11:51:24.5796146Z 
2021-11-24T11:51:24.5796901Z Content-Length: 32
2021-11-24T11:51:24.5797431Z 
2021-11-24T11:51:24.5798169Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5798700Z 
2021-11-24T11:51:24.5799408Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5799926Z 
2021-11-24T11:51:24.5800389Z 
2021-11-24T11:51:24.5800869Z 
2021-11-24T11:51:24.5801579Z {"type":"implicit","ms":60000.0}
2021-11-24T11:51:24.5802312Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5802787Z 
2021-11-24T11:51:24.5803600Z Content-Length: 63
2021-11-24T11:51:24.5804332Z 
2021-11-24T11:51:24.5805167Z Content-Type: application/json
2021-11-24T11:51:24.5805674Z 
2021-11-24T11:51:24.5806151Z 
2021-11-24T11:51:24.5806602Z 
2021-11-24T11:51:24.5807380Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.5807988Z 
2021-11-24T11:51:24.5808467Z 
2021-11-24T11:51:24.5809180Z ==========================================
2021-11-24T11:51:24.5810010Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/window/current/maximize HTTP/1.1
2021-11-24T11:51:24.5810618Z 
2021-11-24T11:51:24.5811323Z Accept: application/json, image/png
2021-11-24T11:51:24.5811827Z 
2021-11-24T11:51:24.5812507Z Content-Length: 2
2021-11-24T11:51:24.5815141Z 
2021-11-24T11:51:24.5815970Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5816668Z 
2021-11-24T11:51:24.5817374Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5817889Z 
2021-11-24T11:51:24.5818341Z 
2021-11-24T11:51:24.5818822Z 
2021-11-24T11:51:24.5819465Z {}
2021-11-24T11:51:24.5820125Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5820596Z 
2021-11-24T11:51:24.5821371Z Content-Length: 63
2021-11-24T11:51:24.5821927Z 
2021-11-24T11:51:24.5822609Z Content-Type: application/json
2021-11-24T11:51:24.5823349Z 
2021-11-24T11:51:24.5823986Z 
2021-11-24T11:51:24.5824515Z 
2021-11-24T11:51:24.5825340Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.5826018Z 
2021-11-24T11:51:24.5826537Z 
2021-11-24T11:51:24.5858621Z ==========================================
2021-11-24T11:51:24.5859796Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element HTTP/1.1
2021-11-24T11:51:24.5860412Z 
2021-11-24T11:51:24.5861140Z Accept: application/json, image/png
2021-11-24T11:51:24.5861659Z 
2021-11-24T11:51:24.5862349Z Content-Length: 43
2021-11-24T11:51:24.5862869Z 
2021-11-24T11:51:24.5863677Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5865258Z 
2021-11-24T11:51:24.5865973Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5866491Z 
2021-11-24T11:51:24.5866942Z 
2021-11-24T11:51:24.5867416Z 
2021-11-24T11:51:24.5868144Z {"using":"accessibility id","value":"Load"}
2021-11-24T11:51:24.5868889Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5869364Z 
2021-11-24T11:51:24.5870256Z Content-Length: 101
2021-11-24T11:51:24.5870812Z 
2021-11-24T11:51:24.5871562Z Content-Type: application/json
2021-11-24T11:51:24.5872105Z 
2021-11-24T11:51:24.5872619Z 
2021-11-24T11:51:24.5873103Z 
2021-11-24T11:51:24.5874180Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0,"value":{"ELEMENT":"7.5860.33860402"}}
2021-11-24T11:51:24.5874927Z 
2021-11-24T11:51:24.5875413Z 
2021-11-24T11:51:24.5876184Z ==========================================
2021-11-24T11:51:24.5877098Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element/7.5860.33860402/click HTTP/1.1
2021-11-24T11:51:24.5877781Z 
2021-11-24T11:51:24.5878666Z Accept: application/json, image/png
2021-11-24T11:51:24.5879239Z 
2021-11-24T11:51:24.5880004Z Content-Length: 2
2021-11-24T11:51:24.5880529Z 
2021-11-24T11:51:24.5881580Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5882226Z 
2021-11-24T11:51:24.5882907Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5883471Z 
2021-11-24T11:51:24.5883927Z 
2021-11-24T11:51:24.5884402Z 
2021-11-24T11:51:24.5885045Z {}
2021-11-24T11:51:24.5885908Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5886421Z 
2021-11-24T11:51:24.5887145Z Content-Length: 63
2021-11-24T11:51:24.5887786Z 
2021-11-24T11:51:24.5888477Z Content-Type: application/json
2021-11-24T11:51:24.5888980Z 
2021-11-24T11:51:24.5889457Z 
2021-11-24T11:51:24.5889910Z 
2021-11-24T11:51:24.5890911Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.5891572Z 
2021-11-24T11:51:24.5892062Z 
2021-11-24T11:51:24.5893022Z ==========================================
2021-11-24T11:51:24.5893841Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element HTTP/1.1
2021-11-24T11:51:24.5894367Z 
2021-11-24T11:51:24.5895012Z Accept: application/json, image/png
2021-11-24T11:51:24.5895467Z 
2021-11-24T11:51:24.5896080Z Content-Length: 40
2021-11-24T11:51:24.5896532Z 
2021-11-24T11:51:24.5897190Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5897747Z 
2021-11-24T11:51:24.5898381Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5898840Z 
2021-11-24T11:51:24.5899264Z 
2021-11-24T11:51:24.5899688Z 
2021-11-24T11:51:24.5900351Z {"using":"accessibility id","value":"1"}
2021-11-24T11:51:24.5901034Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5901478Z 
2021-11-24T11:51:24.5902092Z Content-Length: 94
2021-11-24T11:51:24.5902522Z 
2021-11-24T11:51:24.5903152Z Content-Type: application/json
2021-11-24T11:51:24.5903673Z 
2021-11-24T11:51:24.5904877Z 
2021-11-24T11:51:24.5905311Z 
2021-11-24T11:51:24.5906109Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0,"value":{"ELEMENT":"42.66074"}}
2021-11-24T11:51:24.5906834Z 
2021-11-24T11:51:24.5907261Z 
2021-11-24T11:51:24.5907917Z ==========================================
2021-11-24T11:51:24.5908702Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element/42.66074/click HTTP/1.1
2021-11-24T11:51:24.5909236Z 
2021-11-24T11:51:24.5909880Z Accept: application/json, image/png
2021-11-24T11:51:24.5910405Z 
2021-11-24T11:51:24.5911657Z Content-Length: 2
2021-11-24T11:51:24.5912234Z 
2021-11-24T11:51:24.5912941Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5913556Z 
2021-11-24T11:51:24.5914197Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5914639Z 
2021-11-24T11:51:24.5915061Z 
2021-11-24T11:51:24.5915456Z 
2021-11-24T11:51:24.5916151Z {}
2021-11-24T11:51:24.5916763Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5917215Z 
2021-11-24T11:51:24.5917838Z Content-Length: 63
2021-11-24T11:51:24.5918303Z 
2021-11-24T11:51:24.5918946Z Content-Type: application/json
2021-11-24T11:51:24.5919435Z 
2021-11-24T11:51:24.5919830Z 
2021-11-24T11:51:24.5920250Z 
2021-11-24T11:51:24.5920973Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.5921539Z 
2021-11-24T11:51:24.5921958Z 
2021-11-24T11:51:24.5922610Z ==========================================
2021-11-24T11:51:24.5923439Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/keys HTTP/1.1
2021-11-24T11:51:24.5923942Z 
2021-11-24T11:51:24.5924589Z Accept: application/json, image/png
2021-11-24T11:51:24.5925064Z 
2021-11-24T11:51:24.5925680Z Content-Length: 27
2021-11-24T11:51:24.5926111Z 
2021-11-24T11:51:24.5926774Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5927267Z 
2021-11-24T11:51:24.5927894Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5928325Z 
2021-11-24T11:51:24.5928749Z 
2021-11-24T11:51:24.5929143Z 
2021-11-24T11:51:24.5929858Z {"value":["","N",""]}
2021-11-24T11:51:24.5930589Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5931034Z 
2021-11-24T11:51:24.5931683Z Content-Length: 63
2021-11-24T11:51:24.5932108Z 
2021-11-24T11:51:24.5932825Z Content-Type: application/json
2021-11-24T11:51:24.5933386Z 
2021-11-24T11:51:24.5933788Z 
2021-11-24T11:51:24.5934493Z 
2021-11-24T11:51:24.5935268Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.5935866Z 
2021-11-24T11:51:24.5936329Z 
2021-11-24T11:51:24.5937036Z ==========================================
2021-11-24T11:51:24.5937844Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/keys HTTP/1.1
2021-11-24T11:51:24.5938378Z 
2021-11-24T11:51:24.5939070Z Accept: application/json, image/png
2021-11-24T11:51:24.5939582Z 
2021-11-24T11:51:24.5940253Z Content-Length: 27
2021-11-24T11:51:24.5940717Z 
2021-11-24T11:51:24.5941427Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5941959Z 
2021-11-24T11:51:24.5942627Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5943130Z 
2021-11-24T11:51:24.5943684Z 
2021-11-24T11:51:24.5944111Z 
2021-11-24T11:51:24.5944810Z {"value":["","N",""]}
2021-11-24T11:51:24.5945535Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5946119Z 
2021-11-24T11:51:24.5946769Z Content-Length: 63
2021-11-24T11:51:24.5947197Z 
2021-11-24T11:51:24.5947835Z Content-Type: application/json
2021-11-24T11:51:24.5948305Z 
2021-11-24T11:51:24.5948699Z 
2021-11-24T11:51:24.5949121Z 
2021-11-24T11:51:24.5949843Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.5950441Z 
2021-11-24T11:51:24.5950871Z 
2021-11-24T11:51:24.5951517Z ==========================================
2021-11-24T11:51:24.5952264Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element HTTP/1.1
2021-11-24T11:51:24.5952780Z 
2021-11-24T11:51:24.5953503Z Accept: application/json, image/png
2021-11-24T11:51:24.5953994Z 
2021-11-24T11:51:24.5954598Z Content-Length: 43
2021-11-24T11:51:24.5955053Z 
2021-11-24T11:51:24.5955709Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5956380Z 
2021-11-24T11:51:24.5957017Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5957610Z 
2021-11-24T11:51:24.5958009Z 
2021-11-24T11:51:24.5958435Z 
2021-11-24T11:51:24.5959106Z {"using":"accessibility id","value":"1148"}
2021-11-24T11:51:24.5959793Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5960214Z 
2021-11-24T11:51:24.5960832Z Content-Length: 94
2021-11-24T11:51:24.5961284Z 
2021-11-24T11:51:24.5961921Z Content-Type: application/json
2021-11-24T11:51:24.5962368Z 
2021-11-24T11:51:24.5962790Z 
2021-11-24T11:51:24.5963184Z 
2021-11-24T11:51:24.5964264Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0,"value":{"ELEMENT":"42.66092"}}
2021-11-24T11:51:24.5964872Z 
2021-11-24T11:51:24.5965266Z 
2021-11-24T11:51:24.5965913Z ==========================================
2021-11-24T11:51:24.5966679Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element/42.66092/value HTTP/1.1
2021-11-24T11:51:24.5967232Z 
2021-11-24T11:51:24.5967954Z Accept: application/json, image/png
2021-11-24T11:51:24.5968414Z 
2021-11-24T11:51:24.5969034Z Content-Length: 92
2021-11-24T11:51:24.5969477Z 
2021-11-24T11:51:24.5970940Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5971425Z 
2021-11-24T11:51:24.5972049Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5972508Z 
2021-11-24T11:51:24.5972932Z 
2021-11-24T11:51:24.5973423Z 
2021-11-24T11:51:24.5974169Z {"value":["D:\\a\\1\\s\\boilersGraphics.Test\\bin\\Release\\XmlFiles\\checker_pattern.xml"]}
2021-11-24T11:51:24.5974930Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5975367Z 
2021-11-24T11:51:24.5975978Z Content-Length: 63
2021-11-24T11:51:24.5976408Z 
2021-11-24T11:51:24.5977035Z Content-Type: application/json
2021-11-24T11:51:24.5977494Z 
2021-11-24T11:51:24.5977891Z 
2021-11-24T11:51:24.5978309Z 
2021-11-24T11:51:24.5979019Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.5979538Z 
2021-11-24T11:51:24.5979950Z 
2021-11-24T11:51:24.5980590Z ==========================================
2021-11-24T11:51:24.5981336Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element HTTP/1.1
2021-11-24T11:51:24.5981835Z 
2021-11-24T11:51:24.5982469Z Accept: application/json, image/png
2021-11-24T11:51:24.5982936Z 
2021-11-24T11:51:24.5983633Z Content-Length: 40
2021-11-24T11:51:24.5984064Z 
2021-11-24T11:51:24.5984821Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5985307Z 
2021-11-24T11:51:24.5985927Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.5986359Z 
2021-11-24T11:51:24.5986775Z 
2021-11-24T11:51:24.5987168Z 
2021-11-24T11:51:24.5987827Z {"using":"accessibility id","value":"1"}
2021-11-24T11:51:24.5988501Z HTTP/1.1 200 OK
2021-11-24T11:51:24.5988937Z 
2021-11-24T11:51:24.5989564Z Content-Length: 94
2021-11-24T11:51:24.5989994Z 
2021-11-24T11:51:24.5990644Z Content-Type: application/json
2021-11-24T11:51:24.5991089Z 
2021-11-24T11:51:24.5991485Z 
2021-11-24T11:51:24.5991900Z 
2021-11-24T11:51:24.5992669Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0,"value":{"ELEMENT":"42.66106"}}
2021-11-24T11:51:24.5993355Z 
2021-11-24T11:51:24.5993759Z 
2021-11-24T11:51:24.5994403Z ==========================================
2021-11-24T11:51:24.5995169Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element/42.66106/click HTTP/1.1
2021-11-24T11:51:24.5995716Z 
2021-11-24T11:51:24.5996352Z Accept: application/json, image/png
2021-11-24T11:51:24.5996805Z 
2021-11-24T11:51:24.5997410Z Content-Length: 2
2021-11-24T11:51:24.5997853Z 
2021-11-24T11:51:24.5998505Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.5998977Z 
2021-11-24T11:51:24.5999592Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6000046Z 
2021-11-24T11:51:24.6000437Z 
2021-11-24T11:51:24.6000936Z 
2021-11-24T11:51:24.6001518Z {}
2021-11-24T11:51:24.6002111Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6002526Z 
2021-11-24T11:51:24.6003134Z Content-Length: 63
2021-11-24T11:51:24.6003663Z 
2021-11-24T11:51:24.6004296Z Content-Type: application/json
2021-11-24T11:51:24.6004903Z 
2021-11-24T11:51:24.6005319Z 
2021-11-24T11:51:24.6005820Z 
2021-11-24T11:51:24.6006558Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.6007095Z 
2021-11-24T11:51:24.6007515Z 
2021-11-24T11:51:24.6008165Z ==========================================
2021-11-24T11:51:24.6008910Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element HTTP/1.1
2021-11-24T11:51:24.6009399Z 
2021-11-24T11:51:24.6010032Z Accept: application/json, image/png
2021-11-24T11:51:24.6010495Z 
2021-11-24T11:51:24.6011107Z Content-Length: 45
2021-11-24T11:51:24.6011533Z 
2021-11-24T11:51:24.6012188Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6012670Z 
2021-11-24T11:51:24.6013366Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6013810Z 
2021-11-24T11:51:24.6014225Z 
2021-11-24T11:51:24.6014620Z 
2021-11-24T11:51:24.6015286Z {"using":"accessibility id","value":"Export"}
2021-11-24T11:51:24.6015961Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6016399Z 
2021-11-24T11:51:24.6017006Z Content-Length: 101
2021-11-24T11:51:24.6017525Z 
2021-11-24T11:51:24.6018158Z Content-Type: application/json
2021-11-24T11:51:24.6018622Z 
2021-11-24T11:51:24.6019012Z 
2021-11-24T11:51:24.6019426Z 
2021-11-24T11:51:24.6020205Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0,"value":{"ELEMENT":"7.5860.27762102"}}
2021-11-24T11:51:24.6020801Z 
2021-11-24T11:51:24.6021250Z 
2021-11-24T11:51:24.6021894Z ==========================================
2021-11-24T11:51:24.6022685Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element/7.5860.27762102/click HTTP/1.1
2021-11-24T11:51:24.6023301Z 
2021-11-24T11:51:24.6023967Z Accept: application/json, image/png
2021-11-24T11:51:24.6024416Z 
2021-11-24T11:51:24.6025031Z Content-Length: 2
2021-11-24T11:51:24.6025456Z 
2021-11-24T11:51:24.6026104Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6026589Z 
2021-11-24T11:51:24.6027201Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6027643Z 
2021-11-24T11:51:24.6028062Z 
2021-11-24T11:51:24.6028460Z 
2021-11-24T11:51:24.6029038Z {}
2021-11-24T11:51:24.6029628Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6030057Z 
2021-11-24T11:51:24.6030667Z Content-Length: 63
2021-11-24T11:51:24.6031096Z 
2021-11-24T11:51:24.6031720Z Content-Type: application/json
2021-11-24T11:51:24.6032180Z 
2021-11-24T11:51:24.6032574Z 
2021-11-24T11:51:24.6032985Z 
2021-11-24T11:51:24.6033769Z {"sessionId":"DD6B692A-76CE-40AA-B4D1-6FDCB7E35848","status":0}
2021-11-24T11:51:24.6034378Z 
2021-11-24T11:51:24.6034801Z 
2021-11-24T11:51:24.6035439Z ==========================================
2021-11-24T11:51:24.6036401Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element HTTP/1.1
2021-11-24T11:51:24.6036936Z 
2021-11-24T11:51:24.6037623Z Accept: application/json, image/png
2021-11-24T11:51:24.6038132Z 
2021-11-24T11:51:24.6038787Z Content-Length: 53
2021-11-24T11:51:24.6039246Z 
2021-11-24T11:51:24.6039949Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6040478Z 
2021-11-24T11:51:24.6041164Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6041640Z 
2021-11-24T11:51:24.6042090Z 
2021-11-24T11:51:24.6042518Z 
2021-11-24T11:51:24.6043335Z {"using":"accessibility id","value":"ExportFileName"}
2021-11-24T11:51:24.6043907Z 
2021-11-24T11:51:24.6044335Z 
2021-11-24T11:51:24.6045032Z ==========================================
2021-11-24T11:51:24.6045825Z DELETE /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848 HTTP/1.1
2021-11-24T11:51:24.6046365Z 
2021-11-24T11:51:24.6047046Z Accept: application/json, image/png
2021-11-24T11:51:24.6047531Z 
2021-11-24T11:51:24.6048195Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6048677Z 
2021-11-24T11:51:24.6049111Z 
2021-11-24T11:51:24.6049558Z 
2021-11-24T11:51:24.6049984Z 
2021-11-24T11:51:24.6050629Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6051289Z 
2021-11-24T11:51:24.6051909Z Content-Length: 12
2021-11-24T11:51:24.6052339Z 
2021-11-24T11:51:24.6052964Z Content-Type: application/json
2021-11-24T11:51:24.6054192Z 
2021-11-24T11:51:24.6054598Z 
2021-11-24T11:51:24.6055018Z 
2021-11-24T11:51:24.6055749Z {"status":0}
2021-11-24T11:51:24.6056171Z 
2021-11-24T11:51:24.6056565Z 
2021-11-24T11:51:24.6057208Z ==========================================
2021-11-24T11:51:24.6057891Z POST /session HTTP/1.1
2021-11-24T11:51:24.6058394Z 
2021-11-24T11:51:24.6059053Z Accept: application/json, image/png
2021-11-24T11:51:24.6540533Z 
2021-11-24T11:51:24.6545137Z Content-Length: 152
2021-11-24T11:51:24.6618340Z 
2021-11-24T11:51:24.6622425Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6623086Z 
2021-11-24T11:51:24.6624009Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6624504Z 
2021-11-24T11:51:24.6624913Z 
2021-11-24T11:51:24.6625349Z 
2021-11-24T11:51:24.6625760Z 
2021-11-24T11:51:24.6626399Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6626856Z 
2021-11-24T11:51:24.6627485Z Content-Length: 175
2021-11-24T11:51:24.6627923Z 
2021-11-24T11:51:24.6628564Z Content-Type: application/json
2021-11-24T11:51:24.6629059Z 
2021-11-24T11:51:24.6629464Z 
2021-11-24T11:51:24.6629869Z 
2021-11-24T11:51:24.6630977Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0,"value":{"app":"D:\\a\\1\\s\\boilersGraphics.Test\\bin\\Release\\boilersGraphics.exe","platformName":"Windows"}}
2021-11-24T11:51:24.6631768Z 
2021-11-24T11:51:24.6632195Z 
2021-11-24T11:51:24.6632855Z ==========================================
2021-11-24T11:51:24.6633674Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/timeouts HTTP/1.1
2021-11-24T11:51:24.6634389Z 
2021-11-24T11:51:24.6635057Z Accept: application/json, image/png
2021-11-24T11:51:24.6635521Z 
2021-11-24T11:51:24.6636147Z Content-Length: 32
2021-11-24T11:51:24.6636605Z 
2021-11-24T11:51:24.6637270Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6637754Z 
2021-11-24T11:51:24.6638381Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6638860Z 
2021-11-24T11:51:24.6639281Z 
2021-11-24T11:51:24.6639694Z 
2021-11-24T11:51:24.6640425Z {"type":"implicit","ms":60000.0}
2021-11-24T11:51:24.6642995Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6646740Z 
2021-11-24T11:51:24.6649187Z Content-Length: 63
2021-11-24T11:51:24.6651905Z 
2021-11-24T11:51:24.6652782Z Content-Type: application/json
2021-11-24T11:51:24.6653493Z 
2021-11-24T11:51:24.6653963Z 
2021-11-24T11:51:24.6654421Z 
2021-11-24T11:51:24.6655258Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0}
2021-11-24T11:51:24.6655861Z 
2021-11-24T11:51:24.6656330Z 
2021-11-24T11:51:24.6657055Z ==========================================
2021-11-24T11:51:24.6658043Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/window/current/maximize HTTP/1.1
2021-11-24T11:51:24.6658645Z 
2021-11-24T11:51:24.6659356Z Accept: application/json, image/png
2021-11-24T11:51:24.6659883Z 
2021-11-24T11:51:24.6660561Z Content-Length: 2
2021-11-24T11:51:24.6661049Z 
2021-11-24T11:51:24.6661777Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6662321Z 
2021-11-24T11:51:24.6663011Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6663624Z 
2021-11-24T11:51:24.6664102Z 
2021-11-24T11:51:24.6664555Z 
2021-11-24T11:51:24.6665202Z {}
2021-11-24T11:51:24.6665872Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6666364Z 
2021-11-24T11:51:24.6667042Z Content-Length: 63
2021-11-24T11:51:24.6667540Z 
2021-11-24T11:51:24.6668230Z Content-Type: application/json
2021-11-24T11:51:24.6668741Z 
2021-11-24T11:51:24.6669177Z 
2021-11-24T11:51:24.6669643Z 
2021-11-24T11:51:24.6670437Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0}
2021-11-24T11:51:24.6671018Z 
2021-11-24T11:51:24.6671474Z 
2021-11-24T11:51:24.6672169Z ==========================================
2021-11-24T11:51:24.6672980Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/element HTTP/1.1
2021-11-24T11:51:24.6673622Z 
2021-11-24T11:51:24.6674318Z Accept: application/json, image/png
2021-11-24T11:51:24.6674912Z 
2021-11-24T11:51:24.6675612Z Content-Length: 45
2021-11-24T11:51:24.6676062Z 
2021-11-24T11:51:24.6676719Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6677380Z 
2021-11-24T11:51:24.6678123Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6678583Z 
2021-11-24T11:51:24.6678988Z 
2021-11-24T11:51:24.6679413Z 
2021-11-24T11:51:24.6679812Z 
2021-11-24T11:51:24.6680418Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6681045Z 
2021-11-24T11:51:24.6681708Z Content-Length: 101
2021-11-24T11:51:24.6682540Z 
2021-11-24T11:51:24.6683231Z Content-Type: application/json
2021-11-24T11:51:24.6683841Z 
2021-11-24T11:51:24.6684270Z 
2021-11-24T11:51:24.6684699Z 
2021-11-24T11:51:24.6685554Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0,"value":{"ELEMENT":"7.2008.28475059"}}
2021-11-24T11:51:24.6686299Z 
2021-11-24T11:51:24.6686713Z 
2021-11-24T11:51:24.6687363Z ==========================================
2021-11-24T11:51:24.6688152Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/element/7.2008.28475059/click HTTP/1.1
2021-11-24T11:51:24.6688692Z 
2021-11-24T11:51:24.6689353Z Accept: application/json, image/png
2021-11-24T11:51:24.6689835Z 
2021-11-24T11:51:24.6690457Z Content-Length: 2
2021-11-24T11:51:24.6691085Z 
2021-11-24T11:51:24.6691908Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6692373Z 
2021-11-24T11:51:24.6692989Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6693615Z 
2021-11-24T11:51:24.6694055Z 
2021-11-24T11:51:24.6694475Z 
2021-11-24T11:51:24.6695052Z {}
2021-11-24T11:51:24.6695648Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6696064Z 
2021-11-24T11:51:24.6696675Z Content-Length: 63
2021-11-24T11:51:24.6697123Z 
2021-11-24T11:51:24.6697750Z Content-Type: application/json
2021-11-24T11:51:24.6698195Z 
2021-11-24T11:51:24.6698611Z 
2021-11-24T11:51:24.6699006Z 
2021-11-24T11:51:24.6699423Z 
2021-11-24T11:51:24.6699821Z 
2021-11-24T11:51:24.6700236Z 
2021-11-24T11:51:24.6700875Z ==========================================
2021-11-24T11:51:24.6701616Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/element HTTP/1.1
2021-11-24T11:51:24.6702120Z 
2021-11-24T11:51:24.6702816Z Accept: application/json, image/png
2021-11-24T11:51:24.6703219Z 
2021-11-24T11:51:24.6703841Z Content-Length: 53
2021-11-24T11:51:24.6704214Z 
2021-11-24T11:51:24.6704784Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6705206Z 
2021-11-24T11:51:24.6705766Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6706148Z 
2021-11-24T11:51:24.6706496Z 
2021-11-24T11:51:24.6706859Z 
2021-11-24T11:51:24.6707459Z {"using":"accessibility id","value":"ExportFileName"}
2021-11-24T11:51:24.6708075Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6708439Z 
2021-11-24T11:51:24.6709054Z Content-Length: 100
2021-11-24T11:51:24.6709449Z 
2021-11-24T11:51:24.6710004Z Content-Type: application/json
2021-11-24T11:51:24.6710393Z 
2021-11-24T11:51:24.6710761Z 
2021-11-24T11:51:24.6711105Z 
2021-11-24T11:51:24.6712027Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0,"value":{"ELEMENT":"7.2008.1107452"}}
2021-11-24T11:51:24.6712653Z 
2021-11-24T11:51:24.6713126Z 
2021-11-24T11:51:24.6713765Z ==========================================
2021-11-24T11:51:24.6714450Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/element/7.2008.1107452/value HTTP/1.1
2021-11-24T11:51:24.6714943Z 
2021-11-24T11:51:24.6715497Z Accept: application/json, image/png
2021-11-24T11:51:24.6715885Z 
2021-11-24T11:51:24.6716439Z Content-Length: 77
2021-11-24T11:51:24.6716830Z 
2021-11-24T11:51:24.6717397Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6717804Z 
2021-11-24T11:51:24.6718350Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6718748Z 
2021-11-24T11:51:24.6719093Z 
2021-11-24T11:51:24.6719459Z 
2021-11-24T11:51:24.6720078Z {"value":["D:\\a\\1\\s\\boilersGraphics.Test\\bin\\Release\\ExportTest.jpg"]}
2021-11-24T11:51:24.6720904Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6721340Z 
2021-11-24T11:51:24.6721975Z Content-Length: 63
2021-11-24T11:51:24.6722400Z 
2021-11-24T11:51:24.6723030Z Content-Type: application/json
2021-11-24T11:51:24.6723565Z 
2021-11-24T11:51:24.6723968Z 
2021-11-24T11:51:24.6724634Z 
2021-11-24T11:51:24.6725364Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0}
2021-11-24T11:51:24.6725996Z 
2021-11-24T11:51:24.6726412Z 
2021-11-24T11:51:24.6727058Z ==========================================
2021-11-24T11:51:24.6727804Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/element HTTP/1.1
2021-11-24T11:51:24.6728304Z 
2021-11-24T11:51:24.6728942Z Accept: application/json, image/png
2021-11-24T11:51:24.6729406Z 
2021-11-24T11:51:24.6730015Z Content-Length: 52
2021-11-24T11:51:24.6730439Z 
2021-11-24T11:51:24.6731091Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6731583Z 
2021-11-24T11:51:24.6732200Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6732639Z 
2021-11-24T11:51:24.6733056Z 
2021-11-24T11:51:24.6733734Z 
2021-11-24T11:51:24.6734177Z 
2021-11-24T11:51:24.6734782Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6735202Z 
2021-11-24T11:51:24.6735813Z Content-Length: 101
2021-11-24T11:51:24.6736263Z 
2021-11-24T11:51:24.6736894Z Content-Type: application/json
2021-11-24T11:51:24.6737341Z 
2021-11-24T11:51:24.6737763Z 
2021-11-24T11:51:24.6738181Z 
2021-11-24T11:51:24.6738968Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0,"value":{"ELEMENT":"7.2008.35022440"}}
2021-11-24T11:51:24.6739771Z 
2021-11-24T11:51:24.6740205Z 
2021-11-24T11:51:24.6740922Z ==========================================
2021-11-24T11:51:24.6741867Z POST /session/98111BD1-7BA2-4F31-8515-8A4944BF4934/element/7.2008.35022440/click HTTP/1.1
2021-11-24T11:51:24.6742459Z 
2021-11-24T11:51:24.6743146Z Accept: application/json, image/png
2021-11-24T11:51:24.6743750Z 
2021-11-24T11:51:24.6744409Z Content-Length: 2
2021-11-24T11:51:24.6744874Z 
2021-11-24T11:51:24.6745577Z Content-Type: application/json;charset=utf-8
2021-11-24T11:51:24.6746098Z 
2021-11-24T11:51:24.6746764Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6747236Z 
2021-11-24T11:51:24.6747689Z 
2021-11-24T11:51:24.6748120Z 
2021-11-24T11:51:24.6748567Z 
2021-11-24T11:51:24.6749226Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6749678Z 
2021-11-24T11:51:24.6750336Z Content-Length: 63
2021-11-24T11:51:24.6750820Z 
2021-11-24T11:51:24.6751503Z Content-Type: application/json
2021-11-24T11:51:24.6751986Z 
2021-11-24T11:51:24.6752435Z 
2021-11-24T11:51:24.6752862Z 
2021-11-24T11:51:24.6753710Z {"sessionId":"98111BD1-7BA2-4F31-8515-8A4944BF4934","status":0}
2021-11-24T11:51:24.6754305Z 
2021-11-24T11:51:24.6754735Z 
2021-11-24T11:51:24.6755428Z ==========================================
2021-11-24T11:51:24.6756248Z DELETE /session/98111BD1-7BA2-4F31-8515-8A4944BF4934 HTTP/1.1
2021-11-24T11:51:24.6756815Z 
2021-11-24T11:51:24.6757483Z Accept: application/json, image/png
2021-11-24T11:51:24.6757990Z 
2021-11-24T11:51:24.6758740Z Host: 127.0.0.1:4723
2021-11-24T11:51:24.6759212Z 
2021-11-24T11:51:24.6759658Z 
2021-11-24T11:51:24.6760084Z 
2021-11-24T11:51:24.6760532Z 
2021-11-24T11:51:24.6761252Z HTTP/1.1 200 OK
2021-11-24T11:51:24.6761672Z 
2021-11-24T11:51:24.6762287Z Content-Length: 12
2021-11-24T11:51:24.6762732Z 
2021-11-24T11:51:24.6763535Z Content-Type: application/json
2021-11-24T11:51:24.6763993Z 
2021-11-24T11:51:24.6764406Z 
2021-11-24T11:51:24.6764800Z 
2021-11-24T11:51:24.6765399Z {"status":0}
2021-11-24T11:51:24.6807108Z ##[section]Finishing: WindowsApplicationDriver
```

ここでtimeoutsになっているようです。

```
2021-11-24T11:51:24.5663526Z POST /session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/timeouts HTTP/1.1
```

```
2021-11-24T11:51:12.3734296Z 1) Error : boilersGraphics.Test.UITests.ExportTest.チェッカーパターンを読み込んでエクスポートする
2021-11-24T11:51:12.3746425Z OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://127.0.0.1:4723/session/DD6B692A-76CE-40AA-B4D1-6FDCB7E35848/element timed out after 60 seconds.
2021-11-24T11:51:12.3757425Z   ----> System.Net.WebException : The operation has timed out
2021-11-24T11:51:12.3769726Z    at OpenQA.Selenium.Appium.Service.AppiumCommandExecutor.Execute(Command commandToExecute)
2021-11-24T11:51:12.3781949Z    at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
2021-11-24T11:51:12.4721838Z    at OpenQA.Selenium.Appium.AppiumDriver`1.Execute(String driverCommandToExecute, Dictionary`2 parameters)
2021-11-24T11:51:12.4914311Z    at OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(String mechanism, String value)
2021-11-24T11:51:12.4925116Z    at OpenQA.Selenium.Appium.AppiumDriver`1.FindElement(String by, String value)
2021-11-24T11:51:12.4958725Z    at OpenQA.Selenium.Appium.AppiumDriver`1.FindElementByAccessibilityId(String selector)
2021-11-24T11:51:12.5004117Z    at boilersGraphics.Test.UITests.ExportTest.チェッカーパターンを読み込んでエクスポートする() in D:\a\1\s\boilersGraphics.Test\UITests\ExportTest.cs:line 64
2021-11-24T11:51:12.5021425Z --WebException
2021-11-24T11:51:12.5030030Z    at System.Net.HttpWebRequest.GetResponse()
2021-11-24T11:51:12.5101834Z    at OpenQA.Selenium.Remote.HttpCommandExecutor.MakeHttpRequest(HttpRequestInfo requestInfo)
```

該当箇所はExportFileName（エクスポートウィンドウのFileName欄）を探している時にTimeoutになっているようです。

```
session.FindElementByAccessibilityId("ExportFileName").SendKeys(exportFilePath);
```

これどうしたらいいんだろう...。

# Azure DevOpsにおけるデバッグ手法 (2021/12/02追記)

Azure DevOpsにおいてデバッグする時に必須となる技術は2つあります。一つはログです。これはNLogなどの外部ライブラリを使えば簡単ですね。特筆すべきことはないです。

もう一つはスクリーンショットを撮ることです。WinAppDriverでは以下のようにしてスクリーンショットを撮ることができます。

```csharp
session.GetScreenshot().SaveAsFile($"{AppDomain.CurrentDomain.BaseDirectory}\\filename.png");
```

撮ったスクリーンショットをAzure DevOps上でどのように確認するのかという問題があります。これはNUnitに実装されているTestContext.AddTestAttachmentメソッドを使うことで、Azure Pipelineに「このファイルはテストのアタッチメントですよー」というような感じで伝えることができます。

```csharp
//Azure Pipelineにアタッチメントの存在を教える
TestContext.AddTestAttachment($"{AppDomain.CurrentDomain.BaseDirectory}\\{filename}");
```

これを行うと、以下のようにTestタブの中のテストケースを開き、さらにAttachmentsタブを開くと、AddTestAttachmentメソッドに渡したファイルが列挙されていますね。これをクリックすると、右側にプレビューすることができます。また、More Optionsからアタッチメントをダウンロードすることもできます。

![2021-12-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/44495b0a-ec8f-6cac-773e-28e3608e13d1.png)

この機能に気づき、利用しようとした時のコミットで、各処理が終わる毎にスクリーンショットを撮ろうとしましたが、スクリーンショットを撮り始めた瞬間から、テストがパスするようになりました。timeout問題はスクリーンショットを撮る行為により、解決に至りました...。

原因を調査したところ、timeoutする瞬間のスクリーンショットは以下のようになっています。閉じているはずのOpenダイアログが開きっぱなしになっているではありませんか！！！また開いているはずのエクスポートダイアログがOpenダイアログがモーダルで開いていることで開けなかったということがわかります。そりゃエクスポートダイアログの中のExportFileNameが見つからないはずですわ。これの対処を行ったところ、テストはパスしました。

![png](https://dev.azure.com/dhq-boiler/boiler_s%20Graphics/_apis/test/Runs/1000362/Results/100103/Attachments/1)

![2021-12-02 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4734/5747206b-300c-81e5-04b8-96b1369ba5a3.png)

無事パイプラインは成功しました。やったね✌✌✌
↓以下のリンクは成功したパイプラインです。

https://dev.azure.com/dhq-boiler/boiler_s%20Graphics/_build/results?buildId=258&view=logs&j=12f1170f-54f2-53f3-20dd-22fc7dff55f9


# ソースコード

https://github.com/dhq-boiler/boiler-s-Graphics

ブランチは develop です。

# まとめ

というわけで、Azure DevOps & WinAppDriver の記事を書いてみましたよっと。
何か参考になれば幸いです。

# 宣伝

ベクターグラフィックスドローイングツールを開発しています。チェケラー

https://github.com/dhq-boiler/boiler-s-Graphics

コンピュータビジョンツールも開発しています。こちらは最近ご無沙汰ですが、たまにメンテしてます。スクリーンショット機能が便利でよく使ってますね。

https://github.com/dhq-boiler/ShadowEye