FlaUI icon indicating copy to clipboard operation
FlaUI copied to clipboard

Xpath doesn't work

Open pavlikpatrycja opened this issue 7 years ago • 4 comments

Hi, I have no idea why clicking element by xpath in this way does not work (where xpath is: /Window/Pane/Pane[1]/Table/Pane[1]/Pane/Pane[1]) : var element = window.FindFirstByXPath(xpath); element.Click();

But this way it works (where xpath is: /Window/Pane/Pane[1]/Table):
var element = window.FindFirstByXPath(xpath);
var childs = element.FindAllChildren(); var tmp = childs[0].FindAllChildren(); var ttmp = tmp[0].FindAllChildren(); ttmp[1].Click();

I really need to click element using xpath without finding all children.

Screenshot from FlaUInspect below 2018-08-20_10h47_42

pavlikpatrycja avatar Aug 20 '18 09:08 pavlikpatrycja

The XPath FlaUInspect returns is not really correct (and far from efficient), it is only a starting point. I should document this better. When using indices, you propably need to put more braces around it. In your example probably: Instead of: /Window/Pane/Pane[1]/Table/Pane[1]/Pane/Pane[1] you should use: (((/Window/Pane)/Pane[1]/Table)/Pane[1]/Pane)/Pane[1] or something like that. The XPath syntax is not that easy to use.

Roemer avatar Dec 03 '18 13:12 Roemer

To be honest I firstly met braces in xpath and I used idices many times. I tried some options of braces in this xpath and it does not work.

pavlikpatrycja avatar Dec 06 '18 10:12 pavlikpatrycja

In this particular case I tried xpaths: /Window/Pane/Pane[1]/Table/Pane[1]/Pane/Pane[1] (((/Window/Pane)/Pane[1]/Table)/Pane[1]/Pane)/Pane[1] ((((/Window/Pane)/Pane[1]/Table)/Pane[1]/Pane)/Pane[1]) ((/Window/Pane/Pane[1])/Table/Pane[1])/Pane/Pane[1] (((/Window/Pane/Pane[1])/Table/Pane[1])/Pane/Pane[1]) I have no more ideas for this xpath with braces but no one of this xpaths is working.

pavlikpatrycja avatar Apr 30 '19 12:04 pavlikpatrycja

How about that as an idea (quick try): It gots no special checks yet, but it works at least.

ExtendedFramework.window is the window that is given back by initializing FlaUI anyway.

        public static AutomationElement GetElementByXPath(string xPath)
        {
            AutomationElement automationElement = ExtendedFramework.window.FindFirstByXPath("/"); //Find top Element
            //string xpath1 = FlaUI.Core.Debug.GetXPathToElement(ExtendedFramework.window);

            string elementPattern = "/";

            string[] getElements = Regex.Split(xPath, elementPattern, RegexOptions.IgnoreCase);
            foreach(string element in getElements)
            {
                if (string.IsNullOrEmpty(element)) continue;
                string elementSplitPattern = @"(\[\d\])";
                string[] elements = Regex.Split(element, elementSplitPattern);
                AutomationElement[] automationElements = automationElement.FindAllChildren().Where(x=>x.ControlType.ToString() == elements[0]).ToArray();
                if (elements.Length > 1)
                {
                    int index = int.Parse(elements[1].Trim(']').Trim('['));
                    automationElement = automationElements[index];
                }
                else
                {
                    automationElement = automationElements[0];
                }
            }

            return automationElement;
        }

holbizmetrics avatar Dec 01 '22 18:12 holbizmetrics