Docker上的远程selenium无法正确处理Javascript

时间:2016-06-01 10:35:38

标签: ruby-on-rails selenium docker capybara

我有一个使用远程Selenium服务器运行其Capybara测试的Rails应用程序。

Rails应用程序和Selenium服务器都已Docker化并成功连接:https://github.com/mottalrd/capybara-on-dockerized-selenium/blob/master/docker-compose.yml

我的问题是在Docker上的远程Selenium服务器上执行Javascript不起作用。例如,如果我在本地运行浏览器测试,则此行可以正常工作:

page.execute_script("$('#js-fileupload').fileupload('send', {files: $('#input_file')[0].files});")

但远程Selenium失败如下。可能是什么问题?

 Failure/Error: page.execute_script("$('#js-fileupload').fileupload('send', {files: $('#input_file')[0].files});")

 Selenium::WebDriver::Error::UnknownError:
    (WARNING: The server did not provide any stacktrace information)
   Command duration or timeout: 12 milliseconds
   Build info: version: '2.53.0', revision: '35ae25b', time: '2016-03-15 17:00:58'
   System info: host: 'b5f51c04b891', ip: '172.18.0.2', os.name: 'Linux', os.arch: 'amd64', os.version: '4.1.19-boot2docker', java.version: '1.8.0_03-Ubuntu'
   Driver info: org.openqa.selenium.firefox.FirefoxDriver
   Capabilities [{applicationCacheEnabled=true, rotatable=false, handlesAlerts=true, databaseEnabled=true, version=45.0.2, platform=LINUX, nativeEvents=false, acceptSslCerts=true, webStorageEnabled=true, locationContextEnabled=true, browserName=firefox, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
   Session ID: 40cdda26-bc78-4d56-b3d7-1025483a985b (org.openqa.selenium.WebDriverException)
 # [remote server] sun.reflect.NativeConstructorAccessorImpl(NativeConstructorAccessorImpl.java):-2:in `newInstance0'
 # [remote server] sun.reflect.NativeConstructorAccessorImpl(NativeConstructorAccessorImpl.java):62:in `newInstance'
 # [remote server] sun.reflect.DelegatingConstructorAccessorImpl(DelegatingConstructorAccessorImpl.java):45:in `newInstance'
 # [remote server] java.lang.reflect.Constructor(Constructor.java):423:in `newInstance'
 # [remote server] org.openqa.selenium.remote.ErrorHandler(ErrorHandler.java):206:in `createThrowable'
 # [remote server] org.openqa.selenium.remote.ErrorHandler(ErrorHandler.java):158:in `throwIfResponseFailed'
 # [remote server] org.openqa.selenium.remote.RemoteWebDriver(RemoteWebDriver.java):678:in `execute'
 # [remote server] org.openqa.selenium.remote.RemoteWebDriver(RemoteWebDriver.java):577:in `executeScript'
 # [remote server] sun.reflect.GeneratedMethodAccessor20():-1:in `invoke'
 # [remote server] sun.reflect.DelegatingMethodAccessorImpl(DelegatingMethodAccessorImpl.java):43:in `invoke'
 # [remote server] java.lang.reflect.Method(Method.java):498:in `invoke'
 # [remote server] org.openqa.selenium.support.events.EventFiringWebDriver$2(EventFiringWebDriver.java):103:in `invoke'
 # [remote server] com.sun.proxy.$Proxy1():-1:in `executeScript'
 # [remote server] org.openqa.selenium.support.events.EventFiringWebDriver(EventFiringWebDriver.java):217:in `executeScript'
 # [remote server] org.openqa.selenium.remote.server.handler.ExecuteScript(ExecuteScript.java):56:in `call'
 # [remote server] java.util.concurrent.FutureTask(FutureTask.java):266:in `run'
 # [remote server] org.openqa.selenium.remote.server.DefaultSession$1(DefaultSession.java):176:in `run'
 # [remote server] java.util.concurrent.ThreadPoolExecutor(ThreadPoolExecutor.java):1142:in `runWorker'
 # [remote server] java.util.concurrent.ThreadPoolExecutor$Worker(ThreadPoolExecutor.java):617:in `run'
 # [remote server] java.lang.Thread(Thread.java):745:in `run'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/response.rb:70:in `assert_ok'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/http/common.rb:78:in `new'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/http/common.rb:78:in `create_response'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/http/default.rb:90:in `request'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/http/common.rb:59:in `call'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/bridge.rb:649:in `raw_execute'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/bridge.rb:627:in `execute'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/bridge.rb:353:in `executeScript'
 # /var/lib/gems/2.3.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/common/driver.rb:220:in `execute_script'
 # /var/lib/gems/2.3.0/gems/capybara-2.7.0/lib/capybara/selenium/driver.rb:81:in `execute_script'
 # /var/lib/gems/2.3.0/gems/capybara-2.7.0/lib/capybara/session.rb:524:in `execute_script'
 # ./spec/features/happy_path_spec.rb:95:in `block (3 levels) in <top (required)>'
 # /var/lib/gems/2.3.0/gems/vcr-3.0.1/lib/vcr/util/variable_args_block_caller.rb:9:in `call_block'
 # /var/lib/gems/2.3.0/gems/vcr-3.0.1/lib/vcr.rb:189:in `use_cassette'
 # ./spec/features/happy_path_spec.rb:10:in `block (2 levels) in <top (required)>'

1 个答案:

答案 0 :(得分:1)

考虑以下代码

page.execute_script("$('#js-fileupload').fileupload('send', {files: $('#input_file')[0].files});")

您实际说的是,您应该上传input_file文本框中指定的路径。当您在本地运行它时,浏览器可以访问该路径并可以上载。在容器化的应用程序/浏览器中,容器内的路径与主机上的路径无关

因此,您需要确保浏览器容器使用-v /path/on/host:/path/on/container映射了卷,然后您需要更新脚本以确保使用/path/on/container作为上传字段