public Context() : base() { m_ah = null; m_onFail = null; m_onPass = null; m_tag = "on-context"; }
public void AccessibleObjectFromPoint() { AccessibilityHelper child = m_ah.FindChild("statusBarFw", AccessibleRole.Window); Rect rect; Win32.GetWindowRect((IntPtr)child.HWnd, out rect); Point pt = new Point(rect.left, rect.top); AccessibilityHelper test = new AccessibilityHelper(pt); Assert.AreEqual(child.HWnd, test.HWnd); }
public void Init() { string tePath = SIL.FieldWorks.Common.Utils.DirectoryFinder.GetFWCodeFile(@"\..\Output\Debug\TE.exe"); m_proc = Process.Start(tePath); m_proc.WaitForInputIdle(); while (Process.GetProcessById(m_proc.Id).MainWindowHandle == IntPtr.Zero) Thread.Sleep(100); m_proc.WaitForInputIdle(); Win32.SetForegroundWindow(m_proc.MainWindowHandle); m_ah = new AccessibilityHelper(m_proc.MainWindowHandle); }
public override void Execute() { // first, see if the last test left an error window open //m_memory = System. //Application.Process CheckForErrorDialogs(false); // find any window then switch to its parent until it doesn't have one //IntPtr foundHwndPtr = FindWindow(null, null); // Random Window IntPtr foundHwndPtr = FindWindow(null, "Program Manager"); // 9:Program Manager/9:$NL;/33:Desktop? if ((int)foundHwndPtr != 0) { m_ah = new AccessibilityHelper(foundHwndPtr); isNotNull(m_ah,"window "+(int)foundHwndPtr+"isn't accessible"); areEqual(m_ah.Name, "Program Manager", "window " + m_ah.Name + " found insteadof Program Manager"); // while (m_ah.Name != "Desktop" && m_ah.Role != AccessibleRole.Window && m_ah.Parent != null) // m_ah = m_ah.Parent; } // isTrue(m_ah.Name == "Desktop" && m_ah.Role == AccessibleRole.Window, @"Desktop not found! Got """+m_ah.Role+":"+m_ah.Name+@""" instead"); if (1 == m_logLevel) m_log.paragraph("Desktop is ""+m_ah.Role+":"+m_ah.Name+"""); base.Execute(); Finished = true; // tell do-once it's done }
/// <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; }
private string ClickPath(AccessibilityHelper ah, GuiPath gpath) { //bool forAll = false; //bool clickParent = false; //AccessibilityHelper child; //if (m_for != null && "all" == (string)m_for) forAll = true; if (1 == m_logLevel) m_log.paragraph(makeNameTag() + "Click starting path from "" + ah.Role + ":" + ah.Name + """); ah = gpath.FindInGui(ah, this); if (ah != null) { if (1 == m_logLevel) m_log.paragraph(makeNameTag() + "Clicking last pair in path"); int j; for (j = 0; j < m_repeat; j++) { // click 10 pixels from the left edge - see below if (m_side == "right") ah.SimulateRightClickRelative(m_dx, m_dy); else ah.SimulateClickRelative(m_dx, m_dy); // when @wait="no" don't wait at all between repeated clicks if (m_wait) Thread.Sleep(400); // wait a while eg. let menus open, etc. } m_finished = true; // tell do-once it's done } else return m_message; return ""; }
/// <summary> /// Given the GUI control or view ah, get its entire string value. /// </summary> /// <param name="ah">Accessibility helper from the GUI control or view</param> /// <returns>true if the string value was retrieved.</returns> private bool getStrValue(AccessibilityHelper ah) { m_text = ah.Value; return m_text != null; }
/// <summary> /// method to apply when a non-terminal node has been found /// </summary> /// <param name="ah"></param> public void visitNode(AccessibilityHelper ah) { // does this ah need to be clicked or something to get to its children? ah.MoveMouseOverMe(); // hover if (1 == m_logLevel) m_log.paragraph("HoverOver hovering over "" + ah.Role + ":" + ah.Name + """); }
/// <summary> /// Given the GUI control or view ah, find and highlight the text indicated /// via the location (level) path. /// </summary> /// <param name="lpath">Level path array.</param> /// <param name="ah">Accessibility helper from the GUI control or view</param> /// <returns>true if the selected string was retrieved.</returns> private bool selectText(GuiPath lpath, AccessibilityHelper ah) { IVwRootBox rbox = ah.RootBox(); isNotNull(rbox,"view rootbox not found"); IVwSelection sel = null; // returned selection // create a SelLevInfo[] array to the content using the model view levels. int clevels = 0; SelLevInfo[] rgvsli; if (DrillToContent(lpath, out rgvsli, out clevels)) { int ihvoRoot = 0; // first rootbox int tagTextProp = 16002; // kflidStTxtPara_Contents int cpropPrevious = 0; int ichAnchor = m_at; // starting character number int ichEnd = m_at + m_run; // ending character number in rgvsli[0].ihvo or ihvoEnd if it is not -1 int ws = 0; bool fAssocPrev = false; int ihvoEnd = -1; // paragraph # to end at, if it doesn't exist, get unspecified interop error ITsTextProps ttpIns = null; bool fInstall = true; // make it the view's default selection //int iHeight = rbox.get_Height(); int iHeight = rbox.Height; sel = rbox.MakeTextSelection (ihvoRoot, clevels, rgvsli, tagTextProp, cpropPrevious, ichAnchor, ichEnd, ws, fAssocPrev, ihvoEnd, ttpIns, fInstall); isNotNull(sel,"failed to select text"); //areEqual(true, sel.get_IsValid(), "selection is not valid"); areEqual(true, sel.IsValid, "selection is not valid"); ITsTextProps ttp = spyOnSelection(sel); if(ttp != null) spyOnTextProps(ttp); } string strSeparator = "|"; ITsString tssFromApp; sel.GetSelectionString(out tssFromApp, strSeparator); ITsStreamWrapper tsw = TsStreamWrapperClass.Create(); //UCOMIStream strm = tsw.get_Stream(); System.Runtime.InteropServices.ComTypes.IStream strm = tsw.Stream; // Copy the string to our address space. ITsStrBldr bldr = TsStrBldrClass.Create(); bldr.ReplaceTsString(0,0, tssFromApp); ITsString tss = bldr.GetString(); int icchIndent = 2; int iws = 0; bool fWriteObjData = true; //tsw.WriteTssAsXml(tss2, icchIndent, iws, fWriteObjData); //ISilDataAccess da = rbox.get_DataAccess(); ISilDataAccess da = rbox.DataAccess; //ILgWritingSystemFactory wsf = da.get_WritingSystemFactory(); ILgWritingSystemFactory wsf = da.WritingSystemFactory; tss.WriteAsXml(strm, wsf, icchIndent, iws, fWriteObjData); //m_text = tsw.get_Contents(); // XML formatted string m_text = tsw.Contents; // XML formatted string return m_text != null; }
public AppHandle(string exe) { m_ExePath = exe; m_proc = null; m_AccHelper = null; }
// look for the expected dialog to appear. If it does, make an accessibilty // helper for it. public override void Execute() { // base.Execute(ts); // can't call this yet as it executes the children Wait(); // do call this but make sure Rest is reset to zero! Rest = 0; // reset to zero so there is no delay after the dialog is found. // number is needed in diagnostics for the log if (Number == -1) Number = TestState.getOnly().IncInstructionCount; Process proc = Application.Process; /// If present, use the selected dialog model title Context con = (Context)Ancestor(typeof(Context)); if (m_select != null && m_select != "") { // make a new model context node and move dialog's children to it XmlDocument doc = m_elt.OwnerDocument; XmlElement modElt = doc.CreateElement("model"); modElt.SetAttribute("select", m_select); XmlNodeList children = m_elt.ChildNodes; int count = children.Count; while (count > 0) { // move dialog children to model XmlNode child = children.Item(0); //get the first child modElt.AppendChild(child); // automatically removed from m_elt!! count = children.Count; } m_elt.AppendChild(modElt); // set the title to look for // can only have one text node XmlNodeList pathNodes = XmlInstructionBuilder.selectNodes(this, m_select, makeName()); m_log.isNotNull(pathNodes, "dialog " + this.Id + " select='" + m_select + "' returned no model"); m_log.isTrue(pathNodes.Count > 0, "dialog " + this.Id + " select='" + m_select + "' returned no model nodes"); // This is the model node XmlNode modNode = pathNodes.Item(0); m_title = XmlFiler.getAttribute(modNode, "title"); m_name = XmlFiler.getAttribute(modNode, "name"); m_select = null; // can only do this one time in do-once or model } if (m_title != null && m_title != "") m_title = Utilities.evalExpr(m_title); if (m_name != null && m_name != "") m_name = Utilities.evalExpr(m_name); m_log.paragraph(image()); // Give the window m_Rest seconds to show up int startTick = System.Environment.TickCount; IntPtr foundHwndPtr; string name = null; while (!m_found) { // If there is a regular expression, try it. if (m_title != null && m_title.StartsWith("rexp#")) { // match the window title via the regular expression Process[] allProcs = Process.GetProcesses(); Regex rx = null; try { rx = new Regex(m_title.Substring(5)); } catch (ArgumentException e) { m_log.paragraph("on-dialog title from rexp# " + m_title.Substring(5) + " error: " + e.Message); break; } for (int p = 0; p < allProcs.Length; p++) { Process pro = allProcs[p]; AccessibilityHelper ah = new AccessibilityHelper(pro.Handle); if (rx.IsMatch(ah.Name)) { m_ah = ah; m_found = true; break; } } } else { // get the window handle for windows with the right name // unfortuneately, other windows, or partially formed windows // seem to be obtained too. foundHwndPtr = FindWindow(null, m_title); if ((int)foundHwndPtr != 0) { // is this the window? Is it completely formed? m_ah = new AccessibilityHelper(foundHwndPtr); if (m_ah == null) m_log.paragraph("Obtained window with no Accessibiilty!"); else // this window has accessibility - hope it's fully built { // is this or one of its children the window? name = m_ah.Name; //when name1 = "", m_ah is probably bad - i.e. not an object if (name == "") { } // do nothing, keep looking else if (name.Equals(m_title) || name.Equals(this.m_name)) { // this is likely it m_found = true; } else // m_ah might be the ah for the main app or dialog window { // Maybe one of its children is the window we want m_ah = m_ah.FindChild(m_title, AccessibleRole.Dialog); if (m_ah != null) { // is this the window? name = m_ah.Name; // name1 can't be null if (name == "") { } // do nothing, keep looking else if (name.Equals(m_title) || name.Equals(this.m_name)) { // this might be it m_found = true; } } } } } } if (Utilities.NumTicks(startTick, System.Environment.TickCount) > m_until) break; // time is up System.Threading.Thread.Sleep(100); } m_Rest = 0; // don't wait later when base.Execute is invoked if (m_found) m_DlgHwndStack.Push(m_ah.HWnd); else { // Didn't find the window m_ah = null; } string contextPass, contextFail; PassFailInContext(OnPass, OnFail, out contextPass, out contextFail); // out m_onPass, out m_onFail); m_log.paragraph("on-dialog: passIn="+OnPass+" failIn="+OnFail+" pass="******" fail="+contextFail); if (!m_found && contextFail == "skip") { return; // quietly exit } isTrue(m_found, "Dialog '" + m_title + @"' was not created or not accessible"); if (name == null) { m_log.paragraph("Wierd: ah exists but name was null - should NEVER happen!!"); name = ""; } if (contextPass == "assert") fail("Dialog '"+m_title+"' was not supposed to display."); base.Execute(); m_log.result(this); base.Finished = true; // finished processing this dialog context m_DlgHwndStack.Pop(); if (m_DlgHwndStack.Count > 0) { int hwnd = (int)m_DlgHwndStack.Peek(); SIL.FieldWorks.Common.Utils.Win32.SendMessage((IntPtr)hwnd, (int)SIL.FieldWorks.Common.Utils.Win32.WinMsgs.WM_SETFOCUS,0,0); m_log.paragraph("Sent Focus message to containing context object"); // m_ah.Parent.SendWindowMessage((int)SIL.FieldWorks.Common.Utils.Win32.WinMsgs.WM_SETFOCUS,0,0); } }
bool GlimpseGUI(AccessibilityHelper ah) { AccessibilityHelper ah2 = ah; if (ah.Role == AccessibleRole.MenuItem) { // for menu items, drop to popup menu role, then its children foreach (AccessibilityHelper child in ah) { ah2 = child; break; } } if (ah2.ChildCount > 0) { // check each child against the list. foreach (AccessibilityHelper child in ah2) { if (child.States != AccessibleStates.Invisible) { string Name = child.Name; if (Name == null || Name == "") Name = "#NONE"; if (!m_list.Contains(Name)) { m_extra = Name; break; } } } } else m_extra = "#noChild"; return m_extra == null; }
/// <summary> /// Examines the GUI for the value of the property specified via @prop. /// If @expect is set, the @prop value is compared to it. /// The result is true when @expect = the @prop GUI value. /// When @prop names a boolean property, and @expect is not set, then /// the boolean value is the result. /// </summary> /// <param name="ah">Context accessibility helper, taken as the starting place for gpath. May be null.</param> /// <param name="expect">The expected value of the prop attribute.</param> /// <returns>True if @expect = @prop GUI value, false otherwise, or the boolean value of @prop in the GUI.</returns> bool GlimpseGUI(AccessibilityHelper ah, string expect) { bool result = true; if (m_prop == null) m_prop = "present"; switch (m_prop) { case "absent": { if (ah == null) result = true; else result = false; break; } case "children": { if (expect == null) expect = "0"; int exectedValue = 0; if (Utilities.IsNumber(expect)) exectedValue = (int)Utilities.GetNumber(expect); else fail("children requires an integer not '" + expect + "'."); if (ah == null) { if (exectedValue == 0) result = true; else result = false; } else { // ah != null int val = ah.ChildCount; m_got = val.ToString(); result = val.Equals(exectedValue); } break; } case "handle": { if (expect == null) expect = "0"; int exectedValue = 0; if (Utilities.IsNumber(expect)) exectedValue = (int)Utilities.GetNumber(expect); else fail("handle requires a big integer not '" + expect + "'."); if (ah == null) { if (exectedValue == 0) result = true; else result = false; } else { // ah != null int val = ah.HWnd; m_got = val.ToString(); result = val.Equals(exectedValue); } break; } case "hotkey": { if (ah == null) { if (expect == null) result = true; else result = false; } else { // ah != null m_got = ah.Shortcut; if (m_got == null || m_got == "") m_got = "NONE"; result = m_got == expect; // neither can be null } break; } case "name": { if (ah == null) { if (expect == null) result = true; else result = false; } else { // ah != null m_got = ah.Name; if (m_got == null || m_got == "") m_got = "NAMELESS"; result = m_got == expect; // neither can be null } break; } case "role": { if (expect == null) expect = "none"; m_got = ah.Role.ToString(); result = m_got == expect; break; } case "value": { if (ah == null) { if (expect == null) result = true; else result = false; } else { // ah != null m_got = ah.Value; if (expect != null && expect.StartsWith("rexp#")) { Regex rx = new Regex(expect.Substring(5)); result = rx.IsMatch(m_got); m_log.paragraph("Expect reg exp " + expect.Substring(5) + " on " + m_got + " was " + result.ToString()); } else result = m_got == expect || (m_got == "" && expect == null); // either can be null } break; } case "visible": { if (expect == null) expect = "True"; if (ah == null) { if (expect == "True") result = false; else result = true; } else { // ah != null result = !(((AccessibleStates.Invisible & ah.States) == AccessibleStates.Invisible) || ((AccessibleStates.Offscreen & ah.States) == AccessibleStates.Offscreen)); m_got = result.ToString(); result = m_got.ToLower() == expect.ToLower(); } break; } case "checked": { if (expect == null) expect = "True"; if (ah == null) { if (expect == "True") result = false; else result = true; } else { // ah != null result = ((AccessibleStates.Checked & ah.States) == AccessibleStates.Checked); m_got = result.ToString(); result = m_got.ToLower() == expect.ToLower(); } break; } case "selected": { if (expect == null) expect = "True"; if (ah == null) { if (expect == "True") result = false; else result = true; } else { // ah != null result = ((AccessibleStates.Selected & ah.States) == AccessibleStates.Selected); m_got = result.ToString(); result = m_got.ToLower() == expect.ToLower(); } break; } case "present": { if (ah == null) result = false; else result = true; break; } case "unavailable": { if (expect == null) expect = "True"; if (ah == null) { if (expect == "True") result = true; else result = false; } else { // ah != null result = ((AccessibleStates.Unavailable & ah.States) == AccessibleStates.Unavailable); m_got = result.ToString(); result = m_got.ToLower() == expect.ToLower(); } break; } default: { fail("property '"+m_prop+"' is not understood"); m_got = result.ToString(); result = false; break; } } return result; }
/// <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> /// Collects ah's associated with steps in a path. /// </summary> /// <param name="ah">The ah of a non-terminal node found along a path</param> public void visitNode(AccessibilityHelper ah) { // add them so the first to be visited later is the first one added. base.Add(ah); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Exits the application /// </summary> /// <param name="fOnCurrentWindow">If <c>true</c> send Alt-F4 regardless of what window /// is active. Otherwise switch to the main window first.</param> /// ------------------------------------------------------------------------------------ public void Exit(bool fOnCurrentWindow) { // assume m_proc != null - an assert would have come up during launch in on-application m_proc.WaitForInputIdle(); if (!fOnCurrentWindow) { try { m_proc.Kill(); } catch {} } else KillWithKeys(fOnCurrentWindow); m_proc.WaitForExit(3000); m_proc = null; m_AccHelper = null; }
public AppHandle() { m_ExePath = null; m_proc = null; m_AccHelper = null; }
// look for the expected dialog to appear. If it does, make an accessibilty // helper for it. public override void Execute() { // base.Execute(ts); // can't call this yet as it executes the children WaitMsec(); // do call this but make sure Wait is reset to zero! Wait = 0; // reset to zero so there is no delay after the dialog is found. // number is needed in diagnostics for the log if (Number == -1) Number = TestState.getOnly().IncInstructionCount; /// If present, use the selected dialog model title Context con = (Context)Ancestor(typeof(Context)); if (m_select != null && m_select != "") { // make a new model context node and move dialog's children to it m_select = Utilities.evalExpr(m_select); XmlDocument doc = m_elt.OwnerDocument; XmlElement modElt = doc.CreateElement("model"); modElt.SetAttribute("select", m_select); XmlNodeList children = m_elt.ChildNodes; int count = children.Count; while (count > 0) { // move dialog children to model XmlNode child = children.Item(0); //get the first child modElt.AppendChild(child); // automatically removed from m_elt!! count = children.Count; } m_elt.AppendChild(modElt); // set the title to look for // can only have one text node XmlNodeList pathNodes = Instructionator.selectNodes(this, m_select, makeName()); m_log.isNotNull(pathNodes, makeNameTag() + " select='" + m_select + "' returned no model"); m_log.isTrue(pathNodes.Count > 0, makeNameTag() + " select='" + m_select + "' returned no model nodes"); // This is the model node XmlNode modNode = pathNodes.Item(0); if (m_title == null || m_title == "") { // no title override, so set the title from the model string titleCheck = XmlFiler.getAttribute(modNode, "title"); if (titleCheck != null) { m_title = titleCheck; m_log.paragraph("on-dialog title set from selected model " + titleCheck); } } else { m_log.paragraph("on-dialog title set from @title " + m_title); } string nameCheck = XmlFiler.getAttribute(modNode, "name"); if (nameCheck != null) { m_name = nameCheck; m_log.paragraph("on-dialog name set from selected model " + nameCheck); } m_select = null; // can only do this one time in do-once or model } // if no name, try title if (m_title != null && m_title != "" && (m_name == null || m_name == "")) m_name = m_title; m_log.isNotNull(m_title, makeNameTag() + " No @title in script or model for this dialog."); m_log.isFalse(m_title == "", makeNameTag() + " @title in script or model is blank."); m_log.isFalse(m_name == null && !m_title.StartsWith("rexp#"), makeNameTag() + " No @name step in script or model for this dialog."); m_log.isFalse(m_name == "" && !m_title.StartsWith("rexp#"), makeNameTag() + " @name step in script or model is blank."); //if (m_title != null && m_title != "") m_title = Utilities.evalExpr(m_title); //if (m_name != null && m_name != "") m_name = Utilities.evalExpr(m_name); m_title = Utilities.evalExpr(m_title); m_name = Utilities.evalExpr(m_name); m_log.paragraph(image()); if (Application != null) { try { Application.Process.WaitForInputIdle(); } catch (Win32Exception e) { m_log.paragraph(makeNameTag() + " WaitForInputIdle: " + e.Message); } } // Give the window m_Rest seconds to show up int startTick = System.Environment.TickCount; IntPtr foundHwndPtr; string name = null; Regex rx = null; if (m_title != null && m_title.StartsWith("rexp#")) { // Create a regular expression object try { rx = new Regex(m_title.Substring(5)); } catch (ArgumentException e) { m_log.fail(makeNameTag() + " title from rexp# [" + m_title.Substring(5) + "] error: " + e.Message); } } while (!m_found) { // If there is a regular expression, try it. if (rx != null) { // try the main window name then other windows it may own via the regular expression m_log.paragraph("Searching all processes"); Process[] allProcs = Process.GetProcesses(); for (int p = 0; p < allProcs.Length; p++) { Process pro = allProcs[p]; try { if (rx.IsMatch(pro.MainWindowTitle)) { m_found = true; m_ah = new AccessibilityHelper(pro.Handle); break; } } catch (Exception e) { m_log.paragraph(makeNameTag() + " main title from rexp# [" + m_title.Substring(5) + "] process error: " + e.Message); } #region Attempt to explore process threads - useful? // try the windows that belong to this process /*try { foreach (ProcessThread pt in pro.Threads) { string para = "on-dialog matching proc [" + pro.ProcessName + ":"; if (pt.Site != null) para += pt.Site.Name + "]"; else para += "]"; m_log.paragraph(para); if (pt.Site != null && rx.IsMatch(pt.Site.Name)) { m_found = true; m_ah = new AccessibilityHelper(pro.Handle); break; } } } catch (Exception e) { m_log.paragraph("on-dialog title from rexp# [" + m_title.Substring(5) + "] process error: " + e.Message); } */ #endregion } } if (!m_found) { // get the window handle for windows with the right name // unfortuneately, other windows, or partially formed windows // seem to be obtained too. m_log.paragraph("Searching the desktop for a window via FindWindow"); if (rx != null) foundHwndPtr = FindWindow(null, null); else foundHwndPtr = FindWindow(null, m_title); if ((int)foundHwndPtr != 0) { // is this the window? Is it completely formed? m_ah = new AccessibilityHelper(foundHwndPtr); if (m_ah == null) m_log.paragraph(makeNameTag() + " Obtained window with no Accessibiilty!"); else // this window has accessibility - hope it's fully built { // is this or one of its children the window? name = m_ah.Name; //when name1 = "", m_ah is probably bad - i.e. not an object if (name == "") { } // do nothing, keep looking else if (name.Equals(m_title) || name.Equals(this.m_name)) { // this is likely it m_found = true; } else // m_ah might be the ah for the main app or dialog window { // Maybe one of its children is the window we want m_log.paragraph("Searching for a child window"); m_ah = m_ah.FindChild(m_title, AccessibleRole.Dialog); if (m_ah != null) { // is this the window? name = m_ah.Name; // name1 can't be null if (name == "") { } // do nothing, keep looking else if (name.Equals(m_title) || name.Equals(this.m_name)) { // this might be it m_found = true; } } } } } } if (Utilities.NumTicks(startTick, System.Environment.TickCount) > m_until) break; // time is up System.Threading.Thread.Sleep(100); } m_Rest = 0; // don't wait later when base.Execute is invoked if (m_found) m_DlgHwndStack.Push(m_ah.HWnd); else { // Didn't find the window m_ah = null; } string contextPass, contextFail; PassFailInContext(OnPass, OnFail, out contextPass, out contextFail); // out m_onPass, out m_onFail); m_log.paragraph(makeNameTag() + " passIn=" + OnPass + " failIn=" + OnFail + " pass="******" fail=" + contextFail); if (!m_found && contextFail == "skip") { return; // quietly exit } m_log.isTrue(m_found, makeNameTag() + m_title + @"' was not created or not accessible"); if (name == null) { m_log.paragraph(makeNameTag() + " Wierd: ah exists but name was null - should NEVER happen!!"); name = ""; } if (contextPass == "assert") m_log.fail(makeNameTag() + m_title + " was not supposed to display."); base.Execute(); m_log.result(this); base.Finished = true; // finished processing this dialog context m_DlgHwndStack.Pop(); if (m_DlgHwndStack.Count > 0) { int hwnd = (int)m_DlgHwndStack.Peek(); SendMessage((IntPtr)hwnd, (int)Msg.WM_SETFOCUS,0,0); m_log.paragraph(makeNameTag() + " Sent Focus message to containing context object"); // m_ah.Parent.SendWindowMessage((int)SIL.FieldWorks.Common.Utils.Win32.WinMsgs.WM_SETFOCUS,0,0); } }
public AppHandle(string exe, Process proc, AccessibilityHelper ah) { m_ExePath = exe; m_proc = proc; m_AccHelper = ah; }
public void findInGui() { Process m_proc = Process.Start(@"C:\WINDOWS\NOTEPAD.EXE"); AccessibilityHelper m_ah; m_proc.WaitForInputIdle(); while (Process.GetProcessById(m_proc.Id).MainWindowHandle == IntPtr.Zero) Thread.Sleep(100); m_proc.WaitForInputIdle(); SIL.FieldWorks.Common.Utils. Win32.SetForegroundWindow(m_proc.MainWindowHandle); m_ah = new AccessibilityHelper(m_proc.MainWindowHandle); AccessibilityHelper ah = null; GuiPath gpath = new GuiPath("menu:Help/menu:Help Topics"); ah = gpath.FindInGui(m_ah, null); Assert.IsNotNull(ah,"'menu:Help/menu:Help Topics' Accessibility Helper not found"); Assert.AreEqual("Help Topics",ah.Name,"'menu:Help/menu:Help Topics' menu item not found"); Assert.AreEqual(AccessibleRole.MenuItem,ah.Role,"'menu:Help/menu:Help Topics' menu item role not found"); try { m_proc.WaitForInputIdle(); Win32.SetForegroundWindow(m_proc.MainWindowHandle); SendKeys.SendWait("%{F4}"); m_proc.WaitForInputIdle(); m_proc.WaitForExit(); } catch { } }
public void FindNthChild() { AccessibilityHelper ah = m_ah; // now look for the second instance int nWhich = 3; AccessibilityHelper first = m_ah.Parent.FindNthChild("Paragraph", AccessibleRole.Text, nWhich, 10); nWhich = 4; AccessibilityHelper second = m_ah.Parent.FindNthChild("Paragraph", AccessibleRole.Text, nWhich, 10); nWhich = 300; AccessibilityHelper none = m_ah.Parent.FindNthChild("Paragraph", AccessibleRole.Text, nWhich, 10); m_ah = ah; Assert.IsTrue(first != second); Assert.IsNull(none); }
private AccessibilityHelper findFromPath(AccessibilityHelper ancestor, string path) { // break the path into typed tokens of the form type:name[#] AccessibilityHelper ah = ancestor; ArrayList typedTokens = SplitPath(path); foreach (string typedToken in typedTokens) { string name, type; int duplicate; SplitTypedToken(typedToken, out name, out type, out duplicate); AccessibleRole role = TypeToRole(type); if (duplicate == 1) ah = ah.FindChild(name,role); else ah = ah.FindNthChild(name,role,duplicate,10); } return ah; }
string HoverPath(AccessibilityHelper ah, GuiPath gpath) { ah = gpath.FindInGui(ah, this); visitNode(ah); return m_message; }
private string getPathFromAh(AccessibilityHelper ancestor) { string path = null; // two ways to do this: // 1 : If ancestor is in m_Paths, match the value and return the key. bool hasIt = m_Paths.ContainsValue(ancestor); if (hasIt) { ICollection keys = m_Paths.Keys; IEnumerator key = keys.GetEnumerator(); key.MoveNext(); while (!(m_Paths[key.Current]).Equals(ancestor)) key.MoveNext(); // since it was contained in m_Paths, it must have been found. return (string)(key.Current); } // 2 : Use the Parent attribute of ancestors to build a path. // (must get rid of "client"s and other fluff) if (ancestor.HWnd == m_Root.HWnd) // found the root return root + ":" + m_Root.Name; string prefix = getPathFromAh(ancestor.Parent); string role = RoleToType(ancestor.Role); if (role.Equals("none")) path = prefix; else path = prefix + "/" + role + ":" + ancestor.Name; // if (duplicate) path += "[n]"; return path; }
// when all the instructions pass, do-once passes // otherwise it fails public override void Execute() { // Don't call the base execute method! - want control.. // base.Execute(); if (Number == -1) Number = TestState.getOnly().IncInstructionCount; m_log.mark(this); m_ExecuteTickCount = System.Environment.TickCount; PrepareChildren(); // base method to build child instructions // remove all wait times in this context, but only at the child level this.RemoveWaitTime(); foreach (Instruction ins in m_components) { ins.RemoveWaitTime(); } PassFailInContext(OnPass, OnFail, out m_onPass, out m_onFail); AccessibilityHelper m_ah = Accessibility; if (1 == m_logLevel) m_log.paragraph("Context is "" + m_ah.Role + ":" + m_ah.Name + """); if (m_waitingFor != null && m_waitingFor != "") m_waitingFor = Utilities.evalExpr(m_waitingFor); int startTick = System.Environment.TickCount; m_log.paragraph(image()); bool done = false; bool lastPass = false; // used to allow 1 last pass over instructions after time is up while (!done) { CheckForErrorDialogs(true); // see if there are any cmds not finished done = true; // start as if they're all done foreach (Instruction ins in m_components) { if (!ins.Finished) // not already finished { // Don't assert onFail until it's the last pass (time is up) ins.DeferAssert = !lastPass; ins.Execute(); if (!ins.Finished) // still not finished done = false; } } m_Result = done; AccessibilityHelper ah = null; string title = null; if (m_waitingFor != null && m_waitingFor != "") { m_Result = false; // fail if the window is not found IntPtr foundHwndPtr = FindWindow(null,m_waitingFor); if ((int)foundHwndPtr != 0) { ah = new AccessibilityHelper(foundHwndPtr); // The ah constructor gets the topWindow if our window isn't found // Don't want that // ah = new AccessibilityHelper(m_waitingFor); // get the title, the ah.Name can be different. GuiPath path = new GuiPath("titlebar:NAMELESS"); AccessibilityHelper ah1 = ah.SearchPath(path, null); if (ah1 != null) title = ah1.Value; } } if (ah != null) m_log.paragraph("do-once found window:"+ah.Name); if (title != null) m_log.paragraph("do-once found title:"+title); if (lastPass) done = true; if (title != null && title == m_waitingFor) { lastPass = true; // A window may appear a bit later m_Result = true; } // once time is up, allow finial pass over instructions allowing asserts as needed if (!lastPass) lastPass = Utilities.NumTicks(startTick, System.Environment.TickCount) > m_waitTicks; } // end of while loop Logger.getOnly().result(this); Finished = true; // tell do-once it's done if (m_onPass == "assert" && m_Result == true) fail("do-once accomplished its task(s) but was not supposed to."); if (m_onFail == "assert" && m_Result == false) fail("do-once did not accomplish all of its tasks."); }
AccessibilityHelper m_Root = null; // the root of the accessibility tree #endregion Fields #region Constructors public PathManager(AccessibilityHelper root) { m_Root = root; m_Paths.Add("app",m_Root); }
/// <summary> /// method to apply when a non-terminal node has been found /// </summary> /// <param name="ah"></param> public void visitNode(AccessibilityHelper ah) { // does this ah need to be clicked or something to get to its children? if (1 == m_logLevel) m_log.paragraph(makeNameTag() + "Click found "" + ah.Role + ":" + ah.Name + """); if ((ah.Role == AccessibleRole.MenuItem) || (m_for != null && "all" == (string)m_for)) { if (1 == m_logLevel) m_log.paragraph(makeNameTag() + "Click determining what to do with this intermediate step"); bool isFocused = (ah.States & AccessibleStates.Focused) == AccessibleStates.Focused; if (!isFocused) { if (1 == m_logLevel) m_log.paragraph(makeNameTag() + "Clicking relative to "" + ah.Role + ":" + ah.Name + "" by (" + m_dx + ", " + m_dy + ") since it does not have focus"); ah.SimulateClickRelative(m_dx, m_dy); } else { if (1 == m_logLevel) m_log.paragraph(makeNameTag() + "Click hovering on "" + ah.Role + ":" + ah.Name + "" since it has focus"); ah.MoveMouseOverMe(); // hover } } }
/// <summary> /// Gets an accessible object from a path starting from the ancestor /// provided. /// </summary> /// <param name="ancestor">Begin looking with the children of this object.</param> /// <param name="path">Text in the form type:name[#]/type:name[#]/...</param> /// <returns>The accessible object found at the end of the path</returns> public AccessibilityHelper getAhFromContextPath(AccessibilityHelper ancestor, string path) { AccessibilityHelper ah = null; // is the path a key in the m_Paths? string aPath = getPathFromAh(ancestor); string fullPath = aPath + '/' +path; if (m_Paths.ContainsKey(fullPath)) { ah = (AccessibilityHelper)m_Paths[fullPath]; } else // go find it { // find the accessible object starting from the ancestor provided ah = findFromPath(ancestor, path); if (ah != null) m_Paths.Add(fullPath,ah); } return ah; }
/// <summary> /// Tries to find the target ah repeatedly for the "Wait" period /// </summary> /// <param name="ah"></param> /// <param name="gpath"></param> private void ClickPathUntilFound(AccessibilityHelper ah, GuiPath gpath) { string badPath = ""; if (DoingOnce()) badPath = ClickPath(ah, gpath); else { // act as if it's being done once //IntPtr handle = (IntPtr)ah.HWnd; // get an updated ah based on its window handle bool done = false; while(!done && !m_finished) { //ah = new AccessibilityHelper((handle)); // refresh the context ah ah = new AccessibilityHelper(ah); // refresh the context ah if (ah == null) m_log.paragraph(makeNameTag() + "ClickPathUntilFound on " + gpath + " handled a null context"); if (ah != null) badPath = ClickPath(ah, gpath); done = Utilities.NumTicks(m_ExecuteTickCount, System.Environment.TickCount) > m_until; System.Threading.Thread.Sleep(500); // try every half second } // if not clicked, it waited a long time on a bad path if (!m_finished) m_log.fail(makeNameTag() + badPath); } }
/// <summary> /// Checks for an open error window and closes it. /// This may close the application. /// Also, set doAssert to true if this test should terminate on finding one. /// </summary> /// <param name="doAssert">false when the test should not fail as when another test caused the error window.</param> protected void CheckForErrorDialogs(bool doAssert) { // check for specific error dialogs // Try to get the ah for "An error has occurred" window // Log its info // Close the error window // Assert if directed to AccessibilityHelper ah = new AccessibilityHelper("An error has occurred"); // This constructor returns the top window if it can't find the // one with the title // Even though the ah is not null, sometimes it can't get the name string name = ""; if (ah != null && ah.Name == "An error has occurred") { // this is really bad! string color = "green"; m_log.paragraph("Window: " + name); GuiPath path = new GuiPath("button:Exit the application"); AccessibilityHelper ahExit = ah.SearchPath(path, null); if (ahExit == null) { color = "yellow"; // can continue path = new GuiPath("button:Ok"); ahExit = ah.SearchPath(path, null); } if (ahExit == null) color = "unknown"; if (color == "green") m_log.paragraph("Found a green error window!"); if (color == "yellow") m_log.paragraph("Found a yellow error window! Continuing..."); if (color == "unknown") m_log.paragraph("Found an unknown error window!"); // write the error text to the log path = new GuiPath("window:NAMELESS[2]"); AccessibilityHelper ahTextWin = ah.SearchPath(path, null); AccessibilityHelper ahText = null; if (ahTextWin != null) { path = new GuiPath("text:NAMELESS[2]"); ahText = ah.SearchPath(path, null); } if (ahText != null) m_log.paragraph(ahText.Value); else m_log.paragraph(@"Don't know where to get the message text from."); if (color == "green" || color == "yellow") ahExit.SimulateClickRelative(10,10); if (doAssert && color == "green") m_log.fail("Got an error window!"); if (color == "unknown" && Application != null) Application.SendKeys(@"{ESC}"); // exits error window but maybe not the app if (doAssert && color == "unknown") m_log.fail("Closed the unknown error window."); Thread.Sleep(20000); // if still alive, wait for things to calm down } }