private static WebSearchInfo CreateWebSearchFor(IWebElementInfo elementInfo)
        {
            var           locator       = elementInfo.Locator;
            WebSearchInfo webSearchInfo = null;

            if (elementInfo.ElementType == WebElementTypes.Frame)
            {
                if (locator is IFrameWebLocatorInfo fwli)
                {
                    webSearchInfo = new FrameWebSearchInfo
                    {
                        FrameLocatorType = fwli.FrameLocatorType
                    };
                }
                else
                {
                    throw new Exception("Wow frame element has non frame locator info");
                }
            }
            else
            {
                webSearchInfo = new WebSearchInfo();
            }

            webSearchInfo.LocatorType  = locator.LocatorType;
            webSearchInfo.LocatorValue = locator.LocatorValue;

            return(webSearchInfo);
        }
        public static WebSearchInfo BuildWebSearch(IWebElementInfo elementInfo)
        {
            //if it's directory, return null
            if (elementInfo.ElementType == WebElementTypes.Directory ||
                elementInfo.ElementType == WebElementTypes.Page)
            {
                return(null);
            }

            var           locator    = elementInfo.Locator;
            WebSearchInfo searchInfo = null;

            //if it's element with reference. Frame or Reference
            if (elementInfo is IWebElementWithReferenceInfo elWithRef)
            {
                //if it's Reference, check locator overrides
                if (elWithRef.ElementType == WebElementTypes.Reference)
                {
                    //Reference shouldn't be null
                    if (elWithRef.ReferencedElement == null)
                    {
                        throw new SakiWebElementException(nameof(BuildWebSearch),
                                                          $"Element with type: {elementInfo.ElementType} has nullable reference", elementInfo);
                    }

                    if (elWithRef.Locator == null)
                    {
                        locator = elWithRef.ReferencedElement.Locator;
                    }
                }
                //if it's Frame, check frame locator type
                else if (elWithRef.ElementType == WebElementTypes.Frame)
                {
                    if (locator is IFrameWebLocatorInfo frameLocator)
                    {
                        searchInfo = new FrameWebSearchInfo
                        {
                            FrameLocatorType = frameLocator.FrameLocatorType,
                            LocatorValue     = frameLocator.LocatorValue,
                            LocatorType      = frameLocator.LocatorType
                        };

                        //if locator is not web locator, go to parent frames calculation
                        if (frameLocator.FrameLocatorType != FrameLocatorType.Locator)
                        {
                            BuildWebSearchFrames(elementInfo, searchInfo);
                            return(searchInfo);
                        }
                    }
                    else
                    {
                        throw new SakiWebElementException(nameof(BuildWebSearch),
                                                          $"Frame element has non frame locator.", elementInfo);
                    }
                }
                else
                {
                    throw new SakiWebElementException(nameof(BuildWebSearch),
                                                      $"Unknown element with reference. Element type {elementInfo.ElementType}", elementInfo);
                }
            }

            searchInfo = searchInfo
                         ?? new WebSearchInfo
            {
                LocatorType  = locator.LocatorType,
                LocatorValue = locator.LocatorValue,
                ParentSearch = null
            };

            if (locator.IsRelative && elementInfo.Parent != null)
            {
                var parent = elementInfo.Parent;

                if (parent.ElementType == WebElementTypes.Reference)
                {
                    if (parent.Locator == null)
                    {
                        if (parent is IWebElementWithReferenceInfo parentRefs)
                        {
                            var refed = parentRefs.ReferencedElement;
                            if (refed == null)
                            {
                                throw new SakiWebElementException(nameof(BuildWebSearch),
                                                                  $"Referenced element in parent is NULL.", elementInfo);
                            }

                            if (elementInfo == refed)
                            {
                                parent = parent.Parent;
                            }
                            else if (refed is ICombinedWebElementInfo refedCombined)
                            {
                                parent = refedCombined;
                            }
                            else
                            {
                                throw new SakiWebElementException(nameof(BuildWebSearch),
                                                                  $"Referenced element in parent is not a combined element.", elementInfo);
                            }
                        }
                        else
                        {
                            throw new SakiWebElementException(nameof(BuildWebSearch),
                                                              $"Element with type Reference is not a reference.", elementInfo);
                        }
                    }
                }

                if (parent != null &&
                    parent.ElementType != WebElementTypes.Frame &&
                    parent.ElementType != WebElementTypes.Directory &&
                    parent.ElementType != WebElementTypes.Page)
                {
                    var parentSearch = parent.GetWebSearch();

                    if (searchInfo.LocatorType == parentSearch.LocatorType &&
                        (searchInfo.LocatorType == WebLocatorType.XPath || searchInfo.LocatorType == WebLocatorType.Css))
                    {
                        if (searchInfo.LocatorType == WebLocatorType.XPath)
                        {
                            searchInfo.LocatorValue = MergeXPath(parentSearch.LocatorValue, searchInfo.LocatorValue);
                        }
                        else
                        {
                            searchInfo.LocatorValue = MergeCss(parentSearch.LocatorValue, searchInfo.LocatorValue);
                        }

                        searchInfo.ParentSearch = parentSearch.ParentSearch;
                    }
                    else
                    {
                        if (parentSearch.LocatorType == WebLocatorType.XPath &&
                            parentSearch.LocatorValue == ".")
                        {
                            searchInfo.ParentSearch = parentSearch.ParentSearch;
                        }
                        else
                        {
                            searchInfo.ParentSearch = parentSearch;
                        }
                    }

                    if (searchInfo.LocatorType == WebLocatorType.XPath &&
                        searchInfo.LocatorValue == ".")
                    {
                        return(parentSearch);
                    }

                    return(searchInfo);
                }
            }

            BuildWebSearchFrames(elementInfo, searchInfo);
            return(searchInfo);
        }