This is a migrated thread and some comments may be shown as answers.

[Solved] Recording and Writing Manual Silverlight Tests

11 Answers 73 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Stephen Gyves
Top achievements
Rank 1
Stephen Gyves asked on 17 Dec 2009, 09:44 PM

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

Sort by
0
Missing User
answered on 18 Dec 2009, 12:23 AM
Hello Stephen,

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.
0
Stephen Gyves
Top achievements
Rank 1
answered on 21 Dec 2009, 06:46 PM
Okay, so I managed to get a hold of the RadGridView. I spent at least 4 hours after that trying to programatically navigate the grid manually. What a nightmare this is. Why I cannot just get a data set that represents what is viewable in the grid wheather it visible or not, I will never know. So failing that, I began to try to programatically navigate the grid by scrolling and trying to get the visible rows, but there is no guarantee that you haven't passed up any rows during your scroll. So I tried to highlight a the first row and arrow down row by row (again programatically) but for some reason I cannot reliably work around this issue. As I understand it, the client side Telerik control has an "ItemSource" property on it that does not get translated by the Telerik.WebAii RadGridView translator. This makes scraping all available rows from the RadGridView, so far, impossible. I would love to be able to say that the data will always be the same whenever we run a test, but that just isn't going to be the case. So I need one of two things: I need to be able to tap into the result set that would be represented by the grid whether the rows are visible or not, or, I need to know how to programatically work through the grid seeking out the row I need via a column value representing a unique identifier. Any help with this will be greatly appreciated. Thank you.

0
Missing User
answered on 21 Dec 2009, 09:58 PM
Hello again Stephen,

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.
0
Stephen Gyves
Top achievements
Rank 1
answered on 21 Dec 2009, 10:11 PM
I never had any problem finding anything in the visible rows. It's paging down the grid that troubles me. I want to make sure I page down without skipping over any rows. I don't mind repeating the serach on some rows I already searched...so long as i eventually know I covered all the rows and I find what I am looking for if it is there. Essentially...somehow i need to get the row i am looking for in the visible grid so i can verify it and its data exist. Thank you again for your help.
0
Stephen Gyves
Top achievements
Rank 1
answered on 21 Dec 2009, 10:31 PM
Okay...I have found that I can access the 'VerticalLargeIncreaseRepeatbutton' and page through the grid that way. So I have a workaround. What I am wondering is, would the developers be able to make the item source that the RadGridView uses available to the RadGridView translator...is this the sort of feature request that could be done?
0
Missing User
answered on 21 Dec 2009, 11:58 PM
Hi again Stephen,

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.
0
Stephen Gyves
Top achievements
Rank 1
answered on 22 Dec 2009, 12:31 AM

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.
0
Missing User
answered on 22 Dec 2009, 07:20 PM
Hi again Stephen,

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.
0
Stephen Gyves
Top achievements
Rank 1
answered on 22 Dec 2009, 11:17 PM
Here is the helper method that I  ultimately came up with to solve this problem. It is not completely refined yet, as I would rather not have a while(true) statement in my code....but it demostrates the solution.
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;  
        }  
    } 
0
Missing User
answered on 23 Dec 2009, 04:38 PM
Hello again Stephen,

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.
0
Missing User
answered on 28 Dec 2009, 04:01 PM
Hello Stephen Gyves,

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.
Tags
General Discussions
Asked by
Stephen Gyves
Top achievements
Rank 1
Answers by
Missing User
Stephen Gyves
Top achievements
Rank 1
Missing User
Share this question
or