WinAppDriverとPython/Appiumを使ってGUIアプリを自動操作させるときに、下記のことを解決する方法を説明します。Appiumのエレメントがあるかどうかを調べる関数(driver.find_element_by_name(エレメントの名称))が、エレメントがない場合に関数を抜けてくるまでの時間が長い(10秒だったか、それ以上だったかは覚えていない)ので、win32guiライブラリを使ってエレメントがあるかどうかをチェックするようにしました。同様に、エレメントが表示されているかどうかを調べる関数(driver.find_element_by_name(エレメントの名称).is_displayed())も、エレメントが表示されていない場合の処理時間が長すぎて使えないのでwin32guiライブラリを使うようにしました。

こちらのサイトを参考にしました。 → appium + pyautogui + win32gui for python で、excelの保護ビューを解除 – RPAもどき – end0tknr’s kipple – web写経開発 (hateblo.jp)

1.解決したい内容

(1)GUIアプリが起動するのを待つ。

起動中の表示

起動後の表示

(2)GUIアプリが表示したダイアログのボタンを押す。

ログインのダイアログが表示されたので<取消>ボタンを押したい。

新しいバージョンをダウンロードするかどうかのダイアログが表示されたので<いいえ>ボタンを押したい。

Crawl Limit Reachedダイアログが表示されたので、<OK>ボタンを押したい。

2つのダイアログが表示されたので、最前面のダイアログから消去したい。

2.解決方法

(1)Appiumのエレメントがあるかどうかを調べる関数(driver.find_element_by_name(エレメントの名称))が、エレメントがない場合に関数を抜けてくるまでの時間が長い(10秒だったか、それ以上だったかは覚えていない)ので、win32guiライブラリを使ってエレメントがあるかどうかをチェックするようにしました。

<Appium版(解決前)>

#*********************************************************************
#*** 指定した名称がある場合はクリックする
#*** 表示されていない場合は、何もしない
#*********************************************************************
def 指定した名称がある場合はクリックする(エレメントの名称,クリックするエレメント名):
    # エレメントの名称があるかどうかをチェックする
    try:
        el=driver.find_element_by_name(エレメントの名称)
    # 例外(エラー)発生時
    except:
        pass
    # 例外(エラー)が発生しない場合
    else:
   # エレメントの名称がある場合は、クリックする
        driver.find_element_by_name(クリックするエレメント名).click()

(2)エレメントが表示されているかどうかを調べる関数(driver.find_element_by_name(エレメントの名称).is_displayed())が、エレメントが表示されていない場合の処理時間が長すぎて使えないのでwin32guiライブラリを使うようにしました。

<Appium版(解決前)>

#*********************************************************************
#*** 指定した名称のエレメントが表示されている場合はクリックする
#*** 表示されていない場合は、何もしない
#*********************************************************************
def 指定した名称のエレメントが表示されている場合はクリックする(エレメントの名称):
    # エレメントが表示されているかどうかをチェックする
    try:
        status=driver.find_element_by_name(エレメントの名称).is_displayed()
    # 例外(エラー)発生時
    except:
        pass
    # 例外(エラー)が発生しない場合
    else:
    # エレメントが表示されている場合は、クリックする
        if status==True:
            driver.find_element_by_name(エレメントの名称).click()

 

(1)と(2)の解決策

Win32GUIを使って、アクティブWindowタイトル名と最前面のWindowタイトル名を取得する。

Appiumを使って、エレメントを見つけてクリックする。

<Win32GUI版(解決後)>

win32gui.FindWindow(None, ‘New Version Available’)を使って、Windowタイトルが一致していることを確認してから、Appiumで指定したボタンをクリックする。

最前面のウィンドウのウィンドウハンドルを取得(app_handle = win32gui.GetForegroundWindow())し、
最前面のウィンドウのタイトル名を取得(p_handle_name = win32gui.GetWindowText(app_handle))し、
目的のタイトルの場合は、GUIアプリが起動したと判断する。