[UiPath]Workflow Analyzerカスタムルール作成（セレクターをチェックするルール）

# はじめに

セレクターをリリース前にチェックすることは、UiPathプロジェクトの品質、信頼性、および効率性を確保するために重要です。

セレクターをチェックする手段としては、UiExploerというツールで実際に動作確認を行うのは一般的だと思われます。日々の開発運用で蓄積されたセレクターに関するノウハウは存在するかと思いますが、これらに対するチェックは目視で行われているでしょう。
一般的なUiPath　RPAプロジェクトには、すくなければ数十個、多ければ数百個のUI要素が含まれていて、
それに相応な数のセレクターが存在しているわけです。その規模のセレクターに対して目視チェックはなかなか非効率でしょう。

そこでUiPath Workflow Analyzer カスタムルールで出番です。
カスタムルールを実装することで、すべてまたは特定なシステムのセレクターに対して、任意なチェックルールを作成することができ、ワンクリック操作で一気にセレクターに対するチェックを行うことができるので、作業効率を向上することが期待できます。目視チェックの代わりにカスタムルールのご利用をおすすめします。


UiPath Workflow Analyzer カスタムルールの作り方については、
ぜひ公式資料をご覧ください。
https://www.uipath.com/ja/community-blog/knowledge-base/workflow-analyzer-custom-rule-development-guide

ここでは、カスタムルールを作成する際に、セレクターのチェック方法について紹介します。


# 紹介したいサンプル例　

エクセル内に存在するハイパーリンクをクリックする自動化処理があります。
![sample1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359919/27cabca3-db30-782a-7c73-ca9bb031f65d.png)

このリンクのセレクターを取ってみましょう。
```
<wnd app='excel.exe' cls='XLMAIN' title='Book1 - Excel' />
<uia automationid='Grid' cls='XLSpreadsheetGrid' name='グリッド' />
<uia automationid='B3' cls='XLSpreadsheetCell' name='B3' tableCol='2' tableRow='3' />
<uia automationid='Hyperlink' name='ハイパーリンク ハイパーリンク ' role='リンク' />
```

以下の操作を行った上で、セレクターを検証してみると、検証結果はNGになります。
 a.ハイパーリンクを一度クリックする
 b.エクセルのスクロールバーをいじって、表示を変更する

再度セレクターを取ってみます。
```
<wnd app='excel.exe' cls='XLMAIN' title='Book1 - Excel' />
<uia automationid='Grid' cls='XLSpreadsheetGrid' name='グリッド' />
<uia automationid='B3' cls='XLSpreadsheetCell' name='B3' tableCol='1' tableRow='1' />
<uia automationid='Hyperlink' name='表示済みのハイパーリンク ハイパーリンク ' role='リンク' />
```
その差分を確認すれば、検証NGの理由はわかります。
１．3行目　 tableCol='2' tableRow='3' の部分は　tableCol='1' tableRow='1' に変更されました。
２．4行目　name='ハイパーリンク ハイパーリンク '　の部分はname='表示済みのハイパーリンク ハイパーリンク 'に変更されました。

以下のようにセレクターを改修し、問題なく動作確認を取りました。
```
<wnd app='excel.exe' cls='XLMAIN' title='Book1 - Excel' />
<uia automationid='Grid' cls='XLSpreadsheetGrid' name='グリッド' />
<uia automationid='B3' cls='XLSpreadsheetCell' name='B3'/>
<uia automationid='Hyperlink' name='*ハイパーリンク ハイパーリンク ' role='リンク' />
```

従って、以下のルールが纏められるかと思います。
1．エクセルハイパーリンクのセレクターに対しては、表示位置情報（tableCol='1' tableRow='1'）は存在してはいけない。
2．エクセルハイパーリンクのセレクターに対しては、Nameはクリック前後の値は変わるため、アスタリスクをNameに含むべき。


 実際にそのルールを作成してみましょう
 ```c# rule.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UiPath.Studio.Activities.Api;
using UiPath.Studio.Activities.Api.Analyzer;
using UiPath.Studio.Activities.Api.Analyzer.Rules;
using UiPath.Studio.Analyzer.Models;

namespace custumerRules_CR01
{
    public class SelectorToExcelWithoutRowColNum : IRegisterAnalyzerConfiguration
    {
        public void Initialize(IAnalyzerConfigurationService workflowAnalyzerConfigService)
        {
            System.Diagnostics.Debugger.Launch();   
            var forbiddenSelecotorRule = new Rule<IActivityModel>("CheckExcelSelectorRules", "EXCEL-001", InspectorSelectorWithCertainWords);
            forbiddenSelecotorRule.DefaultErrorLevel = System.Diagnostics.TraceLevel.Error;
            forbiddenSelecotorRule.Parameters.Add("strofparm", new Parameter()
            {
                DefaultValue = "demo",
                Key = "string",
                LocalizedDisplayName = "AnewRule"
            });
            workflowAnalyzerConfigService.AddRule<IActivityModel>(forbiddenSelecotorRule);
        }

        private InspectionResult InspectorSelectorWithCertainWords(IActivityModel activitestoInspect,Rule configerdrule)
        {
            var messagesList = new List<InspectionMessage>();

            foreach (var variable in activitestoInspect.Properties)
            {



                if((0 == variable.DisplayName.CompareTo("ターゲット")) || (0 == variable.DisplayName.CompareTo("Target")))
                {
                    foreach (var variable2 in variable.Arguments)
                    {

                        if ((0 == variable2.DisplayName.CompareTo("セレクター")) || (0 == variable2.DisplayName.CompareTo("Selecor")))
                        {
                            var strSelecotr = variable2.DefinedExpression;

                            //エクセルを対象にするセレクターの場合、TableRow、TableCol情報が含まれると、Warningに出る
                            if (strSelecotr.Contains("app='excel.exe'") && (strSelecotr.Contains("tableCol=") || strSelecotr.Contains("tableRow=")))
                            {
                                messagesList.Add(new InspectionMessage()
                                {
                                    Message = $"Activitie {activitestoInspect.DisplayName} contains keyword 'tableCol' or 'tableRow' which is unstable to excel selectors."
                                });
                            }
                            //エクセルを対象にするセレクターの場合、ハイパーリンクの文字がSelector情報に含まれると、＊がついていなければWarningに出る
                            if (strSelecotr.Contains("app='excel.exe'") && (strSelecotr.Contains("ハイパーリンク") && !strSelecotr.Contains("*ハイパーリンク")))
                            {
                                messagesList.Add(new InspectionMessage()
                                {
                                    Message = $"Activitie {activitestoInspect.DisplayName} contains keyword 'ハイパーリンク' without the char '*'."
                                });
                            }
                        }
                    }
                }
            }

            if (messagesList.Count > 0)
            {
                return new InspectionResult()
                {
                    HasErrors = true,
                    InspectionMessages = messagesList,
                    ErrorLevel = System.Diagnostics.TraceLevel.Warning
                };
            }
            else
            {
                return new InspectionResult()
                {
                    HasErrors = false,
                };
            }
        }

    }
}
```

UiPath Studio で実行してみると問題なく異常を検知することができました。
![sample2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359919/8c9d9bee-1a45-cb3a-8a4b-52f3d2bc5782.png)

 
# 終わりに
カスタムルールを作成し、セレクターに対する簡易てきなチェックルールの作成方法を紹介しました。
ぜひご参考してみて、自分でカスタムルールを作成してみてください。