Population of select lists are often linked to the values of other entries on a page. Here is an example where the first field (text field) entry is used to do a search which populates the second field (select list) on hitting ‘Enter’. Selection of an option from that list populates the third field (also a select list).
This is all done with javascript, so Watir doesn’t know when the select lists are ready. Depending on network and database latency, I could only rely on a long (10+ second) sleep to catch each select field fully ready. With long tests and searches like this that are used quite often, 15-20 seconds a pop can add up.
I did some investigation with this code:
1 2 3 4 5 6 7 8 |
a_frame.text_field(:name, 'borrowerSearch').set('autotest') browser.focus a_frame.text_field(:name, 'borrowerSearch').focus browser.send_keys("{ENTER}") (1..16).each do |x| puts "borrowerId exists: #{@a_frame.select_list(:name, 'borrowerId').enabled?} " sleep(0.25) end |
with this output (in irb):
1 2 3 4 5 6 7 |
borrowerId enabled: true borrowerId enabled: true borrowerId enabled: true borrowerId enabled: true borrowerId enabled: true Watir::Exception::UnknownObjectException: Unable to locate element, using :name, "borrowerID" . . . |
which obviously indicated the select list went away.
I tried this:
1 2 3 4 5 6 7 8 |
a_frame.text_field(:name, 'borrowerSearch').set('autotest') browser.focus a_frame.text_field(:name, 'borrowerSearch').focus browser.send_keys("{ENTER}") (1..16).each do |x| puts "borrowerId exists: #{@a_frame.select_list(:name, 'borrowerId').exists?} " sleep(0.25) end |
with this output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
borrowerId exists: true borrowerId exists: true borrowerId exists: true borrowerId exists: true borrowerId exists: true borrowerId exists: true borrowerId exists: false borrowerId exists: false borrowerId exists: false borrowerId exists: false borrowerId exists: true borrowerId exists: true borrowerId exists: true borrowerId exists: true borrowerId exists: true borrowerId exists: true |
Lo and behold! In this particular application the select list exists for a second unpopulated, then goes away for a bit, returning populated! As the borrower id is a full name string I could tell that the select list was populated when the select field size increased.
Selecting a borrower name automatically triggered a similar (but not quite the same) effect for the Loan number select list:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
loanNum exists: false loanNum exists: false loanNum exists: false loanNum exists: false loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true loanNum exists: true |
Because this functionality is used on several pages in the application under test I put together a method that looks like this to get the options from the first list:
1 2 3 4 5 6 7 8 9 10 |
def select_borrower_and_load(browser, search_string) a_frame = browser.frame(:name, 'contentFrame') a_frame.text_field(:name, 'borrowerSearch').set('<code>search_string</code>') browser.focus a_frame.text_field(:name, 'borrowerSearch').focus browser.send_keys("{ENTER}") Watir::Wait.while(15) {a_frame.select_list(:name, 'borrowerID').exists?} Watir::Wait.until(15) {a_frame.select_list(:name, 'borrowerID').exists?} a_frame.select_list(:name, 'borrowerID').options end |
and after confirming the options contained the desired borrower name used code like this:
1 2 3 |
a_frame.select_list(:name, 'borrowerID').set('Autotest Borrower - Loan') Watir::Wait.until(15) {a_frame.select_list(:name, 'loanNum').exists? a_frame.select_list(:name, 'LoanNum').set('Autotest Loan A') |
Now there is no wasted time waiting unnecessarily and the process of getting to the desired loan is much more reliable.