SafariDriverを使ってみる

スポンサーリンク

Safari10からWebDriverをサポート

SeleniumでのSafariの扱いが、2016年夏から大きく変わった。ネイティブサポートされるようになったのだ。

こんにちは! みなさんmacOSしてますか! アップグレード中にフリーズしたせいでリカバリーするのがたいへんだったよ!!! クソが!!!! なんでわざわざそんなクソなアップグレードを急いでやったかというと、Safariの新バージョン...
古いsafaridriverの話は、もう役に立たないのではないだろうか。

browser

Selenium Gridから使ってみる

なるべく環境を汚さずに試してみる場合、Dockerはとても便利だ。だが、DockerはLinuxの仮想コンテナであるため、Safariを動かすことはできない。

そこで、Selenium Gridを使ってみる。Selenium Gridを使うことで、他のマシンのブラウザをテストプログラムから操作することができるようになるのだ。
テストプログラム -> Selenium Grid -> Safari
というシステム構成で動かしてみる。

テストプログラムをSelenium Gridに対応させる

テストプログラムは、前の記事のコードを使う。Selenideの場合、びっくりするほどわずかな変更でGridに対応させられる。


--- ./selenide-sample/src/test/java/com/example/selenidetest/Test1.java     2017-01-01 12:39:39.000000000 +0900
+++ Test1.java     2017-01-01 06:34:49.000000000 +0900
@@ -22,8 +22,9 @@
     @BeforeClass
     public static void setUp() {
         // Set Browser
-        Configuration.browser = WebDriverRunner.CHROME;
-        System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriver");
+        Configuration.browser = WebDriverRunner.SAFARI;
+        Configuration.remote = "http://selenium-hub:4444/wd/hub";
+//        System.setProperty("webdriver.chrome.driver", "/usr/local/bin/chromedriver");
     }

     @Before
  • Configuration.browserをSAFARIにする
  • Configuration.remoteにSelenium GridのURLを指定する

Selenium Gridを起動する

Selenium Gridは公式のDockerイメージを使う。

docker run -d -p 4444:4444 --name selenium-hub selenium/hub

として起動する。Docker for Macを使っているのであれば、 http://localhost:4444/grid/console を開くと、Grid Consoleの画面が現れるはず。

Safariをnodeとして登録する

SafariはMacで動かす必要がある。

java -jar selenium-server-standalone-3.0.1.jar -role node -nodeConfig node.json

として起動する。node.jsonは

{
  "capabilities":
  [
    {
      "browserName": "safari",
      "maxInstances": 4,
      "seleniumProtocol": "WebDriver"
    }
  ],
  "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
  "maxSession": 5,
  "port": 5555,
  "register": true,
  "registerCycle": 5000,
  "hub": "http://localhost:4444",
  "nodeStatusCheckTimeout": 5000,
  "nodePolling": 5000,
  "role": "node",
  "unregisterIfStillDownAfter": 60000,
  "downPollingLimit": 2,
  "debug": false,
  "servlets" : [],
  "withoutServlets": [],
  "custom": {}
}

selenium-server-standalone-3.0.1.jar はDownloadsのページからダウンロードすればOK。
問題がなければ、リロードするとGrid ConsoleにSafariが表示される。
Selenium Grid

テストプログラムを動かすコンテナを起動する

起動方法はGitHub – hiroaki0404/netbeans-java8-X-windowにあるのと少しだけ異なる。

docker run -P -d -v `pwd`:/src --link selenium-hub nb8

linkオプションでSelenium Gridのコンテナの名前を渡す。こうすると、コンテナ上のプログラムでselenium-hubの名前解決ができるようになるのだ。

テストプログラムの動かし方は、前の記事に書いた通り。Netbeansから実行すれば、Safariが開いてYahoo! Japanのページが表示されるはず。
開かないときは

を確認してみる。

エラーが出た


-------------------------------------------------------------------------------
Test set: com.example.selenidetest.Test1
-------------------------------------------------------------------------------
Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 17.293 sec <<< FAILURE!
searchTsu(com.example.selenidetest.Test1)  Time elapsed: 17.067 sec  << ul > li:nth-child(7) > a}
Element: 'UnsupportedCommandException: Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:48:19 -0700''
Screenshot: file:/src/selenidetest/build/reports/tests/1483220056878.0.png
Timeout: 8 s.
Caused by: UnsupportedCommandException: Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:48:19 -0700'
	at com.codeborne.selenide.impl.WebElementSource.checkCondition(WebElementSource.java:66)
	at com.codeborne.selenide.impl.WebElementSource.findAndAssertElementIsVisible(WebElementSource.java:72)
	at com.codeborne.selenide.commands.Click.execute(Click.java:14)
	at com.codeborne.selenide.commands.Click.execute(Click.java:11)
	at com.codeborne.selenide.commands.Commands.execute(Commands.java:139)
	at com.codeborne.selenide.impl.SelenideElementProxy.dispatchAndRetry(SelenideElementProxy.java:86)
	at com.codeborne.selenide.impl.SelenideElementProxy.invoke(SelenideElementProxy.java:62)
	at com.sun.proxy.$Proxy7.click(Unknown Source)
	at com.example.selenidetest.page.TopPage.ClickWheterLink(TopPage.java:18)
	at com.example.selenidetest.Test1.searchTsu(Test1.java:39)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:53)
	at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:123)
	at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:104)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
	at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
	at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
	at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
	at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: org.openqa.selenium.UnsupportedCommandException: Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:48:19 -0700'
System info: host: 'macbook-air', ip: '192.168.0.14', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.2', java.version: '1.8.0_25'
Driver info: org.openqa.selenium.safari.SafariDriver
Capabilities [{applicationCacheEnabled=true, rotatable=false, databaseEnabled=true, handlesAlerts=true, version=12602.3.12.0.1, cleanSession=true, platform=MAC, nativeEvents=true, locationContextEnabled=false, webStorageEnabled=true, browserName=safari, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: C005525D-D7C4-4E8E-A9A2-A83ECE5645EE
Command duration or timeout: 263 milliseconds
Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:49:13 -0700'
System info: host: 'a770b1f66de2', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.4.39-moby', java.version: '1.8.0_111'
Driver info: org.openqa.selenium.remote.RemoteWebDriver
Capabilities [{applicationCacheEnabled=true, rotatable=false, databaseEnabled=true, handlesAlerts=true, version=12602.3.12.0.1, cleanSession=true, platform=MAC, nativeEvents=true, webdriver.remote.sessionid=6a9f7b59-b295-4b18-a702-6dee7e80571e, locationContextEnabled=false, webStorageEnabled=true, browserName=safari, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: 6a9f7b59-b295-4b18-a702-6dee7e80571e
	at sun.reflect.GeneratedConstructorAccessor10.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:216)
	at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:168)
	at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:635)
	at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:274)
	at org.openqa.selenium.remote.RemoteWebElement.isDisplayed(RemoteWebElement.java:315)
	at com.codeborne.selenide.Condition$1.apply(Condition.java:24)
	at com.codeborne.selenide.impl.WebElementSource.checkCondition(WebElementSource.java:45)
	... 40 more
Caused by: org.openqa.selenium.remote.ScreenshotException: Screen shot has been taken
Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:49:13 -0700'
System info: host: 'a770b1f66de2', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.4.39-moby', java.version: '1.8.0_111'
Driver info: driver.version: RemoteWebDriver
	at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:142)
	... 45 more
Caused by: org.openqa.selenium.UnsupportedCommandException: Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:48:19 -0700'
System info: host: 'macbook-air', ip: '192.168.0.14', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.2', java.version: '1.8.0_25'
Driver info: org.openqa.selenium.safari.SafariDriver
Capabilities [{applicationCacheEnabled=true, rotatable=false, databaseEnabled=true, handlesAlerts=true, version=12602.3.12.0.1, cleanSession=true, platform=MAC, nativeEvents=true, locationContextEnabled=false, webStorageEnabled=true, browserName=safari, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: C005525D-D7C4-4E8E-A9A2-A83ECE5645EE
Build info: version: '3.0.1', revision: '1969d75', time: '2016-10-18 09:49:13 -0700'
System info: host: 'a770b1f66de2', ip: '172.17.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.4.39-moby', java.version: '1.8.0_111'
Driver info: driver.version: RemoteWebDriver
	at sun.reflect.GeneratedConstructorAccessor13.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
	at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:216)
	at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:168)
	at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:635)
	at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:274)
	at org.openqa.selenium.remote.RemoteWebElement.isDisplayed(RemoteWebElement.java:315)
	at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement$1.invoke(EventFiringWebDriver.java:331)
	at com.sun.proxy.$Proxy7.isDisplayed(Unknown Source)
	at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement.isDisplayed(EventFiringWebDriver.java:385)
	at sun.reflect.GeneratedMethodAccessor15.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at org.openqa.selenium.remote.server.KnownElements$1.invoke(KnownElements.java:64)
	at com.sun.proxy.$Proxy8.isDisplayed(Unknown Source)
	at org.openqa.selenium.remote.server.handler.GetElementDisplayed.call(GetElementDisplayed.java:32)
	at org.openqa.selenium.remote.server.handler.GetElementDisplayed.call(GetElementDisplayed.java:23)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at org.openqa.selenium.remote.server.DefaultSession$1.run(DefaultSession.java:176)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加
  • Evernoteに保存Evernoteに保存

フォローする

この記事へのコメント

Loading Facebook Comments ...

No Trackbacks.