[翻訳] RSelenium vignette: RSeleniumの基本

  • 11
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

この文書は John Harrison によるRパッケージ RSelenium (version 1.4.0) のビネット "RSelenium basics" の翻訳です.
ただし文中の注は全て訳者によるものです.

License: AGPL-3


RSeleniumの基本

はじめに

RSeleniumの目的は,RからSeleniumサーバやリモートSeleniumサーバへの接続を容易にすることです.RSeleniumはSelenium WebDriver APIのRバインディングを提供します.Seleniumはwebブラウザの自動化を中心とするプロジェクトです.RSeleniumによって,webアプリやwebページの単体テストや回帰テストを様々なブラウザとOSの組み合わせに対して実行することができます.これにより,shiny, sauceLabsといった人気のあるプロジェクトのテストと操作をRの中から統合的に行えるようになります.

このビネットは6つの節に分かれています.

それぞれの節はSeleniumの主要なアイディアへの入門となっており,他のビネットでのより詳細な解説への案内が付いています.

Seleniumサーバへの接続

Seleniumサーバって何?

Seleniumサーバは様々なブラウザでHTMLテストスイートを実行し,オプションとしてレポーティング等も可能なスタンドアロンのJavaプログラムです.Selenium WebDriver (Rselenium)を使う目的によっては,Seleniumサーバを実行することが必要なこともそうでないこともあります.

Seleniumサーバを実行する必要ある?

RSeleniumを実行しているのと同じマシンでブラウザを操作するつもりなら,そのマシンでSeleniumサーバを実行する必要があります.

Seleniumサーバのスタンドアロンバイナリはどうやって入手するの?

RSeleniumにはスタンドアロンのJavaバイナリをダウンロードしてRSeleniumパッケージの/bin/ディレクトリに配置する関数が組み込まれています.他の場所にバイナリをインストールしたければ,この関数のdir引数を使います.また,既存のバイナリを更新することもできます.

RSelenium::checkForServer()

もし手動でバイナリをダウンロードしたい場合,現在はここからダウンロードできます.selenium-server-standalone-x.xx.x.jarを探してください.

Seleniumサーバはどうやって実行するの?

RSeleniumにはSeleniumサーバのスタンドアロンバイナリを実行するためのユーティリティ関数が含まれています.1

# RSelenium::startServer()
srv <- RSelenium::startServer()

デフォルトの設定ではRSeleniumパッケージの/bin/ディレクトリにバイナリを探しに行きます.バイナリが別の場所にある場合はdir引数で選択できます.また,手動でバイナリを実行することもできます.OSのコンソールを開き,バイナリのある場所に行って実行してください.

java -jar selenium-server-standalone-x.xx.x.jar

デフォルトの設定ではSeleniumサーバはポート4444で接続を待ち受けます.

実行中のサーバにはどうやって接続するの?

RSeleniumにはremoteDriverという名前の主要な参照クラスがあります.サーバに接続するためには適切なオプションを与えて新たなremoteDriverインスタンスを作成する必要があります.

# RSelenium::startServer() (必要であれば)
require(RSelenium)
remDr <- remoteDriver(
  remoteServerAddr = "localhost",
  port = 4444,
  browserName = "firefox"
)

この場合にはremDr <- remoteDriver()を呼ぶだけでもよかったのですが,任意のIPアドレス・ポート・ブラウザに接続する方法を示すために明示的にオプションを指定しています.さらなる詳細はsourceLabsビネットで見つけられるでしょう.サーバに接続するにはopenメソッドを使います.

remDr$open()

これでRSeleniumがSeleniumサーバに接続されているはずです.リモートサーバの状態はgetStatusメソッドで問い合わせることができます.

remDr$getStatus()
## $build
## $build$version
## [1] "2.53.1"
## 
## $build$revision
## [1] "a36b8b1"
## 
## $build$time
## [1] "2016-06-30 17:37:03"
## 
## 
## $os
## $os$name
## [1] "Windows 7"
## 
## $os$arch
## [1] "x86"
## 
## $os$version
## [1] "6.1"
## 
## 
## $java
## $java$version
## [1] "1.8.0_101"

RSeleniumを使ったページ移動

基本的な移動

まずはURLへ移動してみます.

remDr$navigate("http://www.google.com/ncr")

次に二つめのページに移動します.

remDr$navigate("http://www.bbc.co.uk")

goBackメソッドとgoForwardメソッドを使ってページを戻ったり進んだりできます.

remDr$goBack()
remDr$getCurrentUrl()
## [[1]]
## [1] "https://www.google.com/#gws_rd=ssl"
remDr$goForward()
remDr$getCurrentUrl()
## [[1]]
## [1] "http://www.bbc.com/"

現在のページを更新するにはrefreshメソッドが使えます.

remDr$refresh()

DOM要素へのアクセス

DOMとはドキュメント・オブジェクト・モデル(Document Object Model)のことを表しています.DOMはHTML,XHTML,XMLのオブジェクトを表現し操作するための,クロスプラットフォームで言語に依存しない規約です.DOMの操作はSeleniumを使う我々にとって非常に重要です.WebDriverはDOM操作のための多くのメソッドを提供します.基本的なHTMLページは以下のようになっています.

<!DOCTYPE html>
<html>
<body>

<h1>My First Heading</h1>

<p>My first paragraph.</p>

</body>
</html>

http://www.google.comのフロントページにある検索フォームにはinput id="lst-ib" class="gsfi"というHTMLのコードが関連付けられています.inputタグに関連付けられたHTMLの全体は以下のようになっています.2

<input class="gsfi" id="lst-ib" maxlength="2048" name="q" autocomplete="off" title="Search" type="text" value="" aria-label="Search" aria-haspopup="false" role="combobox" aria-autocomplete="both" style="border: none; padding: 0px; margin: 0px; height: auto; width: 100%; position: absolute; z-index: 6; left: 0px; outline: none; background: url(&quot;data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw%3D%3D&quot;) transparent;" dir="ltr" spellcheck="false">

idで検索する

この要素をDOMの中で見つけるには様々な方法が使えます.
まずidで検索することができます.

remDr$navigate("http://www.google.com/ncr")
webElem <- remDr$findElement(using = 'id', value = "lst-ib")
webElem$getElementAttribute("id")
## [[1]]
## [1] "lst-ib"
webElem$getElementAttribute("class")
## [[1]]
## [1] "gsfi lst-d-f"

classで検索する

classの名前でも検索することができます.

webElem <- remDr$findElement(using = 'class name', "gsfi")
webElem$getElementAttribute("class")
## [[1]]
## [1] "gsfi lst-d-f"
webElem$getElementAttribute("type")
## [[1]]
## [1] "text"

cssセレクタを使って検索する

cssセレクタを使う場合,classは.を用いて表現されます.cssセレクタを使ってclassで検索するなら以下のようになるでしょう.

webElem <- remDr$findElement(using = 'css selector', "input.gsfi")

また,cssセレクタを使ってidで検索するなら以下のようにします.

webElem <- remDr$findElement(using = 'css selector', "input#lst-ib")

cssセレクタを使った検索の良い例がここにあります.

nameで検索する

nameが与えられている場合に,これを使って検索するには以下のようにします.与えられたHTMLページでidはユニークですが,nameは必ずしもユニークにならないことに注意してください.

webElem <- remDr$findElement(using = 'name', "q")
webElem$getElementAttribute("name")
## [[1]]
## [1] "q"
webElem$getElementAttribute("id")
## [[1]]
## [1] "lst-ib"

xpathを使って検索する

最後の検索方法はxpathを使うものです.通常,デフォルトではxpathを使って検索することになります.xpathでidを使って検索するには次のようにします.

webElem <- remDr$findElement(using = 'xpath', "//*/input[@id = 'lst-ib']")

xpathでclassを使う場合は以下のようになります.

webElem <- remDr$findElement(using = 'xpath', "//*/input[@class = 'gsfi']")

DOM要素にイベントを送信する

DOM要素とやりとりする方法を示すため,再びhttp://www.google.com/ncrを例に取ります.

DOM要素にテキストを送信する

googleでR Cranを検索したいとしましょう.それには検索フォームの要素を見つけて適切なテキストをそこに送る必要があります.webElementクラスのsendKeysToElementメソッドを使えばこれが可能です.

remDr$navigate("http://www.google.com/ncr")
webElem <- remDr$findElement(using = "xpath", "//*/input[@id = 'lst-ib']")
webElem$sendKeysToElement(list("R Cran"))

キーの押下をDOM要素に送信する

さて,検索フォームにR Cranと入力されたのが見えているはずですが,Enterキーはどうやって押したらよいでしょうか.単に検索フォームにEnterキーを送信すればよいのです.Enterキーは"\uE007"で表現されるので,以下のようにできます.

remDr$navigate("http://www.google.com/ncr")
webElem <- remDr$findElement(using = "xpath", "//*/input[@id = 'lst-ib']")
webElem$sendKeysToElement(list("R Cran", "\uE007"))

適切なキーのUTF8コードを記憶しておくのはあまり簡単ではないので,RSeleniumではキーとUTF8コードの変換表を提供しています.?selKeysと入力すれば変換表について解説したヘルプページが開きます.selKeysではここに書かれているUTF8のコードが覚えやすい名前に変換されています.

selKeysを使うには,以下のようにしてキーを送信します.

remDr$navigate("http://www.google.com/ncr")
webElem <- remDr$findElement(using = "xpath", "//*/input[@id = 'lst-ib']")
webElem$sendKeysToElement(list("R Cran", key = "enter"))

selKeysとタイプすればコンソールに変換表のリストが表示されます.

マウスのイベントをDOM要素に送信する

以下の例では,googleのフロントページに戻ってR Cranを検索した後,The Comprehensive R Archive Networkへのリンクをクリックします.

remDr$navigate("http://www.google.com/ncr")
webElem <- remDr$findElement(using = "xpath", "//*/input[@id = 'lst-ib']")
webElem$sendKeysToElement(list("R Cran", key = "enter"))

検索結果が含まれているのは<div class="g">要素であり,findElementsメソッドを使えば1ページ目の検索結果の全てのエントリを見つけることができます.さらに,各リンクのヘッダは<h3 class = "r">タグに含まれています,まずはh3ヘッダにアクセスします.cssセレクタを使って要素を見つけるのが簡潔です.

webElems <- remDr$findElements(using = 'css selector', "div.g h3.r")
resHeaders <- unlist(lapply(webElems, function(x){x$getElementText()}))
resHeaders
##  [1] "The Comprehensive R Archive Network"       
##  [2] "Download R for Windows"                    
##  [3] "Contributed Packages"                      
##  [4] "CRAN"                                      
##  [5] "R for Windows"                             
##  [6] "R for Mac OS X"                            
##  [7] "CRAN - Mirrors"                            
##  [8] "R: The R Project for Statistical Computing"
##  [9] "The Comprehensive R Archive Network"       
## [10] "CRAN - Package evaluate"                   
## [11] "CRAN - Package backtest"                   
## [12] "CRAN - Package bit"                        
## [13] "CRAN - Package bitops"

最初のリンクが欲しいものであることがわかりますが,googleの検索結果が変わった場合に備えて,以下のようにしてアクセスします3

# webElem <- webElems[[which(resHeaders == "The Comprehensive R Archive Network")]]
webElem <- webElems[[which(resHeaders == "The Comprehensive R Archive Network")[1]]]

クリックはどうすればよいかというと,clickElementメソッドが使えます.

webElem$clickElement()
remDr$getCurrentUrl()
## [[1]]
## [1] "https://www.google.com/#q=R+Cran"
remDr$getTitle()
## [[1]]
## [1] "R Cran - Google Search"

JavaScriptを注入する

時には現在のURLとJavaScriptを使ってやりとりする必要があります.これが必要になるのは,特定の目的のために書かれたメソッドを呼ぶためかもしれませんし,JQueryライブラリがページにない場合にこれを加えてよりページを制御しやすくするためかもしれません.SeleniumにはJavaScriptを実行するのに使えるremoteDriverクラスの2つのメソッド,すなわちexecuteScriptexecuteAsyncScriptとがあります.googleのフロントページに戻ってこれらのメソッドについて調べてみましょう.

同期的にJavaScriptを注入する

googleのホームページに戻ると,googleの画像の要素が見つかります.この画像はid = "hplogo"となっており,これをxpathやid等による検索で要素を選択するのに使うことができます.今回はcssセレクタを使って選択します.

remDr$navigate("http://www.google.com/ncr")
webElem <- remDr$findElement("css selector", "img#hplogo")
remDr$executeScript("return document.getElementById('hplogo').hidden;", args = list())
## [[1]]
## [1] FALSE

うまくいきました.FALSEが示している通り,画像は隠されてはいません.簡単なJavaScriptを実行すれば画像を隠すことができます.

remDr$executeScript("document.getElementById('hplogo').hidden = true;", args = list())
## [[1]]
## [1] FALSE
remDr$executeScript("return document.getElementById('hplogo').hidden;", args = list())
## [[1]]
## [1] TRUE

こうして画像が隠れました.ここではid = "hplogo"で与えられる要素を使いました.要素にアクセスするにはJavaScriptのgetElementByID関数を使う必要がありましたが,もしさきほど特定しておいたwebElemが使えればもっと便利でしょう.webElementオブジェクトをexecuteScriptexecuteAsyncScriptに引数として渡すと,RSeleniumはこれを適切な形式にしてJavaScriptに渡してくれます.

remDr$executeScript(script = "return arguments[0].hidden = false;", args = list(webElem))
## [[1]]
## [1] FALSE

executeScriptメソッドへのwebElementの渡し方に注目してください.script引数は実行するスクリプトを関数のボディの形式で定義します.この関数が返す値はクライアントに返されます.関数は与えられたargs引数とともに呼び出されます.もし関数がDOM要素を返すものであれば,webElementクラスのオブジェクトとして返されます.

test <- remDr$executeScript("return document.getElementById('lst-ib');", args = list())
test[[1]]
## [1] "remoteDriver fields"
## $remoteServerAddr
## [1] "localhost"
## 
## $port
## [1] 4444
## 
## $browserName
## [1] "firefox"
## 
## $version
## [1] ""
## 
## $platform
## [1] "ANY"
## 
## $javascript
## [1] TRUE
## 
## $autoClose
## [1] FALSE
## 
## $nativeEvents
## [1] TRUE
## 
## $extraCapabilities
## list()
## 
## [1] "webElement fields"
## $elementId
## [1] "20"
class(test[[1]])
## [1] "webElement"
## attr(,"package")
## [1] "RSelenium"

非同期的にJavaScriptを注入する

非同期呼び出しと同期呼び出しについてここで簡単に触れておきます.著者の場合,現在のFirefoxとSeleniumサーバの組み合わせ(Firefox 26.0, Selenium server 2.39.0)において,非同期JavaScript呼び出しでnativeEvents = TRUE (デフォルトの設定)とした時に問題が発生しました.

以下の例ではnativeEvents = FALSEと設定しました.

remDr <- remoteDriver(nativeEvents = FALSE)
remDr$open()
## [1] "Connecting to remote server"
## $applicationCacheEnabled
## [1] TRUE
## 
## $rotatable
## [1] FALSE
## 
## $handlesAlerts
## [1] TRUE
## 
## $databaseEnabled
## [1] TRUE
## 
## $version
## [1] "41.0.2"
## 
## $platform
## [1] "WINDOWS"
## 
## $nativeEvents
## [1] FALSE
## 
## $acceptSslCerts
## [1] TRUE
## 
## $webdriver.remote.sessionid
## [1] "1b3c6552-7483-4442-a6cb-03a8db6bb73c"
## 
## $webStorageEnabled
## [1] TRUE
## 
## $locationContextEnabled
## [1] TRUE
## 
## $browserName
## [1] "firefox"
## 
## $takesScreenshot
## [1] TRUE
## 
## $javascriptEnabled
## [1] TRUE
## 
## $cssSelectorsEnabled
## [1] TRUE
## 
## $id
## [1] "1b3c6552-7483-4442-a6cb-03a8db6bb73c"
remDr$navigate("http://www.google.com/ncr")
remDr$setAsyncScriptTimeout(10000)

以下の2つのコードを比べてみてください4

remDr$executeAsyncScript("setTimeout(function(){ alert('Hello'); arguments[arguments.length -1]('DONE');},5000); ", args = list())
remDr$executeScript("setTimeout(function(){ alert('Hello');},5000); return 'DONE';", args = list())

非同期バージョンではコールバック(最後の引数で定義されています)が呼ばれるまで待機します.

フレームとウィンドウ

webブラウザの文脈では,フレームとはwebページやブラウザのウィンドウの一部分であって,自身のコンテナとは独立にコンテンツを表示し,ロードできるもののことです.

Seleniumにおけるフレーム

フレームとのやりとりを例で示します.Rプロジェクトのページは好都合なことにフレームを含んでいるので,RSeleniumを使ってやりとりしてみます5remoteDriverは開いてあるものとします.

remDr$navigate("http://cloud.r-project.org/")
htmlParse(remDr$getPageSource()[[1]])
## <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
## <html xmlns="http://www.w3.org/1999/xhtml">
## <head>
## <title>The Comprehensive R Archive Network</title>
## <meta content="text/html; charset=utf-8" http-equiv="content-type">
## <link type="image/x-icon" href="favicon.ico" rel="icon">
## <link type="image/x-icon" href="favicon.ico" rel="shortcut icon">
## <link href="R.css" type="text/css" rel="stylesheet">
## </head>
## <frameset style="border: none;" cols="1*, 4*">
## <frameset rows="120, 1*">
## <frame frameborder="0" name="logo" src="logo.html">
## <frame frameborder="0" name="contents" src="navbar.html">
## </frameset>
## <frame frameborder="0" name="banner" src="banner.shtml">
## <noframes>
## &lt;h1&gt;The Comprehensive R Archive Network&lt;/h1&gt;
## 
## Your browser seems not to support frames,
## here is the &lt;A href="navbar.html"&gt;contents page&lt;/A&gt; of CRAN.
## </noframes>
## </frameset>
## </html>
## 

3つのフレームにコンテンツが含まれていることが分かりますが,フレームの中のコンテンツにはアクセスできないようです.見ているブラウザの中に全てのコンテンツを表示させてみます.

remDr$maxWindowSize()
remDr$screenshot(display = TRUE)

tmpScreenShot-ja.png

フレームの中のコンテンツにアクセスするにはremoteDriverクラスのswitchToFrameメソッドを使ってフレームを切り替える必要があります.

webElems <- remDr$findElements(using = "tag name", "frame")
# webElems <- remDr$findElements("//frame") # xpathを使う場合

sapply(webElems, function(x){x$getElementAttribute("src")})
## [[1]]
## [1] "https://cloud.r-project.org/logo.html"
## 
## [[2]]
## [1] "https://cloud.r-project.org/navbar.html"
## 
## [[3]]
## [1] "https://cloud.r-project.org/banner.shtml"
remDr$switchToFrame(webElems[[2]])  

htmlParse(remDr$getPageSource()[[1]])
## <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
## <html xmlns="http://www.w3.org/1999/xhtml">
## <head>
## <title>R Contents</title>
## <meta content="text/html; charset=utf-8" http-equiv="content-type">
## <link href="R.css" type="text/css" rel="stylesheet">
## </head>
## <body>
## 
## <em class="navigation">CRAN</em><br><a target="banner" href="mirrors.html">Mirrors</a><br><a target="banner" href="//www.R-project.org/news.html">What's new?</a><br><a target="banner" href="web/views/">Task Views</a><br><a target="banner" href="search.html">Search</a><br><!--<a href="pkg_submit.html" target="_top">Submit</a><BR>--><p>
## <em class="navigation">About R</em><br><a target="_top" href="//www.R-project.org/">R Homepage</a><br><a target="_top" href="http://journal.R-project.org/">The R Journal</a>
## 
## </p>
## <p>
## <em class="navigation">Software</em><br><a target="banner" href="sources.html">R Sources</a><br><a target="banner" href="bin/">R Binaries</a><br><a target="banner" href="web/packages/">Packages</a><br><a target="banner" href="other-software.html">Other</a>
## 
## </p>
## <p>
## <em class="navigation">Documentation</em><br><a target="banner" href="manuals.html">Manuals</a><br><a target="banner" href="faqs.html">FAQs</a><br><a target="banner" href="other-docs.html">Contributed</a><br></p>
## </body>
## </html>
## 

こうして案内用のサイドパネルのソースコードが見えるようになりました.switchToFrameメソッドにおけるwebElementの使い方に注目してください.今このフレームの「中に」いることをさらに明らかにするために,全てのhref属性を取得してみましょう.

webElems <- remDr$findElements("css selector", "[href]")
unlist(sapply(webElems, function(x){x$getElementAttribute("href")}))
##  [1] "https://cloud.r-project.org/R.css"              
##  [2] "https://cloud.r-project.org/mirrors.html"       
##  [3] "https://www.r-project.org/news.html"            
##  [4] "https://cloud.r-project.org/web/views/"         
##  [5] "https://cloud.r-project.org/search.html"        
##  [6] "https://www.r-project.org/"                     
##  [7] "http://journal.r-project.org/"                  
##  [8] "https://cloud.r-project.org/sources.html"       
##  [9] "https://cloud.r-project.org/bin/"               
## [10] "https://cloud.r-project.org/web/packages/"      
## [11] "https://cloud.r-project.org/other-software.html"
## [12] "https://cloud.r-project.org/manuals.html"       
## [13] "https://cloud.r-project.org/faqs.html"          
## [14] "https://cloud.r-project.org/other-docs.html"

switchToFrameメソッドにNULLを渡せばデフォルトのビューに戻ることに注意してください.

remDr$switchToFrame(NULL)
htmlParse(remDr$getPageSource()[[1]])
## <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
## <html xmlns="http://www.w3.org/1999/xhtml">
## <head>
## <title>The Comprehensive R Archive Network</title>
## <meta content="text/html; charset=utf-8" http-equiv="content-type">
## <link type="image/x-icon" href="favicon.ico" rel="icon">
## <link type="image/x-icon" href="favicon.ico" rel="shortcut icon">
## <link href="R.css" type="text/css" rel="stylesheet">
## </head>
## <frameset style="border: none;" cols="1*, 4*">
## <frameset rows="120, 1*">
## <frame frameborder="0" name="logo" src="logo.html">
## <frame frameborder="0" name="contents" src="navbar.html">
## </frameset>
## <frame frameborder="0" name="banner" src="banner.shtml">
## <noframes>
## &lt;h1&gt;The Comprehensive R Archive Network&lt;/h1&gt;
## 
## Your browser seems not to support frames,
## here is the &lt;A href="navbar.html"&gt;contents page&lt;/A&gt; of CRAN.
## </noframes>
## </frameset>
## <body><canvas id="fxdriver-screenshot-canvas" style="display: none;" width="1824" height="1009"></canvas></body>
## </html>
## 

最後になりましたが,名前を使ってメインパネルに切り替えることができます.

remDr$switchToFrame("banner")
htmlParse(iconv(remDr$getPageSource()[[1]], from="UTF-8"))
## <!DOCTYPE html PUBLIC "-//IETF//DTD HTML//EN">
## <html xmlns="http://www.w3.org/1999/xhtml">
## <head>
## <title>The Comprehensive R Archive Network</title>
## <link href="R.css" type="text/css" rel="stylesheet">
## </head>
## <body>
## 
## <h1>The Comprehensive R Archive Network</h1>
## 
## <div align="center">
## <table width="80%" border="1"><tbody>
## <tr>
## <td>
## <h3>Download and Install R</h3>
##       Precompiled binary distributions of the base system and
##       contributed packages, <strong>Windows and
##       Mac</strong> users most likely want one of these versions of R:
##  <ul>
## <li><a href="bin/linux/">Download R for Linux</a></li>
##    <li>
## <a href="bin/macosx/">Download R for (Mac) OS X</a>
##    </li>
## <li><a href="bin/windows/">Download R for Windows</a></li>
##  </ul>
##     R is part of many Linux distributions, you should check with your Linux package management system in addition to the link above.
##     </td>
##   </tr>
## <tr>
## <td>
## <h3>Source Code for all Platforms</h3>
##       Windows and Mac users most likely want to download the
##       precompiled binaries listed in the upper box, not the source
##       code. The sources have to be compiled before you can use
##       them. If you do not know what this means, you probably do not
##       want to do it!
##  <ul>
## <li>The latest release (Tuesday 2016-06-21, Bug in Your Hair)
##        <a href="src/base/R-3/R-3.3.1.tar.gz">R-3.3.1.tar.gz</a>, read
##        <a href="doc/manuals/r-release/NEWS.html">what's new</a> in the latest
##        version.<p>
##        </p>
## </li>
## <li>Sources of
##    <a href="src/base-prerelease/">R alpha and beta releases</a>
##    (daily snapshots, created only in time periods before a planned release).</li>
##    <p>
##    </p>
## <li>Daily snapshots of current patched and development
##               versions are 
##        <a target="_blank" href="https://stat.ethz.ch/R/daily">available
## here</a>. Please read about <a href="doc/manuals/r-devel/NEWS.html">new features and bug
## fixes</a> before filing corresponding feature requests or bug reports.</li>
## <p>
##    </p>
## <li>Source code of 
##    older versions of R is <a href="src/base/">available here</a>.<p>
##        </p>
## </li>
## <li>Contributed extension
##    <a href="web/packages/index.html">packages</a>
## 
##  </li>
## </ul>
## </td>
##   </tr>
## <tr>
## <td>
## <h3>Questions About R</h3>
##       <ul><li>
##       If you have questions about R like how to download and install
##       the software, or what the license terms are,
##       please read our <a href="faqs.html">answers to frequently asked
##       questions</a> before you send an email.
##  </li></ul>
## </td>
##   </tr>
## </tbody></table>
## </div>
## 
## <h2>What are R and CRAN?</h2>
## 
## <p> R is ツ‘GNU Sツ’, a freely available language and environment for
## statistical computing and graphics which provides a wide variety of
## statistical and graphical techniques: linear and nonlinear modelling,
## statistical tests, time series analysis, classification, clustering,
## etc. Please consult the <a target="_top" href="https://www.R-project.org/">R project homepage</a> for further information.
## </p>
## 
## <p> CRAN is a network of ftp and web servers around the world that
## store identical, up-to-date, versions of code and documentation for
## R. Please use the CRAN <a href="mirrors.html">mirror</a> nearest to you to minimize network
## load.
## </p>
## 
## <h2 id="submitting">Submitting to CRAN </h2>
## 
## <p>
## To ツ“submitツ” a package to CRAN,
## check that your submission meets the
## <a href="https://CRAN.R-project.org/web/packages/policies.html">CRAN
##   Repository Policy</a> and then use the
## <a href="https://xmpalantir.wu.ac.at/cransubmit/">web form</a>.
## </p>
## 
## <p>
## If this fails, upload to
## <a target="_blank" href="ftp://CRAN.R-project.org/incoming/">ftp://CRAN.R-project.org/incoming/</a>
## and send an email to
## <a href="mailto:CRAN@R-project.org">CRAN@R-project.org</a> following the policy.
## Please do not attach submissions to emails, because this will clutter up
## the mailboxes of half a dozen people.
## </p>
## 
## <p>
## Note that we generally do not accept submissions of precompiled
## binaries due to security reasons. All binary distribution listed above
## are compiled by selected maintainers, who are in charge for all
## binaries of their platform, respectively.
## </p>
## 
## <p>
## </p>
## <hr>
## <!--#if expr="$CRAN_HOST" --><!--#echo  encoding="none" var="CRAN_HOST"--><br><!--#endif -->
## </body>
## </html>
## 

Seleniumにおけるウィンドウ

RSeleniumにおけるウィンドウについて説明するには,やはり例を見るのが最も簡単です.Rプロジェクトのウェブサイトを例に使います.まずメインのフレームのDownload R要素を選択します.

remDr$navigate("http://cloud.r-project.org")
remDr$switchToFrame("banner")
webElem <- remDr$findElement("partial link text", "Download R")

webElem$getElementText()
## [[1]]
## [1] "Download R for Linux"

それから,この要素が指し示しているリンクを新しいウィンドウで開くためのキーの組み合わせを送信します.もし手動でやるとすれば,マウスをこの要素まで移動させ,リンクを右クリックし,下向き矢印を2回押してからEnterを押すことになるでしょうが,これと同じことをやります.

loc <- webElem$getElementLocation()

loc[c('x','y')]
## $x
## [1] 197
## 
## $y
## [1] 124
remDr$mouseMoveToLocation(webElement = webElem) # マウスを選択した要素に移動
remDr$click(2) # 2はマウスの右クリックを表す
remDr$sendKeysToActiveElement(list(key = 'down_arrow', key = 'down_arrow', key = 'enter'))

リモートブラウザで新しいウインドウが開かれたことに注目してください.

remDr$getCurrentWindowHandle()
## [[1]]
## [1] "{cc17d1d7-d0b9-4f82-99c3-6d2322b5506b}"
remDr$getWindowHandles()[[1]][2]
## [1] "{d12548bb-3bad-4d0d-b494-ccde0bc508f1}"
remDr$getTitle()
## [[1]]
## [1] "The Comprehensive R Archive Network"
remDr$switchToWindow(remDr$getWindowHandles()[[1]][2])
remDr$getTitle()
## [[1]]
## [1] "Index of /bin/linux"

上記のコードによって,リモートブラウザの異なるウィンドウ間を切り替える方法が分かります.6


  1. 原文ではstartServer()の戻り値を捨てているが,戻り値のオブジェクトにはSeleniumサーバを停止するためのstop()メソッドが含まれるので,戻り値を捨てない方がよいと思う(さもないとRの外でサーバプロセスを停止する必要がある). 

  2. 例に使われているgoogle.comの構造は原文が書かれた頃から変化しているため,以下では訳者の環境で意図した動作をするようにコードを適宜変更している. 

  3. 原文のコードではwhich(resHeaders == "The Comprehensive R Archive) Network"が2つ以上の要素を返すとエラーとなるため,1番目の要素を使用するようコードを変更している. 

  4. 訳者の環境では2つのコードは両方とも下記のようなエラーとなった. 

    Error: Summary: UnexpectedAlertOpen
    Detail: A modal dialog was open, blocking this operation
    class: org.openqa.selenium.UnhandledAlertException
    
  5. 現在ではhttp://www.r-project.org/にフレームがないため,以下の例では代わりにCRANミラーのひとつhttp://cloud.r-project.org/を例として使用し,コードも適切に動作するよう適宜原文から変更している. 

  6. 作業が終わった後にremoteDriverを閉じてSeleuniumサーバを停止するには,以下のコードを実行する.. 

    remDr$close()
    srv$stop()
    

    最後に訳者の環境を示しておく.

    devtools::session_info()
    
    ## Session info --------------------------------------------------------------
    
    ##  setting  value                       
    ##  version  R version 3.2.5 (2016-04-14)
    ##  system   x86_64, mingw32             
    ##  ui       RTerm                       
    ##  language (EN)                        
    ##  collate  Japanese_Japan.932          
    ##  tz       Asia/Tokyo                  
    ##  date     2016-08-30
    
    ## Packages ------------------------------------------------------------------
    
    ##  package       * version  date       source        
    ##  bitops        * 1.0-6    2013-08-17 CRAN (R 3.2.3)
    ##  caTools         1.17.1   2014-09-10 CRAN (R 3.2.5)
    ##  devtools        1.11.1   2016-04-21 CRAN (R 3.2.5)
    ##  digest          0.6.9    2016-01-08 CRAN (R 3.2.5)
    ##  evaluate        0.9      2016-04-29 CRAN (R 3.2.5)
    ##  formatR         1.4      2016-05-09 CRAN (R 3.2.5)
    ##  htmltools       0.3.5    2016-03-21 CRAN (R 3.2.5)
    ##  knitr           1.13     2016-05-09 CRAN (R 3.2.5)
    ##  magrittr        1.5      2014-11-22 CRAN (R 3.2.5)
    ##  memoise         1.0.0    2016-01-29 CRAN (R 3.2.5)
    ##  Rcpp            0.12.5   2016-05-14 CRAN (R 3.2.5)
    ##  RCurl         * 1.95-4.8 2016-03-01 CRAN (R 3.2.3)
    ##  RevoUtilsMath * 3.2.5    2016-05-03 local         
    ##  RJSONIO       * 1.3-0    2014-07-28 CRAN (R 3.2.3)
    ##  rmarkdown       1.0      2016-07-08 CRAN (R 3.2.5)
    ##  RSelenium     * 1.4.0    2016-07-30 CRAN (R 3.2.5)
    ##  stringi         1.1.1    2016-05-27 CRAN (R 3.2.5)
    ##  stringr         1.0.0    2015-04-30 CRAN (R 3.2.5)
    ##  withr           1.0.1    2016-02-04 CRAN (R 3.2.5)
    ##  XML           * 3.98-1.4 2016-03-01 CRAN (R 3.2.3)
    ##  yaml            2.1.13   2014-06-12 CRAN (R 3.2.5)