目的
- Adobe Flashで作成されたサイトのUIの自動テストがしたい.
- http://www.adobe.com/jp/products/flashplayer.html
- 主に,Click,Drag & Drop, Double Clickなど.
問題点
- Web Browserの自動テスト=Seleniumを使う,という安直な思考でSelenium Pythonを選択する.
- しかしながら,FlashはHTML上一つのオブジェクトとしてみなされるため,その子供の要素を指定する方法がSeleniumにはない.
解決案
- Selenium Web Driver APIにmove_to_element_with_offset(to_element, xoffset, yoffset)というMethodがある.これを利用できないか
手順
- Flashゲーム・艦隊これくしょんを例にして実装方法を説明する.
- なお,今回は例に用いただけで,実際のゲームに対して行ってはいけません.
- Seleniumで画面のScreenShotを取得する.
- 予め用意しておいたReference画像から,OpenCVを用いてTemplate Matcingを用いて対象の座標位置(x, y)を取得する
- 基準となるHTML Element(今回は会社のロゴ)を指定
- 指定したHTML Elementから対象の座標位置との距離を比較し,offset値を決定,先ほどのMethodを利用して実行する.
実装
-
今回は単純なClick動作だけを実装する.
- なお,Selenium Python APIにはDrag & DropやDouble Clickなども実装されているため,本手法を応用すれば十分に実用が可能ではないかと考えられる.面倒くさいからやらないけど.
-
なお,今回はBrowserの起動, OpenCVによるTemplate Matchingについての処理は割愛し,あくまで手順の3-4についての実装になる.その他の実装方法については各Webサイト等を確認して下さい.
click.py
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
class Browser(object):
...
def click(self, element, x, y):
"""
element : Target HTML Element
x : offset_x
y : offset_y
"""
self.driver = webdriver.Firefox()
target = self.driver.find_element_by_id(element)
off_x = int(target.size["width"]) / 2
off_y = int(target.size["height"]) / 2
actions = ActionChains(self.driver)
actions.move_to_element(target)
actions.move_by_offset(x - off_x, y - off_y)
actions.click()
actions.move_to_element(target)
actions.perform()
...
- ActionChainsを用いて一連の動作を登録・実行している.
- Elementを指定した場合,Elementの中心をClickする仕様になっているみたいなので微調整を行う.
- 最後に指定したElementに再度moveしているのは,そのままにしておくとMouseOver判定を食らう可能性があるから.
結論
- なんかもっと楽に出来る方法がありそうな気がするけれども.