Hello,
I have the following coded step that identifies a specific image I'm looking for and then clicks on it. After clicking, I need to handle a dialog box, but I don't believe there is a way to call a regular step from a coded step from what I've seen so far. So I'm trying to find a way to use this coded step to iteratively find and click on each image, break out to a regular step to handle the dialog, and then repeat the process until all of the images I'm looking for have been clicked.
I set an extracted value of "Repeat" to either "True" or "False" within the coded step. Is there a way to execute a regular step logical loop based on this value since it's independent of any target on the screen?
Thanks for your help!
Tori
// Find the "Void" (Delete) image gif and click on it.
ReadOnlyCollection<HtmlImage> VoidImages = ActiveBrowser.Find.AllByAttributes<HtmlImage>("src=~delete.gif");
if(VoidImages.Count == 0)
Console.Out.WriteLine("Void Image Not Found. . .continuing. ");
int Count = 0;
foreach(HtmlImage i in VoidImages)
{
Count = Count + 1;
Console.Out.WriteLine("Image Count = " + Count);
if(i.IsVisible())
{
i.ScrollToVisible(ScrollToVisibleType.ElementTopAtWindowTop);
Log.WriteLine("Visible Void Image Found: " + Count + " " + i.Src + " clicking! ");
Console.Out.WriteLine("Visible Void Image Found: " + Count + " " + i.Src + " clicking! ");
HtmlImage VisibleImage = i;
if(Count == VoidImages.Count)
{
SetExtractedValue("Repeat", "False");
Console.Out.WriteLine("Last image, stop looping.");
Log.WriteLine("Last image, stop looping.");
}
else
{
SetExtractedValue("Repeat", "True");
Console.Out.WriteLine("More images remaining, keep looping.");
Log.WriteLine("More images remaining, keep looping.");
}
VisibleImage.Click();
break;
}
}
I have the following coded step that identifies a specific image I'm looking for and then clicks on it. After clicking, I need to handle a dialog box, but I don't believe there is a way to call a regular step from a coded step from what I've seen so far. So I'm trying to find a way to use this coded step to iteratively find and click on each image, break out to a regular step to handle the dialog, and then repeat the process until all of the images I'm looking for have been clicked.
I set an extracted value of "Repeat" to either "True" or "False" within the coded step. Is there a way to execute a regular step logical loop based on this value since it's independent of any target on the screen?
Thanks for your help!
Tori
// Find the "Void" (Delete) image gif and click on it.
ReadOnlyCollection<HtmlImage> VoidImages = ActiveBrowser.Find.AllByAttributes<HtmlImage>("src=~delete.gif");
if(VoidImages.Count == 0)
Console.Out.WriteLine("Void Image Not Found. . .continuing. ");
int Count = 0;
foreach(HtmlImage i in VoidImages)
{
Count = Count + 1;
Console.Out.WriteLine("Image Count = " + Count);
if(i.IsVisible())
{
i.ScrollToVisible(ScrollToVisibleType.ElementTopAtWindowTop);
Log.WriteLine("Visible Void Image Found: " + Count + " " + i.Src + " clicking! ");
Console.Out.WriteLine("Visible Void Image Found: " + Count + " " + i.Src + " clicking! ");
HtmlImage VisibleImage = i;
if(Count == VoidImages.Count)
{
SetExtractedValue("Repeat", "False");
Console.Out.WriteLine("Last image, stop looping.");
Log.WriteLine("Last image, stop looping.");
}
else
{
SetExtractedValue("Repeat", "True");
Console.Out.WriteLine("More images remaining, keep looping.");
Log.WriteLine("More images remaining, keep looping.");
}
VisibleImage.Click();
break;
}
}
14 Answers, 1 is accepted
0
Hello Tori,
The While Loop can only be based on an existing verification step that already exists in the test, and a verification step can only verify some property of some target element. An extracted variable cannot be used as the condition for the While Loop.
The While Loop can be based the existence of some element. I am wondering if we can take advantage of that in your loop... while any HTML image exists with "src=~delete.gif" continue the loop, clicking Delete and handling the dialog. This assumes the HTML image will be removed from the page once it is deleted. The loop will break automatically when the last HTML image has been deleted.
Do you think something like that approach would work?
Another method would be to call a subtest from code to do the deleting and handling of the dialog for you. You call a subtest from code like this:
this.ExecuteTest("Delete Current Image.tstest");
Regards,
Cody
Telerik
The While Loop can only be based on an existing verification step that already exists in the test, and a verification step can only verify some property of some target element. An extracted variable cannot be used as the condition for the While Loop.
The While Loop can be based the existence of some element. I am wondering if we can take advantage of that in your loop... while any HTML image exists with "src=~delete.gif" continue the loop, clicking Delete and handling the dialog. This assumes the HTML image will be removed from the page once it is deleted. The loop will break automatically when the last HTML image has been deleted.
Do you think something like that approach would work?
Another method would be to call a subtest from code to do the deleting and handling of the dialog for you. You call a subtest from code like this:
this.ExecuteTest("Delete Current Image.tstest");
Regards,
Cody
Telerik
0
Tori
Top achievements
Rank 1
answered on 13 Oct 2014, 08:19 PM
Thanks, Cody. Very helpful information. I’m out of the office on vacation this coming week, but I do think calling a subtest will work. I’ve had trouble using a regular step to find elements due to the large number of hidden elements (with variable IDs and the same image names) on the same page. I’ve also had trouble getting the “verify is visible” to work in a regular step. My coded step successfully locates the image(s) by putting all of them in a collection and iterating through them to look for the ones that are visible. This seems to work pretty well if I can just get the resulting dialog handled. I’ll try calling a subtest as you describe.
One related question for you, I’ve noticed that my tests seem to run more reliably if I include a 400 msec execution delay between all steps (globally). This often avoids the problem of needing to put in so many manual execution delay steps. I also use the Ajax timeouts, but these don’t always seem to allow controls to fully load before attempting to execute the next step. The problem with including a global delay between every step is that the delay also applies to coded steps. That’s not what you want when you are iterating through a collection of 100 images! Is there any way to exempt coded steps from a global execution delay? If not, may I please suggest it as a feature candidate?
Thanks,
Tori
One related question for you, I’ve noticed that my tests seem to run more reliably if I include a 400 msec execution delay between all steps (globally). This often avoids the problem of needing to put in so many manual execution delay steps. I also use the Ajax timeouts, but these don’t always seem to allow controls to fully load before attempting to execute the next step. The problem with including a global delay between every step is that the delay also applies to coded steps. That’s not what you want when you are iterating through a collection of 100 images! Is there any way to exempt coded steps from a global execution delay? If not, may I please suggest it as a feature candidate?
Thanks,
Tori
0
Hello Tori,
There isn't a way to automatically exclude coded steps from this execution delay, however you can use a coded step to modify the current setting:
Settings.Current.ExecutionDelay = 0;
Put this at the beginning of a series of coded steps to change the delay to 0. Or maybe work it in reverse. Set the global parameter to 0, then use a coded steps to set it to 400 at the right spot and back to 0 when you no longer need it.
Regards,
Cody
Telerik
There isn't a way to automatically exclude coded steps from this execution delay, however you can use a coded step to modify the current setting:
Settings.Current.ExecutionDelay = 0;
Put this at the beginning of a series of coded steps to change the delay to 0. Or maybe work it in reverse. Set the global parameter to 0, then use a coded steps to set it to 400 at the right spot and back to 0 when you no longer need it.
Regards,
Cody
Telerik
0
Tori
Top achievements
Rank 1
answered on 20 Oct 2014, 07:45 PM
Thanks, Cody. Both of your suggestions above are working great with one exception. As you can see in my original post, once I find the image I'm looking for, I click it using the following statement: VisibleImage.Click();. This triggers the dialog box that I was asking about. I'm now handling the dialog box in a separate test that has only a single regular step. The dialog handling test works fine (successfully clicking OK) when I run it independently of my code step. The problem is, once my coded step encounters the dialog box, it stops executing code and waits for dialog handling rather than calling the dialog handling test! How do I force it to run the next line of code that calls the dialog handling test?
this.ExecuteTest(@"C:\Users. . .\Handle Void Cofirmation.tstest");
Thanks again,
Tori
this.ExecuteTest(@"C:\Users. . .\Handle Void Cofirmation.tstest");
Thanks again,
Tori
0
Hi Tori,
When a test contains any sort of dialog handling anywhere within that test (not counting subtests) the dialog handling is actually initialized during initialization of that test, prior to step 1 of that test getting control. I think what you're going to have to do is to move clicking the image and handling of the dialog all into the same, all encompassing, subtest. That's the only way that dialog handling will work... if the same test that handles the dialog also performs the action (clicking on a image in this case) that causes the dialog to open.
Regards,
Cody
Telerik
When a test contains any sort of dialog handling anywhere within that test (not counting subtests) the dialog handling is actually initialized during initialization of that test, prior to step 1 of that test getting control. I think what you're going to have to do is to move clicking the image and handling of the dialog all into the same, all encompassing, subtest. That's the only way that dialog handling will work... if the same test that handles the dialog also performs the action (clicking on a image in this case) that causes the dialog to open.
Regards,
Cody
Telerik
0
Tori
Top achievements
Rank 1
answered on 23 Oct 2014, 12:09 PM
Thanks, Cody. Unfortunately, this brings me back to my original problem. I have been unable to handle the dialog box within my coded step. This is why I was calling a subtest containing a regular step using built in dialog handling (which does work). I've seen several examples of dialog handling in the forums, and have tried a number of approaches with no luck. If you have some good documentation you can point me to, I would appreciate it. This is just a plain "OK / Cancel" dialog box that confirms the user would like to delete the item they just selected.
Thanks,
Tori
Thanks,
Tori
0
Hi Tori,
Since this is a public forum, I am copying my response to your private support ticket on this same subject for the benefit of anyone watching this public thread.
You will have to move the VisibleImage.Click() code into the subtest as well. This can be done pretty easily by setting a globally accessible variable with a reference to the element to be acted on. Then have the subtest initialize dialog handling, do the VisibleImage.Click() referencing the already set variable, then wait for the dialog to be handled, and finally end returning control to the parent test which is doing the looping.
Regards,
Cody
Telerik
Since this is a public forum, I am copying my response to your private support ticket on this same subject for the benefit of anyone watching this public thread.
You will have to move the VisibleImage.Click() code into the subtest as well. This can be done pretty easily by setting a globally accessible variable with a reference to the element to be acted on. Then have the subtest initialize dialog handling, do the VisibleImage.Click() referencing the already set variable, then wait for the dialog to be handled, and finally end returning control to the parent test which is doing the looping.
Regards,
Cody
Telerik
0
Tori
Top achievements
Rank 1
answered on 24 Oct 2014, 12:02 AM
I really appreciate your help. . .and I'm hoping we're almost there!
So. . .as instructed, I have broken out the image click and the dialog handling in separate test, which will contain only a single coded step that gets called each time the main test finds one of the visible images we'd like to click on. So far, my subtest looks like what you see below. I'm hoping you will tell me that I can use Set / Get ExtractedValue to pass the individual HtmlImage objects to the subtest so that I can execute the click, but so far that does not appear to be working for me. If that's not valid, can you please be more specific about how I can pass an HtmlImage object (called VisibleImage in the parent test) to the subtest? I'm also afraid you are going to tell me that a utility class is the only way to make this work. :-)
_________________________
//Start the DialogMonitor - this is only needed for pure coded tests. Test Studio will automatically start it during its initialization.
Manager.DialogMonitor.Start();
// Handle Confirm dialog.
ConfirmDialog confirmDialog = new ConfirmDialog(ActiveBrowser, DialogButton.OK);
Manager.DialogMonitor.AddDialog(confirmDialog);
confirmDialog.WaitUntilHandled(5000);
object<HtmlImage> VisibleImage = GetExtractedValue<HtmlImage>("VIObject");
VisibleImage.Click();
Thanks again,
Tori
So. . .as instructed, I have broken out the image click and the dialog handling in separate test, which will contain only a single coded step that gets called each time the main test finds one of the visible images we'd like to click on. So far, my subtest looks like what you see below. I'm hoping you will tell me that I can use Set / Get ExtractedValue to pass the individual HtmlImage objects to the subtest so that I can execute the click, but so far that does not appear to be working for me. If that's not valid, can you please be more specific about how I can pass an HtmlImage object (called VisibleImage in the parent test) to the subtest? I'm also afraid you are going to tell me that a utility class is the only way to make this work. :-)
_________________________
//Start the DialogMonitor - this is only needed for pure coded tests. Test Studio will automatically start it during its initialization.
Manager.DialogMonitor.Start();
// Handle Confirm dialog.
ConfirmDialog confirmDialog = new ConfirmDialog(ActiveBrowser, DialogButton.OK);
Manager.DialogMonitor.AddDialog(confirmDialog);
confirmDialog.WaitUntilHandled(5000);
object<HtmlImage> VisibleImage = GetExtractedValue<HtmlImage>("VIObject");
VisibleImage.Click();
Thanks again,
Tori
0
Hi Tori,
I'm hoping you will tell me that I can use Set / Get ExtractedValue to pass the individual HtmlImage objects to the subtest...
Yes I'm pretty sure that approach will work. Personally I would implement a global C# static variable to accomplish the same thing.
I'm also afraid you are going to tell me that a utility class is the only way to make this work.
Nope. That is not the case.
The one problem with your code snippet is that you waiting for the dialog to be handled before you do the click that opens the dialog. Try this instead:
Regards,
Cody
Telerik
I'm hoping you will tell me that I can use Set / Get ExtractedValue to pass the individual HtmlImage objects to the subtest...
Yes I'm pretty sure that approach will work. Personally I would implement a global C# static variable to accomplish the same thing.
I'm also afraid you are going to tell me that a utility class is the only way to make this work.
Nope. That is not the case.
The one problem with your code snippet is that you waiting for the dialog to be handled before you do the click that opens the dialog. Try this instead:
//Start the DialogMonitor - this is only needed for pure coded tests. Test Studio will automatically start it during its initialization.
Manager.DialogMonitor.Start();
// Handle Confirm dialog.
ConfirmDialog confirmDialog =
new
ConfirmDialog(ActiveBrowser, DialogButton.OK);
Manager.DialogMonitor.AddDialog(confirmDialog);
object
<HtmlImage> VisibleImage = GetExtractedValue<HtmlImage>(
"VIObject"
);
VisibleImage.Click();
confirmDialog.WaitUntilHandled(5000);
Regards,
Cody
Telerik
0
Tori
Top achievements
Rank 1
answered on 24 Oct 2014, 01:47 PM
Ok. . .I think I'm on the right track, but I'm not having any luck passing the HtmlImage object using Get/Set ExtractedValue. That appears to be for simple strings only (although the API looks like it should work with an object). Just in case, however, here are the errors I'm getting from the following statement:
c:\Telerik\Test Studio Projects\VoidHandler.tstest.cs: Line 62: (CS1001) Identifier expected
c:\Telerik\Test Studio Projects\VoidHandler.tstest.cs: Line 62: (CS1525) Invalid expression term '<'
c:\Telerik\Test Studio Projects\VoidHandler.tstest.cs: Line 62: (CS1002) ; expected
I'm casting the object as an HtmlImage, and the compiler doesn't like it. I've tried lots of different permutations, but please let me know if something jumps out at you.
I'm all for trying the global C# static variable, but it's not clear to me how you do this within an existing class. The original coded step is already in the following class:
So my understanding is that I would simply need to declare a global variable within the class that looks something like this:
For whatever reason, however, this is causing the line of code above it to say that it's expecting another ";". Can you provide any pointers for setting up a my static global variable within the existing coded step?
Thanks,
Tori
object<
HtmlImage
> VisibleImage = GetExtractedValue<
HtmlImage
>("VIObject");
c:\Telerik\Test Studio Projects\VoidHandler.tstest.cs: Line 62: (CS1001) Identifier expected
c:\Telerik\Test Studio Projects\VoidHandler.tstest.cs: Line 62: (CS1525) Invalid expression term '<'
c:\Telerik\Test Studio Projects\VoidHandler.tstest.cs: Line 62: (CS1002) ; expected
I'm casting the object as an HtmlImage, and the compiler doesn't like it. I've tried lots of different permutations, but please let me know if something jumps out at you.
I'm all for trying the global C# static variable, but it's not clear to me how you do this within an existing class. The original coded step is already in the following class:
public class Delete_all_Telerik_FinPlans : BaseWebAiiTest<
br
> {...}
So my understanding is that I would simply need to declare a global variable within the class that looks something like this:
public static HtmlImage GlobalVoidImage = VisibleImage;
For whatever reason, however, this is causing the line of code above it to say that it's expecting another ";". Can you provide any pointers for setting up a my static global variable within the existing coded step?
Thanks,
Tori
0
Tori
Top achievements
Rank 1
answered on 27 Oct 2014, 04:47 PM
Cody,
Please ignore my previous question regarding global variable handling. All of that is working fine now, but I'm still not able to handle the confirm dialog. The image gets clicked, the dialog appears, and then nothing happens until the handler times out. Please take a look at my subtest below and tell me what I'm missing.
Thanks,
Tori
Please ignore my previous question regarding global variable handling. All of that is working fine now, but I'm still not able to handle the confirm dialog. The image gets clicked, the dialog appears, and then nothing happens until the handler times out. Please take a look at my subtest below and tell me what I'm missing.
Thanks,
Tori
//Start the DialogMonitor - this is only needed for pure coded tests. Test Studio will automatically start it during its initialization.
Console.Out.WriteLine("Handling dialog. . .");
Manager.DialogMonitor.Start();
// Handle Confirm dialog.
ConfirmDialog confirmDialog = new ConfirmDialog(ActiveBrowser, DialogButton.OK);
Manager.DialogMonitor.AddDialog(confirmDialog);
//object<
HtmlImage
> VisibleImage = GetExtractedValue<
HtmlImage
>("VIObject");
Console.Out.WriteLine("Clicking image. . .");
GlobalVar.GlobalVisibleImage.Click();
confirmDialog.WaitUntilHandled(5000);
Manager.DialogMonitor.Stop();
0
Hello Tori,
We are moving this discussion to your private support ticket.
Regards,
Cody
Telerik
We are moving this discussion to your private support ticket.
Regards,
Cody
Telerik
0
Tori
Top achievements
Rank 1
answered on 04 Nov 2014, 02:15 PM
All,
Cody was extremely patient and helpful in working me through this problem, but we ended up resolving the problem through the ticketing system rather than in this thread. It's always frustrating when you get to the bottom of a long post and there is no solution, so I wanted to post the code that solved my problem. I think we pretty much described what I was trying to do in prior posts, so I'll just post the relevant snippets here. If anyone has any questions, feel free to ask for more details.
Thanks,
Tori
First of all, here is coded step from the main test:
Here is the subtest coded step:
Finally, here is how I set up the global variable(s). Note that this code is inserted inside the namespace of the project code behind file, but outside the classes that define individual tests.
Cody was extremely patient and helpful in working me through this problem, but we ended up resolving the problem through the ticketing system rather than in this thread. It's always frustrating when you get to the bottom of a long post and there is no solution, so I wanted to post the code that solved my problem. I think we pretty much described what I was trying to do in prior posts, so I'll just post the relevant snippets here. If anyone has any questions, feel free to ask for more details.
Thanks,
Tori
First of all, here is coded step from the main test:
// Temporarily set the execution delay to zero for quick execution of coded step.
Settings.Current.ExecutionDelay = 0;
// Find each "Void" (Delete) image gif and click on it.
ReadOnlyCollection<
HtmlImage
> VoidImages = ActiveBrowser.Find.AllByAttributes<
HtmlImage
>("src=~delete.gif");
if(VoidImages.Count == 0)
{
Console.Out.WriteLine("Void Image Not Found. . .continuing. ");
Log.WriteLine("Void Image Not Found. . .continuing. ");
}
else
{
Console.Out.WriteLine(VoidImages.Count + " Void images found. ");
Log.WriteLine(VoidImages.Count + " Void images found. ");
}
int Count = 0;
foreach(HtmlImage i in VoidImages)
{
Count = Count + 1;
Console.Out.WriteLine("Checking Image " + Count + ".");
Log.WriteLine("Checking Image " + Count + ".");
if(i.IsVisible())
{
i.ScrollToVisible(ScrollToVisibleType.ElementTopAtWindowTop);
Log.WriteLine("Visible Void image found at Count = " + Count + ".");
Console.Out.WriteLine("Visible Void image found at Count = " + Count + ".");
HtmlImage VisibleImage = i;
GlobalVar.GlobalVisibleImage = i;
try
{
// Handle the dialog box (click OK)
this.ExecuteTest(@"C:\Users\Tori Harris\Documents\Tori\Acato\Testing\Telerik\Test Studio Projects\G2 FinPlan Workflow\FinPlan\Data Driven Testing\Handle Void Confirmation.tstest");
}
catch (Exception ex)
{
Console.Out.WriteLine("Error message from dialog handler: " + ex.Message);
Log.WriteLine("Error message from dialog handler: " + ex.Message);
break;
}
if(Count == VoidImages.Count)
{
SetExtractedValue("Repeat", "False");
Console.Out.WriteLine("Last image, stop looping.");
Log.WriteLine("Last image, stop looping.");
}
else
{
SetExtractedValue("Repeat", "True");
Console.Out.WriteLine("More images remaining, keep looping.");
Log.WriteLine("More images remaining, keep looping.");
}
}
}
// Set the execution delay back to 400 ms for more reliable execution of regular steps.
Settings.Current.ExecutionDelay = 400;
Here is the subtest coded step:
// Handle Confirm dialog.
Console.Out.WriteLine("Handling dialog. . .");
ConfirmDialog confirmDialog = ConfirmDialog.CreateConfirmDialog(ActiveBrowser, DialogButton.OK);
Manager.DialogMonitor.AddDialog(confirmDialog);
// Click Void image, which spawns dialog box.
Console.Out.WriteLine("Clicking image. . .");
GlobalVar.GlobalVisibleImage.MouseClick();
confirmDialog.WaitUntilHandled(5000);
Manager.DialogMonitor.RemoveDialog(confirmDialog);
System.Threading.Thread.Sleep(10000);
//ActiveBrowser.Manager.Desktop.KeyBoard.KeyPress(System.Windows.Forms.Keys.Enter);
Finally, here is how I set up the global variable(s). Note that this code is inserted inside the namespace of the project code behind file, but outside the classes that define individual tests.
// Contains global variables for project.
public static class GlobalVar
{
// Global variable that is constant.
public const string GlobalString = "Important Text";
// Static value protected by access routine.
static HtmlImage _globalVisibleImage;
// Access routine for global variable.
public static HtmlImage GlobalVisibleImage
{
get
{
return _globalVisibleImage;
}
set
{
_globalVisibleImage = value;
}
}
// Global static field.
public static bool GlobalBoolean;
}
0
Hello Tori,
Thank you for publicly sharing your solution. I have granted you some Telerik points for being so helpful.
Regards,
Cody
Telerik
Thank you for publicly sharing your solution. I have granted you some Telerik points for being so helpful.
Regards,
Cody
Telerik