如何基于capybara中的元素发送JavaScript

时间:2014-11-13 16:16:42

标签: ruby selenium-webdriver capybara

我希望在Capybara做这样的事情:

browser.execute_script("arguments[0].setAttribute('value', 'value')", element)

上面的行是在selenium / ruby​​上运行的,但是使用带有capybara的execute_script只需要1个参数(脚本),因此我无法定义我希望执行脚本的元素......任何想法?

2 个答案:

答案 0 :(得分:4)

选项1 - 直接调用Selenium的execute_script

最快的解决方案是绕过Capybara API并直接调用Selenium-WebDriver的execute_script方法。

为此,您需要使用以下方式访问底层Selenium :: WebDriver :: Driver:

page.driver.browser

同样,传递给Selenium' execute_script的元素需要是Selenium :: WebDriver :: Element(而不是Capybara :: Node :: Element)。这可以通过以下方式完成:

element.native

例如,假设您有一个包含文本字段的页面:

<input value="5" id="field">

然后以下内容将更改字段的值:

element = find('#field')
p element.value
#=> "5"
page.driver.browser.execute_script("arguments[0].setAttribute('value', 'value')", element.native)
p element.value
#=> "value"

选项2 - 修补Capybara以允许参数

如果你需要经常这样做,你可以修补Capybara的execute_script方法来获取参数,将参数转换为Selenium对象,然后将其传递给Selenium-WebDriver的方法。补丁将是:

require 'capybara'

class Capybara::Session 
  def execute_script(script, *args)
    @touched = true
    driver.execute_script(script, *args)
  end
end

class Capybara::Selenium::Driver 
  def execute_script(script, *args)
    args.map! { |e| e.kind_of?(Capybara::Node::Element) ? e.native : e }
    browser.execute_script(script, *args)
  end
end

这将允许您将Capybara元素传递给会话execute_script方法:

element = page.find('#field')
p element.value
#=> "5"
page.execute_script("arguments[0].setAttribute('value', 'value')", element)
p element.value
#=> "value"

答案 1 :(得分:1)

从Capybara开始,2.12参数通过Session#execute_script传递,并且也应该与最新的poltergeist和capybara-webkit驱动程序一起使用。

page.execute_script("arguments[0].setAttribute('value', 'value')", element)