public void Init() { TestState ts = TestState.getOnly("LT"); ts.Script = "DesktopTest.xml"; m_dsk = new Desktop(); }
public void PassFailContext(string PassIn, string FailIn, out string onPass, out string onFail) { // Set up a typical instruction tree. TestState ts = TestState.getOnly("LT"); NoOp op1 = new NoOp(); NoOp op2 = new NoOp(); NoOp op3 = new NoOp(); Desktop Desk = new Desktop(); Desk.Add(op1); op1.Parent = Desk; Desk.Add(op2); op2.Parent = Desk; Desk.Add(op3); op3.Parent = Desk; ApplicationContext ac = MakeAppContext(); ts.AddNamedInstruction("Find me", ac); ApplicationContext AppCon = new ApplicationContext(); AppCon.SetSource("Find me"); Assert.AreEqual(ac, (ApplicationContext)AppCon.TestGetOfSource(), "Context source not set right"); Desk.Add(AppCon); NoOp ins1 = new NoOp(); NoOp ins2 = new NoOp(); NoOp ins3 = new NoOp(); AppCon.Add(ins1); ins1.Parent = AppCon; AppCon.Add(ins2); ins2.Parent = AppCon; AppCon.Add(ins3); ins3.Parent = AppCon; ins2.PassFailInContext(PassIn, FailIn, out onPass, out onFail); }
public void SetSource(string name) { // It has to be the name of another on-application element already encountered. TestState ts = TestState.getOnly(); Instruction insSource = ts.Instruction(name); isTrue(insSource != null, "Source is null."); isTrue(insSource is ApplicationContext, "Source is not an on-application instruction."); // eventually or other types. m_source = insSource; }
/// <summary> /// Determines if an instruction has an id. If it does, it adds to the named instruction list. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="ins">The instruction to be checked</param> static void CheckForId(XmlNode xn, Instruction ins) { XmlAttribute xa = xn.Attributes["id"]; if (xa != null) { TestState.getOnly().AddNamedInstruction(xa.Value, ins); ins.Id = xa.Value; } }
/// <summary> /// Default implementation that simply waits for the idle state. /// This should be called from each overrided Execute method. /// </summary> public virtual void Execute() { if (m_number == -1) { m_number = TestState.getOnly().IncInstructionCount; } Wait(); // a script specified time CheckForErrorDialogs(true); m_log.mark(this); m_ExecuteTickCount = System.Environment.TickCount; }
public void CreateAppContextFromSource() { TestState ts = TestState.getOnly("LT"); ApplicationContext ac = MakeAppContext(); ts.AddNamedInstruction("Find me", ac); ApplicationContext ac2 = new ApplicationContext(); ac2.SetSource("Find me"); Assert.AreEqual(ac, (ApplicationContext)ac2.TestGetOfSource(), "Context source not set right"); }
public void ExecInstructionsOnDesktop() { TestState ts = TestState.getOnly("LT"); int count; for (count = 1; count == 10; count++) { AddInstructionToDesktop(); } m_dsk.Execute(); // what is there to test? }
/// <summary> /// Gets the name of a test script and runs it. /// There must be a corresponding XML script file in the /// location specified in the GtdConfig.xml file. /// </summary> /// <param name="script">The name of the test script (.xml not needed).</param> public void fromFile(string script) { if (!(script.ToLower()).EndsWith(@".xml")) { script += ".xml"; } TestState ts = null; if (varsDefined) // true only if AddVariable() was called. { ts = TestState.getOnly(); // Re-open the log using the script name - lose what's there. Logger.getOnly().close(Logger.Disposition.Hung); // The next call to Logger.getOnly() will create one with using the script name. } else { ts = TestState.getOnly(m_appSymbol); // Allocating ts here insures deallocation } ts.Script = script; // must come before ts.PublishVars(); ts.PublishVars(); // get the script path from the configuration file string path = ts.getScriptPath() + @"\" + script; XmlElement scriptRoot = XmlFiler.getDocumentElement(path, "accil", false); Assert.IsNotNull(scriptRoot, "Missing document element 'accil'."); Instructionator.initialize("AxilInstructions.xml"); OnDesktop dt = new OnDesktop(); Assert.IsNotNull(dt, "OnDesktop not created for script " + path); dt.Element = scriptRoot; // not quite code-behind, but OK dt.Number = ts.IncInstructionCount; //dt = new XmlInstructionBuilder().Parse(path); // now execute any variables if they've been added before executing the desktop foreach (Var v in m_vars) { v.Execute(); } System.GC.Collect(); // forces collection on NUnit process only Beep beeep = new Beep(); beeep.Execute(); // play a beep tone so we know when the test starts dt.Execute(); varsDefined = false; // the next test may not have any Logger.getOnly().close(Logger.Disposition.Pass); Thread.Sleep(1000); }
public void ParseVarTest() { TestState ts = TestState.getOnly("LT"); ts.Script = "UtilitiesTest.xml"; Var ins2 = new Var(); ts.AddNamedInstruction("one", ins2); ins2.Set = "4"; ins2.Execute(); Assert.IsTrue(GuiPath.parseIndexTesting("stuff[$hi]", "stuff[$hi]", 0, null)); Assert.IsTrue(GuiPath.parseIndexTesting("stuff[$one]", "stuff", 4, null)); Assert.IsTrue(GuiPath.parseIndexTesting("stuff3[$one;3]", "stuff3", 43, null)); Assert.IsTrue(GuiPath.parseIndexTesting("stuff[3$one]", "stuff[3$one]", 0, null)); }
/// <summary> /// Initializes the log with xml header stuff. /// </summary> private void initLog() { TestState ts = TestState.getOnly(); string date = DateTime.Now.Date.ToShortDateString(); m_sw.WriteLine(@"<?xml version=""1.0"" encoding=""UTF-8""?>"); m_sw.WriteLine(@"<?xml-stylesheet type=""text/xsl"" href=""gtdLog.xsl""?>"); m_sw.WriteLine(@"<gtdLog>"); m_sw.WriteLine(@" <set-up date=""{0}"">", date); m_sw.WriteLine(@" <application path=""{0}"" exe=""{1}""/>", ts.getAppPath(), ts.getAppExe()); m_sw.WriteLine(@" <script path=""{0}"" name=""{1}""/>", ts.getScriptPath(), ts.Script); m_sw.WriteLine(@" <model path=""{0}"" name=""{1}""/>", ts.getModelPath(), ts.getModelName()); m_sw.WriteLine(@" </set-up>"); m_init = true; }
/// <summary> /// Inserts the instructions in this include node. /// For now, a context is created to contain them. /// This will work until variables confrom to scoping rules - /// right now, all variables are global. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static Include CreateInclude(XmlNode xn, Context con) { Include includeCon = new Include(); string pathname = XmlFiler.getAttribute(xn, "from"); Logger.getOnly().isNotNull(pathname, @"include must have a 'from' path."); Logger.getOnly().isTrue(pathname != "", @"include must have a 'from' path."); includeCon.From = pathname; AddInstruction(xn, includeCon, con); pathname = TestState.getOnly().getScriptPath() + @"\" + pathname; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; // allows <insert> </insert> try { doc.Load(pathname); } catch (System.IO.FileNotFoundException ioe) { Logger.getOnly().fail(@"include '" + pathname + "' not found: " + ioe.Message); } catch (System.Xml.XmlException xme) { Logger.getOnly().fail(@"include '" + pathname + "' not loadable: " + xme.Message); } XmlNode include = doc["include"]; Logger.getOnly().isNotNull(include, "Missing document element 'include'."); XmlElement conEl = con.Element; // clone insert and add it before so there's an insert before and after // after adding elements, delete the "after" one XmlDocumentFragment df = xn.OwnerDocument.CreateDocumentFragment(); df.InnerXml = xn.OuterXml; conEl.InsertBefore(df, xn); foreach (XmlNode xnode in include.ChildNodes) { string image = xnode.OuterXml; if (image.StartsWith("<")) { XmlDocumentFragment dfrag = xn.OwnerDocument.CreateDocumentFragment(); dfrag.InnerXml = xnode.OuterXml; conEl.InsertBefore(dfrag, xn); } } conEl.RemoveChild(xn); //Logger.getOnly().paragraph(Utilities.attrText(textImage)); return(includeCon); }
static public string evalRef(string refer, out bool found) { string value = null; found = false; TestState ts = TestState.getOnly(); Instruction ins = null; string data = null; // is there a '.' ? int dot = refer.IndexOf('.'); if (-1 == dot) { // no dot, get the default data or function value value = Functions.identifyAndEvaluate(refer); found = value != null; if (!found) { ins = ts.Instruction(refer); } } else { // has a dot, so split it and get the parts. string refer2 = refer.Substring(0, dot); try { data = refer.Substring(dot + 1); } // don't take the dot catch (ArgumentOutOfRangeException) { data = null; } ins = ts.Instruction(refer2); if (data == "") { data = null; } } if (!found) { found = ins != null; if (found) { value = ins.GetDataImage(data); } else { value = refer; // not a reference } } return(value); }
public void evalFunction() { TestState ts = TestState.getOnly("LT"); ts.Script = "UtilitiesTest.xml"; SelectText ins1 = new SelectText(); ts.AddNamedInstruction("one", ins1); ins1.Path = "window:cleaner/item:dust"; // note: ins1 has no default data set (ie. $one.text = null) Var ins2 = new Var(); ts.AddNamedInstruction("_two", ins2); ins2.Set = " how's this??"; Var ins3 = new Var(); ts.AddNamedInstruction("thr-ee", ins3); ins3.Set = "And $_two; this should be ignored?"; ins2.Execute(); ins3.Execute(); string result = Utilities.evalExpr("$random()"); Assert.IsTrue(result == "0" || result == "1", "default random not 0 or 1"); result = Utilities.evalExpr("$random(,)"); Assert.IsTrue(result == "$random(,)", "random can't just have a comma for an argument"); result = Utilities.evalExpr("$random(,4)"); Assert.IsTrue(result == "$random(,4)", "random has to have a max argument"); result = Utilities.evalExpr("$random(4,)"); Assert.IsTrue(result == "$random(4,)", "random has to have a min argument when there's a comma"); result = Utilities.evalExpr("$random(45,50)"); Assert.IsTrue(result == "$random(45,50)", "min has to be less than max"); result = Utilities.evalExpr("$random(50,45)"); Assert.IsTrue(result == "45" || result == "46" || result == "47" || result == "48" || result == "49" || result == "50", "Random must be between 45 and 50"); result = Utilities.evalExpr("$random(-6,-10)"); Assert.IsTrue(result == "-6" || result == "-7" || result == "-8" || result == "-9" || result == "-10", "Random must be between -10 and -6"); result = Utilities.evalExpr("$random(3,-2)"); Assert.IsTrue(result == "-2" || result == "-1" || result == "0" || result == "1" || result == "2" || result == "3", "Random must be between -2 and 3"); }
private Logger() { // open a file TestState ts = TestState.getOnly(); string path = ts.getScriptPath() + @"\"; string script; if (ts.Script == null) { script = "Logger2" + ".xlg"; } else { script = ts.Script.Split(".".ToCharArray(), 2)[0] + ".xlg"; } m_sw = File.CreateText(path + script); m_init = false; s_isClosed = false; }
/// <summary> /// Method to add a variable to a TestState. This is useful for adding vars during /// a test routine in C# that is used in the xml script. Long term it will be beter /// to have the script interact with the teststate and get values directly. /// </summary> /// <param name="name">id of the variable</param> /// <param name="val">value for the variable</param> public void AddVariable(string name, string val) { TestState ts = null; // local if (!varsDefined) { ts = TestState.getOnly(m_appSymbol); // sets a global singleton } // a new Var creates a Logger that needs a TestState to get the script path varsDefined = true; Var var = new Var(); var.Id = name; var.Set = val; m_vars.Add(var); // // have to execute the instruction to get it added to the TestState // var.Execute(); }
/// <summary> /// Constructor that uses a parent instruction instead if the id is null. /// </summary> /// <param name="id">Instruction name or id, can be null</param> /// <param name="parent">Parent instruction of this DataRef</param> public DataRef(string id, Instruction parent) { m_ts = TestState.getOnly(); //Assert.IsNotNull(id,"Null id passed for constructing a DataRef"); //Assert.IsFalse(id == "","Empty id passed for constructing a DataRef"); Assert.IsNotNull(m_ts, "Null TestState passed for constructing a DataRef"); Assert.IsNotNull(parent, "Non-null parent instruction expected for constructing a DataRef"); // the id can be $id.data or $id or $.data or $ (parent default data) // these may occur with suffix ';' or space // replace all '$.' with '$genid.data' if (id == null || id.Equals("")) { id = "$"; } m_id = id; int dol = m_id.IndexOf('$'); if (dol >= 0) { // there are data references string genId = "Internal#Data#Ref" + sm_next_id.ToString(); string dgenId = "$" + genId; sm_next_id += 1; m_id = m_id.Replace("$.", dgenId + "."); m_id = m_id.Replace("$;", dgenId + ";"); m_id = m_id.Replace("$ ", dgenId + " "); if (m_id == "$") { m_id = dgenId; } if (m_id[m_id.Length - 1] == '$') // last char { m_id = m_id.Substring(0, m_id.Length - 1) + dgenId; } // if dgenId was substituted, add the parent to the ts list if (-1 < m_id.IndexOf(dgenId)) { m_ts.AddNamedInstruction(genId, parent); } } else { Assert.IsNotNull(id, "A DataRef has no ref prefixed with '$'. Read: " + id); } }
public void DataRefDefaulted() { TestState ts = TestState.getOnly("LT"); ts.Script = "MessageTest.xml"; NoOp nop1 = new NoOp(); nop1.Data = 123; ts.AddNamedInstruction("niceId", nop1); NoOp nop2 = new NoOp(); nop2.Data = 456; ts.AddNamedInstruction("greatId", nop2); Message message = new Message(); message.AddText("Let's count, '"); message.AddDataRef("$niceId", nop1); message.AddText("' and '"); message.AddDataRef("$greatId.data", nop2); message.AddText("' to see it work!"); string result = message.Read(); Assert.AreEqual("Let's count, '123' and '456' to see it work!", result, "Message not relayed intact!"); }
/// <summary> /// Initialize this context parameters and gui model access. /// Call after all parameters have been set and before execution of any /// script instructions. /// </summary> public void Configure() { TestState ts = null; if (m_gui != null && m_gui != "") { // use the specified Gui Config data ts = new TestState(m_gui); } else { ts = TestState.getOnly(); // the test fixture state } if (m_path == null) { m_path = ts.getAppPath(); } if (m_exeName == null) { m_exeName = ts.getAppExe(); } m_GuiModel = ts.getModelName(); m_GuiModelPath = ts.getModelPath(); m_model_root = getXmlModelRoot(); }
public void Init() { m_ts = TestState.getOnly("LT"); m_ts.Script = "TestStateTest.xml"; }
// 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); } }
// 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 void evalExpr() { TestState ts = TestState.getOnly("LT"); ts.Script = "UtilitiesTest.xml"; SelectText ins1 = new SelectText(); ts.AddNamedInstruction("one", ins1); ins1.Path = "window:cleaner/item:dust"; // note: ins1 has no default data set (ie. $one.text = null) Var ins2 = new Var(); ts.AddNamedInstruction("_two", ins2); ins2.Set = " how's this??"; Var ins3 = new Var(); ts.AddNamedInstruction("thr-ee", ins3); ins3.Set = "And $_two; this should be ignored?"; ins2.Execute(); ins3.Execute(); string result = Utilities.evalExpr("$one"); Assert.AreEqual(null, result); result = Utilities.evalExpr("$one;"); Assert.AreEqual(null, result); result = Utilities.evalExpr("$one "); Assert.AreEqual(" ", result); result = Utilities.evalExpr(" $one"); Assert.AreEqual(" ", result); result = Utilities.evalExpr("$one; "); Assert.AreEqual(" ", result); result = Utilities.evalExpr(";$one; "); Assert.AreEqual("; ", result); result = Utilities.evalExpr(";$one;;"); Assert.AreEqual(";;", result); result = Utilities.evalExpr("$one1"); Assert.AreEqual("$one1", result); result = Utilities.evalExpr("$on;e"); Assert.AreEqual("$on;e", result); result = Utilities.evalExpr("$_two"); Assert.AreEqual(" how's this??", result); result = Utilities.evalExpr("$_two;"); Assert.AreEqual(" how's this??", result); result = Utilities.evalExpr("$_two "); Assert.AreEqual(" how's this?? ", result); result = Utilities.evalExpr(" $_two"); Assert.AreEqual(" how's this??", result); result = Utilities.evalExpr("$_two; "); Assert.AreEqual(" how's this?? ", result); result = Utilities.evalExpr(";$_two; "); Assert.AreEqual("; how's this?? ", result); result = Utilities.evalExpr(";$_two;;"); Assert.AreEqual("; how's this??;", result); result = Utilities.evalExpr("$_two1"); Assert.AreEqual("$_two1", result); result = Utilities.evalExpr("$_tw;o"); Assert.AreEqual("$_tw;o", result); result = Utilities.evalExpr("$one.;"); Assert.AreEqual(null, result); result = Utilities.evalExpr("$one..;"); Assert.AreEqual("[select-text-1 does not have data for '.']", result); result = Utilities.evalExpr("$one.path"); Assert.AreEqual("window:cleaner/item:dust", result); result = Utilities.evalExpr("$one.path;"); Assert.AreEqual("window:cleaner/item:dust", result); result = Utilities.evalExpr("$one.path.;"); Assert.AreEqual("[select-text-1 does not have data for 'path.']", result); result = Utilities.evalExpr("text$one;$_two;$thr-ee"); Assert.AreEqual("text how's this??And how's this?? this should be ignored?", result); result = Utilities.evalExpr("text$one;$_two;$thr-ee"); Assert.AreEqual("text how's this??And how's this?? this should be ignored?", result); result = Utilities.evalExpr("text$one.path;$_two;$thr-ee OK"); Assert.AreEqual("textwindow:cleaner/item:dust how's this??And how's this?? this should be ignored? OK", result); result = Utilities.evalExpr("text $_two $one.path OK"); Assert.AreEqual("text how's this?? window:cleaner/item:dust OK", result); }
// 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> /// Interpret a node as some kind of Instruction. /// Make the class but don't process its child instructions if any. /// Don't execute the instruction. /// Some instructions do not return objects: /// bug - a bug annotation element /// #comment /// #significant-whitespace /// #whitespace /// The ones with '#' are generated by the XML parser. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> /// <returns>Returns an unexecuted instruction or null</returns> static public Instruction MakeShell(XmlNode xn, Context con) { // number the context if it doesn't have one yet to avoid depth-first numbering. if (con != null && con.Number == -1) { con.Number = TestState.getOnly().IncInstructionCount; } switch (xn.Name) { // cases listed in ascending alphabetical order case "beep": return(CreateBeep(xn, con)); case "click": return(CreateClick(xn, con)); case "do-once": return(CreateDoOnceContext(xn, con)); case "file-comp": return(CreateFileComp(xn, con)); case "garbage": return(CreateGarbage(xn, con)); case "glimpse": return(CreateGlimpse(xn, con)); case "glimpse-extra": return(CreateGlimpseExtra(xn, con)); case "hover-over": return(CreateHoverOver(xn, con)); case "include": return(CreateInclude(xn, con)); case "insert": return(CreateInsert(xn, con)); case "if": return(CreateIf(xn, con)); case "match-strings": return(CreateMatchStrings(xn, con)); case "model": return(CreateModelContext(xn, con)); case "monitor-time": return(CreateTime(xn, con)); case "on-application": return(CreateApplicationContext(xn, con)); case "on-desktop": return(CreateDesktopContext(xn, con)); case "on-dialog": return(CreateDialogContext(xn, con)); case "on-startup": return(CreateStartUpContext(xn, con)); case "registry": return(CreateRegistry(xn, con)); case "skip": return(new Skip()); case "sound": return(CreateSound(xn, con)); case "select-text": return(CreateSelectText(xn, con)); case "var": return(CreateVar(xn, con)); case "bug": // bug annotation element case "#comment": // ignore comments, etc.. case "#significant-whitespace": case "#whitespace": return(null); default: Logger.getOnly().fail("Unexpected instruction <" + xn.Name + "> found"); break; } return(null); }
/// <summary> /// Execute this model node context, specified by @select and /// creating and executing child instructions. /// </summary> public override void Execute() { base.Execute(); if (m_created) { Finished = true; // tell do-once it's done return; // all has been done in the base Context.Execute(). } Context con = (Context)Ancestor(typeof(Context)); isNotNull(con, makeNameTag() + " must occur in some context"); AccessibilityHelper ah = con.Accessibility; isNotNull(ah, makeNameTag() + " context is not accessible"); // If there is a @select, select the nodes if (m_select != null && m_select != "") { // each node or attribute selected creates a context m_log.paragraph(makeNameTag() + " creating selection targets via " + m_select); XmlNodeList pathNodes = XmlInstructionBuilder.selectNodes(con, m_select, makeNameTag()); isNotNull(pathNodes, makeNameTag() + " select='" + m_select + "' returned no model nodes"); // The select text may have selected a string that is itself xPath! // If so, select on that xPath if (pathNodes.Count == 1 && pathNodes.Item(0).NodeType == XmlNodeType.Text) { // this text node should be an xpath statement string xPath = pathNodes.Item(0).Value; m_log.paragraph(makeNameTag() + " selected a text node with more XPATH: " + xPath); pathNodes = XmlInstructionBuilder.selectNodes(con, xPath, makeNameTag() + " selecting " + xPath); isNotNull(pathNodes, makeNameTag() + " selecting " + xPath + " from select='" + m_select + "' returned no model nodes"); } // Create a list of paths to loop over Model lastModel = this; // use as an insert reference node foreach (XmlNode node in pathNodes) { // build the path via each model node XmlPath xPath = new XmlPath(node); // xPath may be invalid - it means it has no guiPath //if (!xPath.isValid()) fail(makeNameTag() + " XmlPath not constructable from " + node.OuterXml); if (1 == m_logLevel) { m_log.paragraph(makeNameTag() + " appPath " + xPath.xPath()); m_log.paragraph(makeNameTag() + " guiPath " + xPath.Path); } Model model = new Model(); model.m_created = true; model.m_modelNode = xPath; model.m_path = xPath.Path; model.m_select = xPath.xPath(); model.m_when = m_when; model.m_name = XmlFiler.getAttribute(node, "name"); model.m_role = XmlFiler.getAttribute(node, "role"); model.m_nodeName = node.Name; model.Number = TestState.getOnly().IncInstructionCount; model.Id += (model.Number - Number).ToString(); model.Parent = con; con.Add(lastModel, model); lastModel = model; // insert the next one after this one. m_log.mark(model); // log the progress of interpretation // if there is content, add instructions to the new model context if (m_elt.HasChildNodes) { foreach (XmlNode xnChild in m_elt.ChildNodes) { // a side-effect of MakeShell is to add the instruction to the model XmlInstructionBuilder.MakeShell(xnChild, model); } } } } Finished = true; // tell do-once it's done }
/// <summary> /// Execute method. /// If not already bound, this variable will be assigned a vaule. /// The variable may be bound when it is "built" or "interpreted". /// If bound when built, the variable may only reference preceding /// instruction settings (not results) and other built-bound vars. /// /// When there is reg, env or set data, it replaces the old data. /// When there is add data, it is added if old and add are numbers, /// or it is appended to the old data. /// When there is set and add data, set replaces the old data and /// add is added or appended. /// @env and @reg get values from the environment and the registry. /// The order of concatenation is @reg, @env, @set then @add. /// </summary> public override void Execute() { // Bind the variable to a value if not already bound if (!m_bound) { // not already bound. m_log = Logger.getOnly(); // the log set in Instruction creation may be in another TestState TestState ts = TestState.getOnly(); Instruction ins = ts.Instruction(m_id); if (ins != null) { // already one with this name m_val = ins.GetDataImage(null); m_log.paragraph("Found var " + m_id + " with value=" + m_val); // remove the old ins from ts ts.RemoveInstruction(m_id); if (m_reg != null || m_env != null || m_set != null) { m_val = null; // don't use previous value } } if (m_reg != null) { string value = null; string key; RegistryKey regkey = Utilities.parseRegKey(m_reg, out key); if (regkey != null) { RegistryValueKind rvk = regkey.GetValueKind(key); switch (rvk) { case RegistryValueKind.Binary: m_log.paragraph("Reg key is Binary"); value = Convert.ToString(regkey.GetValue(key)); break; case RegistryValueKind.DWord: m_log.paragraph("Reg key is DWord"); value = Convert.ToString(regkey.GetValue(key)); break; case RegistryValueKind.ExpandString: m_log.paragraph("Reg key is ExpandString"); value = Convert.ToString(regkey.GetValue(key)); break; case RegistryValueKind.MultiString: m_log.paragraph("Reg key is MultiString"); value = Convert.ToString(regkey.GetValue(key)); break; case RegistryValueKind.QWord: m_log.paragraph("Reg key is QWord"); value = Convert.ToString(regkey.GetValue(key)); break; case RegistryValueKind.String: value = (string)regkey.GetValue(key); break; case RegistryValueKind.Unknown: m_log.paragraph("Reg key is Unknown"); break; } regkey.Close(); } else { m_log.paragraph("Invalid Reisitry path: " + m_reg); } if (value != null) { m_val += value; } } if (m_env != null) { // try the process then the user then the machine environment variables. string value = Environment.GetEnvironmentVariable(m_env, EnvironmentVariableTarget.Process); if (value == null) { value = Environment.GetEnvironmentVariable(m_env, EnvironmentVariableTarget.User); } if (value == null) { value = Environment.GetEnvironmentVariable(m_env, EnvironmentVariableTarget.Machine); } if (value != null) { m_val += value; } } if (m_set != null) { m_val += Utilities.evalExpr(m_set); } if (m_add != null) { // add the old and new string newVal = Utilities.evalExpr(m_add); if (Utilities.IsNumber(newVal) && Utilities.IsNumber(m_val)) { try { double old = double.Parse(m_val); double add = double.Parse(newVal); double sum = old + add; m_log.paragraph("Variable(" + m_id + ") = " + old + " + " + add + " = " + sum); m_val = System.Convert.ToString(sum); } catch { fail("Variable(" + m_id + ") = " + m_val + " + " + m_add + " does not compute!"); } } else { m_log.paragraph("Text add: Variable(" + m_id + ") = " + m_val + " + " + newVal); m_val += newVal; // append as strings } } else // even if there was a previous var, but m_add was null, // then m_val is null if nothing was m_set! if (m_set == null) { m_val = null; } if (m_file_exists != null && m_val != null) { // append the file name to the reg and/or env value. if (File.Exists(m_val)) { m_val = m_file_exists; } else { m_val = "#not-exists#"; } } ts.AddNamedInstruction(m_id, this); } m_bound = true; base.Execute(); Finished = true; // tell do-once it's done }
/// <summary> /// Read instruction file. /// Interpret script nodes according to tne instruction file. /// Make the class but don't process its child instructions if any. /// Don't execute the instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> /// <returns>Returns an unexecuted instruction or null</returns> static public Instruction MakeShell(XmlNode xn, Context con) { Logger.getOnly().isNotNull(xn, "Instruction can't be created from nothing!"); if (m_actPrototypes == null) { Logger.getOnly().fail("Can not create: No instruction prototypes loaded."); return null; } Instruction FluffedInstruction = null; // number the context if it doesn't have one yet to avoid depth-first numbering. if (con != null && con.Number == -1) con.Number = TestState.getOnly().IncInstructionCount; // figure out what to do with this node switch (xn.Name) { case "#comment": // ignore comments, etc.. case "#significant-whitespace": case "#whitespace": case "#text": break; default: // Find the instruction prototype based on node name. InsPrototype prototype = findPrototype(xn.Name, m_actPrototypes); if (prototype != null) { var AtValues = new ArrayList(); ArrayList atts = prototype.Attributes; Logger.getOnly().startList("Instruction " + prototype.Name); XmlAttributeCollection atNodes = xn.Attributes; if (atNodes != null && atts != null) { foreach (XmlAttribute atx in atNodes) { // find each attribute in the prototype string atValue = null; foreach (Attribute at in atts) { if (at.Name == atx.Name) { // its this one atValue = XmlFiler.getAttribute(xn, at.Name); if (atValue != null && at.Name != "log") { // log is dealt with in AddInstruction() var atVar = new Attribute(at.Name, atValue, at.Value); AtValues.Add(atVar); Logger.getOnly().listItem(" " + atx.Name + "=" + atValue); break; } } } if (atValue == null) { // This attribute is not expected: make it a variable // Add it as a var instruction so it gets bound at the right time // Use <var id="atx.Name" set="atValue"/> var var = new Var(); var.Id = atx.Name; var.Set = XmlFiler.getAttribute(xn, atx.Name); // Add the var to the growing list of instructions AddInstruction(xn, var, con); Logger.getOnly().paragraph("Added <var id=\"" + var.Id + "\" set=\"" + var.Set + "\"/>"); } } } Logger.getOnly().endList(); // Create the instruction using prototype.Name, AtValues.Name and AtValues.Value string protoName = XmlNameToCName(prototype.Name); string protoNameQ = prefix + protoName; Assembly assem = Assembly.GetExecutingAssembly(); // All instruction classes must have empty constructors Object protoInstruction = null; try { protoInstruction = assem.CreateInstance(protoNameQ, true, BindingFlags.CreateInstance, null, null, null, null);} catch (Exception e) { Logger.getOnly().fail("Instruction " + protoName + " not created: " + e.Message); } Logger.getOnly().isNotNull(protoInstruction, "Instruction " + protoName + " is DOA"); FluffedInstruction = (Instruction)protoInstruction; foreach (Attribute at in AtValues) { // Call each setter to set the instruction properties. int number = 0; UInt32 unsigned = 0; string primative = "string"; if (at.Type == "msec" || at.Type == "int" || at.Type.Contains("[0-10]")) { try { number = Convert.ToInt32(at.Value); primative = "int"; } catch (FormatException) { } } if (at.Type == "m-sec" || at.Type == "hz") { try { unsigned = Convert.ToUInt32(at.Value, 10); primative = "UInt32"; } catch (FormatException) { } } if (primative == "string" && at.Type.Contains("|")) { string[] enumList = makeEnumList(at.Type); foreach (string value in enumList) { if (value == at.Value) { primative = value; break; } } if (primative == "string") Logger.getOnly().fail("Invalid enum {" + at.Value + "} for " + protoNameQ + "." + at.Name + "(" + at.Type + ")"); } string propName = XmlNameToCName(at.Name); string propNameQ = protoNameQ + "." + XmlNameToCName(at.Name); PropertyInfo pi = null; MethodInfo m = null; try { if (primative == "int") { pi = assem.GetType(protoNameQ).GetProperty(propName, typeof(int)); m = pi.GetSetMethod(); m.Invoke(protoInstruction, new Object[] { number }); } else if (primative == "UInt32") { pi = assem.GetType(protoNameQ).GetProperty(propName, typeof(UInt32)); m = pi.GetSetMethod(); m.Invoke(protoInstruction, new Object[] { unsigned }); } else { Type t = assem.GetType(protoNameQ); pi = t.GetProperty(propName, typeof(string)); m = pi.GetSetMethod(); m.Invoke(protoInstruction, new Object[] { at.Value }); } } catch { Logger.getOnly().fail(" Can't find setter: " + protoNameQ + "." + propName + "(" + at.Type + ") using value {" + at.Value + "}"); } if (at.Name == "id" && protoName != "Var") TestState.getOnly().AddNamedInstruction(at.Value, FluffedInstruction); } // end of process attributes // Call the finishCreation method FluffedInstruction.finishCreation(xn, con); //if (prototype.Name != "if" && // prototype.Name != "then" && prototype.Name != "else") // Add the instruction to the growing list of instructions AddInstruction(xn, FluffedInstruction, con); } else { bool unknown = true; if (m_pasPrototypes != null) { InsPrototype IgnoredPrototype = findPrototype(xn.Name, m_pasPrototypes); if (IgnoredPrototype != null) unknown = false; } if (unknown) Logger.getOnly().fail("Can't make <" + xn.Name + "> instruction"); } break; } return FluffedInstruction; }