Skip to content

Commit

Permalink
Element search starts from the focused windows, if the starting point…
Browse files Browse the repository at this point in the history
… is not specified.
  • Loading branch information
imsardine committed May 5, 2015
1 parent c4fc120 commit ed04c56
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 65 deletions.
9 changes: 5 additions & 4 deletions src/WinAppDriver/FindElementHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ public object Handle(Dictionary<string, string> urlParams, string body, ref Sess
{
FindElementRequest request = JsonConvert.DeserializeObject<FindElementRequest>(body);

var root = AutomationElement.RootElement;
AutomationElement start;
this.uiAutomation.TryGetFocusedWindowOrRoot(out start);
if (urlParams.ContainsKey("id"))
{
root = session.GetUIElement(int.Parse(urlParams["id"]));
start = session.GetUIElement(int.Parse(urlParams["id"]));
}

AutomationElement element = null;
if (request.Strategy == "xpath")
{
element = this.uiAutomation.FindFirstByXPath(root, request.Locator);
element = this.uiAutomation.FindFirstByXPath(start, request.Locator);
}
else
{
Expand All @@ -43,7 +44,7 @@ public object Handle(Dictionary<string, string> urlParams, string body, ref Sess
property = AutomationElement.ClassNameProperty;
}

element = root.FindFirst(
element = start.FindFirst(
TreeScope.Descendants,
new PropertyCondition(property, request.Locator));
}
Expand Down
9 changes: 5 additions & 4 deletions src/WinAppDriver/FindElementsHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ public object Handle(Dictionary<string, string> urlParams, string body, ref Sess
{
FindElementRequest request = JsonConvert.DeserializeObject<FindElementRequest>(body);

var root = AutomationElement.RootElement;
AutomationElement start;
this.uiAutomation.TryGetFocusedWindowOrRoot(out start);
if (urlParams.ContainsKey("id"))
{
root = session.GetUIElement(int.Parse(urlParams["id"]));
start = session.GetUIElement(int.Parse(urlParams["id"]));
}

IEnumerable elements = null;
if (request.Strategy == "xpath")
{
elements = this.uiAutomation.FindAllByXPath(root, request.Locator);
elements = this.uiAutomation.FindAllByXPath(start, request.Locator);
}
else
{
Expand All @@ -43,7 +44,7 @@ public object Handle(Dictionary<string, string> urlParams, string body, ref Sess
property = AutomationElement.ClassNameProperty;
}

elements = root.FindAll(
elements = start.FindAll(
TreeScope.Descendants,
new PropertyCondition(property, request.Locator));
}
Expand Down
5 changes: 4 additions & 1 deletion src/WinAppDriver/GetSourceHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ public GetSourceHandler(IUIAutomation uiAutomation)

public object Handle(Dictionary<string, string> urlParams, string body, ref Session session)
{
return this.uiAutomation.DumpXml(AutomationElement.RootElement);
AutomationElement start;
this.uiAutomation.TryGetFocusedWindowOrRoot(out start);

return this.uiAutomation.DumpXml(start);
}
}
}
10 changes: 6 additions & 4 deletions src/WinAppDriver/IUIAutomation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ namespace WinAppDriver

internal interface IUIAutomation
{
string DumpXml(AutomationElement root);
bool TryGetFocusedWindowOrRoot(out AutomationElement window);

string DumpXml(AutomationElement root, out IList<AutomationElement> elements);
string DumpXml(AutomationElement start);

AutomationElement FindFirstByXPath(AutomationElement root, string xpath);
string DumpXml(AutomationElement start, out IList<AutomationElement> elements);

IList<AutomationElement> FindAllByXPath(AutomationElement root, string xpath);
AutomationElement FindFirstByXPath(AutomationElement start, string xpath);

IList<AutomationElement> FindAllByXPath(AutomationElement start, string xpath);
}
}
2 changes: 1 addition & 1 deletion src/WinAppDriver/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private static RequestManager InitRequestManager(SessionManager sessionManager)
var utils = new Utils();
var keyboard = new Keyboard(new KeyboardWrap(), new KeyInteropWrap(), new WinUserWrap());
var uiAutomation = new UIAutomation();
var uacHandler = new UACPromptHandler(keyboard);
var uacHandler = new UACPromptHandler(uiAutomation, keyboard);

manager.AddHandler(new ClickElementHandler());
manager.AddHandler(new DeleteSessionHandler(sessionManager));
Expand Down
33 changes: 5 additions & 28 deletions src/WinAppDriver/UAC/UACPromptHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ internal class UACPromptHandler : IUACPomptHandler
{
private static ILogger logger = Logger.GetLogger("WinAppDriver");

private IUIAutomation uiAutomation;

private IKeyboard keyboard;

private Thread threadLazy;
Expand All @@ -18,8 +20,9 @@ internal class UACPromptHandler : IUACPomptHandler

private bool allowed; // true = Yes, false = No

public UACPromptHandler(IKeyboard keyboard)
public UACPromptHandler(IUIAutomation uiAutomation, IKeyboard keyboard)
{
this.uiAutomation = uiAutomation;
this.keyboard = keyboard;
this.threadLazy = null;
this.stopped = false;
Expand Down Expand Up @@ -76,7 +79,7 @@ private bool DismissUACPrompts()
logger.Info("Trying to find the (focused) UAC elevation prompt.");

AutomationElement window = null;
if (this.TryGetFocusedWindow(out window))
if (this.uiAutomation.TryGetFocusedWindowOrRoot(out window))
{
var conditions = new AndCondition(
Automation.ContentViewCondition,
Expand All @@ -101,32 +104,6 @@ private bool DismissUACPrompts()
return false;
}

private bool TryGetFocusedWindow(out AutomationElement window)
{
window = null;

var walker = TreeWalker.ContentViewWalker;
var parent = AutomationElement.FocusedElement;
while (parent != null)
{
if (parent == AutomationElement.RootElement)
{
return false;
}
else if (parent.Current.ControlType == ControlType.Window)
{
window = parent;
return true;
}
else
{
parent = walker.GetParent(parent);
}
}

return false;
}

private Thread GetThread()
{
if (this.threadLazy == null)
Expand Down
72 changes: 49 additions & 23 deletions src/WinAppDriver/UIAutomation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,47 @@ namespace WinAppDriver

internal class UIAutomation : IUIAutomation
{
public string DumpXml(AutomationElement root)
public bool TryGetFocusedWindowOrRoot(out AutomationElement window)
{
return this.DumpXmlImpl(root, null);
window = AutomationElement.RootElement;

var walker = TreeWalker.ContentViewWalker;
var parent = AutomationElement.FocusedElement;
while (parent != null)
{
if (parent == AutomationElement.RootElement)
{
return false;
}
else if (parent.Current.ControlType == ControlType.Window)
{
window = parent;
return true;
}
else
{
parent = walker.GetParent(parent);
}
}

return false;
}

public string DumpXml(AutomationElement root, out IList<AutomationElement> elements)
public string DumpXml(AutomationElement start)
{
return this.DumpXmlImpl(start, null);
}

public string DumpXml(AutomationElement start, out IList<AutomationElement> elements)
{
elements = new List<AutomationElement>();
return this.DumpXmlImpl(root, elements);
return this.DumpXmlImpl(start, elements);
}

public AutomationElement FindFirstByXPath(AutomationElement root, string xpath)
public AutomationElement FindFirstByXPath(AutomationElement start, string xpath)
{
IList<AutomationElement> nodes;
string xml = this.DumpXml(root, out nodes);
string xml = this.DumpXml(start, out nodes);

var doc = new XPathDocument(new StringReader(xml));
XPathNavigator node = doc.CreateNavigator().SelectSingleNode(xpath);
Expand All @@ -37,10 +63,10 @@ public AutomationElement FindFirstByXPath(AutomationElement root, string xpath)
}
}

public IList<AutomationElement> FindAllByXPath(AutomationElement root, string xpath)
public IList<AutomationElement> FindAllByXPath(AutomationElement start, string xpath)
{
IList<AutomationElement> elements;
string xml = this.DumpXml(root, out elements);
string xml = this.DumpXml(start, out elements);

var doc = new XPathDocument(new StringReader(xml));
XPathNodeIterator nodes = doc.CreateNavigator().Select(xpath);
Expand All @@ -66,34 +92,34 @@ private string DumpXmlImpl(AutomationElement start, IList<AutomationElement> ele

writer.WriteStartDocument();
writer.WriteStartElement("WinAppDriver");
this.WalkTree(AutomationElement.RootElement, walker, writer, elements);
this.WalkTree(start, walker, writer, elements);
writer.WriteEndDocument();

return stringWriter.ToString();
}

private void WalkTree(AutomationElement parent, TreeWalker walker, XmlWriter writer, IList<AutomationElement> elements)
{
var child = walker.GetFirstChild(parent);
while (child != null)
var info = parent.Current;
writer.WriteStartElement(info.ControlType.ProgrammaticName);
if (elements != null)
{
var info = child.Current;
writer.WriteStartElement(info.ControlType.ProgrammaticName);
if (elements != null)
{
writer.WriteAttributeString("_index_", elements.Count.ToString());
elements.Add(child);
}
writer.WriteAttributeString("_index_", elements.Count.ToString());
elements.Add(parent);
}

writer.WriteAttributeString("id", info.AutomationId);
writer.WriteAttributeString("name", info.Name);
writer.WriteAttributeString("class", info.ClassName);
writer.WriteAttributeString("id", info.AutomationId);
writer.WriteAttributeString("name", info.Name);
writer.WriteAttributeString("class", info.ClassName);

var child = walker.GetFirstChild(parent);
while (child != null)
{
this.WalkTree(child, walker, writer, elements);
writer.WriteEndElement();

child = walker.GetNextSibling(child);
}

writer.WriteEndElement();
}
}
}

0 comments on commit ed04c56

Please sign in to comment.