Testing JQuery autocomplete ui with cucumber

2019-02-14 06:45发布

I got this cucumber sceanario:

When I fill in "End User" with "john"
Then wait
Then wait
When I click "John Doe"
Then show me the page

Step definitions:

Then /^wait$/ do
  sleep 2
end

When /^(?:|I )click "([^"]*)"$/ do |selector|
  find(":contains('#{selector}')").click
end

It passes but it doesn't select a user."End User" equals "john" in 'show me the page'.

I even can't get it to work in a javascript console. The following code does not select anything.

$(":contains('John Doe')").last().trigger('click')
# => [<a class=​"ui-corner-all" tabindex=​"-1"...

How can I script a autocomplete select? Be it in pure javascript or in cucumber.

4条回答
家丑人穷心不美
2楼-- · 2019-02-14 06:52

While this is not a solution, this could lead you down the path of the solution:

the click event is bound to the UL, no the a or li:

$('ul.ui-autocomplete').click();

However, this didn't work for me. I imagine the click event relies on some sort of state with the (a)s and the (li)s. It adds a few classes and an ID to the currently hovered item which I simulated...

$('a.ui-corner-all').attr('id','ui-active-menuitem') $('a.ui-corner-all').addClass('ui-active-menuitem')

Still no dice. No errors, but no action either.

This should lead to the correct path...I just wish I could have figured it out!

查看更多
女痞
3楼-- · 2019-02-14 06:54

Give this a go

When /^I type in "([^\"]*)" into autocomplete list "([^\"]*)" and I choose "([^\"]*)"$/ do |typed, input_name,should_select|
   page.driver.browser.execute_script %Q{ $('input[data-autocomplete]').trigger("focus") }
   fill_in("#{input_name}",:with => typed)
   page.driver.browser.execute_script %Q{ $('input[data-autocomplete]').trigger("keydown") }
   sleep 1
   page.driver.browser.execute_script %Q{ $('.ui-menu-item a:contains("#{should_select}")').trigger("mouseenter").trigger("click"); }
end

Use like so

And I type in "Foo" into autocomplete list "input_id" and I choose "Foobar"
查看更多
放我归山
4楼-- · 2019-02-14 07:01

I myself bumped into the same pain spot too. After spending few hours on this, I have one good helper that works both with selenium and polstergeist plus no usage of sleep(). The following code has been tested with Capybara 2.1.0:

  def fill_autocomplete(field, options = {})
    fill_in field, with: options[:with]

    page.execute_script %Q{ $('##{field}').trigger('focus') }
    page.execute_script %Q{ $('##{field}').trigger('keydown') }
    selector = %Q{ul.ui-autocomplete li.ui-menu-item a:contains("#{options[:select]}")}

    page.should have_selector('ul.ui-autocomplete li.ui-menu-item a')
    page.execute_script %Q{ $('#{selector}').trigger('mouseenter').click() }
  end

Basically, I tell Capybara to fill in the input field then use JS to trigger the keydown event to activate autocomplete. However instead of sleep(), I take advantage of page.should have_selector('ul.ui-autocomplete li.ui-menu-item a') that wait till the dropdown list appeared. Then I use JS to trigger the mouseenter event then click. I wish that there are better way than doing things with JS eval, but this is the most reliable solution that I could come up.

查看更多
Animai°情兽
5楼-- · 2019-02-14 07:18

You need to first trigger a mouseover, then a click.

查看更多
登录 后发表回答