/// <summary> /// Creates an insert instruction and parses its content. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static Insert CreateInsert(XmlNode xn, Context con) { Insert insert = new Insert(); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { insert.Rest = Convert.ToInt32(rest); } string pause = XmlFiler.getAttribute(xn, "pause"); if (pause != null) { insert.Pause = Convert.ToInt32(pause); } foreach (XmlNode node in xn.ChildNodes) { switch (node.Name) { case "#text": case "#whitespace": case "#significant-whitespace": // a nameless text node insert.Text = node.Value; break; default: Logger.getOnly().fail("Insert instruction must have something to insert."); break; } } Logger.getOnly().isNotNull(insert.Text, "Insert instruction must have some content."); Logger.getOnly().isTrue(insert.Text != "", "Insert instruction must have non-empty content."); AddInstruction(xn, insert, con); return(insert); }
/// <summary> /// Creates a dialog context instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be created</param> /// <param name="con">The current context object</param> static DialogContext CreateDialogContext(XmlNode xn, Context con) { DialogContext dc = new DialogContext(); dc.Name = XmlFiler.getAttribute(xn, "name"); dc.Title = XmlFiler.getAttribute(xn, "title"); dc.Select = XmlFiler.getAttribute(xn, "select"); Logger.getOnly().isTrue(dc.Title != null || dc.Select != null, "Dialog context '" + dc.Name + "' has no Title or selected model."); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { dc.Rest = Convert.ToInt32(rest); } string until = XmlFiler.getAttribute(xn, "until"); if (until != null) { dc.Until = Convert.ToInt32(until); } dc.OnPass = XmlFiler.getAttribute(xn, "on-pass"); dc.OnFail = XmlFiler.getAttribute(xn, "on-fail"); dc.ModelNode = con.ModelNode; AddInstruction(xn, dc, con); /* foreach (XmlNode xnChild in xn.ChildNodes) * { * InterpretChild(xnChild, dc); * } */ return(dc); }
/// <summary> /// Creates an application context instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static ApplicationContext CreateApplicationContext(XmlNode xn, Context con) { ApplicationContext ac = new ApplicationContext(); ac.Run = XmlFiler.getAttribute(xn, "run"); if (ac.Run == null || ac.Run == "") { ac.Run = "ok"; } ac.Gui = XmlFiler.getAttribute(xn, "gui"); ac.Path = XmlFiler.getAttribute(xn, "path"); ac.Exe = XmlFiler.getAttribute(xn, "exe"); ac.Args = XmlFiler.getAttribute(xn, "args"); ac.Work = XmlFiler.getAttribute(xn, "work"); ac.Title = XmlFiler.getAttribute(xn, "title"); string src = XmlFiler.getAttribute(xn, "source"); if (src != null) { ac.SetSource(src); } ac.Close = XmlFiler.getAttribute(xn, "close"); ac.OnPass = XmlFiler.getAttribute(xn, "on-pass"); ac.OnFail = XmlFiler.getAttribute(xn, "on-fail"); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { ac.Rest = Convert.ToInt32(rest); } ac.Configure(); // set model root for use by children ac.ModelNode = con.ModelNode; AddInstruction(xn, ac, con); return(ac); }
/// <summary> /// Adds an instruction to the growing tree, sets the log level /// and records it to the log. /// </summary> /// <param name="xn">An element node</param> /// <param name="ins">The instruction to be added</param> /// <param name="con">The current context object</param> static private void AddInstruction(XmlNode xn, Instruction ins, Context con) { // Vars put themselves on ts, making sure there is only one ins.Element = (XmlElement)xn; if (xn.Name != "var") { CheckForId(xn, ins); } // If not a new one, make sure the model node is propagated to each child context if (ins is Context && con.ModelNode != null) { ((Context)ins).ModelNode = con.ModelNode; } ins.Parent = con; con.Add(ins); string logLevel = XmlFiler.getAttribute(xn, "log"); if (logLevel != null && "all" == logLevel) { ins.LogLevel = 1; } if (logLevel != null && "time" == logLevel) { ins.LogLevel = 2; } // add one to the instruction count, then assign it to the instruction // A context might already have a number //if (ins.Number == -1) ins.Number = TestState.getOnly().IncInstructionCount; //Logger.getOnly().mark(ins); // log the progress of interpretation }
/// <summary> /// Creates and parses a message contained in some instructions. /// </summary> /// <param name="ins"></param> /// <param name="body"></param> static void InterpretMessage(CheckBase ins, XmlNodeList body) { if (body != null) { Message message = new Message(); foreach (XmlNode node in body) { switch (node.Name) { case "#text": // a nameless text node message.AddText(node.Value); break; case "data": message.AddDataRef(XmlFiler.getAttribute(node, "of"), ins); break; case "beep": message.AddSound(CreateBeep(node)); break; case "sound": message.AddSound(CreateSound(node)); break; } } ins.Message = message; } }
public override void Execute() { base.Execute(); Context con = (Context)Ancestor(typeof(Context)); m_log.isNotNull(con, makeNameTag() + " must occur in some context"); m_Result = Condition.EvaluateList(m_conditions); if (m_Result == true) { XmlNode xThen = m_elt.SelectSingleNode("then"); if (xThen != null) { // then may have been created via do-once before this if (m_then == null) { // not created yet Context thenCon = new Context(); thenCon.ModelNode = con.ModelNode; thenCon.Parent = this; string rest = XmlFiler.getAttribute(xThen, "wait"); if (rest != null) { thenCon.Wait = Convert.ToInt32(rest); } foreach (XmlNode child in xThen.ChildNodes) { // MakeShell adds the ins to thenCon Instructionator.MakeShell(child, thenCon); } SetThen(thenCon); } m_then.Execute(); } } else { XmlNode xElse = m_elt.SelectSingleNode("else"); if (xElse != null) { // else may have been created via do-once before this if (m_else == null) { // not created yet Context elseCon = new Context(); elseCon.ModelNode = con.ModelNode; elseCon.Parent = this; string rest = XmlFiler.getAttribute(xElse, "wait"); if (rest != null) { elseCon.Wait = Convert.ToInt32(rest); } foreach (XmlNode child in xElse.ChildNodes) { // MakeShell adds the ins to elseCon Instructionator.MakeShell(child, elseCon); } SetElse(elseCon); } m_else.Execute(); } } Logger.getOnly().result(this); Finished = true; // tell do-once it's done }
/// <summary> /// Creates a registry instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static Registry CreateRegistry(XmlNode xn, Context con) { string key = XmlFiler.getAttribute(xn, "key"); string data = XmlFiler.getAttribute(xn, "data"); Logger.getOnly().isTrue(key != null && data != null, "Registry instruction must have a key and data."); Registry reg = new Registry(key, data); AddInstruction(xn, reg, con); return(reg); }
/// <summary> /// Creates a garbage instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be created</param> /// <returns>A Garbage intsruction</returns> static Garbage CreateGarbage(XmlNode xn) { Garbage gc = new Garbage(); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { gc.Rest = Convert.ToInt32(rest); } return(gc); }
/// <summary> /// Creates a beep instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be created</param> /// <returns>A Beep intsruction</returns> static Beep CreateBeep(XmlNode xn) { Beep beep = new Beep(); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { beep.Rest = Convert.ToInt32(rest); } return(beep); }
/// <summary> /// Gets the offset integer specified in the xNode. /// If delta has a value other than defaultDelta, it is returned. /// Otherwise, the value returned is parsed from the deltaName attribute of /// xNode. /// </summary> /// <param name="delta">The current value of an offset</param> /// <param name="defaultDelta">Default value of the offset</param> /// <param name="xNode">XmlNode that might have an offset attribute</param> /// <param name="deltaName">Name of the offset attribute</param> /// <returns>The offset from the Xml node, the current value if not the default, the default otherwise</returns> protected int getOffset(int delta, int defaultDelta, XmlNode xNode, string deltaName) { int del = delta; string sdy = XmlFiler.getAttribute(xNode, deltaName); if (delta == defaultDelta && sdy != null) { try { del = Convert.ToInt32(sdy); } catch (FormatException) { del = defaultDelta; } } return(del); }
/// <summary> /// Creates a click instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be created</param> /// <param name="con">The current context object</param> static Click CreateClick(XmlNode xn, Context con) { // check select and path attributes Click click = new Click(); click.Select = XmlFiler.getAttribute(xn, "select"); click.Path = XmlFiler.getAttribute(xn, "path"); Logger.getOnly().isTrue(click.Path != null || click.Select != null, "Click instruction must have a path or select."); Logger.getOnly().isTrue(click.Path != "" || click.Select != "", "Click instruction must have a non-empty path or select."); click.When = XmlFiler.getAttribute(xn, "when"); string until = XmlFiler.getAttribute(xn, "until"); if (until != null) { click.Until = Convert.ToInt32(until); } string repeat = XmlFiler.getAttribute(xn, "repeat"); if (repeat != null) { click.Repeat = Convert.ToInt32(repeat); } click.Side = XmlFiler.getAttribute(xn, "side"); click.For = XmlFiler.getAttribute(xn, "for"); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { if (rest.ToLower().Equals("no")) { click.Rest = -1; } else { click.Rest = Convert.ToInt32(rest); } } string dx = XmlFiler.getAttribute(xn, "dx"); if (dx != null) { click.Dx = Convert.ToInt32(dx); } string dy = XmlFiler.getAttribute(xn, "dy"); if (dy != null) { click.Dy = Convert.ToInt32(dy); } AddInstruction(xn, click, con); return(click); }
/// <summary> /// Creates a sound instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <returns>A Sound intsruction</returns> static Sound CreateSound(XmlNode xn) { string frequency = XmlFiler.getAttribute(xn, "frequency"); string duration = XmlFiler.getAttribute(xn, "duration"); Logger.getOnly().isTrue(frequency != null && duration != null, "Sound instruction must have a frequency and duration."); Sound sound = new Sound(Convert.ToUInt32(frequency), Convert.ToUInt32(duration)); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { sound.Rest = Convert.ToInt32(rest); } return(sound); }
/// <summary> /// Creates a startup context instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static StartUpContext CreateStartUpContext(XmlNode xn, Context con) { StartUpContext su = new StartUpContext(); su.OnPass = XmlFiler.getAttribute(xn, "on-pass"); su.OnFail = XmlFiler.getAttribute(xn, "on-fail"); su.ModelNode = con.ModelNode; AddInstruction(xn, su, con); /* foreach (XmlNode xnChild in xn.ChildNodes) * { * InterpretChild(xnChild, su); * } */ return(su); }
/// <summary> /// Creates a hover-over instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static HoverOver CreateHoverOver(XmlNode xn, Context con) { HoverOver hover = new HoverOver(); hover.Path = XmlFiler.getAttribute(xn, "path"); Logger.getOnly().isNotNull(hover.Path, "Hover-over instruction must have a path."); Logger.getOnly().isTrue(hover.Path != "", "Hover-over instruction must have a non-empty path."); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { hover.Rest = Convert.ToInt32(rest); } AddInstruction(xn, hover, con); return(hover); }
/// <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); }
/// <summary> /// Creates a time context instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static TimeContext CreateTime(XmlNode xn, Context con) { string expect = XmlFiler.getAttribute(xn, "expect"); TimeContext timeIt = new TimeContext(Convert.ToInt32(expect)); string desc = XmlFiler.getAttribute(xn, "desc"); timeIt.Decsription = desc; /* foreach (XmlNode xnChild in xn.ChildNodes) * { * InterpretChild(xnChild, timeIt); * } */ timeIt.ModelNode = con.ModelNode; AddInstruction(xn, timeIt, con); return(timeIt); }
static Model CreateModelContext(XmlNode xn, Context con) { // check select and path attributes Model model = new Model(); model.Select = XmlFiler.getAttribute(xn, "select"); Logger.getOnly().isTrue(model.Select != null, "Model instruction must have a select attribute."); Logger.getOnly().isTrue(model.Select != "", "Model instruction must have a non-empty select."); model.When = XmlFiler.getAttribute(xn, "when"); model.OnPass = XmlFiler.getAttribute(xn, "on-pass"); model.OnFail = XmlFiler.getAttribute(xn, "on-fail"); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { model.Rest = Convert.ToInt32(rest); } AddInstruction(xn, model, con); return(model); }
/// <summary> /// Creates a glimpse-extra instruction and parses its content. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static GlimpseExtra CreateGlimpseExtra(XmlNode xn, Context con) { GlimpseExtra glimpse = new GlimpseExtra(); glimpse.Path = XmlFiler.getAttribute(xn, "path"); glimpse.SelectPath = XmlFiler.getAttribute(xn, "select-path"); glimpse.Names = XmlFiler.getAttribute(xn, "names"); glimpse.Select = XmlFiler.getAttribute(xn, "select"); glimpse.OnPass = XmlFiler.getAttribute(xn, "on-pass"); glimpse.OnFail = XmlFiler.getAttribute(xn, "on-fail"); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { glimpse.Rest = Convert.ToInt32(rest); } InterpretMessage(glimpse, xn.ChildNodes); AddInstruction(xn, glimpse, con); return(glimpse); }
/// <summary> /// Creates a desktop context instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be created</param> /// <param name="con">The current context object</param> static Desktop CreateDesktopContext(XmlNode xn, Context con) { Desktop dt = new Desktop(); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { dt.Rest = Convert.ToInt32(rest); } dt.OnPass = XmlFiler.getAttribute(xn, "on-pass"); dt.OnFail = XmlFiler.getAttribute(xn, "on-fail"); dt.ModelNode = con.ModelNode; AddInstruction(xn, dt, con); /* foreach (XmlNode xnChild in xn.ChildNodes) * { * InterpretChild(xnChild, dt); * } */ return(dt); }
/// <summary> /// Creates a glimpse instruction and parses its content. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static Glimpse CreateGlimpse(XmlNode xn, Context con) { Glimpse glimpse = new Glimpse(); glimpse.Path = XmlFiler.getAttribute(xn, "path"); glimpse.Select = XmlFiler.getAttribute(xn, "select"); Logger.getOnly().isTrue(glimpse.Path != null || glimpse.Select != null, "Glimpse instruction must have a path or select."); Logger.getOnly().isTrue(glimpse.Path != "" || glimpse.Select != "", "Glimpse instruction must have a non-empty path or select."); glimpse.Prop = XmlFiler.getAttribute(xn, "prop"); glimpse.Expect = XmlFiler.getAttribute(xn, "expect"); glimpse.OnPass = XmlFiler.getAttribute(xn, "on-pass"); glimpse.OnFail = XmlFiler.getAttribute(xn, "on-fail"); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { glimpse.Rest = Convert.ToInt32(rest); } InterpretMessage(glimpse, xn.ChildNodes); AddInstruction(xn, glimpse, con); return(glimpse); }
/// <summary> /// Creates a file-comp instruction and parses its content. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static FileComp CreateFileComp(XmlNode xn, Context con) { FileComp fc = new FileComp(); fc.Of = XmlFiler.getAttribute(xn, "of"); Logger.getOnly().isNotNull(fc.Of, "File-Comp instruction must have an 'of'."); Logger.getOnly().isTrue(fc.Of != "", "File-Comp instruction must have a non-empty 'of'."); fc.To = XmlFiler.getAttribute(xn, "to"); Logger.getOnly().isNotNull(fc.To, "File-Comp instruction must have a 'to'."); Logger.getOnly().isTrue(fc.To != "", "File-Comp instruction must have a non-empty 'to'."); fc.OnPass = XmlFiler.getAttribute(xn, "on-pass"); fc.OnFail = XmlFiler.getAttribute(xn, "on-fail"); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { fc.Rest = Convert.ToInt32(rest); } InterpretMessage(fc, xn.ChildNodes); AddInstruction(xn, fc, con); return(fc); }
/// <summary> /// Creates a match-strings instruction and parses its content. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static MatchStrings CreateMatchStrings(XmlNode xn, Context con) { MatchStrings ms = new MatchStrings(); ms.Of = XmlFiler.getAttribute(xn, "of"); Logger.getOnly().isNotNull(ms.Of, "Match-strings instruction must have an 'of'."); Logger.getOnly().isTrue(ms.Of != "", "Match-strings instruction must have a non-empty 'of'."); ms.To = XmlFiler.getAttribute(xn, "to"); Logger.getOnly().isNotNull(ms.To, "Match-strings instruction must have a 'to'."); Logger.getOnly().isTrue(ms.To != "", "Match-strings instruction must have a non-empty 'to'."); ms.Expect = XmlFiler.getAttribute(xn, "expect"); ms.OnPass = XmlFiler.getAttribute(xn, "on-pass"); ms.OnFail = XmlFiler.getAttribute(xn, "on-fail"); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { ms.Rest = Convert.ToInt32(rest); } InterpretMessage(ms, xn.ChildNodes); AddInstruction(xn, ms, con); return(ms); }
/// <summary> /// Creates an if instruction and parses its content. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="ts">The TestState containing the named instruction list</param> /// <param name="con">The current context object</param> static If CreateIf(XmlNode xn, Context con) { Logger.getOnly().isNotNull(xn["condition"], "If instruction must have a condition."); If ifIns = new If(); string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { ifIns.Rest = Convert.ToInt32(rest); } AddInstruction(xn, ifIns, con); foreach (XmlNode elt in xn.ChildNodes) { switch (elt.Name) { case "condition": Condition cond = CreateCondition(elt); ifIns.AddCondition(cond); break; } } return(ifIns); }
/// <summary> /// Creates a select-text instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static SelectText CreateSelectText(XmlNode xn, Context con) { SelectText sel = new SelectText(); sel.Path = XmlFiler.getAttribute(xn, "path"); Logger.getOnly().isNotNull(sel.Path, "Select-text instruction must have a path."); Logger.getOnly().isTrue(sel.Path != "", "Select-text instruction must have a non-empty path."); sel.Loc = XmlFiler.getAttribute(xn, "loc"); string sAt = XmlFiler.getAttribute(xn, "at"); if (sAt == null) { sel.At = 0; } else { sel.At = Convert.ToInt32(sAt); } string sRun = XmlFiler.getAttribute(xn, "run"); if (sRun == null) { sel.Run = 0; } else { sel.Run = Convert.ToInt32(sRun); } string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { sel.Rest = Convert.ToInt32(rest); } AddInstruction(xn, sel, con); return(sel); }
/// <summary> /// Creates a doOnce context instruction. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> static DoOnceContext CreateDoOnceContext(XmlNode xn, Context con) { string maxWait = XmlFiler.getAttribute(xn, "until"); // Assert.IsTrue(maxWait == null || maxWait.Length == 0, "Do-Once context must have an until attribute."); Logger.getOnly().isNotNull(maxWait, "Do-Once context must have an until attribute."); Logger.getOnly().isTrue(maxWait != "", "Do-Once context must have a non-empty 'until' attribute."); DoOnceContext doOnce = new DoOnceContext(Convert.ToInt32(maxWait)); doOnce.WaitingFor = XmlFiler.getAttribute(xn, "waiting-for"); doOnce.OnPass = XmlFiler.getAttribute(xn, "on-pass"); doOnce.OnFail = XmlFiler.getAttribute(xn, "on-fail"); doOnce.ModelNode = con.ModelNode; AddInstruction(xn, doOnce, con); /* foreach (XmlNode xnChild in xn.ChildNodes) * { * InterpretChild(xnChild, doOnce); * } */ return(doOnce); }
/// <summary> /// Creates and parses a condition. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <returns>A Condition intsruction</returns> static Condition CreateCondition(XmlNode xn) { Condition cond = new Condition(); cond.Of = XmlFiler.getAttribute(xn, "of"); // can be an id, 'literal' or number Logger.getOnly().isNotNull(cond.Of, "Condition must have an 'of' attribute."); Logger.getOnly().isTrue(cond.Of != "", "Condition must have a non-null 'of' attribute."); cond.Is = XmlFiler.getAttribute(xn, "is"); // can be equal, true, false, 'literal' or number Logger.getOnly().isNotNull(cond.Is, "Condition must have an 'is' attribute."); Logger.getOnly().isTrue(cond.Is != "", "Condition must have a non-null 'is' attribute."); cond.To = XmlFiler.getAttribute(xn, "to"); // can be an id, 'literal' or number foreach (XmlNode condElt in xn.ChildNodes) { switch (condElt.Name) { case "condition": Condition condChild = CreateCondition(condElt); cond.AddCondition(condChild); break; } } return(cond); }
/// <summary> /// Creates and parses a message contained in some instructions. /// </summary> /// <param name="ins"></param> /// <param name="body"></param> protected void InterpretMessage(XmlNodeList body) { if (body != null) { Message message = new Message(); foreach (XmlNode node in body) { switch (node.Name) { case "#text": // a nameless text node message.AddText(node.Value); break; case "data": message.AddDataRef(XmlFiler.getAttribute(node, "of"), this); break; case "beep": message.AddSound(new Beep()); break; case "sound": string frequency = XmlFiler.getAttribute(node, "frequency"); string duration = XmlFiler.getAttribute(node, "duration"); m_log.isTrue(frequency != null && duration != null, makeNameTag() + "Sound instruction must have a frequency and duration."); Sound sound = null; try { sound = new Sound(Convert.ToUInt32(frequency), Convert.ToUInt32(duration)); } catch { m_log.fail(makeNameTag() + "Sound instruction must have a frequency and duration in milliseconds."); } message.AddSound(sound); break; } } Message = message; } }
/// <summary> /// Creates a variable to be referenced by other instruction attributes. /// </summary> /// <param name="xn">The XML repersentation of the instruction to be checked</param> /// <param name="con">The current context object</param> public static Var CreateVar(XmlNode xn, Context con) { Var var = new Var(); var.Id = XmlFiler.getAttribute(xn, "id"); Logger.getOnly().isNotNull(var.Id, "Var instruction must have a id."); Logger.getOnly().isTrue(var.Id != "", "Var instruction must have a non-empty id."); string s = XmlFiler.getAttribute(xn, "set"); // select should be move to var.execute so it is dynamic! string select = XmlFiler.getAttribute(xn, "select"); if (select != null && select != "") { // the variable can only have one text node or one other node assigned to it. XmlNodeList pathNodes = selectNodes(con, select, "var" + var.Id); Logger.getOnly().isNotNull(pathNodes, "var " + var.Id + " select='" + select + "' returned no result"); if (pathNodes.Count > 0) { // append first node to set string XmlNode modNode = pathNodes.Item(0); // which property of the node to get? string prop = null; string propName = XmlFiler.getAttribute(xn, "prop"); if (propName == null && modNode is XmlElement) { propName = "path"; } if (propName == null) { propName = "value"; } if (propName != null && propName == "value") { prop = XmlPath.ResolveModelPath(modNode, modNode.Value); } if (propName != null && propName == "name") { prop = modNode.Name; } if (propName != null && propName == "type") { prop = modNode.NodeType.ToString(); } if (propName != null && propName == "path") { XmlPath xp = new XmlPath(modNode); if (xp.isValid()) { prop = xp.Path; } else { prop = null; } } s += prop; } else { s += "#NoSelection#"; } } var.Set = s; string when = XmlFiler.getAttribute(xn, "when"); string add = XmlFiler.getAttribute(xn, "add"); if (add != null) { var.Add = add; } if (var.Set == null && when == null) { // if there is a select/when then don't complain if the select found nothing Logger.getOnly().isNotNull(var.Add, "Var " + var.Id + @" set, select or add must result in a string or number value unless when=""exists"" is set."); if (select != null && select != "") { var.Set = @"#not-" + when + @"#"; } } string exists = XmlFiler.getAttribute(xn, "file-exists"); if (exists != null) { var.FileExists = exists; } string rest = XmlFiler.getAttribute(xn, "wait"); if (rest != null) { var.Rest = Convert.ToInt32(rest); } AddInstruction(xn, var, con); return(var); }
// When used in a do-once instruction, this call is repeated. // Note the code that keeps m_select from being prepended to m_path more than once. public override void Execute() { base.Execute(); if (m_path != null && m_path == "") { m_path = null; } if (m_select != null && m_select == "") { m_select = null; } if (m_selectPath != null && m_selectPath == "") { m_selectPath = null; } if (m_names != null && m_names == "") { m_names = null; } // must have: // one of select or names to provide a list to check against // with names, one of path or selectPath to get the place to check in the GUI m_log.isTrue(m_select != null || m_names != null, makeNameTag() + " must have a 'names' or 'select' attribute."); if (m_names != null) { m_log.isTrue(m_path != null || m_selectPath != null, makeNameTag() + " must have a 'path' or 'selectPath' attribute with 'names'."); } Context con = (Context)Ancestor(typeof(Context)); m_log.isNotNull(con, makeNameTag() + " must occur in some context"); m_path = Utilities.evalExpr(m_path); m_selectPath = Utilities.evalExpr(m_selectPath); m_select = Utilities.evalExpr(m_select); // set the gui path from path or select if (m_select != null && !m_doneOnce) { // set m_names and possibly m_path m_log.paragraph(makeNameTag() + " creating selection targets via " + m_select); XmlNodeList pathNodes = Instructionator.selectNodes(con, m_select, makeNameTag()); m_log.isNotNull(pathNodes, makeNameTag() + " select='" + m_select + "' returned no model node"); // 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 xPathImage = pathNodes.Item(0).Value; m_log.paragraph(makeNameTag() + " selected a text node with more XPATH: " + xPathImage); pathNodes = Instructionator.selectNodes(con, xPathImage, makeNameTag() + " selecting " + xPathImage); m_log.isNotNull(pathNodes, makeNameTag() + " selecting " + xPathImage + " from select='" + m_select + "' returned no model node"); } if (pathNodes.Count >= 1) { // there are some nodes - make a list m_names = null; foreach (XmlNode xname in pathNodes) { if (m_names == null) { if (m_path == null) { XmlPath xPath = new XmlPath(xname.ParentNode); m_path = xPath.Path; } } else { m_names += "/"; } string name = XmlFiler.getAttribute(xname, "name"); if (name == null || name == "") { m_names += "#NONE"; } else { m_names += name; } } } m_doneOnce = true; // avoid adding to m_path again on subsequent do-once iterations } if (m_selectPath != null && m_selectPath != "") { XmlPath node = SelectToPath(con, m_selectPath); // process m_select m_path = node.Path + m_path; } GuiPath gpath = new GuiPath(m_path); m_log.isNotNull(gpath, makeNameTag() + " attribute path='" + m_path + "' not parsed"); if (m_names != null) { m_list = Utilities.ParsePath(m_names); } PassFailInContext(m_onPass, m_onFail, out m_onPass, out m_onFail); AccessibilityHelper ah = con.Accessibility; m_log.isNotNull(ah, makeNameTag() + " context not accessible"); //check to see if it is visible m_Result = false; try { Application.Process.WaitForInputIdle(); } catch (Win32Exception e) { m_log.paragraph(makeNameTag() + " WaitForInputIdle: " + e.Message); m_Result = false; } if (m_Result) { ah = gpath.FindInGui(ah, null); } if (ah != null) { m_Result = GlimpseGUI(ah); } Finished = true; // tell do-once it's done if ((m_onPass == "assert" && m_Result == true) || (m_onFail == "assert" && m_Result == false)) { if (m_message != null) { m_log.fail(m_message.Read()); } else { m_log.fail(makeNameTag() + " Result = '" + m_Result + "', on-pass='******', on-fail='" + m_onFail + "'"); } } Logger.getOnly().result(this); }
// 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); } }