在调试器中运行时,execute_script行如何工作,而在脚本本身时却不行?

时间:2015-01-26 17:39:32

标签: ruby testing capybara phantomjs poltergeist

我在javascript capybara测试中有以下(温和匿名)evaluate_script行,在ruby rspec中:

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

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

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

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

这似乎不是时间问题 - 在sleep行之后放置addClass s不会改变任何内容。

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

那么:什么可能导致从调试器运行时同样的事情,而不是从调试器运行时?

Capybara司机是幽灵的恶作剧。

干杯:)

1 个答案:

答案 0 :(得分:0)

好的,毕竟这是一个时间问题。

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

这意味着当我尝试在addClass之后添加睡眠时,如果在添加课程和测试它之间存在竞争条件 - 我没有& < / em>尝试在添加类之前暂停。哪个修好了。显然,这种假设是错误的。

因此,从调试器运行该行的差异只是它在运行之前给了它几秒钟!

为了避免随意睡觉,我添加了一个微调器:

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