Tuesday, August 14, 2007

New in RC0 - The Annotator

In RC0 we also built a cool little feature that was not really planned. Although this feature is not critical to performing automated testing, it can help many automators follow their test execution visually and figure out what their test code is doing step-by-step.

The Annotator can easily be enabled by setting the AnnotateExecution flag to true. This flag is part of WebAii's Settings object so it can be set both in app.config or programmatically using the Settings object. Once this flag is set, each automation action will be annotated on your browser surface. For example, the following two lines:


            // Set Google's search text to 'ArtOfTest'


            Find.ByName<HtmlInputText>("q").Text = "ArtOfTest";


 


            // Click Google's search button


            Find.ByName<HtmlInputSubmit>("btnG").Click();



Will annotate as follows:



If you wish to output your own annotations per Html element or simply output messages to the browser you can easily do that using the Actions object. The following lines:


            // Output a custom message by the search textbox.


            Actions.AnnotateElement(Find.ByName("q"), "This is the google search text box");


 


            // Output a general message to the browser window.


            Actions.AnnotateMessage("Now running Find.Byxx tests");



Output annotations as follows:



And last but not least, this feature won't be complete if the developers didn't get the option to format their own annotation styles and colors :). You can easily customize the colors/fonts to your liking by using the Settings off each annotator object.

For example I can customize my message as follows:


            ActiveBrowser.Annotator.Settings.FontemSize = 12;


            ActiveBrowser.Annotator.Settings.FontStyle = System.Drawing.FontStyle.Bold;


            ActiveBrowser.Annotator.Settings.BackColor = System.Drawing.Color.AliceBlue;


            ActiveBrowser.Annotator.Settings.Color = System.Drawing.Color.DarkKhaki;




Which will output:


If anyone has feedback on what else they would like to see added to this feature, feel free to send us a note or leave us a comment on our blog.

HINT: You should use this feature while setting the ExecutionDelay off the (Settings) also to some value so that you can slow down the execution of tests and follow the execution easier. Place the following two lines of code at the beginning of your tests to get annotation going.



            Manager.Settings.AnnotateExecution = true;


            Manager.Settings.ExecutionDelay = 500;


Thursday, August 2, 2007

New features in RC0

We've been heads down trying to get V1.0 out of the door. We apologize for not being active on the blog...

We've had great feedback from customers regarding issues they want to see fixed or improvements in WebAii. We've been trying to address these issues as they come along and we will be updating the RC builds more frequently to get customers these fixes if any are blocking them.

With RC0, we introduced few additional features that customers have been asking for. Specifically: HtmlControl suite that abstracts out actions/verifications. So you can do: button.Click() instead of Actions.Click(Element). or Assert.IsTrue(textBox.Text.Equals("foo") instead of Element.GetAttribute("value").Equals(""). In addition to many new features to make the abstraction even more powerful.

Here is a taste of what you can do with the HtmlControls suite in RC0:

Finding Controls


// Find an HTML Button with id htmlbutton and click it


Find.ById<HtmlButton>("htmlbutton").Click();



// Find the first table on the page.


HtmlTable outertable = Find.ByTagIndex<HtmlTable>("table", 0);


Assert.IsTrue(outertable.Rows.Count == 3);




A Find object scoped for searching only within the container html control.


// Find the first table inside the outer table


//


// Note: HtmlContainerControls have a Find object


// associated with them that scopes all the Find.Byxx searches


// to elements contained within them only.


// So even if you have multiple controls with similar contained


// elements, this will help avoid any conflicts.


// Also, note how we are referencing the innertable using index 0


// since it is the first table inside our outer table.


//


HtmlTable innerTable = outertable.Find.ByTagIndex<HtmlTable>("table", 0);


HtmlTableCell cell = innerTable.Find.TableCell("TD21");


Assert.IsTrue(cell.Text.Equals("TD21"));




Navigate up the control tree


// Find the table that contains this cell.


// Navigate up until you find the first html table.


HtmlTable table = cell.Parent<HtmlTable>();




Find all controls that meet certain criteria. Just like the Find.AllByxx


// Find all HtmlInputText control with src containing partial value foo


IList<HtmlInputText> txtCtrls = Find.AllByAttributes<HtmlInputText>("src=~foo");




Automate actions on the control


//


// CLICKING


//


// Click using the DOM


Find.ById<HtmlInputButton>("button1").Click();


//


// Click using a pure desktop mouse click


Find.ById<HtmlInputButton>("button1").MouseClick();


//


// Check a checkbox and invoke the onclick event.


HtmlInputCheckBox ck = Find.ById<HtmlInputCheckBox>("checkbox1");


ck.Check(true, true);


//


// Query the checked state


Assert.IsTrue(ck.Checked);


//


// Invoke event on the control.


HtmlAnchor link = Find.ByAttributes<HtmlAnchor>("href=~google");


// Invoke any events on the control


link.InvokeEvent(ScriptEventType.OnFocus);


//


// You can capture any element on the page using the .Capture()


// Will be stored to the Log.LogLocation


Find.ById<HtmlInputImage>("image1").Capture("myfile");


//


// SELECTING


//


HtmlSelect select = Find.ById<HtmlSelect>("select1");


Assert.IsTrue(select.SelectedOption.Value.Equals("Option1Text"));


Assert.IsTrue(select.SelectedOption.Text.Equals("Option1"));


//


//


// and much more...




Get any control property directly from the DOM including Read-Only properties. You can also set any property


// Get whether a checkbox is enabled or disabled.


HtmlInputCheckBox cks = Find.ById<HtmlInputCheckBox>("checkbox1");


bool disabled = cks.GetValue<bool>("disabled");



// Disable it


cks.SetValue<bool>("disabled", true);



Assert.IsTrue(cks.GetValue<bool>("disabled"));




Hope you enjoy using these new features. Send us some feedback on what else you would like to see in the framework that would make your testing more productive..

BTW - A recorder is in the works...