Safari10からWebDriverをサポート
SeleniumでのSafariの扱いが、2016年夏から大きく変わった。ネイティブサポートされるようになったのだ。
http://qiita.com/hiroshitoda/items/6ee3ad892357cda3f0e0
古いsafaridriverの話は、もう役に立たないのではないだろうか。
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が表示される。
テストプログラムを動かすコンテナを起動する
起動方法は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のページが表示されるはず。
開かないときは
- Safari 10 の WebDriver ネイティブサポート – QiitaにあるようにSafariの設定を行ったか?
- WebDriver Support in Safari 10 | WebKitの最後にあるように、webdriverdが動いているか?
を確認してみる。
エラーが出た
-------------------------------------------------------------------------------
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)
コメント