Silverlight - Unable to traverse entire visual tree

8 posts, 0 answers
  1. Geoffrey
    Geoffrey avatar
    4 posts
    Member since:
    Aug 2012

    Posted 22 Mar 2013 Link to this post

    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
  2. Cody
    Admin
    Cody avatar
    3360 posts

    Posted 27 Mar 2013 Link to this post

    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
  3. Geoffrey
    Geoffrey avatar
    4 posts
    Member since:
    Aug 2012

    Posted 16 Apr 2013 Link to this post

    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
  4. Cody
    Admin
    Cody avatar
    3360 posts

    Posted 18 Apr 2013 Link to this post

    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
  5. Geoffrey
    Geoffrey avatar
    4 posts
    Member since:
    Aug 2012

    Posted 25 Apr 2013 Link to this post

    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
  6. Cody
    Admin
    Cody avatar
    3360 posts

    Posted 30 Apr 2013 Link to this post

    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
  7. Geoffrey
    Geoffrey avatar
    4 posts
    Member since:
    Aug 2012

    Posted 17 May 2013 Link to this post

    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
  8. Cody
    Admin
    Cody avatar
    3360 posts

    Posted 17 May 2013 Link to this post

    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
Back to Top