Showing posts with label Javascript. Show all posts
Showing posts with label Javascript. Show all posts

Wednesday, April 11, 2012

Stupid <acronym> tags, and how to find them (or any other deprecated tag).

I ran into a problem where the site I am testing uses the <acronym> tag.  The problem arose because watir-webdriver derives its HTML element objects from the HTML5 spec.  Guess what isn't in that spec?  The <acronym> tag.  I went through a long process to find a fast, reliable solution.  This was the HTML I was trying to deal with:

<acronym class="editable select fillwith:exp_codes default:E100"
title="Expense Code: Expenses" id="expense_code114_582_10777">
E100    </acronym>

This is the code I ended up with:

@browser.element(:tag_name => "acronym", 
                    :class => "default:#{expense_code}").when_present.text

I'm using the generic element tag, passing it the tag name of "acronym", and then a class identifier.  I had to do both the name and class, because neither on its own was sufficient.  I also found out that when passing a class, the values are space-delimited, and that watir-webdriver understands this.  The upshot was that I only needed to include the default:E100 bit.  expense_code is a variable being passed in which represents the E100 portion.  I added .when_present becauseI am running this right after I save changes, and Javascript is updating the page.  Without it, my test consistently fails because it is losing a race condition every time.

My first solution used a regex, and it killed my performance.  So, avoid those whenever possible, but don't be afraid to use them to get your watir-webdriver code working.  I also learned that while xpath and css selectors are options, ultimately there is usually a better (read: cleaner) way - you just have to find it.

If you're interested in my journey through using a regex, trying XPath, and settling on my final solution, you can find it documented on StackOverflow: http://stackoverflow.com/questions/10093114/how-can-i-find-an-acronym-tag-with-watir-webdriver-without-taking-a-huge-perfo

Thursday, April 5, 2012

The perfidy of AJAX and surprise attacks using when_present

If you are testing an asynchronous website which uses Javascript to create widgets, hide and show elements, etc, watir-webdriver can have trouble seeing them.  Watir does great waiting for pages to load without telling it specifically to do so.  However, when your AJAX calls change a website's Javascript, Watir doesn't know it needs to wait.

For example, my company has something called the Dashboard.  The Dashboard is a little tab that you can click and shoot out of the left-hand side of the page.  It's nifty, but my scripts were occasionally failing due to the AJAX not loading the page quickly enough.  An annoying, intermittent problem that took me a while to figure out and fix.

The solution is a little method called when_present.  I have a little method called Dashboard::switch_client.  It ensures I'm on the correct client site after I log in based on an Environment variable.

  def switch_client
    self.dashboard_button.click
    self.company_list.select @client
    self.dashboard_button.click
  end

My problem was in using the select box.  Sometimes it wasn't yet available.  Here's my solution:

  def switch_client
    self.dashboard_button.click
    self.company_list.when_present.select @client
    self.dashboard_button.click
  end

I now do this for all my menus and sub menus, calendar widgets, and any other widgets I have on the page.  when_present gives an element 30 seconds to appear by default before failing the test.  Over laggy connections, that's very helpful.

You can find more information and a couple similar methods for waiting for elements, including one that waits for an element to disappear in the RDoc: http://jarib.github.com/watir-webdriver/doc/Watir/Element.html#when_present-instance_method