in

ArtOfTest, Inc. Community Forums

Discuss and ask questions about ArtOfTest's products.

ArtOfTest Inc.

August 2007 - Posts

  • 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:

    {\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 // Set Google's search text to 'ArtOfTest'\par ??\cf0 Find.ByName<\cf10 HtmlInputText\cf0 >(\cf13 "q"\cf0 ).Text = \cf13 "ArtOfTest"\cf0 ;\par ??\par ?? \cf11 // Click Google's search button\par ??\cf0 Find.ByName<\cf10 HtmlInputSubmit\cf0 >(\cf13 "btnG"\cf0 ).Click();\par ??}
    -->


                // 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:

    {\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 // Output a custom message by the search textbox.\par ??\cf0 Actions.AnnotateElement(Find.ByName(\cf13 "q"\cf0 ), \cf13 "This is the google search text box"\cf0 );\par ??\par ?? \cf11 // Output a general message to the browser window.\par ??\cf0 Actions.AnnotateMessage(\cf13 "Now running Find.Byxx tests"\cf0 );\par ??}
    -->

                // 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:

    {\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 ActiveBrowser.Annotator.Settings.FontemSize = 12;\par ?? ActiveBrowser.Annotator.Settings.FontStyle = System.Drawing.\cf10 FontStyle\cf0 .Bold;\par ?? ActiveBrowser.Annotator.Settings.BackColor = System.Drawing.\cf10 Color\cf0 .AliceBlue;\par ?? ActiveBrowser.Annotator.Settings.Color = System.Drawing.\cf10 Color\cf0 .DarkKhaki;}
    -->

                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.


    {\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 Manager.Settings.AnnotateExecution = \cf2 true\cf0 ;\par ?? Manager.Settings.ExecutionDelay = 500;\par ??}
    -->

                Manager.Settings.AnnotateExecution = true;


                Manager.Settings.ExecutionDelay = 500;


     

  • 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

    {\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...

     

More Posts
Copyrights © 2008 ArtOfTest, Inc. All rights reserved.