AutomationId is exactly CellElement_0_5
XamlTag is exactly textblock
However, I cannot get Test Studio to find the element in a test with this find logic.
I know that the Assigned Cell AutomationId's came pre-packed with the RadGridView, because the developers didn't put that in.
I do have an AutomationId on the RadGridView element itself, is it possible that there might be two different AutomationIds conflicting on the same element?
16 Answers, 1 is accepted
AutomationId is exactly CellElement_4_3
XamlTag is exactly textbox
(the _4_3 changes with respect to the row and column)
However, for all of the elements inside of a cell, Test Studio appears to record a Cell Specific AutomationId, but with any test run, all of them fail on tat step trying to find a cell specific automationid, and it fails because it is unable to locate the element.
First, it is normal for the Silverlight RadGridView control to automatically add AutomationId's as demonstrated in the attached screen shots. Yes they are numbered based on the actual row number and X, Y value of each individual cell.
Now to try and figure out why you're getting an "element not found" error. There are a few possibilities and we'll have to go through each one to figure out which one applies:
- Silverlight has a nasty habit of virtualizing data content. It will only put in the visual tree (which is what we have hooks into) what is needed to paint what can be seen on the screen. Thus if rows 9-20 are visible in the UI, typically the visual tree will only contain rows 8-21 (to include one above and one below what's visible). If the test script wants to find row 1, but 9-20 are being displayed, it won't be able to find it simply because the Silverlight engine didn't bother adding it to the visual tree so that we can automate it.
- The next possibility is the automation ID is dynamically changing at run time. The test recorded "CellElement_4_3" but at run time it changed to "CellElement_9_3".
- Another possibility is we're simply on the wrong screen. We're trying to find the element on screen B but at the time it's trying to find it the application is still on screen A.
Regards,
Cody
Telerik
In this step failure, I attempted to type directly into the element.
I should mention it's wpf instead of silverlight.
In order to get around this find logic failure, right now I am clicking on the cell to gain focus (using the XamlPath logic) and then doing a blind .typetext command.
We're still in the process of figuring out how much code churn is involved to fix this bug. At this time we're we're targeting to include a fix for this in our upcoming R2 release.
Cody
Telerik
Please ignore my last response. I selected the wrong support ticket when i sent it.
I am investigating your problem further now.
Cody
Telerik
Thanks for the additional information. At the core, Silverlight and WPF operate virtually the same... both have a Visual Tree. From an automation POV, the only difference is how the application is launched and how Test Studio connects to it. Once connected all the automation steps are the same.
Looking through the captured Visual Tree, I see that all of the expected AutomationID's are missing! This I cannot explain. I have no idea why they're not there. Compare the two attached images. The second one is from a simple test I created against our public demo site and deliberately made fail.
It's almost as if the application changed in between when it was recorded and when the test was executed. If this is the case the only option is to re-record the failed step(s). Please give this a try. If that doesn't work I'll need to think about how to tackle this problem. I'll need some way to reproduce this so i can study it and come up with a working solution.
Cody
Telerik
I can say for sure the application is not changing in between the time that the test is recorded and when it was executed. The app changes often, but I must commit an overt act in order to get the latest deploy. But I tried it again anyway, and the same thing happened.
I can send you a copy of our app and give you login information to try and reproduce. Or I can send you the source code or both as well as a written .tstest that would show the error. Either way, I'd prefer to keep it off a public forum. I just need to know a place to send them.
Man, if I could get these Cell AutomationIds working and of of the XamlPath logic, that would pretty nice.
Have you considered using code-behind to accomplish what you are trying to do?
With minimal object-oriented programming skills, it is pretty easy to write code to access the Radgridview's rows (only those currently in the visual tree), the Cells in each of these rows and the text content of any cell in any row - using the following objects available via Test Studio's API:
Radgridview - represents a Silverlight Grid view
GridViewRow object - represents a row in a RadGridView
GridViewCell object - represents a row in a RadGridView
GridViewHeaderRow object - represents the column header row of a Radgridview
Here are some useful properties in these objects:
Radgridview.Rows - returns list of rows currently in the visual tree of the RadGridView (IList of GridViewRow objects in .NET/C#)
Radgridview.Rows[rowindex] returns the row at row # rowindex in the visual tree (GridViewRow object)
Radgridview.HeaderRow - returns header row of the Radgridview (GridViewHeaderRow object)
GridViewRow.Cells - returns list of cells in the row an IList of GridViewCell objects in .NET/C#)
GridViewRow.Cells[columnindex] returns the cell at column index <columnindex> (GridViewCell object).
Here is some sample .NET/C# code that illustrates the use of some of the above objects and properties:
public static void PrintRow(RadGridView radGridView, int rowindex)
{
IList<
GridViewHeaderCell
> headerrowcells = radGridView.HeaderRow.HeaderCells;
Log.WriteLine("headerrowcells.count=" + headerrowcells.Count);
for (int i = 0; i <
headerrowcells.Count
; i++)
{
Log.WriteLine(String.Format("{0}: headerrowcells Column: {1} ", i, headerrowcells[i].Text));
}
IList<GridViewCell> rowcells = radGridView.Rows[rowindex].Cells;
Log.WriteLine(String.Format("Number of cells in row = {0}", rowcells.Count));
for (int i = 0; i < rowcells.Count; i++)
{
Log.WriteLine(String.Format("{0}: Column: {1} Value: {2}", i, rowcells[i].Text);
}
}
// Print first row in Radgridview
PrintRow(Pages.xxx.SilverlightApp.DataGridxxxListRadgridview, 0);
Further, if all you need is the text value of the cell, then you do not need to worry about locating the TextBlock object inside the cell, Automation IDs on child objects within Radgridview or anything of that nature. GridViewCell.Text (or one of the other variants of this property) will readily give you what you need. However, if you do need to locate the TextBlock for some other reason, it is pretty easy to do so (even if it doesn't have an Automation ID) using any of .NET's Find operators (supported on all objects derived from FrameworkElement - Radgridview, GridViewRow and GridViewCell fall into this category) or Where operators (available on IList objects).
A word of caution (based on personal experience): I would avoid or minimize dependencies on the internal structure of a complex object such as Radgridview (unless absolutely necessary). Internal structure details (the components, their Automation IDs, etc.) are subject to change from release to release of the control. If your application migrated to the new version of the control, your test is likely to start failing and you may need to make extensive updates. If you must have such dependencies, you may want to look into centralizing the code that accesses the internal structure (shared tests, helper API, etc.) so that you have one place to make updates should changes occur.
Hope that helps.
Shashi
@Shashi, thank you for reaching out and trying to assist Doug. I'll let Doug respond whether or not he can use your recommended approach. We very much appreciate and encourage all our customers to jump in and assist like this!
@Doug, I'll be happy to receive a copy of your application that I can run and repro the problem myself. Once I can repro this problem I can study it and come up with a solution. To keep it private, as a paying customer you have the ability to create a support ticket (different from a forum post). The content of support tickets can only be seen by us in technical support and yourself. They are not visible to the rest of the world. You creating your own support ticket would be the best way to keep the information confidential.
How large is the application? We have a 20MB file size limit on all file attachments. If it's larger than that, let me know and I'll send you an alternate method to send us the file(s) (in your support ticket).
Cody
Telerik
That's really helpful. And I would like to get that point where I have code that is identifying every cell visual to the user and Test Studio can easily find the identifiers and interact with specific cells. But I am unsure how to implement that. Your code is helpful definitely. Would I write my code in the .xaml in the Source Code? Or as a coded step in Test Studio?
Unfortunately I am going to need to interact with textblocks and dropdowns inside the cell because I will be typing into them testing the editable parts we have put into the grid.
And thanks for the tip of centralizing dependencies, definitely a good idea to avoid test maintenance. We just updated to the latest Telerik controls, and I'm learning first hand how fragile some find logic can be.
@ Cody, the .zip file is only 14.5 MB so I can send it off to you. In a support ticket with a test that will take you to the problem.
I get the same issue (AutomationId of textblock in GridViewCell is missed).
I don't know why after i turn on Inspect.exe tool to look up some properties, my scripts can catch the AutomationId of textblock. But if i start my product without start Inspect.exe tool, my scripts cannot catch AutomationId property.
The function script as Shashi mentioned above works fine in case all columns on table are visible without scroll. It will work incorrect if we change order of columns, or there is any column is out of RadGridView's scope (user must do scroll to see that column.)
Do you have any idea on this issue ?
I am using Telerik with Coded UI on VS2012.
Thanks & Regards,
Hoang.
Thank you for contacting us.
In order to assist you best please elaborate a bit more on your scenario.
What exactly do you want to achieve?
Some screen shots of the DOM would help us a lot.
Please give us more detailed information and I will be glad to help you.
Hope to hear from you soon.
Regards,
Boyan Boev
Telerik
Please check out the related items in our feedback portal here and here. The problem is that the Automation Peers are enabled by default and when you are recording, the RadGridView generates Automation IDs at run-time. However during execution these IDs are not generated and Test Studio fails to find the elements.
To overcome this you need to turn off the creation of the automation peers as explained in this article. Also see this short video for more information.
Hope that helps.
Regards,
Boyan Boev
Telerik by Progress
@Boyan Boev, thanks for the information,
I have another question - is there an option, that the AutomationId's were generated during test execution? Could we (e.g in first coded step of the test) generate the AutomationId's in the same way they are generated when test is recorded?
Unfortunately the only way to unify the recording and execution behavior is to disable the automation peers as pointed in my last reply. This requires a respective application update and is out of the control for Test Studio.
Thank you for your understandings.
Regards,
Boyan Boev
Telerik by Progress