ruby - execute_script 行在调试器中运行但在脚本本身中运行时如何工作?

标签 ruby testing capybara phantomjs poltergeist

我在 ruby​​ rspec 中的 javascript capybara 测试中有以下(轻微匿名的)evaluate_script 行:

page.execute_script("$('selector').addClass('-class')")

它不起作用,例如以下打印 false :

page.execute_script("console.log($('selector').hasClass('-class')")

如果我在该行之后放置一个调试器 (binding.pry),然后在调试器中运行 addClass 行——实际上就是刚刚执行的同一行;复制并粘贴 - 然后它确实工作。

这似乎不是时间问题——将 sleep 放在 addClass 行之后不会改变任何东西。

这是非常可重复的:如果我用 binding.pry 替换它并从 pry 运行该行,那么在脚本中没有执行任何操作的确切行突然起作用。哪个 AFAIK 应该是不可能的。

那么:是什么导致同样的事情在从调试器运行时起作用,而不是在不从调试器运行时起作用?

Capybara 驱动程序是 phantomJS 上的恶作剧者。

干杯:)

最佳答案

好吧,事实证明这毕竟是时间问题。

我一直假设 addClass 调用在页面加载时无论何时完成,只要加载了 jQuery 并且元素存在,它们就存在。

这意味着虽然我尝试在 addClass 之后添加 sleep ,以防这是添加类和对其进行测试之间的竞争条件 - 我没有尝试的是在添加类之前休眠。哪个修好了。很显然,这个假设是错误的。

所以从调试器运行该行的不同之处在于它在运行前给了它几秒钟!

为了避免随机休眠,我添加了一个微调器:

def spin_until_thing_done(selector)
  Timeout.timeout(Capybara.default_wait_time) do
    loop do
      do_thing(selector)
      return if thing_done?(selector)
      sleep 0.1
    end
  end
end

def do_thing(selector)
  page.execute_script("$('#{selector}').addClass('-class')")
end

def thing_done?(selector)
  page.evaluate_script("$('#{selector}').hasClass('-clas')")
end

关于ruby - execute_script 行在调试器中运行但在脚本本身中运行时如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28155582/

相关文章:

javascript - Rspec & capybara : Setting focus to an element using jQuery doesn't apply `:focus` CSS

selenium - RSpec/Capybara/JS 测试单独通过,但一起运行时失败

ruby-on-rails - Rspec Capybara 套件超时

ruby-on-rails - 有没有办法判断一条记录在使用 find_or_create_by 创建后是否是新的

ruby - Gem 中的测试需要测试迁移生成器并为测试应用迁移

ruby - 多对多 : how to prevent duplicates? 上的 Rails 嵌套表单

javascript - react 测试库 id 而不是 data-testid?

ruby-on-rails-3 - 如何使用 RSpec 在 after_save 回调中测试类初始化?

ruby-on-rails - 重写的方法仍然被调用

ruby - Rubyist 捕获救援 block 中引发的异常的方法是什么?