Tuesday, August 9, 2011

Watir Tutorial: Error Recovery

So your script is happily humming along, testing myriad little tests, and then despite all your best efforts, it hangs!  Tragedy!  Sometimes despite our best efforts, it will still crash.  But it doesn't have to be like that.  No sir.

Ruby comes with error handling and with just a few lines of code, you can get your script to recover itself when it hangs, as it sometimes will.

If you need a primer on exceptions and error handling, I recommend Alan Skorkin's post about it.  As he covers a great deal of what you need to know, we will just be talking about the Watir code you will use.

And here it is:

  1. while !(b.frame(:id => "e1menuAppIframe").text.include? "Welcome!")
  2.   autoit.Send("^!l")
  3. end
  4. retry

What this will do, is hit cancel until you are back at the welcome screen.  So by placing this in the 'rescue' portion of your error handling and the begin statement after where you would initially be seeing the welcome screen in the first place, it will work like a dream.

I understand this won't work for all cases, but for some it will, and for those that it will, it makes the testing go that much smoother!  Enjoy~

Watir Tutorial: Too fast for ya?

One of the first issues I encountered was my script running too fast for the browser's loading time.  Watir will click a button or tab out of a field, or any number of things that requires a little of time to load and would metaphorically trip on it's own feet.  OATS (Oracle Application Testing Suite), which is run in Java fixes this by waiting until the page is loaded and then 'sleeping' for a second or two and then continuing on.  It will actually time how long the user is paused when you are writing your scripts there.  Watir has a similar functionality in that you can code in:  "sleep 2", and it will pause for 2 seconds, wherever your heart desires.  This is nice as a second line of defense but definitely not as a first, in my opinion.  There are a number of things that can go wrong in a testing script that has 1000 cases, even if 99% of the time it will load within 2 seconds, you will inevitably have some outliers that may make your script choke because the server hung for too long, or whatever may happen.

Watir developers added a nice little method called "wait_until", and it does just that!  It will wait until a given condition is met, checking every half second for a maximum of sixty seconds.  The best way to use this is in conjunction with a method to look for something that will come up in the next screen, or better yet, the actual field that you will be using in the next screen.  There are a couple of places I have used these, which I will illustrate:

1.  Wait until text field exists

Going back to the Watir example, we can make a somewhat redundant improvement to the code that they have there. 

  1. require 'rubygems'
  2. require 'watir'
  3. browser = Watir::Browser.new
  4. browser.goto("http://bit.ly/watir-example")
  5. browser.wait_until {browser.text_field(:name => "entry.0.single").exist?}
  6. browser.text_field(:name => "entry.0.single").set "Watir"

Again:  Probably not necessary in this situation, but it illustrates a point that the difference that we see on one run between a script that includes line 5, and one that excludes it is nil.  But running and rerunning it, or in a different script it will mean the difference between a crash and the computer waiting half a second longer for the page to finish loading. 

2.  Wait until text is included

If your next screen has no fields, or even if it does, this is a good option. 

  1. b.wait_until {b.text.include? "Real Time Account Statement"}

I use this single line of code to tell Watir to wait for a screen within one of our programs.  Is it always necessary?  No.  Sometimes it can completely autopilot, but inevitably it will choke and the script will have to be restarted, this method is very nearly fool-proof.  (I say this because I have still seen it crash, albeit with much less frequency).

The example code is pretty self-explanatory, in that the first part is always the same, what is within the brackets is your conditional of either the '.include?' or '.exist?' flavors as you need.  Don't forget that within the brackets and in your include or exist statement you may have to tell it that the thing it is looking for is within a frame somewhere.  Like in our case with EnterpriseOne, you may need to specify where the specific object is so that Watir can find it. For example: 

  1. b.frame(:id => "e1menuAppIframe").text.include? "Welcome!"

I use this include statement to look for the "Welcome!" message after logging into EnterpriseOne. 

Watir Tutorial: Getting a value from a text field


I ran into this problem today, doing a comparison and thought I should write about it.  I will be using the Watir example to illustrate. 

The short and simple answer is that if you have this defined as your browser, and you set the given text field to a specific value:

  1. require 'rubygems'
  2. require 'watir'
  3. browser = Watir::Browser.new
  4. browser.goto("http://bit.ly/watir-example")
  5. browser.text_field(:name => "entry.0.single").set "Watir"
  6. happy = browser.text_field(:name => "entry.0.single").value
  7. puts happy

Then happy will return the value in that text field:  Watir.

The value that is passed back will be a string, and the same is true even if the value is numerical in nature:  

  1. browser.text_field(:name => "entry.0.single").set "42"
  2. happy = browser.text_field(:name => "entry.0.single").value
  3. happy.is_a?(String)

This will return true if you output it to console. 

Monday, August 8, 2011

Watir and JD Edwards

I started off looking around at testing solutions several weeks ago and stumbled upon a wikipedia article about testing platforms, and the only one listed was a little trinket named "Watir" which stands for "Web Application Testing In Ruby", pronounced "water".

I decided to check it out, and quickly found that it was quite easy to install, implement, and use for a number of different tasks on our system. It is fairly well documented for the most straight-forward of cases, but gets a little hairy when your web applications get much more complicated than straight HTML. There were several problems that I found when using Watir, which I wanted to discuss for the benefit of those that will come after as it took me some digging to solve these issues. I will be blogging about these discoveries from here on out.

Watir Tutorial: AutoIt


This will be a short post:  As this is just a quick primer into what you can do in JD Edwards with AutoIt and Watir.  I will assume you have read this post, so that everything is put together on your computer as it should be.

To be concise, for your reference you will need this page, to reference the different commands and code to get AutoIt to work as you want it to. 

If you want to hit the 'OK' button in the form exit, we use the keyboard shortcut to do so:  'CTRL+ALT+O'

The way you would do this in your script, would be to have the following lines of code:

  1. require 'win32ole'
  2. autoit = WIN32OLE.new('AutoItX3.Control')
  3. autoit.Send("^!o")


The first line is for loading the gem so that you can access AutoIt (I don't know exactly what it does, but I think it is for accessing other programs outside of Ruby, because AutoIt can be used seperately).  A new object called autoit is created, with the specified class.  The third line is where we actually tell the keyboard to click "ctrl+alt+o".

Remember to use this cheatsheet for your reference in using AutoIt!

Watir Tutorial: Installation

This is actually the second tutorial that I have written for this, and I found that there were several things that I should have covered before trying to tackle text fields within a program, that if you are new at this, would be way beyond what you can do already anyways.  So let's start with something slightly easier, installation!

Really, this should be fairly easy to do, as Watir is well documented enough for installation as far as I can tell, but in case it isn't, I will go step by step through it here, for the benefit of those that come after (in memory of the pioneers). So let's start with Ruby installation then, in case you are completely new to this. 

A bit of history:  Ruby was developed in the mid 90's by Yukihiro Matsumoto, who goes by "Matz", and who also happens to be a member of the LDS Church.  Way to go!

In order to install Ruby on Windows, which if you are working with JD Edwards, I'm assuming you are using, go here.  This is the easiest way to do it, most people refer to it as the "one click installation" or something of the sort, making it pretty easy.

What this will do is put into your start menu a shortcut called "Start command prompt with ruby", pretty neat, huh? 

Now we need to update Ruby, and get the necessary "gems" (a fancy name for libraries, or pre-compiled and packaged bits of programs for our use), so that Watir will work correctly.

Go ahead and click on "Start command prompt with ruby", and follow the installation instructions here



Since we are concerned with using this for JD Edwards testing, we have a little bit more to do so that we can do everything that an end-user could and would do.  One of the problems I have encountered involved the menu-exits on the EnterpriseOne screen, and because of this we have to use a little work around for now, if I solve it later I will be sure to post about that, but for now we need to do a little bit more. 

Go ahead and click here to download a program called "AutoIt".  What this is used for is to emulate key strokes on the keyboard.  When using it, you have to put "require 'win32ole'" at the beginning of your script to load the correct library.  I will be going into it's use more later, in a different tutorial. 



The last thing we have to get, is a little program called TinyTDS.  Finding this little gem(literally and figuratively), took forever.  I want you, the reader, to appreciate just how much trouble this took me to find.  (Because obviously the finder has the harder task than the writer of the actual program).  We run our JDE databases off of SQL Server.  I've read just about every article and forum post out there about connecting ruby to the database and getting it to make some queries for testing.  Obviously I hadn't because I didn't find this program until I got a tip off about the creator of the SQL Server gem itself (@metaskills) whose website is here.  I found there the program that sounded like it would work, and lo and behold it did!

Now, I understand that not everyone out there, having trouble with their database playing nicely with Ruby will find a solution in this.  But maybe someone out there will.  Just remember to ask someone that knows better than you do, after you have done all you can.

TinyTDS has a great source of documentation, that takes a little decyphering but works like a charm, I will be detailing my findings here as well, but here is where to start. 

Remember to "require 'tiny_tds'" after you have executed "gem install tiny_tds" from the command prompt with ruby. 

Watir Tutorial: Text fields in JD Edwards Enterprise One

Because JD Edwards' Enterprise One system is a web application, it can be easily tested using Watir.  The only issue I found in the most straightforward of testing is when you encounter Javascript in places like grids.  Text fields and most buttons work as expected, although you do have to drill into the HTML a step or two.  Let me give you an example.  (I will assume that EnterpriseOne, and Watir are both installed and functioning properly, as these are beyond the scope of what I intend to do here.  I will also be using Internet Explorer for this, with the Developer toolbar installed, as per the recommendation by the Watir community to locate the correct HTML tags for testing).





Let's start with a nice basic window:  The Word search window, and in our system the Fastpath would be 'P01BDWRD'.  At first glance we have a text field, a check box and a grid.  This shouldn't require any testing really since it is maintained by Oracle as I understand it, but it's an example for how to write scripts, nothing more.

Let's open the Developer Toolbar and click on the 'Search word' text field to find where it is located in the HTML.  A blue box should appear, as shown below (where the red arrow is pointing).  At the bottom, note the id field, and the name field.  Both are similar and in my tests I have used both (probably redundantly), but you may only need to use one, I'll do some testing and update later.  (Ignore the 'LEWIS*' there for now, I was just testing it.)




The other information you need is a little ways back up on the left hand window, the 'tree view', what you are looking for is indicated below, the id "e1menuAppIframe", and this will also be used later in your testing. 


The way that we tell Watir through Ruby to fill in this field is through these parameters we have just discovered using the Developer Toolbar.  Let me show you what we would code up to illustrate: 

  1. require 'rubygems'
  2. require 'watir'
  3. b = Watir::Browser.new
  4. b.goto("http://my.e1site.org")
  5. b.text_field(:name => "User").set("myUserName")
  6. b.text_field(:name => "Password").set("myPassword")
  7. b.button(:type => "submit").click
  8. b.text_field(:id =>"TE_FAST_PATH_BOX").set "P01BDWRD"
  9. b.form(:action => "/jde/E1Menu_FastPath.mafService?e1.state=maximized&e1.mode=view&e1.namespace=&e1.service=E1Menu_FastPath&RENDER_MAFLET=E1Menu").submit
  10. b.frame(:id => "e1menuAppIframe").text_field(:id => "C0_18").set("LEWIS*")

The line that we are concerned with right now is line 15 which sets our text field to the value that we want.

"b.frame(:id => "e1menuAppIframe")" is what we have to drill into to get within the correct frame.  Simply coding up the last part of line 15 I have found is not enough for Watir to find the text field in question.  Just take it as a rule of thumb, that when you are working in a program within JD Edwards, that you need to tell it that you are using that frame, and then from there tell it the text field or the button or check box or whatever.

The other piece of information we got earlier is what we use to tell it which text field.

".text_field(:id => "C0_18")" is what I had to use next, to tell it that we wanted to talk with the "Search Word" field.

Finally, ".set("LEWIS*")" is used to set the text field to the value in question.

Don't forget, that we could have used ".set("#{variabledata}")" and a for loop to cycle through an array called variabledata to get through a while set of data that we want to test.  If you are following along, and haven't successfully made a call to your database to get that data, then we will cover that later.

I hope that this has been helpful!