"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

Windowsアプリのsend_keys()の制約とネストしたエレメントとか/Appium+python

Windowsアプリをpythonから操作するやり方を整理しています。

今回は、send_keysを使った入力で注意すべき制約と、ファイル参照ダイアログの操作とかでネストしたelementの参照したりしてみます。

f:id:arakan_no_boku:20190817094431p:plain

 

今回の記事の前提

 

WinAppDriverやinspect.exeなど、必要なものがインストールされて、動く環境になっていることが前提です。

まだの場合はこちらの記事を参照して、やっといてください。

WinAppDriverの起動方法とかも、この記事にあります。

arakan-pgm-ai.hatenablog.com 

あと、エレメントの参照方法のバリエーションとかの基本情報はこちらの記事にもあります。

 

今回やってみること

 

今回動かしてみるのは、「WinMerge」です。

ファイル・フォルダを複数指定して、内容を比較して、差分をグラフィカルに表示してくれるソフトです。

自動化しようとしている操作はざっくしこんな感じです。

まず、起動します。

起動したらファイル>開くでダイアログを開きます。

f:id:arakan_no_boku:20190825221000p:plain

ファイル選択ダイアログで、1stと2ndに比較するファイルを入力します。

今回は「参照」ボタンで開くダイアログをだして、指定のファイルを選択して開くというのを、2回繰り返します。

f:id:arakan_no_boku:20190825221333p:plain

2回繰り返した結果がこんな感じ。

f:id:arakan_no_boku:20190825221428p:plain

これでOKボタンを押します。

今回は、両方に同じファイルを選択しているので、差異がないと表示されます。

f:id:arakan_no_boku:20190825221553p:plain

ここまでを自動化してやってみようというわけです。

雰囲気的に「オートメーションっぽい・・」感じはしますね。

 

上記を自動実行するpythonソースについて

 

動作環境が整って、WinAppDriverが動いていることが前提です。

ソースコードはこんな感じ。

import unittest
from appium import webdriver


class SampleTests(unittest.TestCase):

    def setUp(self):
        # set up appium
        desired_caps = {}
        # WinMergeを起動
        desired_caps["app"] = 'C:/Program Files/WinMerge/WinMergeU.exe'
        self.driver = webdriver.Remote(
            command_executor='http://127.0.0.1:4723',
            desired_capabilities=desired_caps)

    def tearDown(self):
        # self.driver.quit()
        # 結果画面を確認するためdriverを強制終了しないようにしている
        print("tear down")

    def test_input(self):
        # ファイル>開くのメニューを選択する
        self.driver.find_element_by_name("ファイル(F)").click()
        self.driver.find_element_by_accessibility_id("57601").click()
        # 1stの参照ボタンを押す
        self.driver.find_element_by_accessibility_id('1001').click()
        # 指定ファイルを選択して「開く」ボタンを押す
        self.driver.find_element_by_class_name(
            'UIItemsView').find_element_by_name(
            '20160603_juyo1_kansai.csv').click()
        self.driver.find_element_by_accessibility_id('1').click()
        # 2ndの参照ボタンを押す
        self.driver.find_element_by_accessibility_id('1002').click()
        # 指定ファイルを選択して「開く」ボタンを押す
        self.driver.find_element_by_class_name(
            'UIItemsView').find_element_by_name(
            '20160603_juyo1_kansai.csv').click()
        self.driver.find_element_by_accessibility_id('1').click()
        # OKボタンを押す
        self.driver.find_element_by_name("OK").click()
        # 強制的にOKにしておく
        self.assertTrue(1)


if __name__ == '__main__':
    suite = unittest.TestLoader().loadTestsFromTestCase(SampleTests)
    unittest.TextTestRunner(verbosity=2).run(suite)

なお、各パラメータの値は自分の環境で「inspect.exe」で調べた値です。

たぶん大丈夫と思いますが、環境によって変わる(特に数字の部分)可能性はゼロではないので、一応お断りをいれておきます。

以下、ポイントを補足していきます。

 

send_keys()の制約について

 

本当は、片方は「参照」ボタンにして、片方はWindowsのPathをダイレクトにテキストボックスにsend_keysで入力しようとしました。

f:id:arakan_no_boku:20190825225504p:plain

ところがsend_keysでは、pathがうまく入力できないのです。

まず。

"\" がうまく入力できません。

エラーになったり、"]"に変換されてしまったりします。

なので、c:/xxxx/xxxxx/csv のように"/"(スラッシュ)で指定するように変更してみました。

WinMergeはそれでもいけますから。

そしたら、今度は":"(コロン)が通りません。

残念ながら、回避する方法が現時点ではわかりません。

ということで・・。

両方共参照ボタンを押して選択する方法を選ばざるをえなかった・・という訳です。

 

ネストするエレメント

 

参照ボタンで開くダイアログを開いて、ファイルを選択する部分です。

inspect.exeで確認すると「Name」がファイル名になっているので、単純に以下のようにやってみたところ、エラーになりました。

find_element_by_name( '20160603_juyo1_kansai.csv')

inspect.exeで再確認してみると。

f:id:arakan_no_boku:20190825231709p:plain

どうも「項目ビュー一覧」というビューがあって、その下にファイル名のビューが並んでいるみたいです。

だから、以下のようにネストした形でエレメントを取得しています。

self.driver.find_element_by_class_name( 'UIItemsView').find_element_by_name( '20160603_juyo1_kansai.csv').click()

 UIItemsViewは、項目一覧ビューの「ClassName」です。

 

こんなものかな・・

 

今回は以上です。

わずか2例ほど試行錯誤してみた結果でしかないですが、WinAppDriverを使って、WindowsアプリケーションをPythonで動かすのは、現時点では・・SeleniumでWebアプリを動かすのと似て非なるものだな・・とは思いました。

確かに、Seleniumライクなんですけどね。

Seleniumの感覚で単純にできる・・とは感じませんでした。

あくまで個人的感想ですが。

それに。

やっぱりDriverを動かすのに、都度都度開発者モードに切り替えないといけないのは、ちょっと面倒です。

テストで使うにしても手順が複雑にならざるをえませんし。

とはいえ。

WindowsアプリケーションをPythonでコントロールできるのは、面白いです。

現時点での問題とかは、どんどん解消されていくでしょうしね。

まだまだ、試行錯誤は続けないといけなさそうですが・・、楽しみな機能ではあります。

今回はこんなところで。

ではでは。