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
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Lucida Console;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf11 // Find an HTML Button with id htmlbutton and click it\par ??\cf0 Find.ById<\cf10 HtmlButton\cf0 >(\cf13 "htmlbutton"\cf0 ).Click();\par ??\par ?? \cf11 // Find the first table on the page.\par ??\cf0 \cf10 HtmlTable\cf0 outertable = Find.ByTagIndex<\cf10 HtmlTable\cf0 >(\cf13 "table"\cf0 , 0);\par ?? \cf10 Assert\cf0 .IsTrue(outertable.Rows.Count == 3);}
-->
// 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.
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Lucida Console;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf11 // Find the first table inside the outer table\par ??\cf0 \cf11 //\par ??\cf0 \cf11 // Note: HtmlContainerControls have a Find object \par ??\cf0 \cf11 // associated with them that scopes all the Find.Byxx searches\par ??\cf0 \cf11 // to elements contained within them only. \par ??\cf0 \cf11 // So even if you have multiple controls with similar contained\par ??\cf0 \cf11 // elements, this will help avoid any conflicts.\par ??\cf0 \cf11 // Also, note how we are referencing the innertable using index 0\par ??\cf0 \cf11 // since it is the first table inside our outer table.\par ??\cf0 \cf11 //\par ??\cf0 \cf10 HtmlTable\cf0 innerTable = outertable.Find.ByTagIndex<\cf10 HtmlTable\cf0 >(\cf13 "table"\cf0 , 0);\par ?? \cf10 HtmlTableCell\cf0 cell = innerTable.Find.TableCell(\cf13 "TD21"\cf0 );\par ?? \cf10 Assert\cf0 .IsTrue(cell.Text.Equals(\cf13 "TD21"\cf0 ));}
-->
// 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{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Lucida Console;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf11 // Find the table that contains this cell.\par ??\cf0 \cf11 // Navigate up until you find the first html table.\par ??\cf0 \cf10 HtmlTable\cf0 table = cell.Parent<\cf10 HtmlTable\cf0 >();}
-->
// 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{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Lucida Console;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf11 // Find all HtmlInputText control with src containing partial value foo\par ??\cf0 \cf10 IList\cf0 <\cf10 HtmlInputText\cf0 > txtCtrls = Find.AllByAttributes<\cf10 HtmlInputText\cf0 >(\cf13 "src=~foo"\cf0 );\par ??}
-->
// Find all HtmlInputText control with src containing partial value foo
IList<HtmlInputText> txtCtrls = Find.AllByAttributes<HtmlInputText>("src=~foo");
Automate actions on the control{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Lucida Console;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf11 //\par ??\cf0 \cf11 // CLICKING\par ??\cf0 \cf11 //\par ??\cf0 \cf11 // Click using the DOM\par ??\cf0 Find.ById<\cf10 HtmlInputButton\cf0 >(\cf13 "button1"\cf0 ).Click();\par ?? \cf11 //\par ??\cf0 \cf11 // Click using a pure desktop mouse click\par ??\cf0 Find.ById<\cf10 HtmlInputButton\cf0 >(\cf13 "button1"\cf0 ).MouseClick();\par ?? \cf11 //\par ??\cf0 \cf11 // Check a checkbox and invoke the onclick event.\par ??\cf0 \cf10 HtmlInputCheckBox\cf0 ck = Find.ById<\cf10 HtmlInputCheckBox\cf0 >(\cf13 "checkbox1"\cf0 );\par ?? ck.Check(\cf2 true\cf0 , \cf2 true\cf0 );\par ?? \cf11 //\par ??\cf0 \cf11 // Query the checked state\par ??\cf0 \cf10 Assert\cf0 .IsTrue(ck.Checked);\par ?? \cf11 //\par ??\cf0 \cf11 // Invoke event on the control.\par ??\cf0 \cf10 HtmlAnchor\cf0 link = Find.ByAttributes<\cf10 HtmlAnchor\cf0 >(\cf13 "href=~google"\cf0 );\par ?? \cf11 // Invoke any events on the control\par ??\cf0 link.InvokeEvent(\cf10 ScriptEventType\cf0 .OnFocus);\par ?? \cf11 //\par ??\cf0 \cf11 // You can capture any element on the page using the .Capture()\par ??\cf0 \cf11 // Will be stored to the Log.LogLocation\par ??\cf0 Find.ById<\cf10 HtmlInputImage\cf0 >(\cf13 "image1"\cf0 ).Capture(\cf13 "myfile"\cf0 ); \par ?? \cf11 //\par ??\cf0 \cf11 // SELECTING\par ??\cf0 \cf11 //\par ??\cf0 \cf10 HtmlSelect\cf0 select = Find.ById<\cf10 HtmlSelect\cf0 >(\cf13 "select1"\cf0 );\par ?? \cf10 Assert\cf0 .IsTrue(select.SelectedOption.Value.Equals(\cf13 "Option1Text"\cf0 ));\par ?? \cf10 Assert\cf0 .IsTrue(select.SelectedOption.Text.Equals(\cf13 "Option1"\cf0 ));\par ?? \cf11 //\par ??\cf0 \cf11 //\par ??\cf0 \cf11 // and much more...}
-->
//
// 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{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Lucida Console;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0??;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;??\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;??\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;??\red192\green192\blue192;}??\fs20 \cf11 // Get whether a checkbox is enabled or disabled.\par ??\cf0 \cf10 HtmlInputCheckBox\cf0 cks = Find.ById<\cf10 HtmlInputCheckBox\cf0 >(\cf13 "checkbox1"\cf0 );\par ?? \cf2 bool\cf0 disabled = cks.GetValue<\cf2 bool\cf0 >(\cf13 "disabled"\cf0 );\par ??\par ?? \cf11 // Disable it\par ??\cf0 cks.SetValue<\cf2 bool\cf0 >(\cf13 "disabled"\cf0 , \cf2 true\cf0 );\par ??\par ?? \cf10 Assert\cf0 .IsTrue(cks.GetValue<\cf2 bool\cf0 >(\cf13 "disabled"\cf0 ));}
-->
// 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...