So, for my next post, I thought I would focus on the first step to web-testing with TC. A simple function to return the page object of your browser. Using a function for this allows you to code for both IE and FF simultaneously, in addition to allowing you to use more complex logic to look through multiple windows, check for navigation warnings, or anything else you need.
To start, open up TC7, and IE7. Navigate to any web page, for this example we can use google. Go to google and search for testcomplete. (this is important so we are on the search results page). The url should be : http://www.google.com/search?hl=en&source=hp&q=testcomplete&aq=f&oq=&aqi=g1g-s1g4g-s1g1g-s2. If your url is different, modify any references to the url to match YOUR url.
Now using the object finder, highlight the search box, and look at its path:
Sys.Process("iexplore").Page("http://www.google.com/search?hl=en&source=hp&q=testcomplete&aq=f&oq=&aqi=g1g-s1g4g-s1g1g-s2").Panel("header").Form("tsf").Table("sft").Cell(0, 1).Table(0).Cell(0, 0).Textbox("q")
Textbox("q") is the search field we are trying to access. If you look at its properties, you will see a "value" field. Anything entered into the text field will be stored as its value, and by modifying this directly we can interact with the search box.
Now that we have a unique identifier for the search textbox on the page, and we know how to modify it. We can use this to access our object, and perform searches, but if anything about the path changes (such as the url) our test will break.
To illustrate, put the following function into your Project (using javascript as your language). There are two lines, the first line modifies the search parameter, the second step clicks on the search button.
function testGoogle()
{
Sys.Process("iexplore").Page("http://www.google.com/search?hl=en&source=hp&q=testcomplete&aq=f&oq=&aqi=g1g-s1g4g-s1g1g-s2").Panel("header").Form("tsf").Table("sft").Cell(0, 1).Table(0).Cell(0, 0).Textbox("q").value="TestComplete Tricks";
Sys.Process("iexplore").Page("http://www.google.com/search?hl=en&source=hp&q=testcomplete&aq=f&oq=&aqi=g1g-s1g4g-s1g1g-s2").Panel("header").Form("tsf").Table("sft").Cell(0, 1).Table(0).Cell(0, 0).SubmitButton("btnG").Click();
}
Right click inside the function, and Run the Current Routine. TC should modify the search box to be the words "TextComplete Tricks", and then click the search button. Congrats, you have just automated a google search.
Now, if you try to run the function a second time, it will fail. Why? Because our url changed. There are a couple options on what to do now. The easiest is to use wildcards to remove the url from inside Page(), and replace it with Page("*"). This tells TC to use ANY open page, which works fine as long as we only have 1 window or tab open. If you have more than one, it will pick one essentially randomly. And if it picks the wrong one, your tests will fail in a giant flame. We can also have a substring, so you can modify it to say Page("*google*"), and this will use the page that contains google in the url.
Again, this works, but we will need to modify every single instance of the Page() call every time we change url's. Or, if we want to run the same test in firefox, we will need a completely different test.
The easy solution is to create a new function called Page(). We can then create custom logic to determine which page object we want to use.
So, copy and paste the following function into TC.
function Page()
{
return Sys.Process("iexplore").Page("*");
}
This function returns the Page object of ANY open IE page. We can then modify our original function to be as follows, and the run the routine. You can execute this multiple times, or change the search string, and it will not fail.
function testGoogle()
{
Page().Panel("header").Form("tsf").Table("sft").Cell(0, 1).Table(0).Cell(0, 0).Textbox("q").value="TestComplete Tricks";
Page().Panel("header").Form("tsf").Table("sft").Cell(0, 1).Table(0).Cell(0, 0).SubmitButton("btnG").Click();
}
In addition, note how much smaller and more compact our code is. In addition, if we want to put a if/else statement in to switch between FF and IE (with say a global variable), our tests will now work for both browsers. In addition, if we want to add Opera/Chrome support at a later date, we just need to add another if/else statement to the Page() function, and not modify our tests at all.
As an example I have modified our Page() function to have a switch for a simple variable. We would typically use this as a global variable, but for this demonstration I have included it in the Page() function.
function Page()
{
var Browser = "IE";
if(Browser=="IE")
{
return Sys.Process("iexplore").Page("*");
}
if(Browser=="FF")
{
return Sys.Process("firefox").Page("*");
}
}
Now all we need to do is modify the Browser variant, and our tests will run in both IE and FF.
However, there is still a problem. To illustrate, navigate to http://www.google.com/ and execute our TestGoogle() function. It will fail. Why? Because the path of the search box is different on the google home page than it is on a google search results page.
Here is the path to the search box on the home page:
Page().Form("f").Table(0).Cell(0, 1).Textbox("q")
And here is the path to the search box on the search results page:
Page().Panel("header").Form("tsf").Table("sft").Cell(0, 1).Table(0).Cell(0, 0).Textbox("q").value="TestComplete Tricks";
The search box/button is located in a different spot on the search results page, and cannot be accessed using the same path. However, we don't really care about the path. All we need is to get to that Textbox("q") node and SubmitButton("btnG") node, which is what we need to modify to perform our search.
Finally, here is the Page() function I use in my own testing. This was not designed to switch between IE and FF, but was designed to restart IE if it locks up, freezes, or is not open.
function Page()
{
var page = Sys.Process("iexplore").WaitPage("*",10000);
if(!page.exists)
{
while(Sys.WaitProcess("iexplore",1000).Exists)
{
Sys.Process("iexplore").Terminate();
}
Open_Browser();
}
return page;
}
My next post will focus on how to use find functionality to find the elements you are looking for, instead of locating them by path.
Subscribe to:
Post Comments (Atom)
Hi Brian,
ReplyDeleteGreat article, on a webpage there's an autocomplete editbox how can you check if search result container is displayed, and I use the id to find the control. I have the following code to find the edit box
Sub searchSuburb
Dim page
Set page = Sys.Browser("*").Page("*")
aqUtils.Delay(2000)
Browsers.Refresh
page.NativeWebObject.Find("id","nav-search-container-search-input","input").value = "Pretoria"
aqUtils.Delay(2000)
End Sub
Hi Brian,
ReplyDeleteGreat article, on a webpage there's an autocomplete editbox how can you check if search result container is displayed, and I use the id to find the control. I have the following code to find the edit box
Sub searchSuburb
Dim page
Set page = Sys.Browser("*").Page("*")
aqUtils.Delay(2000)
Browsers.Refresh
page.NativeWebObject.Find("id","nav-search-container-search-input","input").value = "Pretoria"
aqUtils.Delay(2000)
End Sub