水豚不会等到文件上传结束

Capybara doesn't wait till the end of file upload

我正在用 Ruby 和水豚编写脚本。此脚本应上传文件,文件上传后,脚本应单击“保存”按钮。 我成功地使文件开始上传,但几秒钟后脚本就停止了。结果文件没上传,一切从头开始。

页面上有一个“保存”按钮,在上传文件之前该按钮一直处于禁用状态。所以我试图用它的状态作为一个指标。但是水豚不认识。

我的代码:

upload_btn = browser.all(:element, 'span', text: 'Upload')
browser.attach_file($app_path) do
  upload_btn[0].click
end
browser.has_button?('Save', wait: 200)
browser.click_on('Save')

页面的 UI 是怎样的(抱歉截屏):

我认为它不起作用,因为它不是 button,而是 material-button,并且 Capybara 无法识别此元素。使用 classes/ids 不是最好的主意,因为所有 类 都是动态的,我不能指望它

你能告诉我这里可以做什么吗?或者我如何让水豚等到这个按钮被禁用?

谢谢!

假设当按钮激活时 is_disabled class 和 disabled 属性被删除,那么您可以使用以下任何方法(假设 200 秒足以完成上传)

find('material-button:not([disabled])', text: 'Save', wait: 200).click
find('material-button:not(.is_disabled)', text: 'Save', wait:200).click
find('material-button', class: '^is_disabled', text: 'Save', wait: 200).click # The ^ in front of the class name indicates to negate

如果 debug-id 可用且稳定,那么您可以跳过 text 选项,这样会更有效率

find("material-button[debug-id='save-button']:not([disabled])", wait:200).click

最后一个选项是使用 Capybara :element 选择器类型

find(:element, 'material-design', 'debug-id': 'save-button', disabled: false, wait: 200).click
find(:element, 'material-design', disabled: false, text: 'Save', wait: 200).click

所以,转变可能不是最专业的,但至少它起作用了,我现在可以自动化一些事情了。

基本上,我使用 has_button? 让我的脚本等待 APK 文件上传。 200 秒足以上传文件(统计数据)。 最后,脚本暂停了,但为了安全起见,我决定在最后添加 sleep 3

这是为我上传APK的功能。也许有人会需要它

 def create_release
   puts('Create release and upload APK')
   browser.find(:element, 'div', role: 'menuitem', text: 'Production').click
   create_release_btn = browser.all(:button, text: 'Create new release')
   create_release_btn[0].click

   #OPT out
   browser.click_button('Manage preferences', wait: 200)
   sleep 2
   browser.choose('Opt out of app signing by Google Play')
   browser.click_button('Update', wait: 100)
   sleep 3
   op_out_btn = browser.all(:button, text: 'Opt out', wait: 500)
   op_out_btn[0].click
   sleep 4

   #File upload part and saving
   upload_btn = browser.all(:element, 'span', text: 'Upload')
   browser.attach_file($app_path) do
     upload_btn[0].click
   end
   save_btn = browser.all(:element, 'material-button', text: 'Save', disabled: false, wait: 200)
   browser.has_button?(save_btn, disabled: false, wait: 200)
   button_test = browser.all(:button, text: 'Save', wait: 100)
   button_test[0].click

   sleep 3
end

现在 OP 已经发布了他们的完整方法,对于以后遇到这个问题的任何人,请不要像当前接受的答案那样编写水豚代码。

  1. 当您只关心 first 元素时,请不要使用 all

  2. 当你真的不需要时不要使用 :element 选择器类型

  3. 不要仅仅为了等待而使用谓词方法

  4. 比睡觉更喜欢 expectation/assertion

归结起来更像是

def create_release
  puts('Create release and upload APK')
  browser.find('div[role="menuitem"]', text: 'Production').click
  browser.first(:button, 'Create new release').click

  #OPT out
  browser.click_button('Manage preferences', wait: 200) # 200 seems like a really long max wait time here
  browser.choose('Opt out of app signing by Google Play')
  browser.click_button('Update', wait: 100) # again - seems really long

  browser.first(:button, 'Opt out', wait: 500).click # and again

  #File upload part and saving
  browser.attach_file($app_path) do
    browser.first('span', text: 'Upload').click
  end

  expect(browser).to have_selector(:element, 'material-button', text: 'Save', disabled: false, wait: 200)
  browser.first(:button, 'Save', wait: 300).click

  expect(browser).to ... # whatever change clicking the button triggers 
end