/// <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); }
/// <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 = Logger.getOnly(); 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") { fail("Got an error window!"); } if (color == "unknown") { Application.SendKeys(@"{ESC}"); // exits error window but maybe not the app } if (doAssert && color == "unknown") { fail("Closed the unknown error window."); } Thread.Sleep(20000); // if still alive, wait for things to calm down } }
// 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_instructions) { ins.RemoveWaitTime(); } PassFailInContext(OnPass, OnFail, out m_onPass, out m_onFail); AccessibilityHelper m_ah = Accessibility; if (1 == m_logLevel) { m_log.paragraph(makeNameTag() + "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_instructions) { 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(makeNameTag() + "do-once found window:" + ah.Name); } if (title != null) { m_log.paragraph(makeNameTag() + "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) { m_log.fail(makeNameTag() + "do-once accomplished its task(s) but was not supposed to."); } if (m_onFail == "assert" && m_Result == false) { m_log.fail(makeNameTag() + "do-once did not accomplish all of its tasks."); } }
/// <summary> /// Determines the result of a Simian sensation. /// Problems with sensors are not generally logged /// since they are frequently called and most are not /// fatal. /// </summary> /// <param name="sensorRef">A sensor expression in a rule.</param> /// <returns>true if the sensor detected its target.</returns> public bool sensation(EmptyElement sensorRef) { if (sensorRef.getName().Equals("window")) { // is the window showing? string id = sensorRef.getValue("id"); // a VarNode string title = sensorRef.getValue("title"); MarkedNode mn = null; if (Utilities.isGoodStr(id) && Utilities.isGoodStr(title)) { // fetch the title from the model node via id + title mn = m_varNodes.get(id); // bail out if id not defined yet. if (mn == null) { return(false); } if (mn.node != null) { title = m_GuiModel.selectToString(mn.node, title, "title"); } if (!Utilities.isGoodStr(title)) { return(false); } } else if (id == null && title == null) { // get the main window title from the model title = m_Config.getDataBase() + m_GuiModel.getTitle(); } if (title == null) { return(false); // model lacks title } if (Utilities.isGoodStr(title)) { IntPtr winHand = FindWindow(null, title); if ((int)winHand != 0) { AccessibilityHelper ah = new AccessibilityHelper(winHand); // look for a titlebar GuiPath gPath = new GuiPath("1:NAMELESS"); AccessibilityHelper tah = ah.SearchPath(gPath, this); if (tah == null || !tah.Value.Equals(title)) { return(false); } m_ah = ah; return(true); } } } if (sensorRef.getName().Equals("tested")) { string id = sensorRef.getValue("id"); // which controls string control = sensorRef.getValue("control"); // which controls string count = sensorRef.getValue("count"); // indicates how many if (control != null && count == null) { return(false); } if (control == null && count != null) { return(false); } if (control == null && count == null && id == null) { return(false); } if (id != null) { MarkedNode mn = m_varNodes.get(id); if (mn != null) { if (mn.mark == null) { return(false); } return(mn.mark.Equals("tested")); } } // if id fails to return a marked node, try a control count if (control != null) { int n = 0; int k = 0; if (control.Equals("view")) { if (m_views == null) { m_views = new MarkedList(m_GuiModel, "//*[@role='view']"); } n = m_views.Count(); k = m_views.Count("tested"); } if (count.Equals("all") && n == k) { return(true); } if (count.Equals("not-all") && k < n) { return(true); } return(false); } return(false); } if (sensorRef.getName().Equals("glimpse")) { string id = sensorRef.getValue("id"); // a VarNode string appPath = sensorRef.getValue("on"); // an appPath string guiPath = sensorRef.getValue("at"); // a giuPath string property = sensorRef.getValue("prop"); // an ah property string expect = sensorRef.getValue("expect"); // value expected // Id provides a context ah that must be used to find the rest of the path! // can't just use the appPath from it. What if it's a dialog? XmlNode context = null; MarkedNode mn = null; if (Utilities.isGoodStr(id)) { mn = m_varNodes.get(id); // bail out if id not defined yet. if (mn == null) { return(false); } if (mn.node != null) { context = mn.node; } } return(glimpse(context, appPath, guiPath, property, expect)); } return(false); }