Watir 6.18

Written by: Titus Fortner on February 26, 2021

Watir 6.18 is now available on RubyGems. As (one of?) the last 6.x release before Watir 7, this release adds some deprecations necessary for us to add the improvements we want for Watir 7. Most changes are for browser windows, with some updates to select lists and element collections.

To install:

gem install watir

or in your Gemfile:

gem "watir", "~> 6.18"

Browser Windows

The biggest deprecation is :index as a window locator, and the use of indexing (#[], #first, #last) on window collections. You can read the explanation here.

Because the vast majority of the time, there is only one other window you need to work with, there is now a Browser#switch_window method. It can only be used if there are 2 windows, and all it does is switch to the other window. This should be sufficient for the vast majority of users:

browser.switch_window
browser.button(id: 'close').click
browser.switch_window

Still, it’s only fair to add a locator since one is being taken away. Introducing the new :element locator which allows you to select a window based on a unique element on the page:

browser.window(element: browser.div(id: 'my-element'))

Also, to make sure people don’t continue to use indexing with an Array of Window instances, Browser#windows now returns a new WindowCollection object with the deprecation notices. This object will let us do some interesting things in the future, but right off it’s hooked up to use Watir’s powerful waiting functionality, so you can do things like:

browser.link(id: 'open-third-window').click
browser.windows.wait_until(size: 3)

Waiting for Multiple Elements

Many users do a lot of work with collections of elements instead of specific elements, which means that many of Watir’s best synchronization functionality has not been available to them. Similar to what we did with WindowCollection, we’ve hooked up ElementCollection to use Watir’s waiting features. You can now do things like:

browser.elements(divs: /foo/).wait_until(size: 3)
browser.elements(divs: /foo/).wait_until(&:exists?)
browser.elements(divs: /foo/).wait_while(&:empty?)

To accomplish this, Watir will now relocate the collection whenever an enumerable method is used. It shouldn’t be an issue for you unless you are doing a lot of size calls on the same collection. Indexing and iterating with ElementCollection#to_a won’t be affected.

So Long Select All

There is a lot of overhead to treating a select list like it might be a multiple select list, especially when multiple select lists are not very common. Way back in Watir 6.6 I had this brilliant idea for optimizing Select Lists. If we use Select#select for non-multiple select lists and Select#select_all for multiple select lists, it makes it really easy to only do the performance expensive things when needed.

Except… It turns out that we couldn’t easily completely stop using #select for multiple select lists, and there are some advantages for automatic form filling implementations to have everything necessary go through one method. So, Select#select_all and Select#select_all! are now deprecated, and I apologize for making people move to them only to ask them to move back away from them.

If you are working with a multiple select list and you want to select multiple things, you now need to pass in what you want to be selected as an Array, even if it is just one thing (like a Regexp instance):

browser.select_list(id: 'languages').select([/ish/])
browser.select_list(id: 'languages').select([/ish/, 'Latin'])
browser.select_list(id: 'languages').select(['English', 'Swedish'])

See the Changelog for the complete history of updates.

Tags:

Thoughts about this article? Let us know!