Ruby 水豚不';不要等到文件上传结束

Ruby 水豚不';不要等到文件上传结束,ruby,capybara,Ruby,Capybara,我正在用Ruby和Capybara编写一个脚本。此脚本应上载文件,文件上载后,脚本应单击“保存”按钮。 我成功地使文件开始上传,但几秒钟后脚本就停止了。最后,文件没有上传,我需要从头开始 页面上有一个“保存”按钮,在上传文件之前一直处于禁用状态。所以我试着用它的状态作为指标。但是水豚不认识它 我的代码: upload_btn = browser.all(:element, 'span', text: 'Upload') browser.attach_file($app_path) do up

我正在用Ruby和Capybara编写一个脚本。此脚本应上载文件,文件上载后,脚本应单击“保存”按钮。 我成功地使文件开始上传,但几秒钟后脚本就停止了。最后,文件没有上传,我需要从头开始

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

我的代码:

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外观(很抱歉屏幕截图):

我假设它不工作,因为它不是
按钮
,而是
材质按钮
,而且水豚不识别这个元素。使用类/id不是最好的主意,因为所有的类都是动态的,我不能指望它

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


谢谢大家!

假设按钮激活时,
被禁用
类和
被禁用
属性被删除,则您可以使用以下任一选项(假设200秒足以完成上载)

如果
调试id
可用且稳定,则可以跳过
文本
选项,这样效率会更高

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

假设按钮处于活动状态时,
被禁用
类和
禁用
属性被删除,则您可以使用以下任一选项(假设200秒足以完成上载)

如果
调试id
可用且稳定,则可以跳过
文本
选项,这样效率会更高

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_按钮?
让脚本等待APK文件上传。200秒足够上传文件(统计)。 最后,脚本暂停了,但为了安全起见,我决定在最后添加
sleep3

下面是为我上传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


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

基本上,我使用了
has_按钮?
让脚本等待APK文件上传。200秒足够上传文件(统计)。 最后,脚本暂停了,但为了安全起见,我决定在最后添加
sleep3

下面是为我上传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已经发布了他们的完整方法,对于稍后讨论这个问题的任何人,请不要像当前接受的答案中那样编写水豚代码

  • 当您只关心
    第一个元素时,不要使用
    all

  • 当您不真正需要时,不要使用:element选择器类型

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

  • 喜欢期望/断言而不是仅仅睡觉

  • 这可以归结为更像

    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
    

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

  • 当您只关心
    第一个元素时,不要使用
    all

  • 当您不真正需要时,不要使用:element选择器类型

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

  • 喜欢期望/断言而不是仅仅睡觉

  • 这可以归结为更像

    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
    

    不是说我是专家,而是说等待真的有必要吗?似乎(根据我的阅读)capybara将自动等待查找,直到匹配发生。@engineersmnky默认情况下,capybara将等待到
    capybara。默认情况下,等待时间为
    以满足条件。默认值为2秒,取决于用于测试的硬件,该值通常设置在1-5秒的范围内。根据原始帖子,我假设上传没有在该范围内完成,因此包含了
    wait
    选项。这是一个最长的等待时间,因此当满足条件时,它将继续(即,它不会等待整整200次),所以最坏的情况是,如果/当上传实际失败时,它会延迟失败的情况。完美。认为我陶冶了性情。我很感谢你的澄清,现在我知道我应该在将来使用水豚。我的转变与你写的有点不同。但最接近的是你提出的最后一个变体。我现在将在下面发布解决方案。谢谢你们的建议,伙计们!不是说我是专家,而是说等待真的有必要吗?似乎(根据我的阅读)capybara将自动等待查找,直到匹配发生。@engineersmnky默认情况下,capybara将等待到
    capybara。默认情况下,等待时间为
    以满足条件。默认值为2秒,取决于用于测试的硬件,该值通常设置在1-5秒的范围内。根据原始帖子,我假设上传没有在该范围内完成,因此包含了
    wait
    选项。这是一个最长的等待时间,因此当满足条件时,它将继续(即,它不会等待整整200次),所以最坏的情况是,如果/当上传实际失败时,它会延迟失败的情况。完美。认为我陶冶了性情。我很感谢你的澄清,现在我知道我应该在将来使用水豚。我的转变与你写的有点不同。但最接近的是你提出的最后一个变体。我现在将在下面发布解决方案。谢谢你的帮助