question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Quickly finding all child elements

See original GitHub issue

Hello,

I recently discovered the WinAppDriver and have been attempting to create a GUI stress test using Appium that randomly clicks all elements in my application. I’ve hit a lot of snags along the way which I’ve worked around but this latest one I can’t seem to conquer.

I have successfully written code that recursively does the following:

  1. Click highest level element “e” and find all immediate children. -----2. Click first child of “e” and check if the child also has children. ----------3. If yes, continue recursively until no more children. ----------4. If no, return. -----5. Click second child of of element “e”.

etc.

The problem is that querying to see if an element has children is extremely slow. I manually construct my own xPath so that I know which element to search underneath (since there’s no way to get the xPath from an element otherwise) but even with the narrowed scope, it takes super long to find all children. We’re talking about 24 seconds.

My question is:

Is there a faster way to find all the children of an element? Or perhaps, any tips on achieving a GUI stress test another way? The app is a rather complex Windows Forms app that also has hosted WPF controls.

I’ve pasted the test code below for reference.

using TestApp.API;
using NUnit.Framework;
using System.Collections.Generic;
using OpenQA.Selenium.Appium;

namespace GuiAutomationTest
{
[TestFixture]
    public class Program
    {
        DesktopSession desktopSession;
        TestApp app;

        public Program()
        {
            app = new TestApp();
            app.Visible = true;
            desktopSession = new DesktopSession();
        }

        [Test]
        public void StartStress()
        {
            app.CreateNewProject();
            string startingxPath = $"//";
            var startingElement = desktopSession.DesktopSessionElement.FindElementByAccessibilityId("MainForm");
            var window = desktopSession.DesktopSessionElement.CurrentWindowHandle;
            RecursivelyClickAllElements(window, startingElement,startingxPath);
        }

        public void RecursivelyClickAllElements(string window, AppiumWebElement e,  string xPath)
        {
            xPath += ConstructXPathFromElement(e);

            System.Diagnostics.Debug.WriteLine($"Control: {e.GetAttribute("AutomationId")}; Displayed: {e.Displayed}");

            //Check if the element is displayed (clickable) to avoid errors when clicking. An error occurs, for example, when attempting to click the selected item of a list box instead of the listbox itself.
            if (e.Displayed)
                e.Click();

            //Grab the current window in case clicking the control changed the active window by popping up a dialog
            string currentWindow = desktopSession.DesktopSessionElement.CurrentWindowHandle;
            if (currentWindow != window)
            {
                //Need to write code to handle new dialog
            }

            //Find all immediate children under the current element
            var childElements = desktopSession.DesktopSessionElement.FindElementsByXPath($"{xPath}*");
            
            //If there are no children, abort and return back to parent element (if it exists)
            if (childElements == null)
                return;
            else if (childElements.Count == 0)
                return;

            //If there are children, continue recursively down the chain
            foreach (var element in childElements)
            {
                RecursivelyClickAllElements(currentWindow, element, xPath);
            }
        }

        //Create an XPath based off of an elements attributes.
        public string ConstructXPathFromElement(AppiumWebElement e)
        {
            string className = e.GetAttribute("LocalizedControlType");
            className = (char.ToUpper(className[0]) + className.Substring(1));
            string automationId = e.GetAttribute("AutomationId");
            string name = e.GetAttribute("Name");
            string xPath = $"{className}[@AutomationId=\"{automationId}\"][@Name=\"{name}\"]/";

            return xPath;
        }
    }

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:12 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
GaneshMucherlacommented, Apr 16, 2019

@timotiusmargo ,

When can we expect the enhancement? I am seeing the same issue with our application. It will be really helpful if it is quicker

Regards, M. Ganesh

1reaction
0lkscommented, Oct 7, 2021

We use the XPath “/” to get the children of an element, e.g. e.findElements(By.xpath(“/”))

The expected XPath “*” returns the element again, looks like a bug to me…

Thank you, this simple prefix helped me as well. I agree that this looks like a bug… I was calling WindowsElement.FindElementByXPath(“child:😗”) and it made no sense to get back the same element.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Finding child element of parent with JavaScript - dom
You have a parent element, you want to get all child of specific attribute 1. get the parent 2. get the parent nodename...
Read more >
How to select all child elements recursively using CSS?
Select all child elements. element > element; If child elements select recursively then use the following syntax.
Read more >
How to select all child elements recursively using CSS
Sometimes there may be a case, where we need to select all child elements, we can use CSS selectors using the (*) operator...
Read more >
Getting Child Elements of a Node in JavaScript
In this tutorial, you will learn how to get the first child element, last child element, and all elements of a specified element....
Read more >
How to find the child element quickly? - Questions
Hi! In my plugin, there is a list of elements. Where the user clicks on any element, the element should be focused on....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found