Hello. I have been working with the Web UI Studio tool in an attempt to research the possibility of automating tests against our Silverlight application. I have been trying to record actions on the interface and they do apparently get picked up by the tool. However, when I play back it appears to attempt to take actions before the controls are active. So I try to use the 'wait until visible' task, but that does not seem to work. What will be the proper course of action...a small "Loading" pop up dialog comes up along with the controls I want to reference...so technically, the control is visible...but I don’t want it clicked just yet. Do I have to put a manual delay that compensates for this or is there some property I can address so I can cause the test to wait until this control is actually useable?
Another thing I anticipate is the need to manually code some things. For example, we cannot rely on a result being in a particular row of a RADGrid after a certain operation, so we may have to intelligently search for it by a value in a column. Is this possible, and if so I would be ever so grateful to hear anything close to how it's done.
Thank you in advance to anyone who can help in any way.
11 Answers, 1 is accepted
We appreciate your evaluation of WebUI Test Studio and hope you find it useful for your Silverlight testing requirements.
So for the loading pop up dialog, is it a Silverlight type pop up window as in a ChildWindow Element? If so, WebUI currently is unable to detect and automate this type of Silverlight control.
If it is not a Silverlight pop up, you can see if WebUI is able to highlight it. You can then:
-Wait for the Elements Menu nub to appear, then click for the Elements Menu.
-Try adding a Quick Tasks step that is a 'Wait for Visibility is Collpased'.
- Insert this step before you do any type of further automation to delay the mouse clicks.
Alternatively, you can add a 'Delay Execution' step under the 'Add...' drop down to wait for the dialog to finish.
And for custom programming against your RadGridView, you can highlight it in WebUI and then:
-Wait for the Elements Menu to appear, then click for the Elements Menu.
-When the translator fanouts appear, click on the RadGridView tab
-In the Element Menu click 'Add to Project Elements'
From here in the custom code behind file you can accces the grid as below:
[CodedStep("MyCustom Step Description")] public void MyCustomStep() { RadGridView g = Pages.TelerikRadGridViewFor.SilverlightApp.RadGridView1Radgridview; }You can then program against the RadGridView's methods and properties.
Please let us know if you have any further questions on this or anything else in WebUI.
Greetings,
Nelson Sin
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
I'm glad you were able to get the RadGridView in your Silverlight app (even though I forgot to add the 'RequiresSilverlight = true' annotation, sorry about that).
I'm attaching a test for reference that uses this sample page and hopefully is what you are looking for. Unfortunately, as far as I know, rows must become visual at some point in order to become part of the Visual Tree and for WebUI to be able to access them.
The attached test scrolls all the rows into view using the scroll bar via a recorded test step, then uses a custom coded step to get the row number. Here is the custom coded step:
[CodedStep("MyCustom Step Description", RequiresSilverlight = true)] public void MyCustomStep() { RadGridView g = Pages.TelerikRadGridViewFor.SilverlightApp.RadGridView1Radgridview; g.Refresh(); //Refresh Control after making all row visible int colIndex = 0; foreach (GridViewHeaderCell hc in g.HeaderRow.HeaderCells) if (hc.Text == "Last Name") { colIndex = hc.TabIndex; break; } int neededRowNum; bool keepLooking = true; foreach (GridViewRow r in g.Rows) if (keepLooking) { foreach (GridViewCell c in r.Cells) if (c.Index == colIndex && c.Text.Equals("Callahan", StringComparison.OrdinalIgnoreCase)) { neededRowNum = r.Index; keepLooking = false; break; } } else break; }Since you know the Silverlight app more than I would, you can possibly use the Find Expressions for Silverlight explained at the bottom of that linked page to find the rows and cells faster.
Please post back if you have any further questions on this. I will also ask a colleague who is more familar with the RadGridView to see if he can suggest anything further.
Kind regards,
Nelson
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
So if I understand correctly, you wanted to assign or reassign certain values in the RadGridView? If this is the case, there is a way to probably do so.
You can try to let WebUI initially enter a value or do a verification on the RadType Silverlight element in question. You can then convert that step to code, see the implementation and enter values or modifiy the code to do what you wanted.
But if it's for your row finder implmentation, you can try getting the values inside the cells if they are editable. If it's plain text, you can modify the values using GridViewCell.TextBlockEditor.Text = "MyText". If it's a more complext type you can try using a find on the cell, as in GridViewCell.Find.ByType<>() to get the Rad/Silverlight type control.
If you had something else in mind, please let us know.
All the best,
Nelson
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Okay...I am trying to parse all rows in a grid. I need to scan the first visible rows, page down, scan the next set of rows and repeat...until I find a value in a certain column. Here is the code I have so far...its rough but I am just trying to get something that works and then refine it.
| [CodedStep("Step To Locate Row In RadGrid by a value in a column", RequiresSilverlight = true)] |
| public void FindRowByColumnValue() |
| { |
| int neededRowNum; |
| string lastValueVisible = string.Empty; |
| string lastValueChecked = string.Empty; |
| bool keepLooking = true; |
| RadGridView g = Pages.ACBSClient.SilverlightApp.CustomerDataGridRadgridview; |
| g.Refresh(); //Refresh Control after making all row visible |
| int colIndex = 0; |
| foreach (GridViewHeaderCell hc in g.HeaderRow.HeaderCells) |
| { |
| if (hc.Text == "Customer ID") |
| { |
| colIndex = hc.TabIndex; |
| break; |
| } |
| } |
| while(keepLooking) |
| { |
| g.Refresh(); |
| foreach (GridViewRow r in g.Rows) |
| { |
| if (keepLooking) |
| { |
| if(r.Cells[colIndex].Text.Equals("CONT241", StringComparison.OrdinalIgnoreCase)) |
| { |
| //Then you found it |
| r.Cells[colIndex].User.Click(); |
| keepLooking = false; |
| } |
| lastValueChecked = r.Cells[colIndex].Text; |
| } |
| } |
| //Advance Grid |
| Pages.ACBSClient.SilverlightApp.VerticalLargeIncreaseRepeatbutton.UserPress(10); |
| Pages.ACBSClient.SilverlightApp.CustomerDataGridRadgridview.Refresh(); |
| //Make sure this was not the last page |
| if (lastValueChecked.Equals(lastValueVisible)) |
| { |
| //Row is not in the data set and we are at end of page |
| keepLooking = false; |
| } |
| else |
| { |
| //Reset last visible value |
| lastValueVisible = lastValueChecked; |
| } |
| } |
| } |
For some reason, the rows that are in the grid once the grid is paged down, even after a refresh of the control, do not reflect the rows that are now visible. I am not sure why that is. This is rediculously difficult considering what I am trying to do should be a very very simple task. I hope there is a way to accomplish this.
Yeah, it gets a little complicated when we go to code and thanks for posting your implementation. Just to verifiy, the rows/cells are being populated dynamically along with their Silverlight attributes (Name, AutomationId, etc) in the RadGridView?
Would it be possible to let WebUI record parts of this scenario? At least the scrolling of the rows into view using the scroll arrow button, just to make sure all of the rows are being made visible.
Also, if there are alot of rows, you may need to slow down the test after the scroll and before the Grid gets refreshed in order to get all the new visible rows, so perhaps a System.Threading.Thread.Sleep(int). And you can also try refreshing the entire tree using SilverlighApp.VisualTree.Refresh();
And based on your code, you can also try getting the TextBlock within the cell using a Find param or just a Find.ByContent() as in the following:
//By Find Expression TextBlock b = RadGridView.Find.ByExpression(new XamlFindExpression("TextContent=CONT241")).As<TextBlock>(); lastValueVisible = b.Text; //Or By Find.ByText() TextBlock b = g.Find.ByText("CONT241"); lastValueVisible = b.Text;Hope that helps.
Best wishes,
Nelson
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
| static class FindCellByColValue |
| { |
| public static GridViewRow FindCellWithValue(RadGridView targetGrid, string columnName, string value) |
| { |
| bool keepLooking = true; |
| Thumb th = targetGrid.Find.ByName<Thumb>("VerticalThumb"); |
| RepeatButton largeScroll = targetGrid.Find.ByName<RepeatButton>("VerticalLargeIncrease"); |
| System.Drawing.Rectangle rect = th.GetScreenRectangle(); |
| int ulCorner = rect.Top; |
| int newPosition; |
| int searchColIndex = 0; |
| int targetColIndex = 0; |
| //Locate the column index to be found |
| foreach (GridViewHeaderCell hc in targetGrid.HeaderRow.HeaderCells) |
| { |
| if (hc.Text == columnName) |
| { |
| searchColIndex = hc.TabIndex; |
| } |
| } |
| while (true) |
| { |
| targetGrid.Refresh(); |
| foreach (GridViewRow r in targetGrid.Rows) |
| { |
| if (r.Cells[searchColIndex].Text.Equals(value, StringComparison.OrdinalIgnoreCase)) |
| { |
| //Then you found it |
| r.ScrollToVisible(); |
| System.Drawing.Rectangle cellPos = r.Cells[searchColIndex].GetScreenRectangle(); |
| //Even though the cell was found, it can sometimes be off screen |
| //Bump the scroll bar one more time in this case |
| if (cellPos.Top < 0) |
| { |
| largeScroll.UserPress(10); |
| } |
| return r; |
| } |
| } |
| //Advance Grid |
| largeScroll.UserPress(10); |
| targetGrid.Refresh(); |
| newPosition = th.GetScreenRectangle().Top; |
| //Make sure this was not the last page |
| if (newPosition == ulCorner) |
| { |
| //Row is not in the data set and we are at end of page |
| return null; |
| } |
| else |
| { |
| //Update scroll position |
| ulCorner = newPosition; |
| } |
| } |
| return null; |
| } |
| } |
Thanks for posting your code as this discussion could also help others looking for solutions in the forums.
I asked a couple more colleagues to look into this to try and see if they can suggest anything else you might be able to try to optimize the implmentation.
This custom solution may have indeed been necessary for the scenario you decribed (i.e dynamic rows with unknown attributes and data).
I would suggest if you could record some of the less complex test sequences in WebUI in conjuction with custom code steps/solutions to lessen the burden of having to code as much.
We'll look to post back with any possible suggestions and please feel free to post any further refined solutions you may come up with.
Kind regards,
Nelson
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
This is just a follow-up to my colleague's response
We have decided to expose 2 new methods of RadGridView - BringIndexIntoView and ScrollIntoView , which I think will help you to optimize your implementation.
These methods should be available with our next internal build (under your account).
Sincerely yours,
Anastasia
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.