我在 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/