Selenium sendKeys and clear doesn't work on Kendo Autocomplete field in Safari 11

1.1k Views Asked by At

While coding an automation test in Selenium-Ruby when sendKeys / clear is used on a Autocomplete text field (Kendo UI) in Safari browser 11.0.1,

Test Code:

actions.push(is_element_enabled?(PROF_IN_CHARGE,'PROF_IN_CHARGE'))
actions.push(is_element_displayed?(PROF_IN_CHARGE,'PROF_IN_CHARGE'))
actions.push(type(PROF_IN_CHARGE,first_name, 'PROF_IN_CHARGE'))

Selenium methods:

def is_element_enabled?(locator, name, raise_exception = true)
$logger.info "Verify whether #{name} is enabled."
highlight(web_driver.find_element(locator))
web_driver.find_element(locator).enabled?
$logger.info "Element enabled: #{name}"

def is_element_displayed?(locator, name, raise_exception = true, log_error = true)
$logger.info(__method__) { "Verifying element #{name}" }
$logger.debug(__method__) { locator }
web_driver.find_element(locator).displayed?
highlight(web_driver.find_element(locator), 0, "red")
return true

def type(locator, text, name, raise_exception = true)
$logger.info(__method__) { "Typing #{text} to #{name}" }
$logger.debug(__method__) { locator }
highlight(web_driver.find_element(locator), 0, "red")
#Clear existing text before typing
web_driver.find_element(locator).clear
web_driver.find_element(locator).send_keys(text)

the following error is displayed:

 # --- Caused by: ---
 # Selenium::WebDriver::Error::ElementNotVisibleError:
 #   An element command could not be completed because the element is not visible on the page.
 #   /Users/admin/.rvm/gems/ruby-2.4.1/gems/selenium-webdriver-3.6.0/lib/selenium/webdriver/remote/response.rb:71:in `assert_ok'

Here's logs:

I, [2017-12-11T15:19:00.611929 #5324]  INFO -- : Verify whether PROF_IN_CHARGE is enabled.
I, [2017-12-11T15:19:00.635876 #5324]  INFO -- : Element enabled: PROF_IN_CHARGE
I, [2017-12-11T15:19:00.635940 #5324]  INFO -- is_element_displayed?: Verifying element PROF_IN_CHARGE
D, [2017-12-11T15:19:00.635964 #5324] DEBUG -- is_element_displayed?: {:id=>"fcCreateMainAssingee"}
I, [2017-12-11T15:19:00.647651 #5324]  INFO -- is_element_displayed?: true
I, [2017-12-11T15:19:00.660760 #5324]  INFO -- type: Typing Report to PROF_IN_CHARGE
D, [2017-12-11T15:19:00.660834 #5324] DEBUG -- type: {:id=>"fcCreateMainAssingee"}
E, [2017-12-11T15:19:00.685450 #5324] ERROR -- create_new_matter:  failed.
I, [2017-12-11T15:19:00.725482 #5324]  INFO -- screenshot: Screenshot saved in path: /Users/admin/PivotQA/screenshots/2017-12-11_1
5_18_15/MattersLib_create_new_matter_20171211_151900.png
E, [2017-12-11T15:19:00.725531 #5324] ERROR -- : An element command could not be completed because the element is not visible on t
he page.

This happens even after successfully checking whether that element is enabled and visible, using selenium's enabled? and displayed? methods.

BUT, this issue is not seen on the other browsers like chrome, IE and Edge.

I have used javascript("document.getElementById('fcCreateMainAssingee'.value='text')") to change the value of that text field and it worked fine, but the dynamic options dropdown is not displayed, which is the problem.

So, is there anybody who has had similar issue and resolved it ? Would be great to get your help.

Also, if there is any other way to accomplish this kindly suggest.

Here's the DOM of that autocomplete field:

<input formcontrolname="fcCreateMainAssingee" id="fcCreateMainAssingee" type="text" class="ng-untouched ng-pristine ng-valid k-input" data-role="autocomplete" placeholder="Username" autocomplete="off" role="textbox" aria-haspopup="true" aria-disabled="false" aria-readonly="false" aria-owns="fcCreateMainAssingee_listbox" aria-autocomplete="list" style="width: 100%;">

Thanks!

1

There are 1 best solutions below

0
On BEST ANSWER

During my research on Kendo autocomplete fields, I stumbled upon JavaScript code that would help solve this problem.

The following is a credible alternative to the selenium functions and has been thoroughly tested on Safari, Chrome, IE and Edge browser and works fine.

Hope this helps someone who is in the same boat as I was for past few days!

Here's selenium equivalent of JS for send_keys -

"document.getElementById('<ID>').value='<search_string>'"

(no need to clear the text as js types in the search_string removing existing placeholder string)

and then to trigger the search that happens after typing the , execute the below js:

"$( #{locator[:id]} ).data('kendoAutoComplete').search();"

the above js will trigger search and then the dynamic drop down opens up. Now, its just a matter of finding that element by xpath using selenium's find_element method and then clicking on it using js (given below)

js_script = 'arguments[0].click();'
element   = web_driver.find_element(locator)
web_driver.execute_script(js_script, element)

Here's the complete method:

def kendo_auto_complete(locator, loc_name, full_name, raise_exception = true)
    $logger.info(__method__) { 'begin' }
    # Split full name ( Last_name, first_name) and get first_name
    first_name = full_name.split(",").last.strip
    # Type in the name using JS
    $logger.info(__method__) { "Typing #{first_name} into #{loc_name}" }
    web_driver.execute_script("document.getElementById('#{locator[:id]}').value='#{first_name}'")
    short_delay
    #Trigger search using JS
    $logger.info(__method__) { "Starting search.." }
    if BROWSER.upcase == 'IE'
      web_driver.execute_script("$( '##{locator[:id]}' ).data('kendoAutoComplete').search();")
    else
      web_driver.execute_script("$( #{locator[:id]} ).data('kendoAutoComplete').search();")
    end
    # Select the name from results in dynamic dropdown
    wait_for_element(create_dynamic_xpath(AUTO_CMP_OPTION[:xpath],full_name), full_name)
    js_click(create_dynamic_xpath(AUTO_CMP_OPTION[:xpath],full_name), full_name)
    $logger.info(__method__) { 'end' }
rescue StandardError => e
    $logger.error "Value of Kendo autocomplete - #{name} could not be set."
    raise e if raise_exception
    false
end

But, still if someone has a better way of doing things, kindly comment here. Thanks!