简体   繁体   English

如何使用Capybara和Select2 v3.5.4选择元素

[英]How to select and element with Capybara and Select2 v3.5.4

I've been reading different answers for hours but couldn't find a solution for testing using select2 and Capybara (Webkit driver). 我已经阅读了几个小时的不同答案,但是找不到使用select2和Capybara(Webkit驱动程序)进行测试的解决方案。

I want to select an option from the select2 and, after that, check if some element value has changed (selecting and option fires an event to add a fee to a number that is in the view also). 我想从select2中选择一个选项,然后,检查某些元素值是否已更改(selecting和option会触发一个事件,以向视图中的数字添加费用)。 The problem is that I don't know how to select the element in order to fire the js event, because doing something like this works for the select but doesn't fire the js event: 问题是我不知道如何选择元素来触发js事件,因为这样做对select起作用,但不会触发js事件:

select('VISA 4242 2020/10').select_option

(I've set the Capybara driver to use Webkit Javascript Driver) (我已经将Capybara驱动程序设置为使用Webkit Javascript驱动程序)

This is the html before clicking on the select input (container is closed): 这是单击选择输入之前的html(容器已关闭):

<fieldset class="form-group">
  <label for="source_id">Payment Method</label>
  <select name="source_id" id="js-payment-method" required="required" autofocus="autofocus" class="form-control normal-select2 select2-hidden-accessible" tabindex="-1" aria-hidden="true">
    <option value="">Select a payment method</option>
    <option value="ba_1">TEST BANK 6789 </option>
    <option value="card_1">VISA 4242 2021/4</option>
    <option value="ba_2">TEST BANK 1116 </option>
  </select>
  <span class="select2 select2-container select2-container--default select2-container--below" dir="ltr" style="width: 100px;">
    <span class="selection">
      <span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-labelledby="select2-js-payment-method-container">
        <span class="select2-selection__rendered" id="select2-js-payment-method-container" title="VISA 4242 2021/4">
          <span class="select2-selection__placeholder">Search...</span>
        </span>
        <span class="select2-selection__arrow" role="presentation">
          <b role="presentation"></b>
        </span>
      </span>
   </span>
   <span class="dropdown-wrapper" aria-hidden="true"></span>
  </span>
</fieldset>

This is the html after clicking on the select input (container is opened): 这是单击选择输入(打开容器)后的html:

<fieldset class="form-group">
  <label for="source_id">Payment Method</label>
  <select name="source_id" id="js-payment-method" required="required" autofocus="autofocus" class="form-control normal-select2 select2-hidden-accessible" tabindex="-1" aria-hidden="true">
    <option value="">Select a payment method</option>
    <option value="ba_1">TEST BANK 6789 </option>
    <option value="card_1">VISA 4242 2021/4</option>
    <option value="ba_2">TEST BANK 1116 </option>
  </select>
  <span class="select2 select2-container select2-container--default select2-container--below select2-container--open" dir="ltr" style="width: 100px;">
    <span class="selection">
      <span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="true" tabindex="0" aria-labelledby="select2-js-payment-method-container" aria-owns="select2-js-payment-method-results" aria-activedescendant="select2-js-payment-method-result-1rcw-card_1">
        <span class="select2-selection__rendered" id="select2-js-payment-method-container" title="TEST BANK 6789 ">
          <span class="select2-selection__placeholder">Search...</span>
        </span>
        <span class="select2-selection__arrow" role="presentation">
          <b role="presentation"></b>
        </span>
      </span>
    </span>
    <span class="dropdown-wrapper" aria-hidden="true"></span>
  </span>
</fieldset>

Thanks a lot! 非常感谢!

The code select('VISA 4242 2020/10').select_option makes no sense in Capybara. 代码select('VISA 4242 2020/10').select_optionselect('VISA 4242 2020/10').select_option中没有意义。 select('VISA 4242 2020/10') would select the option element containing the text 'VISA 4242 2020/10' and return that option element, which you then call select_option on again. select('VISA 4242 2020/10')将选择包含文本'VISA 4242 2020/10'的option元素,并返回该option元素,然后再次调用select_option So it would just attempt to select the same option twice. 因此,它只会尝试选择相同的选项两次。 If you were dealing with a normal HTML select it would make more sense to call select('VISA 4242 2020/10', from: 'js-payment-method') . 如果您要处理的是普通HTML选择,那么调用select('VISA 4242 2020/10', from: 'js-payment-method')会更有意义。 That would find the relevant <option> inside the <select> element with the id of 'js-payment-method' and then select it (see more about this at the bottom of this answer). 那将在ID为'js-payment-method'的<select>元素内找到相关的<option> ,然后选择它(有关更多信息,请参见此答案的底部)。

That being said, you're not dealing with a normal HTML <select> element, you're dealing with a JS widget which is replacing that select. 话虽这么说,您不是在处理普通的HTML <select>元素,而是在处理替换该选择的JS小部件。 If you inspect the page while in a browser you'll see that the actual <select> element is non-visible, and hence you can't use the select method. 如果在浏览器中检查页面,您会发现实际的<select>元素是不可见的,因此您不能使用select方法。 The rule when dealing with JS widgets is to do exactly what a user would have to do. 处理JS小部件的规则是完全执行用户必须要做的事情。 In this case that would be to click on the JS widget, then click on the correct choice which appears. 在这种情况下,可以单击JS小部件,然后单击出现的正确选择。 You don't show the actual HTML of the dropdown which appears when the widget is clicked on (it gets dynamically appended to the end of the document) but something along the lines of 您没有显示单击小部件时会出现的下拉列表的实际HTML(它会动态附加到文档的末尾),而是类似

find('span.select2-selection__arrow').click # click on the dropdown arrow to open the selection choices
find('li.select2-results__option', text: 'VISA 4242 2021/4').click # click on the option to select it

should probably work (the class names may need to be adjusted if you've changed the default select2 configuration). 应该可以工作(如果更改了默认的select2配置,则可能需要调整类名)。


Note: Given your description the code select('VISA 4242 2020/10').select_option should have raised an error about not being able to find an element (since the select is hidden). 注意:根据您的描述,代码select('VISA 4242 2020/10').select_option应该引发有关无法找到元素的错误(由于选择被隐藏)。 Reasons why it wouldn't could be 为什么不会的原因

  1. You've changed Capybara from its default of ignoring hidden elements (bad idea to do that for app testing) 您已将Capybara从默认设置更改为忽略隐藏元素(对于应用程序测试,不建议这样做)
  2. You aren't actually using capybara-webkit as the driver for this test 您实际上并没有使用capybara-webkit作为此测试的驱动程序
  3. There's an error causing the JS on your page not to run (JS syntax error, not transpiling/polyfilling to ES5 compatibility levels required by capybara-webkit , etc). 发生错误,导致页面上的JS无法运行(JS语法错误,未将capybara capybara-webkit等所要求的ES5兼容级别转换/填充)。

So if you haven't done the first of those, you might want to look into the other two (and if you have done the first consider reverting that if you want your tests to be meaningful). 因此,如果您没有完成第一个操作,则可能需要研究其他两个(如果您执行了第一个操作,那么如果您想使测试有意义,请考虑将其还原)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM