リファラによって挙動が変わるWebアプリをRobot Frameworkでテストすることがありました。
Webアプリのコードを書き換えたくないため、なにか良い方法がないかを探したところ、
を組み合わせれば良さそうでした。
その時に試した内容をメモしておきます。
2017/9/2追記
Selenium2Libraryですが、バージョン3からは SeleniumLibrary
へと名称が変更されています。詳しくはこちらに書きました。
RobotFrameworkのSelenium2Libraryの名前が、SeleniumLibraryへと変更されてた - メモ的な思考的な
なお、本文はSelenium2Libraryのままにしてあります。
2017/9/2追記ここまで
目次
環境
- Mac OS X 10.11.6
- Python 3.6.2
- Google Chrome 60.0.3112.78 (stable)
- ChromeDriver 2.31 (stable)
- Referer Control 1.21
- RobotFramework 3.0.2
- robotframework-requests 0.4.7
- Selenium2Library 1.8.1dev1
- Selenium 3.4.3
- Bottle 0.12.13
- Webアプリ用
Seleniumで開くChromeDriverに拡張を入れる
packedとunpacked、どちらの方式の拡張を入れるか
Seleniumで使うChromeDriverに拡張を入れる方法は、ChromeDriverの公式サイトにありました。
Chrome Extensions - ChromeDriver - WebDriver for Chrome
方法としては、
の2つがあるようです。
紹介されているコードはJavaっぽいため、Pythonのコードを探したところ、前者については以下などがありました。
google chrome - Running Selenium WebDriver using Python with extensions (.crx files) - Stack Overflow
一方、後者のDesiredCapabilitiesオブジェクトの setCapability()
メソッドを使う方法を調べてみましたが、それらしい事例はなく、Pythonライブラリのソースコードにもそれらしいメソッドは見当たりませんでした。
selenium/desired_capabilities.py at master · SeleniumHQ/selenium
そこで今回は、前者の crxファイルを使う方法で実装することにしました。
packedな拡張を作成する方法
Chrome拡張がどこにインストールされるかを調べたところ、 ~/Library/Application Support/Google/Chrome
のようでした。
User Data Directory
また、Chrome拡張のID(ディレクトリ名)は、以下を参考にして確認しました。
Google Chrome のアプリや拡張機能、テーマが保存されている場所 - Qiita
そのディレクトリを見たところ、unpackedな状態だったため、何らかの方法で crxファイルを取得する必要がありました。
調べてみたところ、以下のページにpackedな拡張の作り方が記載されていました。
CRX Package Format - Google Chrome
ただ、pemファイルを用意するなどの手間がかかりそうなため、もっと容易な方法を探してみたところ、Chrome拡張のページからcrxファイルを取得するChrome拡張 Get CRX
がありました。
Get CRX - Chrome ウェブストア
試しに Referer Control のページで使ってみたところ、crxファイルが取得できました。
今回はそのファイルを、テストを実行するディレクトリ直下に referer_control.crx
として保存します。
Robot Frameworkで実装する
HeadlessなChromeだとChrome拡張ページが開けないため、今回は普通のChromeを使って実装します。
${options} = evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys # HeadlessだとChrome拡張ページが開けない # call method ${options} add_argument --headless # ${OUTPUT DIR}は、テストを実行するディレクトリ call method ${options} add_extension ${OUTPUT DIR}/referer_control.crx create webdriver Chrome chrome_options=${options}
Referer Controlでリファラを書き換える
上記のままではChrome拡張を入れるだけで何も設定がされないため、Referer Controlの設定を行います。
Referer Controlの設定方法を調べる
以下が参考になりました。
Chromeでリファラ偽装する方法(リファラコントロールの使い方)
Robot Frameworkで実装する
上記の通り、Referer Controlの設定はブラウザから行うため、Robot Frameworkで実装できそうでした。
Robot Frameworkのlocatorに何を使うか悩みましたが、Chrome拡張のHTMLはそれほど変わらないだろうと考えました。
そこで、Chrome Developer Toolを使ってXPathを取得し、それをlocatorとして使いました。*1
あとは、Robot Frameworkで実装します。
今回は http://localhost:8084/referer/target
というURLの場合のみ、リファラを https://www.google.co.jp
へと書き換えるようにしました。
# 「Referer Control」拡張の設定ページを開く go to chrome-extension://hnkcfpcejkafcihlgbojoidoihckciin/chrome/content/options.html wait until page contains element xpath=//*[@id="settingsTable"]/tbody/tr/td[2]/input click element xpath=//*[@id="settingsTable"]/tbody/tr/td[2]/input # site filterに入力する # 今回は、「http://localhost:8084/referer/target」というサイトであればリファラを書き換える input text xpath=//*[@id="settingsTable"]/tbody/tr/td[2]/input http://localhost:8084/referer/target # Customボタンを押す click element xpath=//*[@id="settingsTable"]/tbody/tr/td[8] # Custom refererを入力する(Googleから来たことにする) # 1秒待たないとうまくいかない sleep 1s input text xpath=//*[@id="settingsTable"]/tbody/tr[5]/td[2]/table/tbody/tr[1]/td[1]/input https://www.google.co.jp # 適当なところをクリックして保存 click element xpath=//*[@id="settingsTable"]/tbody/tr/td[2]/input
Bottleアプリの実装と動作確認
Bottleアプリの実装
上記のRobot Frameworkのテストコードが正しく動作するかを確認するため、Bottleアプリを作成して動作を確認します。
今回は、単純にリクエストヘッダの Referer
を表示するだけにします。
target.py
@get('/referer/target') @get('/referer/exclude') def get_referer_target(): referer = request.get_header('Referer') return f'<p id="referer">Referer: {referer}</p>'
Robot Frameworkで動作確認するコードを実装
先ほどのChrome拡張の設定に続いて以下のコードを書きます。
# リファラが書き換わるページへアクセス go to http://localhost:8084/referer/target ${target} = get text id=referer # リファラが書き換わらないページへアクセス go to http://localhost:8084/referer/exclude ${exclude} = get text id=referer # 検証してブラウザを閉じる log to console ${EMPTY} log to console ${target} log to console ${exclude} should not be equal ${target} ${exclude} close browser
動作確認
テストがパスしました。Chrome拡張の設定がうまくいき、リファラが書き換わっているようです。
$ robot selenium_modify_referer_test.robot =================================== Selenium Modify Referer Test =================================== Chrome拡張でリファラを書き換えるテスト Referer: https://www.google.co.jp Referer: None Chrome拡張でリファラを書き換えるテスト | PASS | ...
その他参考
Firefoxを使う場合
Firefoxを使う場合の例が以下にありました。
webdriver - setting request headers in selenium - Stack Overflow
Chromeのコマンドライン・オプション
以下にまとまっていました。
List of Chromium Command Line Switches « Peter Beverloo
OpenSSLでのpemファイル作成
もしpemファイルを作る場合は、以下を参考にします。
ssl - How to create a self-signed certificate with openssl? - Stack Overflow
ソースコード
GitHubに上げました。 selenium2_library_sample/tests/selenium_modify_referer_test.robot
ファイルが今回のテストファイルです。
thinkAmi-sandbox/RobotFramework-sample: Robot Framewrok samples