public static IEElement[] GetElementsWithuiSelector(IESelector selector, IElement fromElement = null, int maxresults = 1) { IEElement iefromElement = fromElement as IEElement; Browser browser; if (iefromElement != null) { browser = iefromElement.Browser; } else { browser = Browser.GetBrowser(false); } if (browser == null) { Log.Warning("Failed locating an Internet Explore instance"); return(new IEElement[] { }); } var sw = new System.Diagnostics.Stopwatch(); sw.Start(); IEElement _fromElement = fromElement as IEElement; var selectors = selector.Where(x => x.Enabled == true && x.Selector == null).ToList(); var current = new List <IEElement>(); IEElement[] result = null; int startIndex = 1; if (!string.IsNullOrEmpty(selector.xpath)) { // https://stackoverflow.com/questions/6953553/is-there-a-js-library-to-provide-xpath-capacities-to-ie var _results = new List <IEElement>(); try { string body = null; Log.Selector(string.Format("Create IHTMLDocument3 {0:mm\\:ss\\.fff}", sw.Elapsed)); MSHTML.IHTMLDocument3 sourceDoc = (MSHTML.IHTMLDocument3)browser.Document; body = sourceDoc.documentElement.outerHTML; HtmlAgilityPack.HtmlDocument targetDoc = new HtmlAgilityPack.HtmlDocument(); Log.SelectorVerbose(string.Format("targetDoc.LoadHtml {0:mm\\:ss\\.fff}", sw.Elapsed)); targetDoc.LoadHtml(body); if (fromElement != null && fromElement is IEElement fromie) { HtmlAgilityPack.HtmlNode from = targetDoc.DocumentNode.SelectSingleNode(fromie.xpath); if (from == null) { throw new Exception("Failed locating from node, by xpath '" + fromie.xpath + "'"); } Log.Selector(string.Format("SelectNodes {0:mm\\:ss\\.fff}", sw.Elapsed)); var xpath = selector.xpath; if (xpath.StartsWith("//")) { xpath = "." + xpath; } var nodes = from.SelectNodes(xpath); if (nodes != null) { foreach (var node in nodes) { Log.SelectorVerbose(string.Format("new IEElement {0:mm\\:ss\\.fff}", sw.Elapsed)); var ele = new IEElement(browser, node); _results.Add(ele); if (_results.Count >= maxresults) { break; } } } } else { Log.Selector(string.Format("SelectNodes {0:mm\\:ss\\.fff}", sw.Elapsed)); var nodes = targetDoc.DocumentNode.SelectNodes(selector.xpath); if (nodes != null) { foreach (var node in nodes) { Log.SelectorVerbose(string.Format("new IEElement {0:mm\\:ss\\.fff}", sw.Elapsed)); var ele = new IEElement(browser, node); _results.Add(ele); if (_results.Count >= maxresults) { break; } } } } } catch (Exception) { browser = Browser.GetBrowser(true); } Log.Selector(string.Format("GetElementsWithuiSelector::end {0:mm\\:ss\\.fff}", sw.Elapsed)); return(_results.ToArray()); } if (iefromElement != null) { startIndex = 0; current.Add(iefromElement); } else { MSHTML.IHTMLElement startfrom = null; startfrom = browser.Document.documentElement; current.Add(new IEElement(browser, startfrom)); } for (var i = startIndex; i < selectors.Count; i++) { var s = new IESelectorItem(selectors[i]); var elements = new List <IEElement>(); elements.AddRange(current); current.Clear(); int failcounter = 0; do { foreach (var _element in elements) { MSHTML.IHTMLElement[] matches; if (frameTags.Contains(_element.TagName.ToUpper())) { if (s.tagName.ToUpper() == "HTML") { i++; s = new IESelectorItem(selectors[i]); } var _f = _element.RawElement as MSHTML.HTMLFrameElement; MSHTML.DispHTMLDocument doc = (MSHTML.DispHTMLDocument)((SHDocVw.IWebBrowser2)_f).Document; var _doc = doc.documentElement as MSHTML.IHTMLElement; matches = ((IESelectorItem)s).matches(_doc); browser.elementx += _f.offsetLeft; browser.elementy += _f.offsetTop; browser.frameoffsetx += _f.offsetLeft; browser.frameoffsety += _f.offsetTop; } else { matches = ((IESelectorItem)s).matches(_element.RawElement); } var uimatches = new List <IEElement>(); foreach (var m in matches) { var ui = new IEElement(browser, m); uimatches.Add(ui); } current.AddRange(uimatches.ToArray()); Log.Selector("add " + uimatches.Count + " matches to current"); } if (current.Count == 0) { ++failcounter; string message = string.Format("Failer # " + failcounter + " finding any hits for selector # " + i + " {0:mm\\:ss\\.fff}", sw.Elapsed) + "\n"; message += "lookin for \n" + s.ToString() + "\n"; foreach (var _element in elements) { MSHTML.IHTMLElementCollection children = (MSHTML.IHTMLElementCollection)_element.RawElement.children; foreach (MSHTML.IHTMLElement elementNode in children) { var ui = new IEElement(browser, elementNode); message += ui.ToString() + "\n"; } var matches = ((IESelectorItem)s).matches(_element.RawElement); } Log.Selector(message); } else { Log.Selector(string.Format("Found " + current.Count + " hits for selector # " + i + " {0:mm\\:ss\\.fff}", sw.Elapsed)); } } while (failcounter < 2 && current.Count == 0); if (i == (selectors.Count - 1)) { result = current.ToArray(); } if (current.Count == 0 && Config.local.log_selector) { var message = "needed to find " + Environment.NewLine + selectors[i].ToString() + Environment.NewLine + "but found only: " + Environment.NewLine; foreach (var element in elements) { MSHTML.IHTMLElementCollection children = (MSHTML.IHTMLElementCollection)element.RawElement.children; foreach (MSHTML.IHTMLElement c in children) { try { // message += automationutil.getSelector(c, (i == selectors.Count - 1)) + Environment.NewLine; } catch (Exception) { } } } Log.Selector(message); return(new IEElement[] { }); } } if (result == null) { return new IEElement[] { } } ; Log.Selector(string.Format("GetElementsWithuiSelector::end {0:mm\\:ss\\.fff}", sw.Elapsed)); return(result); } }
public static IEElement[] GetElementsWithuiSelector(IESelector selector, IElement fromElement = null, int maxresults = 1) { IEElement iefromElement = fromElement as IEElement; Browser browser; if (iefromElement != null) { browser = iefromElement.Browser; } else { browser = Browser.GetBrowser(); } if (browser == null) { Log.Warning("Failed locating an Internet Explore instance"); return(new IEElement[] { }); } var sw = new System.Diagnostics.Stopwatch(); sw.Start(); IEElement _fromElement = fromElement as IEElement; var selectors = selector.Where(x => x.Enabled == true && x.Selector == null).ToList(); var current = new List <IEElement>(); IEElement[] result = null; int startIndex = 1; if (iefromElement != null) { startIndex = 0; current.Add(iefromElement); } else { MSHTML.IHTMLElement startfrom = null; startfrom = browser.Document.documentElement; current.Add(new IEElement(browser, startfrom)); } for (var i = startIndex; i < selectors.Count; i++) { var s = new IESelectorItem(selectors[i]); var elements = new List <IEElement>(); elements.AddRange(current); current.Clear(); int failcounter = 0; do { foreach (var _element in elements) { MSHTML.IHTMLElement[] matches; if (frameTags.Contains(_element.tagName.ToUpper())) { if (s.tagName.ToUpper() == "HTML") { i++; s = new IESelectorItem(selectors[i]); } var _f = _element.RawElement as MSHTML.HTMLFrameElement; MSHTML.DispHTMLDocument doc = (MSHTML.DispHTMLDocument)((SHDocVw.IWebBrowser2)_f).Document; var _doc = doc.documentElement as MSHTML.IHTMLElement; matches = ((IESelectorItem)s).matches(_doc); browser.elementx += _f.offsetLeft; browser.elementy += _f.offsetTop; browser.frameoffsetx += _f.offsetLeft; browser.frameoffsety += _f.offsetTop; } else { matches = ((IESelectorItem)s).matches(_element.RawElement); } var uimatches = new List <IEElement>(); foreach (var m in matches) { var ui = new IEElement(browser, m); uimatches.Add(ui); } current.AddRange(uimatches.ToArray()); Log.Selector("add " + uimatches.Count + " matches to current"); } if (current.Count == 0) { ++failcounter; string message = string.Format("Failer # " + failcounter + " finding any hits for selector # " + i + " {0:mm\\:ss\\.fff}", sw.Elapsed) + "\n"; message += "lookin for \n" + s.ToString() + "\n"; foreach (var _element in elements) { MSHTML.IHTMLElementCollection children = _element.RawElement.children; foreach (MSHTML.IHTMLElement elementNode in children) { var ui = new IEElement(browser, elementNode); message += ui.ToString() + "\n"; } var matches = ((IESelectorItem)s).matches(_element.RawElement); } Log.Selector(message); } else { Log.Selector(string.Format("Found " + current.Count + " hits for selector # " + i + " {0:mm\\:ss\\.fff}", sw.Elapsed)); } } while (failcounter < 2 && current.Count == 0); if (i == (selectors.Count - 1)) { result = current.ToArray(); } if (current.Count == 0) { var message = "needed to find " + Environment.NewLine + selectors[i].ToString() + Environment.NewLine + "but found only: " + Environment.NewLine; foreach (var element in elements) { MSHTML.IHTMLElementCollection children = element.RawElement.children; foreach (MSHTML.IHTMLElement c in children) { try { // message += automationutil.getSelector(c, (i == selectors.Count - 1)) + Environment.NewLine; } catch (Exception) { } } } Log.Selector(message); return(new IEElement[] { }); } } if (result == null) { return new IEElement[] { } } ; Log.Selector(string.Format("GetElementsWithuiSelector::end {0:mm\\:ss\\.fff}", sw.Elapsed)); return(result); } }