/// <summary> /// Allows a visitor to go through the list of captured Accessibility objects. /// </summary> /// <param name="visitor">The visitor to step through each ah collected.</param> public void StepDownPath(IPathVisitor visitor) { foreach (AccessibilityHelper ah in this) { visitor.visitNode(ah); } }
/// <summary> /// Glimpse one gui-path and return the result. If the expected value is not found, /// an assertion is raised. /// </summary> /// <param name="ah">Context accessibility helper, taken as the starting place for gpath.</param> /// <param name="gpath">The path through the GUI to the control.</param> /// <param name="expect">The expected value of the property for the control.</param> /// <returns></returns> bool GlimpsePath(AccessibilityHelper ah, GuiPath gpath, string expect) { m_Result = true; m_got = null; IPathVisitor visitor = null; ah = gpath.FindInGui(ah, visitor); m_Result = GlimpseGUI(ah, expect); if (m_Result) { base.Finished = true; // teminates do-once } if ((m_onPass == "assert" && m_Result == true) || (m_onFail == "assert" && m_Result == false)) { if (m_message != null && m_message.HasContent()) { fail(m_message.Read()); } else { string image = "Property [" + m_prop + "] was [" + m_got + "] expecting [" + m_expect + "] Result = '" + m_Result + "', on-pass='******', on-fail='" + m_onFail + "'"; if (gpath != null) { fail(image + " on gPath = " + gpath.toString()); } else { fail(image); } } } return(m_Result); }
/// <summary> /// Find the GUI element represented by this path step in the application GUI /// beginning from the context specified. /// /// </summary> /// <param name="ahContext">The context to start the search from</param> /// <param name="visitor">The class with the visitNode() method to /// apply to each node except the last found, may be null</param> /// <returns>The AccessibilityHelper of the last node found or null if the path does not exist</returns> public AccessibilityHelper FindInGui(AccessibilityHelper ahContext, IPathVisitor visitor) { AccessibilityHelper ah = ahContext; if (m_name == "#focus") { // get the ah from the focused Gui element ah = ah.GetFocused; } else { ah = ah.SearchPath(this, visitor); } return(ah); }
public override void Execute() { base.Execute(); bool exists = false; isNotNull(m_path, "attribute 'path' must be set"); m_path = Utilities.evalExpr(m_path); GuiPath gpath = new GuiPath(m_path); isNotNull(gpath, "attribute path='" + m_path + "' not parsed"); GuiPath lpath = null; if (m_loc != null) // if it's null, get the whole string content { lpath = new GuiPath(m_loc); isNotNull(lpath, "attribute path='" + m_loc + "' not parsed"); } Context con = (Context)Ancestor(typeof(Context)); isNotNull(con, "Select-text must occur in some context"); AccessibilityHelper ah = con.Accessibility; isNotNull(ah, "Select-text context not accessible"); // The model names are needed in selectText. IPathVisitor visitor = null; ah = gpath.FindInGui(ah, visitor); isNotNull(ah, "context not accessible from path"); if (ah != null) { if (m_loc == null) { exists = getStrValue(ah); } else { exists = selectText(lpath, ah); } } Logger.getOnly().result(this); Finished = true; // tell do-once it's done }
/// <summary> /// Searches the path depth-first. /// Nth is not used - if it were, it could get a sibling, ancestor or child. /// </summary> /// <param name="path">The path to search. Each step in the path contains an /// Accessibility name and Accessibility role of the matching gui object.</param> /// <param name="visitor">null or the object providing methods that are called when steps are found.</param> /// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the matched /// window.</returns> private AccessibilityHelper SearchPathByDepth(GuiPath path, IPathVisitor visitor) { Logger log = Logger.getOnly(); log.startList("SearchPathByDepth('" + path.toString() + "') starting from ('" + this.Role + "','" + this.Name + "')"); if (ChildCount <= 0) { if (visitor != null) visitor.notFound(path); return null; } AccessibilityHelper ah = null; // try the client first if there is one, but don't visit it AccessibilityHelper client = FindClient(); if (client != null) ah = client.SearchPathByDepth(path, visitor); if (ah != null) { log.endList(); return ah; } // Rats!! It wasn't below the client, the caller wants some system widget or something foreach (AccessibilityHelper child in this) { if (child == null || child.Equals(client)) continue; // does this object match? // treat name == "" and child.Name == null as a match // Note: a null string shows as "" in the debugger! log.startList("SearchPathByDepth('" + path.toString() + "') Child: ('" + child.Role + "','" + child.Name + "')"); if (MatchNameAndRole(path.Name, path.Role, child)) { if (path.Next != null) { if (visitor != null) visitor.visitNode(child); // allow processing of this ah by caller log.endList(); return ValueOrChild(path.Next, child, visitor); } } // if not a "real" object, a child takes on it's parent's // attributes, so it appears to have the same # of children. // The first child is always the first child, so you get // infinite recursion on it if you don't check "realness". if (child.m_fRealAccessibleObject && child.ChildCount > 0) { // look through the child objects ah = child.SearchPathByDepth(path, visitor); if (ah != null) { if (path.Next != null) { if (visitor != null) visitor.visitNode(ah); // allow processing of this ah by caller log.endList(); return ValueOrChild(path.Next, ah, visitor); } log.endList(); return ah; } } } if (visitor != null) visitor.notFound(path); log.endList(); return null; }
/// <summary> /// ValueOrChild determines if the ah's value should be macthed or /// if a child should be matched. /// </summary> /// <param name="nextGP">The next path step beyond this ah</param> /// <param name="ah">The accessibility object currently considered</param> /// <param name="visitor">null or the object providing methods that are called when steps are found.</param> /// <returns>An AccessibilityHelper if checking for a value, otherwise null</returns> public AccessibilityHelper ValueOrChild(GuiPath nextGP, AccessibilityHelper ah, IPathVisitor visitor) { bool result = false; if (nextGP.Role == AccessibleRole.Alert) { // check if the name is a regular expression if (nextGP.Name != null && nextGP.Name.StartsWith("rexp#")) { Regex rx = new Regex(nextGP.Name.Substring(5)); result = rx.IsMatch(ah.Value); Logger.getOnly().paragraph("Path name reg exp " + nextGP.Name.Substring(5) + " on " + ah.Value + " was " + result.ToString()); } else result = nextGP.Name == ah.Value; // match the value to the next path's name if (!result) { // it didn't match, so the search failed if (visitor != null) visitor.notFound(nextGP); return null; } } if (result) return ah; return ah.SearchPath(nextGP, visitor); // continue on the path }
/// <summary> /// The search is almost breadth-first: /// The first step in the path is searched breath-first. /// Subsequent path steps are searched for depending on their content. /// The Accessibility helper representing the step is returned it is found and is the last step. /// Otherwise, the search continues with the next path step or if not found, null is returned. /// If the first step is found, the visitor is applied before continuing to the next step. /// </summary> /// <param name="path">The path to search. Each step in the path contains an /// Accessibility name and Accessibility role of the matching gui object.</param> /// <param name="visitor">null or the object providing methods that are called when steps are found.</param> /// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the matched /// window.</returns> private AccessibilityHelper SearchPathByBreadth(GuiPath path, IPathVisitor visitor) { if (ChildCount <= 0 || path.Nth <= 0) { if (visitor != null) visitor.notFound(path); return null; } int place = path.Nth; Logger log = Logger.getOnly(); log.startList("SearchPathByBreadth('" + path.toString() + "') starting from ('" + this.Role + "','" + this.Name + "')"); ArrayList lists = new ArrayList(); // list of child lists ArrayList nodes = MakeChildList(this); lists.Add(nodes); // Examine the first node in the list, dropping it after examination // and adding its children to the end if prudent. int lnum = 0; while (lists.Count > 0) { int count = 0; // reset match count nodes = (ArrayList)lists[0]; int nnum = 0; ++lnum; while (nodes.Count > 0) { AccessibilityHelper ah = (AccessibilityHelper)nodes[0]; string logStr = "-> Child(" + lnum + ":" + (++nnum) + ") ('" + ah.Role + "','" + ah.Name + "')"; if (path.Next != null && path.Next.Role == AccessibleRole.Alert) logStr += "val[" + ah.Value + "]"; log.listItem(logStr); if (MatchNameAndRole(path.Name, path.Role, ah)) { // this is the only way to return if (++count >= place) { // Found this step, keep stepping along the path if (path.Next != null) { if (visitor != null) visitor.visitNode(ah); // allow processing of this ah by caller ah = ValueOrChild(path.Next, ah, visitor); } log.endList(); return ah; } } if (ah.m_fRealAccessibleObject && ah.ChildCount > 0) lists.Add(MakeChildList(ah)); nodes.RemoveAt(0); // when 0 is removed, all indices slide down 1 } lists.RemoveAt(0); // when 0 is removed, all indices slide down 1 } if (visitor != null) visitor.notFound(path); log.endList(); return null; }
/// <summary> /// The search is almost breadth-first: /// The first step in the path has an unknown sibling index and its role is not 'value'. /// If this ah has children of the step type, they are searched until all the /// subsequent steps find matching ah's. This search substitutes its own visitor /// that records the successful path ah's. Upon success, a sibling index is assigned to /// the variable named in the step, the non-terminal subpath ah's are exposed /// to the caller's visitor in turn and this method returns the last ah on the path. /// Subpath steps are searched for depending on their content. /// </summary> /// <param name="path">The path to search. Each step in the path contains an /// Accessibility name and Accessibility role of the matching gui object.</param> /// <param name="visitor">null or the object providing methods that are called when steps are found.</param> /// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the matched /// window.</returns> private AccessibilityHelper SearchPathForIndex(GuiPath path, IPathVisitor visitor) { Logger log = Logger.getOnly(); log.startList("SearchPathForIndex('" + path.toString() + "') starting from ('" + this.Role + "','" + this.Name + "')"); if (ChildCount <= 0) { if (visitor != null) visitor.notFound(path); log.endList(); return null; } AccessibilityHelper ah = null; int nnum = 0; int index = 0; string parentName = null; if (path.Prev != null) parentName = path.Prev.Name; foreach (AccessibilityHelper child in this) { if (child == null) continue; string logStr = "-> Child(" + (++nnum) + ") ('" + child.Role + "','" + child.Name + "')"; if (path.Next != null && path.Next.Role == AccessibleRole.Alert) logStr += "NOT SUPPOSED TO BE VALUE!! val[" + child.Value + "]"; log.listItem(logStr); if (MatchNameAndRole(path.Name, path.Role, child)) { // this is a candidate for matching the path ++index; // the first one is 1 if (path.Next != null) { // This method won't allow for caller's visitors on candidate nodes until proved needed TrackingVisitor tv = new TrackingVisitor(); // tv may need to open sub menus if (tv != null) tv.visitNode(child); // add child to node list to visit later if this is the right path ah = ValueOrChild(path.Next, child, tv); if (ah != null) { // the subpath was matched to the end if (path.VarId != null && path.VarId != "") { // Create and execute a variable to record the index Var var = new Var(); var.Id = path.VarId; var.Set = System.Convert.ToString(index); // 1 based count var.Execute(); // puts the var in the TestState hash // don't set path.Nth = index since it might change if the path is used again } // let the caller's visitor tend to all the path ah's if (visitor != null) { if (tv != null) tv.StepDownPath(visitor); } log.endList(); return ah; } } } else if (parentName != null && child.Role == AccessibleRole.Client && child.Name == parentName) { // try the client instead ah = child.SearchPathForIndex(path, visitor); if (ah != null) { log.endList(); return ah; // found it } } } if (visitor != null) visitor.notFound(path); log.endList(); return null; }
/// <summary> /// Finds the accessible object at the end of the path with optional place and varId from /// which it creates a variable object to hold the sibling number of the object found. /// An optional path visitor allows the caller to do something with intermediate steps /// along the path for debugging or interface control. /// The value of a node can be specified via a path step like "value:whatever the value is". /// When place is greater than 0, the search is breadth-first. /// Generally, clients need not be included in the "path". /// When place is 0, a value must be the leaf node of the path /// as there is typically some repeated structure /// like a table, row and cell with value. The structure is /// traversed repeatedly until the leaf node with the value is found. /// When place is negative, depth-first search is used. It tends to be /// the slowest way to search the Accessibility tree. /// </summary> /// <param name="path">The path to search. Each step in the path contains an /// Accessibility name and Accessibility role of the matching gui object.</param> /// <param name="visitor">null or the object providing methods that are called when steps are found.</param> /// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the object found at the end of the path.</returns> public AccessibilityHelper SearchPath(GuiPath path, IPathVisitor visitor) { if (path == null) return null; // three cases based on Nth if (path.Nth > 0) { // psuedo breadth-first return this.SearchPathByBreadth(path, visitor); } if (path.Nth == 0) { // loop over FindChildBreadth to find a sibling index to set a var with varId return this.SearchPathForIndex(path, visitor); } else if (path.Nth < 0) { // depth-first return this.SearchPathByDepth(path, visitor); } return null; }
void IPathCommand.Visit <T>(T state, IPathVisitor <T> visitor) { visitor.CreateLineSegment(state, Point0, Point1); }
void IPathCommand.Visit <T>(T state, IPathVisitor <T> visitor) { visitor.CreateArcSegment(state, Point0, Point1, LargeArcFlag, AxisRotation, RadiusX, RadiusY, SweepFlag); }
/// <summary> /// ValueOrChild determines if the ah's value should be macthed or /// if a child should be matched. /// </summary> /// <param name="nextGP">The next path step beyond this ah</param> /// <param name="ah">The accessibility object currently considered</param> /// <param name="visitor">null or the object providing methods that are called when steps are found.</param> /// <returns>An AccessibilityHelper if checking for a value, otherwise null</returns> public AccessibilityHelper ValueOrChild(GuiPath nextGP, AccessibilityHelper ah, IPathVisitor visitor) { bool result = false; if (nextGP.Role == AccessibleRole.Alert) { // check if the name is a regular expression if (nextGP.Name != null && nextGP.Name.StartsWith("rexp#")) { Regex rx = new Regex(nextGP.Name.Substring(5)); result = rx.IsMatch(ah.Value); Log log = Log.getOnly(); log.writeElt("ValueOrChild"); log.writeAttr("pattern", nextGP.Name.Substring(5)); log.writeAttr("to", ah.Value); log.writeAttr("result", result.ToString()); log.endElt(); } else result = nextGP.Name == ah.Value; // match the value to the next path's name if (!result) { // it didn't match, so the search failed if (visitor != null) visitor.notFound(nextGP); return null; } } if (result) return ah; return ah.SearchPath(nextGP, visitor); // continue on the path }
void IPathCommand.Visit <T>(T state, IPathVisitor <T> visitor) { visitor.ClosePath(state, Point0, ClosePath); }
/// <summary> /// Find the GUI element represented by this path step in the application GUI /// beginning from the context specified. /// /// </summary> /// <param name="ahContext">The context to start the search from</param> /// <param name="visitor">The class with the visitNode() method to /// apply to each node except the last found, may be null</param> /// <returns>The AccessibilityHelper of the last node found or null if the path does not exist</returns> public AccessibilityHelper FindInGui(AccessibilityHelper ahContext, IPathVisitor visitor) { AccessibilityHelper ah = ahContext; if (m_name == "#focus") { // get the ah from the focused Gui element ah = ah.GetFocused; } else ah = ah.SearchPath(this, visitor); return ah; }
void IPathCommand.Visit <T>(T state, IPathVisitor <T> visitor) { visitor.CreateQuadSegment(state, Point0, Point1, Point2); }
void IPathCommand.Visit <T>(T state, IPathVisitor <T> visitor) { visitor.BeginPath(state, Point1, true); }
void IPathCommand.Visit <T>(T state, IPathVisitor <T> visitor) { visitor.CreateBezierSegment(state, Point0, Point1, Point2, Point3); }
/// <summary> /// The search is almost breadth-first: /// The first step in the path has an unknown sibling index and its role is not 'value'. /// If this ah has children of the step type, they are searched until all the /// subsequent steps find matching ah's. This search substitutes its own visitor /// that records the successful path ah's. Upon success, a sibling index is assigned to /// the variable named in the step, the non-terminal subpath ah's are exposed /// to the caller's visitor in turn and this method returns the last ah on the path. /// Subpath steps are searched for depending on their content. /// </summary> /// <param name="path">The path to search. Each step in the path contains an /// Accessibility name and Accessibility role of the matching gui object.</param> /// <param name="visitor">null or the object providing methods that are called when steps are found.</param> /// <returns>A new <see cref="AccessibilityHelper"/> object that wraps the matched /// window.</returns> private AccessibilityHelper SearchPathForIndex(GuiPath path, IPathVisitor visitor) { Log log = Log.getOnly(); log.writeElt("head"); log.writeElt("SearchPathForIndex"); log.writeAttr("from", this.Role + ":" + this.Name); log.writeAttr("to", path.toString()); log.endElt(); if (ChildCount <= 0) { if (visitor != null) visitor.notFound(path); return null; } AccessibilityHelper ah = null; int nnum = 0; int index = 0; string parentName = null; if (path.Prev != null) parentName = path.Prev.Name; foreach (AccessibilityHelper child in this) { if (child == null) continue; log.writeElt("SearchPathForIndex"); log.writeAttr("child", (++nnum)); log.writeAttr("path", ah.Role + ":" + ah.Name); // not supposed to be a value! if (path.Next != null && path.Next.Role == AccessibleRole.Alert) log.writeAttr("bad-value", ah.Value); log.endElt(); if (MatchNameAndRole(path.Name, path.Role, child)) { // this is a candidate for matching the path ++index; // the first one is 1 if (path.Next != null) { // This method won't allow for caller's visitors on candidate nodes until proved needed TrackingVisitor tv = new TrackingVisitor(); // tv may need to open sub menus if (tv != null) tv.visitNode(child); // add child to node list to visit later if this is the right path ah = ValueOrChild(path.Next, child, tv); if (ah != null) { // the subpath was matched to the end if (path.VarId != null && path.VarId != "") { // Create and execute a variable to record the index // Var var = new Var(); // var.Id = path.VarId; // var.Set = System.Convert.ToString(index); // 1 based count // var.Execute(); // puts the var in the TestState hash // don't set path.Nth = index since it might change if the path is used again } // let the caller's visitor tend to all the path ah's if (visitor != null) { if (tv != null) tv.StepDownPath(visitor); } log.endElt(); // end head element return ah; } } } else if (parentName != null && child.Role == AccessibleRole.Client && child.Name == parentName) { // try the client instead ah = child.SearchPathForIndex(path, visitor); if (ah != null) { log.endElt(); // end head element return ah; // found it } } } if (visitor != null) visitor.notFound(path); log.endElt(); // end head element return null; }