Photo by Sai Kiran Anagani on Unsplash
こんにちは!
個人開発をしている南です!
今回はPythonでSeleniumを使ってWordPressの自動テストに取り組んでいた時に出てきた、ポップアップ問題に対処した方法をシェアします。
WordPressのブラウザのポップアップ問題とは?
Photo by Olav Ahrens Røtne on Unsplash
WordPressのブラウザのポップアップ問題とは、SeleniumでWordPressに投稿を追加している時に出てくる下記のポップアップが出て処理が止まってしまうという問題です。
WordPressで投稿を詰めたり、ページの更新をしている時に下記のようなポップアップが出てきた止まったことはありませんか?
「このサイトを離れますか?行った変更が保存されない可能性があります。」
このポップの何が問題って、このポップアップが出てくると下記のようにエラーが吐かれてSeleniumの処理が止まってしまうということ。
「unexpected alert open: {Alert text : }」
せっかく自動テストしているのに、毎回これが出てきて処理が止まってしまう。。。
いや、自動テストの意味ないやん!!!
って思ってしまうわけです。
最初はSeleniumの投稿スピードが早すぎるのかと思って、sleep処理を入れて対処していたのですが結局何回も出てきて処理が止まってしまうという自体に。。。
このポップアップに対応する方法
Photo by Gaston Abascal on Unsplash
このポップアップ問題に対処しなければ、先に進めないと思ったのでネットで色々解決方法を調べてみました。
色々調べた結果、下記のようにコードを書いたことで解決することができました!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
publish_btn_path = '//div[@id="publishing-action"]/input[@id="publish"]' publish_btn = self.chrome.find_element_by_xpath(publish_btn_path) try: WebDriverWait( self.chrome, 3 ).until( EC.alert_is_present() ) alert = self.chrome.switch_to.alert alert.accept() print("alert accepted") except TimeoutException: print("no alert") publish_btn.click() |
使っているコードの説明について
Photo by Ilya Pavlov on Unsplash
このコードでは主に次のようなセクションに別れています。
・公開、更新ボタンの要素を取得
・try、exceptで例外処理
・WebDriverWait.untileで要素が出てくるまで待機
・何も問題なければ、公開更新ボタンをクリックして保存
公開、更新ボタンの要素を取得
公開、更新ボタンの要素取得についてはコードの下記の部分です。
1 2 |
publish_btn_path = '//div[@id="publishing-action"]/input[@id="publish"]' publish_btn = self.chrome.find_element_by_xpath(publish_btn_path) |
これは単純にxpathで指定して、find_element_by_xpathで要素を取得しています。
try、exceptで例外処理
お馴染みの例外処理。
このtry,exceptを使うことで、普通に書いていたら致命的なエラーが出て処理が止まるエラーも、止めずにエラーが出た時の処理を書くことができます。
下記のコードでも使用されています。
1 2 3 4 5 6 7 8 |
try: WebDriverWait( self.chrome, 3 ).until( EC.alert_is_present() ) alert = self.chrome.switch_to.alert alert.accept() print("alert accepted") except TimeoutException: print("no alert") |
WebDriverWait.untilで要素が出てくるまで待機
このコードの目玉部分。
実際のコードは下記。
1 2 3 4 5 6 7 8 |
try: WebDriverWait( self.chrome, 3 ).until( EC.alert_is_present() ) alert = self.chrome.switch_to.alert alert.accept() print("alert accepted") except TimeoutException: print("no alert") |
主に次の3つの要素が出てきます。
1.WebDriverWait.until
2.EC.alert_is_present()
3.switch_to.alertとalert.accept()
1.WebDriverWait.untilについて
WebDriverWait.untilはAjaxや外部サービスの処理が原因で、要素が表示されない場合はその要素が表示されるまで待機すると言ったことができるコードです。
使い方的には、下記の通り。
1 |
WebDriverWait(driver(使っているドライバーを指定します。), 3(待機する秒数を指定。この場合は3秒待機) ).until( 待機処理の内容 ) |
2.EC.alert_is_present()
EC.alert_is_present()のECはExpected Condition(想定される状況)の略で、ECになっています。
importする際のasでECとしてあります。
1 2 |
#import部分。 from selenium.webdriver.support import expected_conditions as EC |
alert_is_presentは、アラートが表示されるかチェックする処理になります。
3.switch_to.alertとalert.accept()について
アラートが表示されたらswitch_to.alertでアラートが表示されているウィンドウに、フォーカスを移します。
フォーカスを移すは、単純に現在Seleniumで行っている作業ウィンドウをポップアップのウィンドウに移すという意味です。
ポップアップのウィンドウに移ったら、alert.accept()を使って「このページを離れる」をクリックしてポップアップを閉じるという処理を行っています。
ちなみに、switch_to.alertの他にも親要素のフレームに戻るswitch_to_defaultなど色々あるので、気になる方は下記のドキュメントを見てみてください。
何も問題なければ、公開更新ボタンをクリックして保存
最後に、try exceptの例外処理が終わったので、seleniumのクリック処理で保存、更新ボタンをクリックして更新しています。
1 |
publish_btn.click() |
インポートしているもの
Photo by Clem Onojeghuo on Unsplash
今回使用しているWebDriverWaitやEC.alert_is_present()、例外処理のTimeoutExceptionを使うには、下記のようにそれぞれのクラスをインポートするようにします。
1 2 3 4 |
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.ui import WebDriverWait from selenium.common.exceptions import TimeoutException from selenium.webdriver.support import expected_conditions as EC |
おまけ
僕は、下記のように書いてclick_publish_btn()で固定ページや投稿ページに移動した時は要素を保存できるようにクラス化してあります。
良いなと思った人は、ぜひ同じようにやってみてください。
他にも、いい方法がある場合はぜひ教えてほしいです!笑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#固定ページの公開ボタンをクリックする。 def click_publish_btn(self): publish_btn_path = '//div[@id="publishing-action"]/input[@id="publish"]' publish_btn = self.chrome.find_element_by_xpath(publish_btn_path) try: WebDriverWait(self.chrome, 3).until( EC.alert_is_present() ) alert = self.chrome.switch_to.alert alert.accept() print("alert accepted") except TimeoutException: print("no alert") publish_btn.click() |
まとめ
今回は、WordPressの投稿や固定ページを作る時に出てくるブラウザのポップアップに対処する方法を紹介しました。
テストの処理って書くのめんどくさいのですが、そのうち毎回手動でテストをするめんどくささが勝ってきます。。。
この記事が、同じようにWordPressのポップアップが出てきてしまって、seleniumのエラーが出て困っているというあなたの助けになれば嬉しいです!!