QA/TDAI/Gristmill/Boilerplate Explained: Difference between revisions

From MozillaWiki
< QA‎ | TDAI‎ | Gristmill
Jump to navigation Jump to search
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 4: Line 4:
Here is the generated code from the "Test->New Boilerplate" step in the Gristmill UI.  We'll go through it line by line to see what each item does.
Here is the generated code from the "Test->New Boilerplate" step in the Gristmill UI.  We'll go through it line by line to see what each item does.
<pre>
<pre>
var elementslib = {}; Components.utils.import('resource://mozmill/modules/elementslib.js', elementslib);
var elementslib = {};  
var controller = {}; Components.utils.import('resource://mozmill/modules/controller.js', controller);
Components.utils.import('resource://mozmill/modules/elementslib.js', elementslib);
 
var mozmill = {};  
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
Components.utils.import('resource://mozmill/modules/mozmill.js', mozmill);
var _w = wm.getMostRecentWindow("navigator:browser");
var browser = new controller.MozMillController(_w);


var test_foo = function(){
var test_foo = function(){
  browser.type(new elementslib.ID(_w.document, 'urlbar'), "http://www.heckyes.com");
  var controller = mozmill.getBrowserController();
  browser.sleep(5000);
controller.open('http://www.google.com');
  browser.click(new elementslib.ID(_w.document, 'home-button'));
  controller.sleep(2000);
  browser.open('http://www.google.com');
  controller.type(new elementslib.Name(controller.window.content.document, 'q'), 'Mozilla');
  controller.click(new elementslib.Name(controller.window.content.document, 'btnG'));
}
}</pre>
}</pre>


Line 26: Line 26:
This statement imports a Javascript library file to the scope of your test.  This means that you can now access all the exported functions from the elementslib.  The elementslib is used to locate and grab UI elements to interact with.
This statement imports a Javascript library file to the scope of your test.  This means that you can now access all the exported functions from the elementslib.  The elementslib is used to locate and grab UI elements to interact with.


<pre>var controller = {};
<pre>var mozmill = {};  
Components.utils.import('resource://mozmill/modules/controller.js', controller);</pre>
Components.utils.import('resource://mozmill/modules/mozmill.js', mozmill);</pre>
This is the same thing, except we are loading the controller library.  The controller allows us the ability to perform interactions on UI elements.
This is the same thing, except we are loading the mozmill library.  The mozmill library is the library that will give us access to everything else in the application, particularly the controller library.
 
<pre>var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);</pre>
The WindowMediator allows us to flip between different open windows.
 
<pre>var _w = wm.getMostRecentWindow("navigator:browser");</pre>
This grabs the most recent browser window.
 
<pre>var browser = new controller.MozMillController(_w);</pre>
This creates a controller instance for the most recently opened browser window.  It names it "browser" so that the code will later look like you are telling the browser what to do.  We think it makes the code more readable.


== The Real Test Code ==
== The Real Test Code ==
Line 44: Line 35:
Here is an overview of the test function before we dismantle it line by line:
Here is an overview of the test function before we dismantle it line by line:
<pre>var test_foo = function(){
<pre>var test_foo = function(){
  browser.type(new elementslib.ID(_w.document, 'urlbar'), "http://www.heckyes.com");
  var controller = mozmill.getBrowserController();
  browser.sleep(5000);
controller.open('http://www.google.com');
  browser.click(new elementslib.ID(_w.document, 'home-button'));
  controller.sleep(2000);
  browser.open('http://www.google.com');
  controller.type(new elementslib.Name(controller.window.content.document, 'q'), 'Mozilla');
  controller.click(new elementslib.Name(controller.window.content.document, 'btnG'));
}</pre>
}</pre>


Line 53: Line 45:
This names our test "test_foo" and creates a function.  Each test is one function, named test_<something>. Try to name them descriptively for what you are testing.  The test function can call other functions, but other functions won't be called by Gristmill unless they begin with "test_".
This names our test "test_foo" and creates a function.  Each test is one function, named test_<something>. Try to name them descriptively for what you are testing.  The test function can call other functions, but other functions won't be called by Gristmill unless they begin with "test_".


<pre>browser.type(new elementslib.ID(_w.document, 'urlbar'), "http://www.heckyes.com");</pre>
<pre>var controller = mozmill.getBrowserController();</pre>
This is a typical embedded statement.  The interior: "new elementslib.ID(_w.document, 'urlbar')" piece creates an element object from the urlbar in the main window _w"urlbar" is the XUL ID of the Location Bar in the browser.  You can find that using the DOM Explorer Extension or the Explorers->DOM Explorer UI from the Mozmill IDE window.
This gives us a controller object for the current browser window.  Most of the [[QA/TDAI/Gristmill/Gristmill_API|Gristmill API's]] are accessible through the controller object.


The rest of this statement then becomes a bit clearer if we substitute the word "UrlBarObject" for the element Object we discussed above.  For example it becomes:
<pre>controller.open('http://www.google.com');</pre>
<pre>browser.type(<UrlBarObject>, "http://www.heckyes.com");</pre>
This opens a new page to google.com
Now, it's easy to see that this is going to type the string "http://www.heckyes.com" into the URLBar of the browser.  And that's exactly what it does.


We write the action lines using this embedded statement method so that each line of the file is one action in the test.  It makes sense to us to do it this way so that you can quickly read what the test does.
<pre>controller.sleep(2000);</pre>
It looks like we are telling the controller to put the browser to sleep for 2000 milliseconds (i.e. 2 seconds).  What we are '''actually''' doing is telling the controller to sleep our test for 2000 millisecondsThis way the test stops executing while we await the page load of google.com.  You would use these sleeps and the related "WaitForElement" actions in order to allow the browser time to do something before you go on with the next instruction in the test.  Note that all sleeps and timeouts are in milliseconds.  (1000 milliseconds == 1 second)
 
<pre>controller.type(new elementslib.Name(controller.window.content.document, 'q'), 'Mozilla');</pre>
This is a typical embedded statement.  The interior: "new elementslib.Name(controller.window.content.document, 'q')" piece creates an element object from the element in the content document named 'q'.  The content document is the loaded web page.  And the element named on this page named 'q'  is the search bar text box.  So this generates an element object referring to the search textbox.  You can find this name using the DOM Explorer Extension or the Explorers->DOM Explorer UI from the Mozmill IDE window.


<pre>browser.sleep(5000);</pre>
The rest of this statement then becomes a bit clearer if we substitute the word "TextBoxObject" for the element object we discussed above.  For example it becomes:
This is a little confusing here.  It looks like we are telling the browser to sleep for 5000 milliseconds (i.e. 5 seconds).  What we are '''actually''' doing is telling the browser to sleep our test for 5000 milliseconds.  This way the test stops executing while the typing is performed.  You would use these sleeps and the related "WaitForElement" actions in order to allow the browser time to do something before you go on with the next instruction in the testNote that all sleeps and timeouts are in milliseconds.  (1000 milliseconds == 1 second).
<pre>controller.type(<TextBoxObject>, "Mozilla");</pre>
Now, it's easy to see that this is going to type the string "Mozilla" into the Google search textbox of the HTML pageAnd that's exactly what it does.


<pre>browser.click(new elementslib.ID(_w.document, 'home-button'));</pre>
We write the action lines using this embedded statement method so that each line of the file is one action in the testIt makes sense to us to do it this way so that you can quickly read what the test does.
Now that we are pro's at reading these embedded statements.  We see that this creates an element object from the home button (which is found in the current Window's Document interface) and clicks itThis will cause us to load the currently set home page.


<pre>browser.open('http://www.google.com');</pre>
<pre>controller.click(new elementslib.Name(controller.window.content.document, 'btnG'));</pre>
This is a shortcut to tell the browser to open the given URL (in this case, "http://www.google.com") using the currently active tab.
Now that we are pro's at reading these embedded statements.  We see that this creates an element object from the button named 'btnG' in the content document and clicks it.  So, this causes us to click the search button, initiating a Google search for "Mozilla".


<pre>}</pre>
<pre>}</pre>
This is the closing brace of our test_foo function.  This marks the end of that function.  More test_* functions can follow, and those will be executed as separate tests by Gristmill. Or, other functions can follow that do not have a name beginning with "test_", and these will be seen as helper functions by Gristmill and will '''not''' be executed automatically.
This is the closing brace of our test_foo function.  This marks the end of that function.  More test_* functions can follow, and those will be executed as separate tests by Gristmill. Or, other functions can follow that do not have a name beginning with "test_", and these will be seen as helper functions by Gristmill and will '''not''' be executed automatically.

Latest revision as of 01:55, 15 August 2008

<< Back to Gristmill Main Page

The BoilerPlate

Here is the generated code from the "Test->New Boilerplate" step in the Gristmill UI. We'll go through it line by line to see what each item does.

var elementslib = {}; 
Components.utils.import('resource://mozmill/modules/elementslib.js', elementslib);
var mozmill = {}; 
Components.utils.import('resource://mozmill/modules/mozmill.js', mozmill);

var test_foo = function(){
 var controller = mozmill.getBrowserController();
 controller.open('http://www.google.com');
 controller.sleep(2000);
 controller.type(new elementslib.Name(controller.window.content.document, 'q'), 'Mozilla');
 controller.click(new elementslib.Name(controller.window.content.document, 'btnG'));
}
}

Line by Line Explanation

Setting up the Envrionment

The first block of code sets up the proper environment for your test.

var elementslib = {};
Components.utils.import('resource://mozmill/modules/elementslib.js', elementslib);

This statement imports a Javascript library file to the scope of your test. This means that you can now access all the exported functions from the elementslib. The elementslib is used to locate and grab UI elements to interact with.

var mozmill = {}; 
Components.utils.import('resource://mozmill/modules/mozmill.js', mozmill);

This is the same thing, except we are loading the mozmill library. The mozmill library is the library that will give us access to everything else in the application, particularly the controller library.

The Real Test Code

This is the test code, and it is the section you should customize to write your test. We've included a simple sample test in the boilerplate to give you a place to start.

Here is an overview of the test function before we dismantle it line by line:

var test_foo = function(){
 var controller = mozmill.getBrowserController();
 controller.open('http://www.google.com');
 controller.sleep(2000);
 controller.type(new elementslib.Name(controller.window.content.document, 'q'), 'Mozilla');
 controller.click(new elementslib.Name(controller.window.content.document, 'btnG'));
}
var test_foo = function(){

This names our test "test_foo" and creates a function. Each test is one function, named test_<something>. Try to name them descriptively for what you are testing. The test function can call other functions, but other functions won't be called by Gristmill unless they begin with "test_".

var controller = mozmill.getBrowserController();

This gives us a controller object for the current browser window. Most of the Gristmill API's are accessible through the controller object.

controller.open('http://www.google.com');

This opens a new page to google.com

controller.sleep(2000);

It looks like we are telling the controller to put the browser to sleep for 2000 milliseconds (i.e. 2 seconds). What we are actually doing is telling the controller to sleep our test for 2000 milliseconds. This way the test stops executing while we await the page load of google.com. You would use these sleeps and the related "WaitForElement" actions in order to allow the browser time to do something before you go on with the next instruction in the test. Note that all sleeps and timeouts are in milliseconds. (1000 milliseconds == 1 second)

controller.type(new elementslib.Name(controller.window.content.document, 'q'), 'Mozilla');

This is a typical embedded statement. The interior: "new elementslib.Name(controller.window.content.document, 'q')" piece creates an element object from the element in the content document named 'q'. The content document is the loaded web page. And the element named on this page named 'q' is the search bar text box. So this generates an element object referring to the search textbox. You can find this name using the DOM Explorer Extension or the Explorers->DOM Explorer UI from the Mozmill IDE window.

The rest of this statement then becomes a bit clearer if we substitute the word "TextBoxObject" for the element object we discussed above. For example it becomes:

controller.type(<TextBoxObject>, "Mozilla");

Now, it's easy to see that this is going to type the string "Mozilla" into the Google search textbox of the HTML page. And that's exactly what it does.

We write the action lines using this embedded statement method so that each line of the file is one action in the test. It makes sense to us to do it this way so that you can quickly read what the test does.

controller.click(new elementslib.Name(controller.window.content.document, 'btnG'));

Now that we are pro's at reading these embedded statements. We see that this creates an element object from the button named 'btnG' in the content document and clicks it. So, this causes us to click the search button, initiating a Google search for "Mozilla".

}

This is the closing brace of our test_foo function. This marks the end of that function. More test_* functions can follow, and those will be executed as separate tests by Gristmill. Or, other functions can follow that do not have a name beginning with "test_", and these will be seen as helper functions by Gristmill and will not be executed automatically.