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

Silverlight - Unable to traverse entire visual tree

7 Answers 89 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Geoffrey
Top achievements
Rank 1
Geoffrey asked on 22 Mar 2013, 08:38 PM
Hi there,

I'm new to WebAii, but I was able to get some level of Silverlight automation up and running. Now, however, it appears I've hit an obstacle.

I've attached a picture of the subset of elements I'm working with. I can get a reference to the DashboardPanel element shown at the top of the image, and I can traverse the children up to the Canvas element. When debugging in Visual Studio, however, Canvas shows as having no children whatsoever. I've tried several different tactics for getting the element, but I'm confident none will work as long as Canvas supposedly has no children. Code below. Thoughts?

// Initialize the settings
Settings mySettings = new Settings();
Manager mgr = null;
SilverlightApp app = null;
 
try
{
    mySettings.Web.EnableSilverlight = true;
    mySettings.Web.DefaultBrowser = BrowserType.Chrome;
     
    // Create the manager object
    mgr = new Manager(mySettings);
 
    // Start the manager
    mgr.Start();
 
    // Launch a browser instance and navigate to the page
    mgr.LaunchNewBrowser();
    mgr.ActiveBrowser.NavigateTo("http://<;url>/");
 
    // Initialize the Silverlight app
    app = mgr.ActiveBrowser.SilverlightApps()[0];
 
    // Log into Jovix
    app.Find.WaitOnElementsTimeout = 20000;
    app.FindName<TextBox>("txtUsername").Text = "<username>";
    app.FindName<PasswordBox>("txtPassword").SetPassword(true, "<password>", 0, 0);
    app.FindName<Button>("btnLogin").User.Click();
 
    // Get the navigation tree control
    TreeView navTree = app.FindName<TreeView>("TreeView");
 
    // Navigate to Custom Fields tree view item
    navTree.Find.WaitOnElementsTimeout = 20000;
    navTree.Find.ByTextContent("Materials").Parent<TreeViewItem>()
        .Find.ByType<ItemsPresenter>()
        .Find.ByName<ToggleButton>("ExpanderButton").User.Click();
 
    navTree.Find.ByTextContent("Custom Fields").User.Click();
 
    // Try to click Add button on the toolbar
    FrameworkElement dpMain = app.Find.ByExpression(
        new XamlFindExpression("Name=dpMain")); // this works
 
    FrameworkElement dragDockPanelHost = dpMain.Find.ByExpression(
        new XamlFindExpression("XamlTag=DragDockPanelHost")); // this works
 
    FrameworkElement widget = dragDockPanelHost.Find.ByExpression(
        new XamlFindExpression("XamlTag=WidgetBase")); // this returns null

Thanks in advance!
Geoffrey

7 Answers, 1 is accepted

Sort by
0
Cody
Telerik team
answered on 27 Mar 2013, 09:34 PM
Hello Geoffrey,

It could be a case of stale cached copy of the Silverlight Visual Tree. Try this:

app.FindName<Button>("btnLogin").User.Click();
app.RefreshVisualTrees();


Greetings,
Cody
the Telerik team
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Geoffrey
Top achievements
Rank 1
answered on 17 Apr 2013, 01:51 AM
Thanks, Cody, but that did not seem to do the trick. Although, I'm very glad to know about the RefreshVisualTrees() method.

I read in the Telerik documentation that WebAii exposes the entire Visual Tree, but I'm wondering if it's possible to jump over to the Logical Tree and traverse that until the next object in the Visual Tree is found. That's going to be my next attempt, but if anyone has another suggestion in the meantime, please let me know.

Thanks!
Geoffrey
0
Cody
Telerik team
answered on 18 Apr 2013, 09:19 PM
Hello Geoffrey,

Test Studio's API can only get at the Visual Tree. The only way to get at the Logical Tree is within the code of the application itself.

Can you point me to a publicly accessible URL that reproduces the problem, or send me a sample Silverlight project? I will be glad to investigate the cause of this, but I need to be able to reproduce it on my own machine first before i can begin diagnosing the cause.

Greetings,
Cody
the Telerik team
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Geoffrey
Top achievements
Rank 1
answered on 25 Apr 2013, 08:30 PM
Hi Cody,

I'm not going to be able to share our application in such a way that you can access it, but I was able to make some progress in Test Studio.
Maybe, from the following information, you can shed some more light on the problem.

If I put in the appropriate wait statements, I can get Test Studio to find and click the "Add" button that I'm aiming for. Here are the properties of the object as displayed in Test Studio:

Expression
XamlTag=barbuttonitemlinkcontrol,automationid=BarButtonItemLink0btnAdd,|,XamlPath=/baritemlayoutpanel[name=PART_LayoutPanel]/contentcontrol[0]

FindLogic
[automationid 'Exact' BarButtonItemLink0btnAdd] AND [XamlTag 'Exact' barbuttonitemlinkcontrol][XamlPath 'Exact' /baritemlayoutpanel[name=PART_LayoutPanel]/contentcontrol[0]]

ControlType
ArtOfTest.WebAii.Silverlight.UI.ContentControl

RootName
FindExpressionElement

But when I attempt to use the same XamlFindExpression with the test framework, it doesn't work:

FrameworkElement btnAdd = app.Find.ByExpression(
     new XamlFindExpression("XamlTag=barbuttonitemlinkcontrol,automationid=BarButtonItemLink0btnAdd,|,XamlPath=/baritemlayoutpanel[name=PART_LayoutPanel]/contentcontrol[0]"));

Is there anything else I need to specify to find the FrameworkElement?

Thank you,
Geoffrey
0
Cody
Telerik team
answered on 30 Apr 2013, 06:04 PM
Hi Geoffrey,

I apologize for the delay getting back to you.

But when I attempt to use the same XamlFindExpression with the test framework, it doesn't work:

What does happen/what do you get when you try? To get a clear handle on what's going on in your application I'll need to see the DOM (it will actually be the Visual Tree at this point) starting at the element "XamlTag 'Exact' barbuttonitemlinkcontrol" all the way to ".../contentcontrol[0]".

One possibility is that you simply need to add a wait for the element  This is an example how to wait for a Silverlight element using code:
CheckBox cbox = Pages.SilverlightGridControl.SilverlightApp.Get<CheckBox>(Pages.SilverlightGridControl.SilverlightApp.Expressions.Item0Checkbox, true, 33000);


Greetings,
Cody
the Telerik team
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
0
Geoffrey
Top achievements
Rank 1
answered on 17 May 2013, 12:23 PM
Cody, I appreciate your persistence in helping me. I'm not sure what exactly changed, but I finally managed to get things working!

For the benefit of others, I ended up with the following working code:

private static string _appUrl = "http://my.webaddress.com/";
private static Settings _settings = new Settings();
private static Manager _mgr = null;
private static SilverlightApp _app = null;
 
_settings.Web.EnableSilverlight = true;
_settings.Web.DefaultBrowser = BrowserType.Chrome;
_settings.ClientReadyTimeout = 120000;
_settings.ElementWaitTimeout = 120000;
_settings.ExecuteCommandTimeout = 30000;
 
// Create the manager object
_mgr = new Manager(_settings);
 
// Start the manager
_mgr.Start();
 
// Launch a browser instance and navigate to the page
_mgr.LaunchNewBrowser();
_mgr.ActiveBrowser.NavigateTo(_appUrl);
 
// My Silverlight app takes so long to load, that I usually need to
// put a break point here and wait for it to load before continuing
System.Threading.Thread.Sleep(1000);
 
// Initialize the Silverlight app
_app = _mgr.ActiveBrowser.SilverlightApps()[0];
_app.Find.WaitOnElementsTimeout = 30000;
 
// At the moment, I need to assume the button is first in the list
// of this type of element
FrameworkElement addButton = _app.Find.AllByExpression(new XamlFindExpression("XamlTag=BarButtonItemLinkControl"))[1];
 
// Click the button
addButton.User.Click();

I think the problem I was running into was actually a technical issue with the DevExpress way of putting buttons on a toolbar of a data grid.
The object I was originally trying to "Find" was the actual button with name "btnAdd," but that button isn't what you're actually seeing on the UI. While the button is actually hidden, you're actually looking at an element of type "BarButtonItemLinkControl," which is the clickable link that fires the command for the button. 

The other trouble I was having is that there isn't enough uniquely-identifiable information on the BarButtonItemLinkControl element to get the specific element I want, so I'm having to get back all of them and just assume the index position of the element in the returned list. That's something I can address with our development team, though.

Since this obstacle, however, I've found that the framework does a great job! 

Thanks again for your help,
Geoffrey
0
Cody
Telerik team
answered on 17 May 2013, 03:44 PM
Hi Geoffrey,

Excellent news! Thank you for the update and sharing the solution you came up with.

Kind regards,
Cody
the Telerik team
Quickly become an expert in Test Studio, check out our new training sessions!
Test Studio Trainings
Tags
General Discussions
Asked by
Geoffrey
Top achievements
Rank 1
Answers by
Cody
Telerik team
Geoffrey
Top achievements
Rank 1
Share this question
or