From 1daf880c940526875ba2d66606901e3d1efa1073 Mon Sep 17 00:00:00 2001 From: Mohammed Hany <47370413+Mohammed-Hani@users.noreply.github.com> Date: Mon, 29 Apr 2019 14:18:14 +0200 Subject: [PATCH 01/38] Add arrays to the output of ExecuteDLLCommand Adding if (returnType.Namespace != "System" || returnType.IsArray) in line206 --- taskt/Core/Automation/Commands/ExecuteDLLCommand.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs b/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs index 5351775ec..648cd50c3 100644 --- a/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs +++ b/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs @@ -203,7 +203,7 @@ where rws.Field("Parameter Name") == paramName var returnType = result.GetType(); //check namespace - if (returnType.Namespace != "System") + if (returnType.Namespace != "System" || returnType.IsArray) { //conversion of type is required due to type being a complex object @@ -254,4 +254,4 @@ public override string GetDisplayValue() return base.GetDisplayValue() + " [Call Method '" + v_MethodName + "' in '" + v_ClassName + "']"; } } -} \ No newline at end of file +} From 91acfd96ce8a8569bcac5dd3b6cf0630448780b7 Mon Sep 17 00:00:00 2001 From: Mohammed Hany <47370413+Mohammed-Hani@users.noreply.github.com> Date: Tue, 30 Apr 2019 03:11:58 +0200 Subject: [PATCH 02/38] Add arrays to the input of ExecuteDLLCommand Added line from line 186 to 190; to let user use arrays as an input parameter of the DLL command in the form of "value1,value2,value3" without double quotes. --- taskt/Core/Automation/Commands/ExecuteDLLCommand.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs b/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs index 648cd50c3..0e246dc1b 100644 --- a/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs +++ b/taskt/Core/Automation/Commands/ExecuteDLLCommand.cs @@ -183,6 +183,11 @@ where rws.Field("Parameter Name") == paramName var parseResult = DateTime.Parse(requiredParameterValue); parameters.Add(parseResult); } + else if ((param.ParameterType.IsArray)) + { + var parseResult = requiredParameterValue.Split(new char[] {','},StringSplitOptions.RemoveEmptyEntries); + parameters.Add(parseResult); + } else { throw new NotImplementedException("Only system parameter types are supported!"); From f287081a5d18e7bdd2d470aae29b6759a322a966 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Mon, 6 May 2019 17:35:48 -0400 Subject: [PATCH 03/38] Fixed Bug where Exit Loop would exit all List loops instead of the current https://github.com/saucepleez/taskt/issues/117 --- taskt/Core/Automation/Commands/BeginListLoopCommand.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/taskt/Core/Automation/Commands/BeginListLoopCommand.cs b/taskt/Core/Automation/Commands/BeginListLoopCommand.cs index cd228a2b4..e54bb0471 100644 --- a/taskt/Core/Automation/Commands/BeginListLoopCommand.cs +++ b/taskt/Core/Automation/Commands/BeginListLoopCommand.cs @@ -85,7 +85,7 @@ public override void RunCommand(object sender, Core.Script.ScriptAction parentCo if (complexVariable != null) complexVariable.CurrentPosition = i; - (i + 1).ToString().StoreInUserVariable(engine, "Loop.CurrentIndex"); + engine.ReportProgress("Starting Loop Number " + (i + 1) + "/" + loopTimes + " From Line " + loopCommand.LineNumber); @@ -94,12 +94,17 @@ public override void RunCommand(object sender, Core.Script.ScriptAction parentCo if (engine.IsCancellationPending) return; + (i + 1).ToString().StoreInUserVariable(engine, "Loop.CurrentIndex"); engine.ExecuteCommand(cmd); if (engine.CurrentLoopCancelled) + { + engine.ReportProgress("Exiting Loop From Line " + loopCommand.LineNumber); + engine.CurrentLoopCancelled = false; return; + } } engine.ReportProgress("Finished Loop From Line " + loopCommand.LineNumber); From d916bedf72ce18016e4ed8666ae82dbff149c389 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Mon, 6 May 2019 17:36:15 -0400 Subject: [PATCH 04/38] Enhanced the Number Of Times Loop Command to allow starting from a different index than 0 --- .../Commands/BeginNumberOfTimesLoopCommand.cs | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/taskt/Core/Automation/Commands/BeginNumberOfTimesLoopCommand.cs b/taskt/Core/Automation/Commands/BeginNumberOfTimesLoopCommand.cs index 104dfa0e9..dc47ebd2e 100644 --- a/taskt/Core/Automation/Commands/BeginNumberOfTimesLoopCommand.cs +++ b/taskt/Core/Automation/Commands/BeginNumberOfTimesLoopCommand.cs @@ -25,12 +25,21 @@ public class BeginNumberOfTimesLoopCommand : ScriptCommand [Attributes.PropertyAttributes.Remarks("")] public string v_LoopParameter { get; set; } + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + [Attributes.PropertyAttributes.PropertyDescription("Optional - Define Start Index (Default: 0)")] + [Attributes.PropertyAttributes.InputSpecification("Enter the starting index of the loop.")] + [Attributes.PropertyAttributes.SampleUsage("**5** or **10**")] + [Attributes.PropertyAttributes.Remarks("")] + public string v_LoopStart { get; set; } + public BeginNumberOfTimesLoopCommand() { this.CommandName = "BeginNumberOfTimesLoopCommand"; this.SelectionName = "Loop Number Of Times"; this.CommandEnabled = true; this.CustomRendering = true; + this.v_LoopStart = "0"; } public override void RunCommand(object sender, Core.Script.ScriptAction parentCommand) @@ -52,12 +61,17 @@ public override void RunCommand(object sender, Core.Script.ScriptAction parentCo loopTimes = int.Parse(loopParameter); - for (int i = 0; i < loopTimes; i++) + + int startIndex = 0; + int.TryParse(v_LoopStart.ConvertToUserVariable(sender), out startIndex); + + + for (int i = startIndex; i < loopTimes; i++) { if (complexVarible != null) complexVarible.CurrentPosition = i; - (i + 1).ToString().StoreInUserVariable(engine, "Loop.CurrentIndex"); + // (i + 1).ToString().StoreInUserVariable(engine, "Loop.CurrentIndex"); engine.ReportProgress("Starting Loop Number " + (i + 1) + "/" + loopTimes + " From Line " + loopCommand.LineNumber); @@ -66,6 +80,8 @@ public override void RunCommand(object sender, Core.Script.ScriptAction parentCo if (engine.IsCancellationPending) return; + (i + 1).ToString().StoreInUserVariable(engine, "Loop.CurrentIndex"); + engine.ExecuteCommand(cmd); if (engine.CurrentLoopCancelled) @@ -77,7 +93,11 @@ public override void RunCommand(object sender, Core.Script.ScriptAction parentCo } + engine.ReportProgress("Finished Loop From Line " + loopCommand.LineNumber); + + + } } public override List Render(frmCommandEditor editor) @@ -85,13 +105,23 @@ public override List Render(frmCommandEditor editor) base.Render(editor); RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_LoopParameter", this, editor)); + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_LoopStart", this, editor)); return RenderedControls; } public override string GetDisplayValue() { - return "Loop " + v_LoopParameter + " Times"; + if (v_LoopStart != "0") + { + return "Loop From (" + v_LoopStart + "+1) to " + v_LoopParameter; + + } + else + { + return "Loop " + v_LoopParameter + " Times"; + } + } } } \ No newline at end of file From d6163ccf25fd90e530fc2809821feb36e510f067 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Mon, 6 May 2019 23:42:29 -0400 Subject: [PATCH 05/38] Added Basic NLG Support --- .../Commands/NLGCreateInstanceCommand.cs | 63 +++++++++++ .../Commands/NLGGeneratePhraseCommand.cs | 73 +++++++++++++ .../Commands/NLGSetParameterCommand.cs | 100 ++++++++++++++++++ .../Core/Automation/Commands/ScriptCommand.cs | 3 + taskt/Properties/Resources.Designer.cs | 10 ++ taskt/Properties/Resources.resx | 3 + taskt/Resources/command-nlg.png | Bin 0 -> 23295 bytes .../NLG Sample [3.0.0.0].xml | 50 +++++++++ taskt/UI/CustomControls/CustomControls.cs | 4 + taskt/packages.config | 1 + taskt/taskt.csproj | 7 ++ 11 files changed, 314 insertions(+) create mode 100644 taskt/Core/Automation/Commands/NLGCreateInstanceCommand.cs create mode 100644 taskt/Core/Automation/Commands/NLGGeneratePhraseCommand.cs create mode 100644 taskt/Core/Automation/Commands/NLGSetParameterCommand.cs create mode 100644 taskt/Resources/command-nlg.png create mode 100644 taskt/Sample Scripts/3.x Use Case Samples/NLG Sample [3.0.0.0].xml diff --git a/taskt/Core/Automation/Commands/NLGCreateInstanceCommand.cs b/taskt/Core/Automation/Commands/NLGCreateInstanceCommand.cs new file mode 100644 index 000000000..0570cbc39 --- /dev/null +++ b/taskt/Core/Automation/Commands/NLGCreateInstanceCommand.cs @@ -0,0 +1,63 @@ +using SimpleNLG; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; +using System.Xml.Serialization; +using taskt.UI.CustomControls; +using taskt.UI.Forms; + +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("NLG Commands")] + [Attributes.ClassAttributes.Description("This command pauses the script for a set amount of time specified in milliseconds.")] + [Attributes.ClassAttributes.UsesDescription("Use this command when you want to pause your script for a specific amount of time. After the specified time is finished, the script will resume execution.")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements 'Thread.Sleep' to achieve automation.")] + public class NLGCreateInstanceCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + [Attributes.PropertyAttributes.InputSpecification("Enter the unique instance name that was specified in the **Create NLG Instance** command")] + [Attributes.PropertyAttributes.SampleUsage("**nlgDefaultInstance** or **myInstance**")] + [Attributes.PropertyAttributes.Remarks("Failure to enter the correct instance name or failure to first call **Create NLG Instance** command will cause an error")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_InstanceName { get; set; } + + public NLGCreateInstanceCommand() + { + this.CommandName = "NLGCreateInstanceCommand"; + this.SelectionName = "Create NLG Instance"; + this.CommandEnabled = true; + this.CustomRendering = true; + this.v_InstanceName = "nlgDefaultInstance"; + } + + public override void RunCommand(object sender) + { + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + + Lexicon lexicon = Lexicon.getDefaultLexicon(); + NLGFactory nlgFactory = new NLGFactory(lexicon); + SPhraseSpec p = nlgFactory.createClause(); + + var vInstance = v_InstanceName.ConvertToUserVariable(sender); + + engine.AddAppInstance(vInstance, p); + + } + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + + return RenderedControls; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [Instance Name: '" + v_InstanceName + "']"; + } + } +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/NLGGeneratePhraseCommand.cs b/taskt/Core/Automation/Commands/NLGGeneratePhraseCommand.cs new file mode 100644 index 000000000..75f3ac791 --- /dev/null +++ b/taskt/Core/Automation/Commands/NLGGeneratePhraseCommand.cs @@ -0,0 +1,73 @@ +using SimpleNLG; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; +using System.Xml.Serialization; +using taskt.UI.CustomControls; +using taskt.UI.Forms; + +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("NLG Commands")] + [Attributes.ClassAttributes.Description("This command pauses the script for a set amount of time specified in milliseconds.")] + [Attributes.ClassAttributes.UsesDescription("Use this command when you want to pause your script for a specific amount of time. After the specified time is finished, the script will resume execution.")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements 'Thread.Sleep' to achieve automation.")] + public class NLGGeneratePhraseCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + [Attributes.PropertyAttributes.InputSpecification("Enter the unique instance name that was specified in the **Create NLG Instance** command")] + [Attributes.PropertyAttributes.SampleUsage("**nlgDefaultInstance** or **myInstance**")] + [Attributes.PropertyAttributes.Remarks("Failure to enter the correct instance name or failure to first call **Create NLG Instance** command will cause an error")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_InstanceName { get; set; } + + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Select Variable to Receive Output")] + public string v_applyToVariableName { get; set; } + + public NLGGeneratePhraseCommand() + { + this.CommandName = "NLGGeneratePhraseCommand"; + this.SelectionName = "Generate NLG Phrase"; + this.CommandEnabled = true; + this.CustomRendering = true; + this.v_InstanceName = "nlgDefaultInstance"; + } + + public override void RunCommand(object sender) + { + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + var vInstance = v_InstanceName.ConvertToUserVariable(engine); + var p = (SPhraseSpec)engine.GetAppInstance(vInstance); + + Lexicon lexicon = Lexicon.getDefaultLexicon(); + Realiser realiser = new Realiser(lexicon); + + String phraseOutput = realiser.realiseSentence(p); + phraseOutput.StoreInUserVariable(sender, v_applyToVariableName); + + } + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + + //apply to variable name + RenderedControls.Add(CommandControls.CreateDefaultLabelFor("v_applyToVariableName", this)); + var applyToVariableControl = CommandControls.CreateStandardComboboxFor("v_applyToVariableName", this).AddVariableNames(editor); + RenderedControls.AddRange(CommandControls.CreateUIHelpersFor("v_applyToVariableName", this, new Control[] { applyToVariableControl }, editor)); + RenderedControls.Add(applyToVariableControl); + + return RenderedControls; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [Apply to '" + v_applyToVariableName + "', Instance Name: '" + v_InstanceName + "']"; + } + } +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs b/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs new file mode 100644 index 000000000..35e3bf139 --- /dev/null +++ b/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs @@ -0,0 +1,100 @@ +using SimpleNLG; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; +using System.Xml.Serialization; +using taskt.UI.CustomControls; +using taskt.UI.Forms; + +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("NLG Commands")] + [Attributes.ClassAttributes.Description("This command allows you to define a NLG parameter")] + [Attributes.ClassAttributes.UsesDescription("Use this command when you want to define NLG parameters")] + public class NLGSetParameterCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + [Attributes.PropertyAttributes.InputSpecification("Enter the unique instance name that was specified in the **Create NLG Instance** command")] + [Attributes.PropertyAttributes.SampleUsage("**nlgDefaultInstance** or **myInstance**")] + [Attributes.PropertyAttributes.Remarks("Failure to enter the correct instance name or failure to first call **Create NLG Instance** command will cause an error")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_InstanceName { get; set; } + + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please select the NLG Parameter Type")] + [Attributes.PropertyAttributes.InputSpecification("Enter the unique instance name that was specified in the **Create NLG Instance** command")] + [Attributes.PropertyAttributes.SampleUsage("**nlgDefaultInstance** or **myInstance**")] + [Attributes.PropertyAttributes.Remarks("Failure to enter the correct instance name or failure to first call **Create NLG Instance** command will cause an error")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Subject")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Verb")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Object")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Add Complement")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_ParameterType { get; set; } + + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please define the input")] + [Attributes.PropertyAttributes.InputSpecification("Enter the value that should be associated to the parameter")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_Parameter { get; set; } + + public NLGSetParameterCommand() + { + this.CommandName = "NLGSetParameterCommand"; + this.SelectionName = "Set NLG Parameter"; + this.CommandEnabled = true; + this.CustomRendering = true; + this.v_InstanceName = "nlgDefaultInstance"; + } + + public override void RunCommand(object sender) + { + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + var vInstance = v_InstanceName.ConvertToUserVariable(engine); + var p = (SPhraseSpec)engine.GetAppInstance(vInstance); + + var userInput = v_Parameter.ConvertToUserVariable(sender); + + + switch (v_ParameterType) + { + case "Set Subject": + p.setSubject(userInput); + break; + case "Set Object": + p.setObject(userInput); + break; + case "Set Verb": + p.setVerb(userInput); + break; + case "Add Complement": + p.addComplement(userInput); + break; + default: + break; + } + + engine.AddAppInstance(vInstance, p); + + + } + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + RenderedControls.AddRange(CommandControls.CreateDefaultDropdownGroupFor("v_ParameterType", this, editor)); + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_Parameter", this, editor)); + + return RenderedControls; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [" + v_ParameterType + ": '" + v_Parameter + "', Instance Name: '" + v_InstanceName + "']"; + } + } +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/ScriptCommand.cs b/taskt/Core/Automation/Commands/ScriptCommand.cs index 334c0fba6..c612efe90 100644 --- a/taskt/Core/Automation/Commands/ScriptCommand.cs +++ b/taskt/Core/Automation/Commands/ScriptCommand.cs @@ -106,6 +106,9 @@ namespace taskt.Core.Automation.Commands [XmlInclude(typeof(EnvironmentVariableCommand))] [XmlInclude(typeof(OSVariableCommand))] [XmlInclude(typeof(ModifyVariableCommand))] + [XmlInclude(typeof(NLGCreateInstanceCommand))] + [XmlInclude(typeof(NLGSetParameterCommand))] + [XmlInclude(typeof(NLGGeneratePhraseCommand))] public abstract class ScriptCommand { [XmlAttribute] diff --git a/taskt/Properties/Resources.Designer.cs b/taskt/Properties/Resources.Designer.cs index 71c8e2344..5ad6cb28f 100644 --- a/taskt/Properties/Resources.Designer.cs +++ b/taskt/Properties/Resources.Designer.cs @@ -310,6 +310,16 @@ internal static System.Drawing.Bitmap command_input { } } + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap command_nlg { + get { + object obj = ResourceManager.GetObject("command_nlg", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// diff --git a/taskt/Properties/Resources.resx b/taskt/Properties/Resources.resx index f36b73799..9897c1a22 100644 --- a/taskt/Properties/Resources.resx +++ b/taskt/Properties/Resources.resx @@ -301,4 +301,7 @@ ..\Resources\IEDriverServer.exe;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\command-nlg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/taskt/Resources/command-nlg.png b/taskt/Resources/command-nlg.png new file mode 100644 index 0000000000000000000000000000000000000000..bb8a0de3297aae092ee83e1a8471d5ed20b45b9e GIT binary patch literal 23295 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%0A?TLxdk)n+b4V%c+wxRE**Awvv9(Y0<&U9 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 v@mY + \ No newline at end of file diff --git a/taskt/UI/CustomControls/CustomControls.cs b/taskt/UI/CustomControls/CustomControls.cs index 5a7a4877d..05c3873c7 100644 --- a/taskt/UI/CustomControls/CustomControls.cs +++ b/taskt/UI/CustomControls/CustomControls.cs @@ -516,6 +516,10 @@ public static Dictionary UIImageDictionary() uiImages.Add("StopwatchCommand", taskt.Properties.Resources.command_stopwatch); uiImages.Add("SystemActionCommand", taskt.Properties.Resources.command_script); uiImages.Add("RemoteDesktopCommand", taskt.Properties.Resources.command_system); + uiImages.Add("NLGGeneratePhraseCommand", taskt.Properties.Resources.command_nlg); + uiImages.Add("NLGSetParameterCommand", taskt.Properties.Resources.command_nlg); + uiImages.Add("NLGCreateInstanceCommand", taskt.Properties.Resources.command_nlg); + return uiImages; } public static ImageList UIImageList() diff --git a/taskt/packages.config b/taskt/packages.config index 9b7b29438..0ff3640f9 100644 --- a/taskt/packages.config +++ b/taskt/packages.config @@ -26,6 +26,7 @@ limitations under the License. + diff --git a/taskt/taskt.csproj b/taskt/taskt.csproj index 700fca32f..1d9d3dd7f 100644 --- a/taskt/taskt.csproj +++ b/taskt/taskt.csproj @@ -111,6 +111,9 @@ ..\packages\Serilog.Sinks.File.4.0.0\lib\net45\Serilog.Sinks.File.dll + + ..\packages\SharpSimpleNLG.1.2.0\lib\net45\SharpSimpleNLG.dll + ..\packages\SuperSocket.ClientEngine.Core.0.8.0.13\lib\net45\SuperSocket.ClientEngine.dll @@ -154,12 +157,15 @@ + + + @@ -621,6 +627,7 @@ + Always From 9367de764b5c622849bcd505b7f37eaf1eedf594 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Mon, 6 May 2019 23:42:54 -0400 Subject: [PATCH 06/38] Update to 3.0.0.0 --- taskt/Properties/AssemblyInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taskt/Properties/AssemblyInfo.cs b/taskt/Properties/AssemblyInfo.cs index cdaa5703b..24793a879 100644 --- a/taskt/Properties/AssemblyInfo.cs +++ b/taskt/Properties/AssemblyInfo.cs @@ -45,6 +45,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("0.0.*")] -[assembly: AssemblyFileVersion("2.9.0.0")] +[assembly: AssemblyFileVersion("3.0.0.0")] //[assembly: AssemblyVersion("0.0.0.2")] //[assembly: AssemblyFileVersion("0.0.0.2")] From 896372ee4e574e507fc3cdf116b5278cb20bd153 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Mon, 6 May 2019 23:47:32 -0400 Subject: [PATCH 07/38] Fixed NLG Set Parameter for Override Instances --- taskt/Core/Automation/Commands/NLGSetParameterCommand.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs b/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs index 35e3bf139..487cdf4ee 100644 --- a/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs +++ b/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs @@ -77,6 +77,10 @@ public override void RunCommand(object sender) break; } + //remove existing associations if override app instances is not enabled + engine.AppInstances.Remove(vInstance); + + //add to app instance to track engine.AddAppInstance(vInstance, p); From 5659a3f141b18b9ce4610b67afb031e116362995 Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Tue, 7 May 2019 18:13:51 +0200 Subject: [PATCH 08/38] Reintroduced, adapted and tested "IE Browser" commands from sharpRPA for the legacy browser lucky man. Added [crLF] to the WriteTextFileCommand. Corrected a couple of typos. --- taskt-updater/taskt-updater.csproj | 174 +- taskt.sln | 72 +- .../Commands/IEBrowserCloseCommand.cs | 59 + .../Commands/IEBrowserCreateCommand.cs | 101 ++ .../Commands/IEBrowserElementActionCommand.cs | 486 ++++++ .../Commands/IEBrowserFindBrowserCommand.cs | 109 ++ .../Core/Automation/Commands/ScriptCommand.cs | 7 +- .../SeleniumBrowserElementActionCommand.cs | 2 +- .../Commands/WriteTextFileCommand.cs | 4 +- taskt/UI/Forms/frmCommandEditor.cs | 16 +- taskt/taskt.csproj | 1427 +++++++++-------- 11 files changed, 1618 insertions(+), 839 deletions(-) create mode 100644 taskt/Core/Automation/Commands/IEBrowserCloseCommand.cs create mode 100644 taskt/Core/Automation/Commands/IEBrowserCreateCommand.cs create mode 100644 taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs create mode 100644 taskt/Core/Automation/Commands/IEBrowserFindBrowserCommand.cs diff --git a/taskt-updater/taskt-updater.csproj b/taskt-updater/taskt-updater.csproj index 9f6160ae6..673f5b440 100644 --- a/taskt-updater/taskt-updater.csproj +++ b/taskt-updater/taskt-updater.csproj @@ -1,84 +1,92 @@ - - - - - Debug - AnyCPU - {3FC72D0C-D083-44C4-96E9-13FE599F8E0E} - WinExe - taskt_updater - taskt-updater - v4.6.1 - 512 - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - Form - - - frmUpdating.cs - - - - - frmUpdating.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - + + + + + Debug + AnyCPU + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E} + WinExe + taskt_updater + taskt-updater + v4.6.1 + 512 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + x64 + bin\x64\Debug\ + + + x64 + bin\x64\Release\ + + + + + + + + + + + + + + + + + + + Form + + + frmUpdating.cs + + + + + frmUpdating.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + \ No newline at end of file diff --git a/taskt.sln b/taskt.sln index 9bdb68548..4ed5a1bd2 100644 --- a/taskt.sln +++ b/taskt.sln @@ -1,31 +1,41 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.10 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "taskt", "taskt\taskt.csproj", "{C1BE3204-94D1-4A9A-AE30-C3E302383182}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "taskt-updater", "taskt-updater\taskt-updater.csproj", "{3FC72D0C-D083-44C4-96E9-13FE599F8E0E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Release|Any CPU.Build.0 = Release|Any CPU - {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Debug|Any CPU.Build.0 = Release|Any CPU - {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {CF7B0F64-1C1B-4350-867B-E06CEB778E6F} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.10 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "taskt", "taskt\taskt.csproj", "{C1BE3204-94D1-4A9A-AE30-C3E302383182}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "taskt-updater", "taskt-updater\taskt-updater.csproj", "{3FC72D0C-D083-44C4-96E9-13FE599F8E0E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Debug|x64.ActiveCfg = Debug|x64 + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Debug|x64.Build.0 = Debug|x64 + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Release|Any CPU.Build.0 = Release|Any CPU + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Release|x64.ActiveCfg = Release|x64 + {C1BE3204-94D1-4A9A-AE30-C3E302383182}.Release|x64.Build.0 = Release|x64 + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Debug|Any CPU.ActiveCfg = Release|Any CPU + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Debug|Any CPU.Build.0 = Release|Any CPU + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Debug|x64.ActiveCfg = Debug|x64 + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Debug|x64.Build.0 = Debug|x64 + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Release|Any CPU.Build.0 = Release|Any CPU + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Release|x64.ActiveCfg = Release|x64 + {3FC72D0C-D083-44C4-96E9-13FE599F8E0E}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CF7B0F64-1C1B-4350-867B-E06CEB778E6F} + EndGlobalSection +EndGlobal diff --git a/taskt/Core/Automation/Commands/IEBrowserCloseCommand.cs b/taskt/Core/Automation/Commands/IEBrowserCloseCommand.cs new file mode 100644 index 000000000..894893fb1 --- /dev/null +++ b/taskt/Core/Automation/Commands/IEBrowserCloseCommand.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Xml.Serialization; +using taskt.UI.CustomControls; +using taskt.UI.Forms; + +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("IE Browser Commands")] + [Attributes.ClassAttributes.Description("This command allows you to close the associated IE web browser")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements the 'InternetExplorer' application object from SHDocVw.dll to achieve automation.")] + public class IEBrowserCloseCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + public string v_InstanceName { get; set; } + + public IEBrowserCloseCommand() + { + this.CommandName = "IEBrowserCloseCommand"; + this.SelectionName = "Close Browser"; + this.CommandEnabled = true; + this.v_InstanceName = "default"; + this.CustomRendering = true; + } + + public override void RunCommand(object sender) + { + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + + var vInstance = v_InstanceName.ConvertToUserVariable(engine); + + var browserObject = engine.GetAppInstance(vInstance); + + + var browserInstance = (SHDocVw.InternetExplorer)browserObject; + browserInstance.Quit(); + + engine.RemoveAppInstance(vInstance); + } + + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + + return RenderedControls; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [Instance Name: '" + v_InstanceName + "']"; + } + } + +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/IEBrowserCreateCommand.cs b/taskt/Core/Automation/Commands/IEBrowserCreateCommand.cs new file mode 100644 index 000000000..90f8aa607 --- /dev/null +++ b/taskt/Core/Automation/Commands/IEBrowserCreateCommand.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Xml.Serialization; +using taskt.UI.CustomControls; +using taskt.UI.Forms; + +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("IE Browser Commands")] + [Attributes.ClassAttributes.Description("This command allows you to create a new IE web browser session.")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements the 'InternetExplorer' application object from SHDocVw.dll to achieve automation.")] + public class IEBrowserCreateCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + public string v_InstanceName { get; set; } + + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Instance Tracking (after task ends)")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Forget Instance")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Keep Instance Alive")] + [Attributes.PropertyAttributes.InputSpecification("Specify if taskt should remember this instance name after the script has finished executing.")] + [Attributes.PropertyAttributes.SampleUsage("Select **Forget Instance** to forget the instance or **Keep Instance Alive** to allow subsequent tasks to call the instance by name.")] + [Attributes.PropertyAttributes.Remarks("Calling the **Close Browser** command or ending the browser session will end the instance. This command only works during the lifetime of the application. If the application is closed, the references will be forgetten automatically.")] + public string v_InstanceTracking { get; set; } + + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the URL to navigate to")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_URL { get; set; } + + public IEBrowserCreateCommand() + { + this.CommandName = "IEBrowserCreateCommand"; + this.SelectionName = "Create Browser"; + this.v_InstanceName = "default"; + this.CommandEnabled = true; + this.CustomRendering = true; + } + + public override void RunCommand(object sender) + { + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + + var instanceName = v_InstanceName.ConvertToUserVariable(sender); + + SHDocVw.InternetExplorer newBrowserSession = new SHDocVw.InternetExplorer(); + try + { + newBrowserSession.Navigate(v_URL.ConvertToUserVariable(sender)); + WaitForReadyState(newBrowserSession); + newBrowserSession.Visible = true; + } + catch (Exception ex) { } + + //add app instance + engine.AddAppInstance(instanceName, newBrowserSession); + + //handle app instance tracking + if (v_InstanceTracking == "Keep Instance Alive") + { + GlobalAppInstances.AddInstance(instanceName, newBrowserSession); + } + + } + + public static void WaitForReadyState(SHDocVw.InternetExplorer ieInstance) + { + try + { + DateTime waitExpires = DateTime.Now.AddSeconds(15); + + do + { + System.Threading.Thread.Sleep(500); + } + + while ((ieInstance.ReadyState != SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE) && (waitExpires > DateTime.Now)); + } + catch (Exception ex) { } + } + + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_URL", this, editor)); + + return RenderedControls; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [Instance Name: '" + v_InstanceName + "']"; + } + } + +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs new file mode 100644 index 000000000..4e9d035a5 --- /dev/null +++ b/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs @@ -0,0 +1,486 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using System.Xml.Serialization; +using Newtonsoft.Json; +using OpenQA.Selenium; +using taskt.UI.CustomControls; +using taskt.UI.Forms; +using SHDocVw; +using System.Data; +using MSHTML; +using taskt.Core.Automation.User32; + +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("IE Browser Commands")] + [Attributes.ClassAttributes.Description("This command allows you to manipulate (get or set) elements within the HTML document of the associated IE web browser. Features an assisting element capture form")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements the 'InternetExplorer' application object from SHDocVw.dll and MSHTML.dll to achieve automation.")] + public class IEBrowserElementActionCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + public string v_InstanceName { get; set; } + [XmlElement] + [Attributes.PropertyAttributes.PropertyDescription("Please enter or capture element search parameters")] + public System.Data.DataTable v_WebSearchParameter { get; set; } + [XmlElement] + [Attributes.PropertyAttributes.PropertyDescription("IE Element Action")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Invoke Click")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Left Click")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Middle Click")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Right Click")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Get Text")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Text")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Get Attribute")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Attribute")] + [Attributes.PropertyAttributes.InputSpecification("Select the appropriate corresponding action to take once the element has been located")] + [Attributes.PropertyAttributes.SampleUsage("Select from **Invoke Click**, **Set Text**, **Get Text**, **Get Attribute**")] + [Attributes.PropertyAttributes.Remarks("Selecting this field changes the parameters that will be required in the next step")] + public string v_WebAction { get; set; } + [XmlElement] + [Attributes.PropertyAttributes.PropertyDescription("Action Parameters")] + public System.Data.DataTable v_WebActionParameterTable { get; set; } + + [XmlIgnore] + [NonSerialized] + private DataGridView ElementsGridViewHelper; + + [XmlIgnore] + [NonSerialized] + private ComboBox ElementActionDropdown; + + [XmlIgnore] + [NonSerialized] + private List SearchParameterControls; + + [XmlIgnore] + [NonSerialized] + private DataGridView SearchGridViewHelper; + + [XmlIgnore] + [NonSerialized] + private List ElementParameterControls; + + [XmlIgnore] + [NonSerialized] + private static IHTMLElementCollection lastElementCollectionFound; + + [XmlIgnore] + [NonSerialized] + private static HTMLDocument lastDocFound; + + public IEBrowserElementActionCommand() + { + this.CommandName = "IEBrowserElementActionCommand"; + this.SelectionName = "Element Action"; + this.CommandEnabled = true; + this.v_InstanceName = "default"; + this.CustomRendering = true; + + this.v_WebSearchParameter = new System.Data.DataTable(); + this.v_WebSearchParameter.TableName = DateTime.Now.ToString("WebSearchParamTable" + DateTime.Now.ToString("MMddyy.hhmmss")); + this.v_WebSearchParameter.Columns.Add("Enabled", typeof(Boolean)); + this.v_WebSearchParameter.Columns.Add("Property Name"); + this.v_WebSearchParameter.Columns.Add("Property Value"); + + this.v_WebActionParameterTable = new System.Data.DataTable(); + this.v_WebActionParameterTable.TableName = DateTime.Now.ToString("WebActionParamTable" + DateTime.Now.ToString("MMddyy.hhmmss")); + this.v_WebActionParameterTable.Columns.Add("Parameter Name"); + this.v_WebActionParameterTable.Columns.Add("Parameter Value"); + + SearchGridViewHelper = new DataGridView(); + SearchGridViewHelper.AllowUserToAddRows = true; + SearchGridViewHelper.AllowUserToDeleteRows = true; + SearchGridViewHelper.Size = new Size(400, 250); + SearchGridViewHelper.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + SearchGridViewHelper.DataBindings.Add("DataSource", this, "v_WebSearchParameter", false, DataSourceUpdateMode.OnPropertyChanged); + + ElementsGridViewHelper = new DataGridView(); + ElementsGridViewHelper.AllowUserToAddRows = true; + ElementsGridViewHelper.AllowUserToDeleteRows = true; + ElementsGridViewHelper.Size = new Size(400, 250); + ElementsGridViewHelper.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + ElementsGridViewHelper.DataBindings.Add("DataSource", this, "v_WebActionParameterTable", false, DataSourceUpdateMode.OnPropertyChanged); + } + + private Boolean InspectFrame(IHTMLElementCollection elementCollection, EnumerableRowCollection elementSearchProperties, object sender, SHDocVw.InternetExplorer browserInstance) + { + bool qualifyingElementFound = false; + foreach (IHTMLElement element in elementCollection) // browserInstance.Document.All) + { + qualifyingElementFound = FindQualifyingElement(elementSearchProperties, element); + if (qualifyingElementFound) + { + RunCommandActions(element, sender, browserInstance); + lastElementCollectionFound = elementCollection; + return (true); + //break; + } + if (element.outerHTML != null && element.outerHTML.ToLower().Trim().StartsWith("(v_WebSearchParameter); + + DataColumn matchFoundColumn = new DataColumn(); + matchFoundColumn.ColumnName = "Match Found"; + matchFoundColumn.DefaultValue = false; + searchTable.Columns.Add(matchFoundColumn); + + var elementSearchProperties = from rws in searchTable.AsEnumerable() + where rws.Field("Enabled").ToString() == "True" + select rws; + + bool qualifyingElementFound = false; + + HTMLDocument doc = browserInstance.Document; + + if (doc == lastDocFound) + { + qualifyingElementFound = InspectFrame(lastElementCollectionFound, elementSearchProperties, sender, browserInstance); + } + if (!qualifyingElementFound) + { + qualifyingElementFound = InspectFrame(doc.all, elementSearchProperties, sender, browserInstance); + } + if (qualifyingElementFound) + { + lastDocFound = doc; + } + + if (!qualifyingElementFound) + { + throw new Exception("Could not find the element!"); + } + } + + private bool FindQualifyingElement(EnumerableRowCollection elementSearchProperties, IHTMLElement element) + { + foreach (DataRow seachCriteria in elementSearchProperties) + { + string searchPropertyName = seachCriteria.Field("Property Name"); + string searchPropertyValue = seachCriteria.Field("Property Value"); + string searchPropertyFound = seachCriteria.Field("Match Found"); + + string innerHTML = element.innerHTML; + string outerHTML = element.outerHTML; + + searchPropertyFound = "False"; + + //if (element.GetType().GetProperty(searchPropertyName) == null) + if ((outerHTML == null) || (element.getAttribute(searchPropertyName) == null) || (System.Convert.IsDBNull(element.getAttribute(searchPropertyName)))) + { + return false; + } + + int searchValue; + if (int.TryParse(searchPropertyValue, out searchValue)) + { + //int elementValue = (int)element.GetType().GetProperty(searchPropertyName).GetValue(element, null); + int elementValue = (int)element.getAttribute(searchPropertyName); + if (elementValue == searchValue) + { + seachCriteria.SetField("Match Found", "True"); + } + else + { + seachCriteria.SetField("Match Found", "False"); + } + } + else + { + //string elementValue = (string)element.GetType().GetProperty(searchPropertyName).GetValue(element, null); + string elementValue = (string)element.getAttribute(searchPropertyName); + if ((elementValue != null) && (elementValue == searchPropertyValue)) + { + seachCriteria.SetField("Match Found", "True"); + } + else + { + seachCriteria.SetField("Match Found", "False"); + } + } + } + + foreach (var seachCriteria in elementSearchProperties) + { + Console.WriteLine(seachCriteria.Field("Property Value")); + } + + return elementSearchProperties.Where(seachCriteria => seachCriteria.Field("Match Found") == "True").Count() == elementSearchProperties.Count(); + } + + private void RunCommandActions(IHTMLElement element, object sender, InternetExplorer browserInstance) + { + if (v_WebAction == "Invoke Click") + { + element.click(); + IEBrowserCreateCommand.WaitForReadyState(browserInstance); + } + else if ((v_WebAction == "Left Click") || (v_WebAction == "Middle Click") || (v_WebAction == "Right Click")) + { + int elementXposition = FindElementXPosition(element); + int elementYposition = FindElementYPosition(element); + + //inputs need to be validated + + int userXAdjust = Convert.ToInt32((from rw in v_WebActionParameterTable.AsEnumerable() + where rw.Field("Parameter Name") == "X Adjustment" + select rw.Field("Parameter Value")).FirstOrDefault()); + + int userYAdjust = Convert.ToInt32((from rw in v_WebActionParameterTable.AsEnumerable() + where rw.Field("Parameter Name") == "Y Adjustment" + select rw.Field("Parameter Value")).FirstOrDefault()); + + var ieClientLocation = User32Functions.GetWindowPosition(new IntPtr(browserInstance.HWND)); + + SendMouseMoveCommand newMouseMove = new SendMouseMoveCommand(); + + newMouseMove.v_XMousePosition = ((elementXposition + ieClientLocation.left + 10) + userXAdjust).ToString(); // + 10 gives extra padding + newMouseMove.v_YMousePosition = ((elementYposition + ieClientLocation.top + 90 + System.Windows.Forms.SystemInformation.CaptionHeight) + userYAdjust).ToString(); // +90 accounts for title bar height + newMouseMove.v_MouseClick = v_WebAction; + newMouseMove.RunCommand(sender); + } + else if (v_WebAction == "Set Attribute") + { + string attributeName = (from rw in v_WebActionParameterTable.AsEnumerable() + where rw.Field("Parameter Name") == "Attribute Name" + select rw.Field("Parameter Value")).FirstOrDefault(); + + string valueToSet = (from rw in v_WebActionParameterTable.AsEnumerable() + where rw.Field("Parameter Name") == "Value To Set" + select rw.Field("Parameter Value")).FirstOrDefault(); + + valueToSet = valueToSet.ConvertToUserVariable(sender); + + element.setAttribute(attributeName, valueToSet); + } + else if (v_WebAction == "Set Text") + { + string attributeName = "value"; + + string textToSet = (from rw in v_WebActionParameterTable.AsEnumerable() + where rw.Field("Parameter Name") == "Text To Set" + select rw.Field("Parameter Value")).FirstOrDefault(); + + textToSet = textToSet.ConvertToUserVariable(sender); + + element.setAttribute(attributeName, textToSet); + } + else if (v_WebAction == "Get Attribute") + { + string attributeName = (from rw in v_WebActionParameterTable.AsEnumerable() + where rw.Field("Parameter Name") == "Attribute Name" + select rw.Field("Parameter Value")).FirstOrDefault(); + + string variableName = (from rw in v_WebActionParameterTable.AsEnumerable() + where rw.Field("Parameter Name") == "Variable Name" + select rw.Field("Parameter Value")).FirstOrDefault(); + + string convertedAttribute = Convert.ToString(element.getAttribute(attributeName)); + + convertedAttribute.StoreInUserVariable(sender, variableName); + } + } + + private int FindElementXPosition(MSHTML.IHTMLElement obj) + { + int curleft = 0; + if (obj.offsetParent != null) + { + while (obj.offsetParent != null) + { + curleft += obj.offsetLeft; + obj = obj.offsetParent; + } + } + + return curleft; + } + + public int FindElementYPosition(MSHTML.IHTMLElement obj) + { + int curtop = 0; + if (obj.offsetParent != null) + { + while (obj.offsetParent != null) + { + curtop += obj.offsetTop; + obj = obj.offsetParent; + } + } + + return curtop; + } + + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + + SearchParameterControls = new List(); + SearchParameterControls.Add(CommandControls.CreateDefaultLabelFor("v_WebSearchParameter", this)); + SearchParameterControls.AddRange(CommandControls.CreateUIHelpersFor("v_WebSearchParameter", this, new Control[] { SearchGridViewHelper }, editor)); + + SearchParameterControls.Add(SearchGridViewHelper); + RenderedControls.AddRange(SearchParameterControls); + + ElementActionDropdown = (ComboBox)CommandControls.CreateDropdownFor("v_WebAction", this); + RenderedControls.Add(CommandControls.CreateDefaultLabelFor("v_WebAction", this)); + RenderedControls.AddRange(CommandControls.CreateUIHelpersFor("v_WebAction", this, new Control[] { ElementActionDropdown }, editor)); + ElementActionDropdown.SelectionChangeCommitted += ElementActionDropdown_SelectionChangeCommitted; + RenderedControls.Add(ElementActionDropdown); + + ElementParameterControls = new List(); + ElementParameterControls.Add(CommandControls.CreateDefaultLabelFor("v_WebActionParameterTable", this)); + ElementParameterControls.AddRange(CommandControls.CreateUIHelpersFor("v_WebActionParameterTable", this, new Control[] { ElementsGridViewHelper }, editor)); + ElementParameterControls.Add(ElementsGridViewHelper); + RenderedControls.AddRange(ElementParameterControls); + + return RenderedControls; + } + + private void ElementActionDropdown_SelectionChangeCommitted(object sender, EventArgs e) + { + + Core.Automation.Commands.IEBrowserElementActionCommand cmd = (Core.Automation.Commands.IEBrowserElementActionCommand)this; + DataTable actionParameters = cmd.v_WebActionParameterTable; + DataGridViewComboBoxCell comparisonComboBox; + + if (sender != null) + { + actionParameters.Rows.Clear(); + } + + + switch (ElementActionDropdown.SelectedItem) + { + case "Invoke Click": + case "Clear Element": + + foreach (var ctrl in ElementParameterControls) + { + ctrl.Hide(); + } + + break; + + case "Set Text": + foreach (var ctrl in ElementParameterControls) + { + ctrl.Show(); + } + if (sender != null) + { + actionParameters.Rows.Add("Text To Set"); + //actionParameters.Rows.Add("Clear Element Before Setting Text"); + } + + //comparisonComboBox = new DataGridViewComboBoxCell(); + //comparisonComboBox.Items.Add("Yes"); + //comparisonComboBox.Items.Add("No"); + + //assign cell as a combobox + //if (sender != null) + //{ + // ElementsGridViewHelper.Rows[1].Cells[1].Value = "No"; + //} + //ElementsGridViewHelper.Rows[1].Cells[1] = comparisonComboBox; + + + break; + + case "Get Text": + case "Get Matching Elements": + foreach (var ctrl in ElementParameterControls) + { + ctrl.Show(); + } + if (sender != null) + { + actionParameters.Rows.Add("Variable Name"); + } + break; + + case "Get Attribute": + foreach (var ctrl in ElementParameterControls) + { + ctrl.Show(); + } + if (sender != null) + { + actionParameters.Rows.Add("Attribute Name"); + actionParameters.Rows.Add("Variable Name"); + } + break; + + case "Set Attribute": + foreach (var ctrl in ElementParameterControls) + { + ctrl.Show(); + } + if (sender != null) + { + actionParameters.Rows.Add("Attribute Name"); + actionParameters.Rows.Add("Value To Set"); + } + + break; + + default: + break; + } + + ElementsGridViewHelper.DataSource = v_WebActionParameterTable; + } + + public override string GetDisplayValue() + { + string parameters = string.Empty; + //foreach (DataRow oRow in v_WebActionParameterTable.Rows) + foreach (DataRow oRow in v_WebSearchParameter.Rows) + { + parameters += ", " + oRow["Property Name"] + "=" + oRow["Property Value"]; + } + if (parameters.Length > 0) parameters = parameters.Substring(1); + return base.GetDisplayValue() + " [ Action: '" + v_WebAction + " " + parameters + "', Instance Name: '" + v_InstanceName + "']"; + } + + } + +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/IEBrowserFindBrowserCommand.cs b/taskt/Core/Automation/Commands/IEBrowserFindBrowserCommand.cs new file mode 100644 index 000000000..e0cae97be --- /dev/null +++ b/taskt/Core/Automation/Commands/IEBrowserFindBrowserCommand.cs @@ -0,0 +1,109 @@ +using SHDocVw; +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Xml.Serialization; +using taskt.UI.CustomControls; +using taskt.UI.Forms; + +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("IE Browser Commands")] + [Attributes.ClassAttributes.Description("This command allows you to find and attach to an existing IE web browser session.")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements the 'InternetExplorer' application object from SHDocVw.dll to achieve automation.")] + public class IEBrowserFindBrowserCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + public string v_InstanceName { get; set; } + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Select or Enter the Browser Name")] + public string v_IEBrowserName { get; set; } + + [XmlIgnore] + [NonSerialized] + private ComboBox IEBrowerNameDropdown; + + public IEBrowserFindBrowserCommand() + { + this.CommandName = "IEBrowserFindBrowserCommand"; + this.SelectionName = "Find Browser"; + this.v_InstanceName = "default"; + this.CommandEnabled = true; + this.CustomRendering = true; + } + + public override void RunCommand(object sender) + { + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + + var instanceName = v_InstanceName.ConvertToUserVariable(sender); + + bool browserFound = false; + var shellWindows = new ShellWindows(); + foreach (IWebBrowser2 shellWindow in shellWindows) + { + if ((shellWindow.Document is MSHTML.HTMLDocument) && (v_IEBrowserName==null || shellWindow.Document.Title == v_IEBrowserName)) + { + engine.AddAppInstance(instanceName, shellWindow.Application); + browserFound = true; + break; + } + } + + //try partial match + if (!browserFound) + { + foreach (IWebBrowser2 shellWindow in shellWindows) + { + if ((shellWindow.Document is MSHTML.HTMLDocument) && ((shellWindow.Document.Title.Contains(v_IEBrowserName) || shellWindow.Document.Url.Contains(v_IEBrowserName)))) + { + engine.AddAppInstance(instanceName, shellWindow.Application); + browserFound = true; + break; + } + } + } + + if (!browserFound) + { + throw new Exception("Browser was not found!"); + } + } + + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + + IEBrowerNameDropdown = (ComboBox)CommandControls.CreateDropdownFor("v_IEBrowserName", this); + var shellWindows = new ShellWindows(); + foreach (IWebBrowser2 shellWindow in shellWindows) + { + if (shellWindow.Document is MSHTML.HTMLDocument) + IEBrowerNameDropdown.Items.Add(shellWindow.Document.Title); + } + RenderedControls.Add(CommandControls.CreateDefaultLabelFor("v_IEBrowserName", this)); + RenderedControls.AddRange(CommandControls.CreateUIHelpersFor("v_IEBrowserName", this, new Control[] { IEBrowerNameDropdown }, editor)); + //IEBrowerNameDropdown.SelectionChangeCommitted += seleniumAction_SelectionChangeCommitted; + RenderedControls.Add(IEBrowerNameDropdown); + + //ElementParameterControls = new List(); + //ElementParameterControls.Add(CommandControls.CreateDefaultLabelFor("v_WebActionParameterTable", this)); + //ElementParameterControls.AddRange(CommandControls.CreateUIHelpersFor("v_WebActionParameterTable", this, new Control[] { ElementsGridViewHelper }, editor)); + //ElementParameterControls.Add(ElementsGridViewHelper); + + //RenderedControls.AddRange(ElementParameterControls); + + return RenderedControls; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [Browser Name: '" + v_IEBrowserName + "', Instance Name: '" + v_InstanceName + "']"; + } + } + +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/ScriptCommand.cs b/taskt/Core/Automation/Commands/ScriptCommand.cs index c612efe90..6d6bfece4 100644 --- a/taskt/Core/Automation/Commands/ScriptCommand.cs +++ b/taskt/Core/Automation/Commands/ScriptCommand.cs @@ -106,9 +106,10 @@ namespace taskt.Core.Automation.Commands [XmlInclude(typeof(EnvironmentVariableCommand))] [XmlInclude(typeof(OSVariableCommand))] [XmlInclude(typeof(ModifyVariableCommand))] - [XmlInclude(typeof(NLGCreateInstanceCommand))] - [XmlInclude(typeof(NLGSetParameterCommand))] - [XmlInclude(typeof(NLGGeneratePhraseCommand))] + [XmlInclude(typeof(IEBrowserCreateCommand))] + [XmlInclude(typeof(IEBrowserCloseCommand))] + [XmlInclude(typeof(IEBrowserFindBrowserCommand))] + [XmlInclude(typeof(IEBrowserElementActionCommand))] public abstract class ScriptCommand { [XmlAttribute] diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs index 6fd0f57e6..177176b67 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs @@ -91,7 +91,7 @@ public class SeleniumBrowserElementActionCommand : ScriptCommand public SeleniumBrowserElementActionCommand() { - this.CommandName = "SeleniumBrowserCreateCommand"; + this.CommandName = "SeleniumBrowserElementActionCommand"; this.SelectionName = "Element Action"; this.v_InstanceName = "default"; this.CommandEnabled = true; diff --git a/taskt/Core/Automation/Commands/WriteTextFileCommand.cs b/taskt/Core/Automation/Commands/WriteTextFileCommand.cs index 230c37238..ab0532f43 100644 --- a/taskt/Core/Automation/Commands/WriteTextFileCommand.cs +++ b/taskt/Core/Automation/Commands/WriteTextFileCommand.cs @@ -28,7 +28,7 @@ public class WriteTextFileCommand : ScriptCommand public string v_FilePath { get; set; } [XmlAttribute] - [Attributes.PropertyAttributes.PropertyDescription("Please indicate the text to be written")] + [Attributes.PropertyAttributes.PropertyDescription("Please indicate the text to be written. [crLF] inserts a newline.")] [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] [Attributes.PropertyAttributes.InputSpecification("Indicate the text should be written to files.")] [Attributes.PropertyAttributes.SampleUsage("**[vText]** or **Hello World!**")] @@ -55,7 +55,7 @@ public override void RunCommand(object sender) { //convert variables var filePath = v_FilePath.ConvertToUserVariable(sender); - var outputText = v_TextToWrite.ConvertToUserVariable(sender); + var outputText = v_TextToWrite.ConvertToUserVariable(sender).ToString().Replace("[crLF]",Environment.NewLine); //append or overwrite as necessary if (v_Overwrite == "Append") diff --git a/taskt/UI/Forms/frmCommandEditor.cs b/taskt/UI/Forms/frmCommandEditor.cs index 63b40c9f3..c66239120 100644 --- a/taskt/UI/Forms/frmCommandEditor.cs +++ b/taskt/UI/Forms/frmCommandEditor.cs @@ -74,13 +74,13 @@ private void frmNewCommand_Load(object sender, EventArgs e) //Set DisplayMember to track DisplayValue from the class cboSelectedCommand.DisplayMember = "FullName"; - if ((creationMode == CreationMode.Add) && (defaultStartupCommand != null) && (commandList.Where(x => x.FullName == defaultStartupCommand).Count() > 0)) + if ((creationMode == CreationMode.Add) && (defaultStartupCommand != null) && (commandList.Where(x => x.FullName == defaultStartupCommand).Count() > 0)) { cboSelectedCommand.SelectedIndex = cboSelectedCommand.FindStringExact(defaultStartupCommand); } else if ((creationMode == CreationMode.Edit) && (defaultStartupCommand != null) && (commandList.Where(x => x.FullName.Contains(defaultStartupCommand)).Count() > 0)) { - var requiredCommand = commandList.Where(x => x.FullName.Contains(defaultStartupCommand)).FirstOrDefault(); + var requiredCommand = commandList.Where(x => x.FullName.Contains(defaultStartupCommand) && x.CommandClass.Name == originalCommand.CommandName).FirstOrDefault(); cboSelectedCommand.SelectedIndex = cboSelectedCommand.FindStringExact(requiredCommand.FullName); } else @@ -117,13 +117,13 @@ private void frmNewCommand_Load(object sender, EventArgs e) typedControl.Image = Core.Common.Base64ToImage(cmd.v_ImageCapture); } - - + + } - + } - + //handle selection change events @@ -156,7 +156,7 @@ private void CopyPropertiesTo(object fromObject, object toObject) private void AfterFormInitialization() { - + frmCommandEditor_Resize(null, null); } @@ -204,7 +204,7 @@ private void cboSelectedCommand_SelectionChangeCommitted(object sender, EventArg flw_InputVariables.Controls.Add(ctrl); } - + //resize controls frmCommandEditor_Resize(null, null); diff --git a/taskt/taskt.csproj b/taskt/taskt.csproj index 1d9d3dd7f..632c693a0 100644 --- a/taskt/taskt.csproj +++ b/taskt/taskt.csproj @@ -1,718 +1,723 @@ - - - - - Debug - AnyCPU - {C1BE3204-94D1-4A9A-AE30-C3E302383182} - WinExe - Properties - taskt - taskt - v4.5.2 - 512 - true - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - taskt_logo_alt.ico - - - false - - - - - - false - - - F078BC2BE5CD9B63ECEFE9E3C41F1F6BF76F1260 - - - JasonBayldonCodeSigning.p12 - - - - - - - OnOutputUpdated - - - - ..\packages\HtmlAgilityPack.1.6.10\lib\Net45\HtmlAgilityPack.dll - - - ..\packages\ImapX.2.0.0.18\lib\net452\ImapX.dll - - - ..\packages\JetBrains.Annotations.11.0.0\lib\net20\JetBrains.Annotations.dll - - - True - ..\packages\Microsoft.Office.Interop.Excel.14.0.0.1\lib\net20\Microsoft.Office.Interop.Excel.dll - True - - - - ..\packages\TaskScheduler.2.6.1\lib\net452\Microsoft.Win32.TaskScheduler.dll - - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - - - ..\packages\OneNoteOCR.1.0.0.0\lib\OneNoteOCRDll.dll - - - ..\packages\RestSharp.106.6.9\lib\net452\RestSharp.dll - - - ..\packages\Serilog.2.7.1\lib\net45\Serilog.dll - - - ..\packages\Serilog.Formatting.Compact.1.0.0\lib\net45\Serilog.Formatting.Compact.dll - - - ..\packages\Serilog.Sinks.File.4.0.0\lib\net45\Serilog.Sinks.File.dll - - - ..\packages\SharpSimpleNLG.1.2.0\lib\net45\SharpSimpleNLG.dll - - - ..\packages\SuperSocket.ClientEngine.Core.0.8.0.13\lib\net45\SuperSocket.ClientEngine.dll - - - - - - - - - - - - - - - - - - - - - - ..\packages\Selenium.WebDriver.3.7.0\lib\net45\WebDriver.dll - - - ..\packages\WebSocket4Net.0.15.0\lib\net45\WebSocket4Net.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - True - True - Resources.resx - - - - UserControl - - - CommandGroupControl.cs - - - UserControl - - - CommandItemControl.cs - - - Component - - - Form - - - frmAttendedMode.cs - - - Form - - - frmSequenceRecorder.cs - - - Form - - - frmSettings.cs - - - Form - - - frmAddVariable.cs - - - Form - - - frmCodeBuilder.cs - - - Form - - - frmDisplayManager.cs - - - Form - - - frmDLLExplorer.cs - - - Form - - - frmHTMLBuilder.cs - - - Form - - - frmHTMLDisplayForm.cs - - - Form - - - frmImageCapture.cs - - - Form - - - frmKeysBuilder.cs - - - Form - - - frmRemoteDesktopViewer.cs - - - Form - - - frmSplash.cs - - - Form - - - frmThickAppElementRecorder.cs - - - Form - - - frmUserInput.cs - - - Form - - - frmVariableSelector.cs - - - Form - - - frmUpdate.cs - - - Form - - - ThemedForm.cs - - - Form - - - Form - - - frmDialog.cs - - - Form - - - frmScheduleManagement.cs - - - Form - - - frmAbout.cs - - - Form - - - frmBrowserElementBuilder.cs - - - Form - - - frmScriptVariables.cs - - - Form - - - frmCommandEditor.cs - - - Form - - - frmScriptEngine.cs - - - Form - - - frmScriptBuilder.cs - - - Form - - - frmShowCursorPosition.cs - - - - - CommandGroupControl.cs - - - CommandItemControl.cs - - - CustomControls.cs - - - frmAttendedMode.cs - - - frmScheduleManagement.cs - - - frmScriptBuilder.cs - - - frmSequenceRecorder.cs - - - frmSettings.cs - - - frmAbout.cs - - - frmAddVariable.cs - - - frmBrowserElementBuilder.cs - - - frmCommandEditor.cs - - - frmScriptEngine.cs - - - frmScriptBuilder.cs - Designer - - - frmCodeBuilder.cs - - - frmDialog.cs - - - frmDisplayManager.cs - - - frmDLLExplorer.cs - - - frmHTMLBuilder.cs - - - frmHTMLDisplayForm.cs - - - frmImageCapture.cs - - - frmScriptVariables.cs - - - frmKeysBuilder.cs - - - frmRemoteDesktopViewer.cs - - - frmShowCursorPosition.cs - - - ResXFileCodeGenerator - Designer - Resources.Designer.cs - - - frmSplash.cs - - - frmThickAppElementRecorder.cs - - - frmUserInput.cs - - - frmVariableSelector.cs - - - frmUpdate.cs - - - ThemedForm.cs - - - UIForm.cs - - - - Designer - - - - - Designer - - - - - {8C11EFA1-92C3-11D1-BC1E-00C04FA31489} - 1 - 0 - 0 - aximp - False - - - {3050F1C5-98B5-11CF-BB82-00AA00BDCE0B} - 4 - 0 - 0 - tlbimp - False - True - - - {8C11EFA1-92C3-11D1-BC1E-00C04FA31489} - 1 - 0 - 0 - tlbimp - False - True - - - {EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B} - 1 - 1 - 0 - tlbimp - False - True - - - - - - - - - - - - - - - - - - - - - - - - - - Always - - - Always - - - - Always - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Always - - - - - - - - - - - - False - Microsoft .NET Framework 4.5.2 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 - false - - - - - - - + + + + + Debug + AnyCPU + {C1BE3204-94D1-4A9A-AE30-C3E302383182} + WinExe + Properties + taskt + taskt + v4.5.2 + 512 + true + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + taskt_logo_alt.ico + + + false + + + + + + false + + + F078BC2BE5CD9B63ECEFE9E3C41F1F6BF76F1260 + + + JasonBayldonCodeSigning.p12 + + + + + + + OnOutputUpdated + + + x64 + bin\x64\Debug\ + + + x64 + bin\x64\Release\ + + + + ..\packages\HtmlAgilityPack.1.6.10\lib\Net45\HtmlAgilityPack.dll + + + ..\packages\ImapX.2.0.0.18\lib\net452\ImapX.dll + + + ..\packages\JetBrains.Annotations.11.0.0\lib\net20\JetBrains.Annotations.dll + + + True + ..\packages\Microsoft.Office.Interop.Excel.14.0.0.1\lib\net20\Microsoft.Office.Interop.Excel.dll + True + + + + ..\packages\TaskScheduler.2.6.1\lib\net452\Microsoft.Win32.TaskScheduler.dll + + + ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\OneNoteOCR.1.0.0.0\lib\OneNoteOCRDll.dll + + + ..\packages\RestSharp.106.6.9\lib\net452\RestSharp.dll + + + ..\packages\Serilog.2.7.1\lib\net45\Serilog.dll + + + ..\packages\Serilog.Formatting.Compact.1.0.0\lib\net45\Serilog.Formatting.Compact.dll + + + ..\packages\Serilog.Sinks.File.4.0.0\lib\net45\Serilog.Sinks.File.dll + + + ..\packages\SuperSocket.ClientEngine.Core.0.8.0.13\lib\net45\SuperSocket.ClientEngine.dll + + + + + + + + + + + + + + + + + + + + + + ..\packages\Selenium.WebDriver.3.7.0\lib\net45\WebDriver.dll + + + ..\packages\WebSocket4Net.0.15.0\lib\net45\WebSocket4Net.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + UserControl + + + CommandGroupControl.cs + + + UserControl + + + CommandItemControl.cs + + + Component + + + Form + + + frmAttendedMode.cs + + + Form + + + frmSequenceRecorder.cs + + + Form + + + frmSettings.cs + + + Form + + + frmAddVariable.cs + + + Form + + + frmCodeBuilder.cs + + + Form + + + frmDisplayManager.cs + + + Form + + + frmDLLExplorer.cs + + + Form + + + frmHTMLBuilder.cs + + + Form + + + frmHTMLDisplayForm.cs + + + Form + + + frmImageCapture.cs + + + Form + + + frmKeysBuilder.cs + + + Form + + + frmRemoteDesktopViewer.cs + + + Form + + + frmSplash.cs + + + Form + + + frmThickAppElementRecorder.cs + + + Form + + + frmUserInput.cs + + + Form + + + frmVariableSelector.cs + + + Form + + + frmUpdate.cs + + + Form + + + ThemedForm.cs + + + Form + + + Form + + + frmDialog.cs + + + Form + + + frmScheduleManagement.cs + + + Form + + + frmAbout.cs + + + Form + + + frmBrowserElementBuilder.cs + + + Form + + + frmScriptVariables.cs + + + Form + + + frmCommandEditor.cs + + + Form + + + frmScriptEngine.cs + + + Form + + + frmScriptBuilder.cs + + + Form + + + frmShowCursorPosition.cs + + + + + CommandGroupControl.cs + + + CommandItemControl.cs + + + CustomControls.cs + + + frmAttendedMode.cs + + + frmScheduleManagement.cs + + + frmScriptBuilder.cs + + + frmSequenceRecorder.cs + + + frmSettings.cs + + + frmAbout.cs + + + frmAddVariable.cs + + + frmBrowserElementBuilder.cs + + + frmCommandEditor.cs + + + frmScriptEngine.cs + + + frmScriptBuilder.cs + Designer + + + frmCodeBuilder.cs + + + frmDialog.cs + + + frmDisplayManager.cs + + + frmDLLExplorer.cs + + + frmHTMLBuilder.cs + + + frmHTMLDisplayForm.cs + + + frmImageCapture.cs + + + frmScriptVariables.cs + + + frmKeysBuilder.cs + + + frmRemoteDesktopViewer.cs + + + frmShowCursorPosition.cs + + + ResXFileCodeGenerator + Designer + Resources.Designer.cs + + + frmSplash.cs + + + frmThickAppElementRecorder.cs + + + frmUserInput.cs + + + frmVariableSelector.cs + + + frmUpdate.cs + + + ThemedForm.cs + + + UIForm.cs + + + + Designer + + + + + Designer + + + + + {8C11EFA1-92C3-11D1-BC1E-00C04FA31489} + 1 + 0 + 0 + aximp + False + + + {3050F1C5-98B5-11CF-BB82-00AA00BDCE0B} + 4 + 0 + 0 + tlbimp + False + True + + + {8C11EFA1-92C3-11D1-BC1E-00C04FA31489} + 1 + 0 + 0 + tlbimp + False + True + + + {EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B} + 1 + 1 + 0 + tlbimp + False + True + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + Always + + + + Always + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Always + + + + + + + + + + + + False + Microsoft .NET Framework 4.5.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + --> \ No newline at end of file From ef121abe6fe9dc9d7d6cdea8757daa5c1196c5ad Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 8 May 2019 08:09:39 -0400 Subject: [PATCH 09/38] Added Additional NLG parameter options --- .../Commands/NLGSetParameterCommand.cs | 16 ++++++++++++++++ .../NLG Sample [3.0.0.0].xml | 14 ++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs b/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs index 487cdf4ee..36d8df880 100644 --- a/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs +++ b/taskt/Core/Automation/Commands/NLGSetParameterCommand.cs @@ -32,6 +32,10 @@ public class NLGSetParameterCommand : ScriptCommand [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Verb")] [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Object")] [Attributes.PropertyAttributes.PropertyUISelectionOption("Add Complement")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Add Modifier")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Add Pre-Modifier")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Add Front Modifier")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Add Post Modifier")] [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] public string v_ParameterType { get; set; } @@ -73,6 +77,18 @@ public override void RunCommand(object sender) case "Add Complement": p.addComplement(userInput); break; + case "Add Modifier": + p.addModifier(userInput); + break; + case "Add Front Modifier": + p.addFrontModifier(userInput); + break; + case "Add Post Modifier": + p.addPostModifier(userInput); + break; + case "Add Pre-Modifier": + p.addPreModifier(userInput); + break; default: break; } diff --git a/taskt/Sample Scripts/3.x Use Case Samples/NLG Sample [3.0.0.0].xml b/taskt/Sample Scripts/3.x Use Case Samples/NLG Sample [3.0.0.0].xml index af2d9d042..0144198b0 100644 --- a/taskt/Sample Scripts/3.x Use Case Samples/NLG Sample [3.0.0.0].xml +++ b/taskt/Sample Scripts/3.x Use Case Samples/NLG Sample [3.0.0.0].xml @@ -29,16 +29,22 @@ - + - + - + - + + + + + + + From 56424472a965166854a86f187b288b166a13846a Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Mon, 6 May 2019 23:42:29 -0400 Subject: [PATCH 10/38] Added Basic NLG Support --- taskt/Core/Automation/Commands/ScriptCommand.cs | 3 +++ taskt/taskt.csproj | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/taskt/Core/Automation/Commands/ScriptCommand.cs b/taskt/Core/Automation/Commands/ScriptCommand.cs index 6d6bfece4..51f04d9fc 100644 --- a/taskt/Core/Automation/Commands/ScriptCommand.cs +++ b/taskt/Core/Automation/Commands/ScriptCommand.cs @@ -106,6 +106,9 @@ namespace taskt.Core.Automation.Commands [XmlInclude(typeof(EnvironmentVariableCommand))] [XmlInclude(typeof(OSVariableCommand))] [XmlInclude(typeof(ModifyVariableCommand))] + [XmlInclude(typeof(NLGCreateInstanceCommand))] + [XmlInclude(typeof(NLGSetParameterCommand))] + [XmlInclude(typeof(NLGGeneratePhraseCommand))] [XmlInclude(typeof(IEBrowserCreateCommand))] [XmlInclude(typeof(IEBrowserCloseCommand))] [XmlInclude(typeof(IEBrowserFindBrowserCommand))] diff --git a/taskt/taskt.csproj b/taskt/taskt.csproj index 632c693a0..3e07be457 100644 --- a/taskt/taskt.csproj +++ b/taskt/taskt.csproj @@ -119,6 +119,9 @@ ..\packages\Serilog.Sinks.File.4.0.0\lib\net45\Serilog.Sinks.File.dll + + ..\packages\SharpSimpleNLG.1.2.0\lib\net45\SharpSimpleNLG.dll + ..\packages\SuperSocket.ClientEngine.Core.0.8.0.13\lib\net45\SuperSocket.ClientEngine.dll @@ -162,6 +165,8 @@ + + @@ -169,6 +174,7 @@ + @@ -633,6 +639,7 @@ + Always From a973d7cb4fa95ae1bb613149edd300792c7fd606 Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Mon, 13 May 2019 14:12:14 +0200 Subject: [PATCH 11/38] IE Browser element action added Fire onmousedown event added CloseWhenDone option --- .../Commands/IEBrowserElementActionCommand.cs | 6 +++ taskt/Program.cs | 6 +-- taskt/UI/Forms/frmScriptEngine.cs | 42 +++++++++++-------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs index 4e9d035a5..2d4b2872e 100644 --- a/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs @@ -38,6 +38,7 @@ public class IEBrowserElementActionCommand : ScriptCommand [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Text")] [Attributes.PropertyAttributes.PropertyUISelectionOption("Get Attribute")] [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Attribute")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Fire onmousedown event")] [Attributes.PropertyAttributes.InputSpecification("Select the appropriate corresponding action to take once the element has been located")] [Attributes.PropertyAttributes.SampleUsage("Select from **Invoke Click**, **Set Text**, **Get Text**, **Get Attribute**")] [Attributes.PropertyAttributes.Remarks("Selecting this field changes the parameters that will be required in the next step")] @@ -246,6 +247,10 @@ private bool FindQualifyingElement(EnumerableRowCollection elementSearc private void RunCommandActions(IHTMLElement element, object sender, InternetExplorer browserInstance) { + if (v_WebAction == "Fire onmousedown event") + { + ((IHTMLElement3)element).FireEvent("onmousedown"); + } if (v_WebAction == "Invoke Click") { element.click(); @@ -391,6 +396,7 @@ private void ElementActionDropdown_SelectionChangeCommitted(object sender, Event switch (ElementActionDropdown.SelectedItem) { case "Invoke Click": + case "Fire onmousedown event": case "Clear Element": foreach (var ctrl in ElementParameterControls) diff --git a/taskt/Program.cs b/taskt/Program.cs index 3041c4029..776479865 100644 --- a/taskt/Program.cs +++ b/taskt/Program.cs @@ -56,7 +56,7 @@ static void Main(string[] args) return; } - Application.Run(new UI.Forms.frmScriptEngine(filePath, null)); + Application.Run(new UI.Forms.frmScriptEngine(filePath, null, null, true)); } else { @@ -84,8 +84,8 @@ static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEv MessageBox.Show("An unhandled exception occured: " + (e.ExceptionObject as Exception).ToString(), "Oops"); } - public static UI.Forms.Supplemental.frmSplash SplashForm {get; set;} + public static UI.Forms.Supplemental.frmSplash SplashForm { get; set; } + - } } \ No newline at end of file diff --git a/taskt/UI/Forms/frmScriptEngine.cs b/taskt/UI/Forms/frmScriptEngine.cs index 75ffa34af..619574045 100644 --- a/taskt/UI/Forms/frmScriptEngine.cs +++ b/taskt/UI/Forms/frmScriptEngine.cs @@ -41,11 +41,12 @@ public partial class frmScriptEngine : ThemedForm private bool advancedDebug { get; set; } private Core.Automation.Engine.AutomationEngineInstance engineInstance { get; set; } private List Variables { get; set; } + public bool CloseWhenDone = false; #endregion //events and methods #region Form Events/Methods - public frmScriptEngine(string pathToFile, frmScriptBuilder builderForm, List variables = null) + public frmScriptEngine(string pathToFile, frmScriptBuilder builderForm, List variables = null, bool blnCloseWhenDone = false) { InitializeComponent(); @@ -54,6 +55,8 @@ public frmScriptEngine(string pathToFile, frmScriptBuilder builderForm, List /// Triggers the automation engine to stop based on a hooked key press @@ -185,7 +188,7 @@ void OnHookStopped(object sender, EventArgs e) engineInstance.CancelScript(); } - + #endregion //engine event handlers @@ -212,14 +215,14 @@ private void Engine_ScriptFinishedEvent(object sender, ScriptFinishedEventArgs e case ScriptFinishedEventArgs.ScriptFinishedResult.Successful: AddStatus("Script Completed Successfully"); UpdateUI("debug info (success)"); - + break; case ScriptFinishedEventArgs.ScriptFinishedResult.Error: AddStatus("Error: " + e.Error); AddStatus("Script Completed With Errors!"); UpdateUI("debug info (error)"); - + break; case ScriptFinishedEventArgs.ScriptFinishedResult.Cancelled: @@ -231,9 +234,14 @@ private void Engine_ScriptFinishedEvent(object sender, ScriptFinishedEventArgs e } - + AddStatus("Total Execution Time: " + e.ExecutionTime.ToString()); + if(CloseWhenDone) + { + this.Close(); + } + } private void EngineInstance_LineNumberChangedEvent(object sender, LineNumberChangedEventArgs e) @@ -262,12 +270,12 @@ private void AddStatus(string text) } else { - //update status + //update status lblAction.Text = text + ".."; lstSteppingCommands.Items.Add(DateTime.Now.ToString("MM/dd/yy hh:mm:ss.fff") + " | " + text + ".."); lstSteppingCommands.SelectedIndex = lstSteppingCommands.Items.Count - 1; - + } } @@ -336,7 +344,7 @@ public void ShowMessage(string message, string title, UI.Forms.Supplemental.frmD var confirmationForm = new UI.Forms.Supplemental.frmDialog(message, title, dialogType, closeAfter); confirmationForm.ShowDialog(); } - + } public void LaunchRDPSession(string machineName, string userName, string password, int width, int height) { @@ -392,9 +400,9 @@ public List ShowInput(Core.Automation.Commands.UserInputCommand inputs) { return null; } - - + + } } @@ -448,7 +456,7 @@ public void UpdateLineNumber(int lineNumber) { callBackForm.DebugLine = lineNumber; } - + } } #endregion @@ -491,7 +499,7 @@ private void uiBtnCancel_Click(object sender, EventArgs e) private void uiBtnPause_Click(object sender, EventArgs e) { - + if (uiBtnPause.DisplayText == "Pause") { From 6ba03ff6a5b46611e575d05f80bf891591a4f7d7 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 15 May 2019 17:45:24 -0400 Subject: [PATCH 12/38] Fixed bug in command editing where a different command name would fail to render the command --- taskt/UI/Forms/frmCommandEditor.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/taskt/UI/Forms/frmCommandEditor.cs b/taskt/UI/Forms/frmCommandEditor.cs index c66239120..9dfee8dbb 100644 --- a/taskt/UI/Forms/frmCommandEditor.cs +++ b/taskt/UI/Forms/frmCommandEditor.cs @@ -80,8 +80,18 @@ private void frmNewCommand_Load(object sender, EventArgs e) } else if ((creationMode == CreationMode.Edit) && (defaultStartupCommand != null) && (commandList.Where(x => x.FullName.Contains(defaultStartupCommand)).Count() > 0)) { - var requiredCommand = commandList.Where(x => x.FullName.Contains(defaultStartupCommand) && x.CommandClass.Name == originalCommand.CommandName).FirstOrDefault(); - cboSelectedCommand.SelectedIndex = cboSelectedCommand.FindStringExact(requiredCommand.FullName); + var requiredCommand = commandList.Where(x => x.FullName.Contains(defaultStartupCommand)).FirstOrDefault(); //&& x.CommandClass.Name == originalCommand.CommandName).FirstOrDefault(); + + if (requiredCommand == null) + { + MessageBox.Show("Command was not found! " + defaultStartupCommand); + } + else + { + cboSelectedCommand.SelectedIndex = cboSelectedCommand.FindStringExact(requiredCommand.FullName); + } + + } else { From 0e81a2d1bc6b1aceadafeeaf915894368303f405 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Fri, 17 May 2019 21:44:12 -0400 Subject: [PATCH 13/38] Updates to Command Selection Logic --- taskt/UI/Forms/frmCommandEditor.cs | 10 +++++++--- taskt/UI/Forms/frmScriptBuilder.cs | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/taskt/UI/Forms/frmCommandEditor.cs b/taskt/UI/Forms/frmCommandEditor.cs index 9dfee8dbb..c3ec655ba 100644 --- a/taskt/UI/Forms/frmCommandEditor.cs +++ b/taskt/UI/Forms/frmCommandEditor.cs @@ -43,8 +43,10 @@ public partial class frmCommandEditor : ThemedForm public Core.Automation.Commands.ScriptCommand originalCommand; //assigned by frmScriptBuilder to restrict inputs for editing existing commands public CreationMode creationMode; - //startup command, assigned from frmCommand Browser + //startup command, assigned from frmScriptBuilder public string defaultStartupCommand; + //editing command, assigned from frmScriptBuilder when editing a command + public Core.Automation.Commands.ScriptCommand editingCommand; public frmCommandEditor(List commands) { InitializeComponent(); @@ -78,9 +80,11 @@ private void frmNewCommand_Load(object sender, EventArgs e) { cboSelectedCommand.SelectedIndex = cboSelectedCommand.FindStringExact(defaultStartupCommand); } - else if ((creationMode == CreationMode.Edit) && (defaultStartupCommand != null) && (commandList.Where(x => x.FullName.Contains(defaultStartupCommand)).Count() > 0)) + else if (creationMode == CreationMode.Edit) { - var requiredCommand = commandList.Where(x => x.FullName.Contains(defaultStartupCommand)).FirstOrDefault(); //&& x.CommandClass.Name == originalCommand.CommandName).FirstOrDefault(); + // var requiredCommand = commandList.Where(x => x.FullName.Contains(defaultStartupCommand)).FirstOrDefault(); //&& x.CommandClass.Name == originalCommand.CommandName).FirstOrDefault(); + + var requiredCommand = commandList.Where(x => x.Command.ToString() == editingCommand.ToString()).FirstOrDefault(); if (requiredCommand == null) { diff --git a/taskt/UI/Forms/frmScriptBuilder.cs b/taskt/UI/Forms/frmScriptBuilder.cs index 41466d69d..cd22c4b87 100644 --- a/taskt/UI/Forms/frmScriptBuilder.cs +++ b/taskt/UI/Forms/frmScriptBuilder.cs @@ -781,7 +781,8 @@ private void lstScriptActions_DoubleClick(object sender, EventArgs e) //creation mode edit locks form to current command editCommand.creationMode = UI.Forms.frmCommandEditor.CreationMode.Edit; - editCommand.defaultStartupCommand = currentCommand.SelectionName; + //editCommand.defaultStartupCommand = currentCommand.SelectionName; + editCommand.editingCommand = currentCommand; //create clone of current command so databinding does not affect if changes are not saved editCommand.originalCommand = Core.Common.Clone(currentCommand); From ce04b24f8ac7f36ca61289c002115b15f68cc461 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Fri, 17 May 2019 22:09:58 -0400 Subject: [PATCH 14/38] Added handling for dropdowns in Element Action when editing --- .../SeleniumBrowserElementActionCommand.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs index 177176b67..5e1ff1059 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs @@ -112,10 +112,15 @@ public SeleniumBrowserElementActionCommand() ElementsGridViewHelper.DataBindings.Add("DataSource", this, "v_WebActionParameterTable", false, DataSourceUpdateMode.OnPropertyChanged); ElementsGridViewHelper.AllowUserToAddRows = false; ElementsGridViewHelper.AllowUserToDeleteRows = false; - + ElementsGridViewHelper.MouseEnter += ElementsGridViewHelper_MouseEnter; } + private void ElementsGridViewHelper_MouseEnter(object sender, EventArgs e) + { + seleniumAction_SelectionChangeCommitted(null, null); + } + public override void RunCommand(object sender) { var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; @@ -436,7 +441,12 @@ public override List Render(frmCommandEditor editor) return RenderedControls; } - private void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) + public override void Refresh(UI.Forms.frmCommandEditor editor) + { + + //seleniumAction_SelectionChangeCommitted(null, null); + } + public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) { Core.Automation.Commands.SeleniumBrowserElementActionCommand cmd = (Core.Automation.Commands.SeleniumBrowserElementActionCommand)this; From 7d122fecf6a77bdb0155ae19aff0b3adb499ebb8 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Fri, 17 May 2019 22:10:20 -0400 Subject: [PATCH 15/38] Updated form resizing event to trigger once --- taskt/UI/Forms/frmCommandEditor.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/taskt/UI/Forms/frmCommandEditor.cs b/taskt/UI/Forms/frmCommandEditor.cs index c3ec655ba..89a44a355 100644 --- a/taskt/UI/Forms/frmCommandEditor.cs +++ b/taskt/UI/Forms/frmCommandEditor.cs @@ -169,8 +169,7 @@ private void CopyPropertiesTo(object fromObject, object toObject) private void AfterFormInitialization() { - - + //force control resizing frmCommandEditor_Resize(null, null); } @@ -217,11 +216,7 @@ private void cboSelectedCommand_SelectionChangeCommitted(object sender, EventArg { flw_InputVariables.Controls.Add(ctrl); } - - - //resize controls - frmCommandEditor_Resize(null, null); - + } From 03c9f50b7743e021c229e5a0b1ba8e371ac099cf Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Fri, 17 May 2019 22:12:38 -0400 Subject: [PATCH 16/38] Updaated Combobox Selections when editing If Command --- taskt/Core/Automation/Commands/BeginIfCommand.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/taskt/Core/Automation/Commands/BeginIfCommand.cs b/taskt/Core/Automation/Commands/BeginIfCommand.cs index 0b715d9ad..2c3889f0f 100644 --- a/taskt/Core/Automation/Commands/BeginIfCommand.cs +++ b/taskt/Core/Automation/Commands/BeginIfCommand.cs @@ -89,6 +89,7 @@ public BeginIfCommand() IfGridViewHelper.DataBindings.Add("DataSource", this, "v_IfActionParameterTable", false, DataSourceUpdateMode.OnPropertyChanged); IfGridViewHelper.AllowUserToAddRows = false; IfGridViewHelper.AllowUserToDeleteRows = false; + IfGridViewHelper.MouseEnter += IfGridViewHelper_MouseEnter; RecorderControl = new taskt.UI.CustomControls.CommandItemControl(); RecorderControl.Padding = new System.Windows.Forms.Padding(10, 0, 0, 0); @@ -102,6 +103,11 @@ public BeginIfCommand() + } + + private void IfGridViewHelper_MouseEnter(object sender, EventArgs e) + { + ifAction_SelectionChangeCommitted(null, null); } public override void RunCommand(object sender, Core.Script.ScriptAction parentCommand) From 69d11fdb620d6d718f15c10afad09c86bb1d0458 Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Tue, 28 May 2019 16:24:58 +0200 Subject: [PATCH 17/38] --- .../Commands/IEBrowserElementActionCommand.cs | 140 ++++++++++++------ .../Commands/IEBrowserNavigateURLCommand.cs | 77 ++++++++++ .../Core/Automation/Commands/ScriptCommand.cs | 1 + taskt/Core/ExtensionMethods.cs | 68 +++++---- taskt/taskt.csproj | 1 + 5 files changed, 215 insertions(+), 72 deletions(-) create mode 100644 taskt/Core/Automation/Commands/IEBrowserNavigateURLCommand.cs diff --git a/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs index 2d4b2872e..1d0531e9a 100644 --- a/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/IEBrowserElementActionCommand.cs @@ -39,6 +39,7 @@ public class IEBrowserElementActionCommand : ScriptCommand [Attributes.PropertyAttributes.PropertyUISelectionOption("Get Attribute")] [Attributes.PropertyAttributes.PropertyUISelectionOption("Set Attribute")] [Attributes.PropertyAttributes.PropertyUISelectionOption("Fire onmousedown event")] + [Attributes.PropertyAttributes.PropertyUISelectionOption("Fire onmouseover event")] [Attributes.PropertyAttributes.InputSpecification("Select the appropriate corresponding action to take once the element has been located")] [Attributes.PropertyAttributes.SampleUsage("Select from **Invoke Click**, **Set Text**, **Get Text**, **Get Attribute**")] [Attributes.PropertyAttributes.Remarks("Selecting this field changes the parameters that will be required in the next step")] @@ -114,30 +115,41 @@ private Boolean InspectFrame(IHTMLElementCollection elementCollection, Enumerabl bool qualifyingElementFound = false; foreach (IHTMLElement element in elementCollection) // browserInstance.Document.All) { - qualifyingElementFound = FindQualifyingElement(elementSearchProperties, element); - if (qualifyingElementFound) + if (element.outerHTML != null) { - RunCommandActions(element, sender, browserInstance); - lastElementCollectionFound = elementCollection; - return (true); - //break; - } - if (element.outerHTML != null && element.outerHTML.ToLower().Trim().StartsWith("("Enabled").ToString() == "True" select rws; + foreach (DataRow seachCriteria in elementSearchProperties) + { + string searchPropertyValue = seachCriteria.Field("Property Value"); + searchPropertyValue = searchPropertyValue.ConvertToUserVariable(engine); + seachCriteria.SetField("Property Value", searchPropertyValue); + } bool qualifyingElementFound = false; @@ -202,45 +220,68 @@ private bool FindQualifyingElement(EnumerableRowCollection elementSearc searchPropertyFound = "False"; - //if (element.GetType().GetProperty(searchPropertyName) == null) - if ((outerHTML == null) || (element.getAttribute(searchPropertyName) == null) || (System.Convert.IsDBNull(element.getAttribute(searchPropertyName)))) + try { - return false; - } - - int searchValue; - if (int.TryParse(searchPropertyValue, out searchValue)) - { - //int elementValue = (int)element.GetType().GetProperty(searchPropertyName).GetValue(element, null); - int elementValue = (int)element.getAttribute(searchPropertyName); - if (elementValue == searchValue) - { - seachCriteria.SetField("Match Found", "True"); - } - else + //if (element.GetType().GetProperty(searchPropertyName) == null) + if ((outerHTML == null) || (element.getAttribute(searchPropertyName) == null) || (System.Convert.IsDBNull(element.getAttribute(searchPropertyName)))) { - seachCriteria.SetField("Match Found", "False"); + return false; } - } - else - { - //string elementValue = (string)element.GetType().GetProperty(searchPropertyName).GetValue(element, null); - string elementValue = (string)element.getAttribute(searchPropertyName); - if ((elementValue != null) && (elementValue == searchPropertyValue)) + + if (searchPropertyName.ToLower() == "href") { - seachCriteria.SetField("Match Found", "True"); + try + { + HTMLAnchorElement anchor = (HTMLAnchorElement)element; + if (anchor.href.Contains(searchPropertyValue)) + { + seachCriteria.SetField("Match Found", "True"); + } + else + { + seachCriteria.SetField("Match Found", "False"); + } + } + catch (Exception ex) { } } else { - seachCriteria.SetField("Match Found", "False"); + int searchValue; + if (int.TryParse(searchPropertyValue, out searchValue)) + { + //int elementValue = (int)element.GetType().GetProperty(searchPropertyName).GetValue(element, null); + int elementValue = (int)element.getAttribute(searchPropertyName); + if (elementValue == searchValue) + { + seachCriteria.SetField("Match Found", "True"); + } + else + { + seachCriteria.SetField("Match Found", "False"); + } + } + else + { + //string elementValue = (string)element.GetType().GetProperty(searchPropertyName).GetValue(element, null); + string elementValue = (string)element.getAttribute(searchPropertyName); + if ((elementValue != null) && (elementValue == searchPropertyValue)) + { + seachCriteria.SetField("Match Found", "True"); + } + else + { + seachCriteria.SetField("Match Found", "False"); + } + } } } + catch (Exception ex) { } } - foreach (var seachCriteria in elementSearchProperties) + /*foreach (var seachCriteria in elementSearchProperties) { Console.WriteLine(seachCriteria.Field("Property Value")); - } + }*/ return elementSearchProperties.Where(seachCriteria => seachCriteria.Field("Match Found") == "True").Count() == elementSearchProperties.Count(); } @@ -251,7 +292,11 @@ private void RunCommandActions(IHTMLElement element, object sender, InternetExpl { ((IHTMLElement3)element).FireEvent("onmousedown"); } - if (v_WebAction == "Invoke Click") + else if (v_WebAction == "Fire onmouseover event") + { + ((IHTMLElement3)element).FireEvent("onmouseover"); + } + else if (v_WebAction == "Invoke Click") { element.click(); IEBrowserCreateCommand.WaitForReadyState(browserInstance); @@ -397,6 +442,7 @@ private void ElementActionDropdown_SelectionChangeCommitted(object sender, Event { case "Invoke Click": case "Fire onmousedown event": + case "Fire onmouseover event": case "Clear Element": foreach (var ctrl in ElementParameterControls) diff --git a/taskt/Core/Automation/Commands/IEBrowserNavigateURLCommand.cs b/taskt/Core/Automation/Commands/IEBrowserNavigateURLCommand.cs new file mode 100644 index 000000000..978248dfc --- /dev/null +++ b/taskt/Core/Automation/Commands/IEBrowserNavigateURLCommand.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Xml.Serialization; +using taskt.UI.CustomControls; +using taskt.UI.Forms; + +namespace taskt.Core.Automation.Commands +{ + + + + [Serializable] + [Attributes.ClassAttributes.Group("IE Browser Commands")] + [Attributes.ClassAttributes.Description("This command allows you to navigate a IE web browser session to a given URL or resource.")] + [Attributes.ClassAttributes.UsesDescription("Use this command when you want to navigate an existing IE instance to a known URL or web resource")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements the 'InternetExplorer' application object from SHDocVw.dll to achieve automation.")] + public class IEBrowserNavigateURLCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the instance name")] + [Attributes.PropertyAttributes.InputSpecification("Enter the unique instance name that was specified in the **Create IE Browser** command")] + [Attributes.PropertyAttributes.SampleUsage("**myInstance** or **IEInstance**")] + [Attributes.PropertyAttributes.Remarks("Failure to enter the correct instance name or failure to first call **Create IE Browser** command will cause an error")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_InstanceName { get; set; } + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please Enter the URL to navigate to")] + [Attributes.PropertyAttributes.InputSpecification("Enter the destination URL that you want the IE instance to navigate to")] + [Attributes.PropertyAttributes.SampleUsage("https://mycompany.com/orders")] + [Attributes.PropertyAttributes.Remarks("")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + public string v_URL { get; set; } + + public IEBrowserNavigateURLCommand() + { + this.CommandName = "IEBrowserNavigateURLCommand"; + this.SelectionName = "Navigate to URL"; + this.v_InstanceName = "default"; + this.CommandEnabled = true; + this.CustomRendering = true; + } + + public override void RunCommand(object sender) + { + object browserObject = null; + + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + + var vInstance = v_InstanceName.ConvertToUserVariable(engine); + + browserObject = engine.GetAppInstance(vInstance); + + var browserInstance = (SHDocVw.InternetExplorer)browserObject; + + browserInstance.Navigate(v_URL.ConvertToUserVariable(sender)); + + IEBrowserCreateCommand.WaitForReadyState(browserInstance); + + } + public override List Render(frmCommandEditor editor) + { + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_URL", this, editor)); + + return RenderedControls; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [URL: '" + v_URL + "', Instance Name: '" + v_InstanceName + "']"; + } + } +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/ScriptCommand.cs b/taskt/Core/Automation/Commands/ScriptCommand.cs index 51f04d9fc..49c1db268 100644 --- a/taskt/Core/Automation/Commands/ScriptCommand.cs +++ b/taskt/Core/Automation/Commands/ScriptCommand.cs @@ -113,6 +113,7 @@ namespace taskt.Core.Automation.Commands [XmlInclude(typeof(IEBrowserCloseCommand))] [XmlInclude(typeof(IEBrowserFindBrowserCommand))] [XmlInclude(typeof(IEBrowserElementActionCommand))] + [XmlInclude(typeof(IEBrowserNavigateURLCommand))] public abstract class ScriptCommand { [XmlAttribute] diff --git a/taskt/Core/ExtensionMethods.cs b/taskt/Core/ExtensionMethods.cs index aedcbf144..a0efd04d8 100644 --- a/taskt/Core/ExtensionMethods.cs +++ b/taskt/Core/ExtensionMethods.cs @@ -23,8 +23,8 @@ public static string ConvertToUserVariable(this String str, object sender) if (sender == null) return str; - var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; - + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + var variableList = engine.VariableList; var systemVariables = Core.Common.GenerateSystemVariables(); @@ -61,15 +61,15 @@ public static string ConvertToUserVariable(this String str, object sender) { //get the value from the list - complexJsonVariable = complexJsonVariable.Replace("^" + potentialSubVariable + "^", matchingVar.GetDisplayValue()); - continue; - } - - } - - - - //split by json select token pointer + complexJsonVariable = complexJsonVariable.Replace("^" + potentialSubVariable + "^", matchingVar.GetDisplayValue()); + continue; + } + + } + + + + //split by json select token pointer var element = complexJsonVariable.Split(new string[] { "=>" }, StringSplitOptions.None); //verify length @@ -110,24 +110,32 @@ public static string ConvertToUserVariable(this String str, object sender) } } - } - } - + } + } + string varcheckname = potentialVariable; + string[] aPotentialVariable = potentialVariable.Split(new string[] { "[", "]" }, StringSplitOptions.None); + int ix=0; + if (aPotentialVariable.Length == 3 && int.TryParse(aPotentialVariable[1], out ix)) + { + varcheckname = aPotentialVariable[0]; + } + var varCheck = (from vars in searchList - where vars.VariableName == potentialVariable + where vars.VariableName == varcheckname select vars).FirstOrDefault(); - if (potentialVariable.Length == 0) - continue; + if (potentialVariable.Length == 0) + continue; if (potentialVariable == "taskt.EngineContext") { //set json settings JsonSerializerSettings settings = new JsonSerializerSettings(); - settings.Error = (serializer, err) => { + settings.Error = (serializer, err) => + { err.ErrorContext.Handled = true; }; settings.Formatting = Formatting.Indented; @@ -141,12 +149,22 @@ public static string ConvertToUserVariable(this String str, object sender) var searchVariable = startVariableMarker + potentialVariable + endVariableMarker; if (str.Contains(searchVariable)) - { - str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue()); + { + if (ix != 0) + { + int savePosition = varCheck.CurrentPosition; + varCheck.CurrentPosition = ix; + str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue()); + varCheck.CurrentPosition = savePosition; + } + else + { + str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue()); + } } else if (str.Contains(potentialVariable)) - { - str = str.Replace(potentialVariable, (string)varCheck.GetDisplayValue()); + { + str = str.Replace(potentialVariable, (string)varCheck.GetDisplayValue()); } } @@ -201,7 +219,7 @@ public static string ConvertToUserVariable(this String str, object sender) //if the string matches the char then return //as the user does not want to do math - if (mathChars.Any( f => f.ToString() == str) || (mathChars.Any(f => str.StartsWith(f.ToString())))) + if (mathChars.Any(f => f.ToString() == str) || (mathChars.Any(f => str.StartsWith(f.ToString())))) { return str; } @@ -246,8 +264,8 @@ public static void StoreInUserVariable(this String str, object sender, string ta /// The string to be wrapped as a variable public static string ApplyVariableFormatting(this String str) { - var settings = new ApplicationSettings().GetOrCreateApplicationSettings(); - + var settings = new ApplicationSettings().GetOrCreateApplicationSettings(); + return str.Insert(0, settings.EngineSettings.VariableStartMarker).Insert(str.Length + 1, settings.EngineSettings.VariableEndMarker); } } diff --git a/taskt/taskt.csproj b/taskt/taskt.csproj index 3e07be457..0adcef7a6 100644 --- a/taskt/taskt.csproj +++ b/taskt/taskt.csproj @@ -190,6 +190,7 @@ + From 7ca0eb9f2e0c68bc12873a55d9af779a6766626d Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Wed, 29 May 2019 09:35:22 +0200 Subject: [PATCH 18/38] --- .../Commands/SeleniumBrowserElementActionCommand.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs index 5e1ff1059..a3680757a 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs @@ -118,7 +118,7 @@ public SeleniumBrowserElementActionCommand() private void ElementsGridViewHelper_MouseEnter(object sender, EventArgs e) { - seleniumAction_SelectionChangeCommitted(null, null); + // seleniumAction_SelectionChangeCommitted(null, null); } public override void RunCommand(object sender) @@ -441,11 +441,12 @@ public override List Render(frmCommandEditor editor) return RenderedControls; } + public override void Refresh(UI.Forms.frmCommandEditor editor) { - //seleniumAction_SelectionChangeCommitted(null, null); } + public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) { From 7dc9c2d3f4dcaa533da1ce82817de2c807256bc0 Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Wed, 29 May 2019 11:25:39 +0200 Subject: [PATCH 19/38] --- .../Commands/SeleniumBrowserElementActionCommand.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs index a3680757a..c5130e4c2 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs @@ -112,13 +112,13 @@ public SeleniumBrowserElementActionCommand() ElementsGridViewHelper.DataBindings.Add("DataSource", this, "v_WebActionParameterTable", false, DataSourceUpdateMode.OnPropertyChanged); ElementsGridViewHelper.AllowUserToAddRows = false; ElementsGridViewHelper.AllowUserToDeleteRows = false; - ElementsGridViewHelper.MouseEnter += ElementsGridViewHelper_MouseEnter; - - } + ElementsGridViewHelper.MouseEnter += ElementsGridViewHelper_MouseEnter; + + } private void ElementsGridViewHelper_MouseEnter(object sender, EventArgs e) { - // seleniumAction_SelectionChangeCommitted(null, null); + //seleniumAction_SelectionChangeCommitted(null, null); } public override void RunCommand(object sender) @@ -466,7 +466,7 @@ public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) foreach (var ctrl in ElementParameterControls) { - ctrl.Hide(); + //ctrl.Hide(); } break; From d9a525f8bfd9e4208385237272d8ead9f87200cb Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Wed, 29 May 2019 12:13:01 +0200 Subject: [PATCH 20/38] --- .../Commands/SeleniumBrowserElementActionCommand.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs index c5130e4c2..1de19fdb5 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs @@ -439,13 +439,13 @@ public override List Render(frmCommandEditor editor) RenderedControls.AddRange(ElementParameterControls); - return RenderedControls; + return RenderedControls; } - public override void Refresh(UI.Forms.frmCommandEditor editor) - { - //seleniumAction_SelectionChangeCommitted(null, null); - } + //public override void Refresh(UI.Forms.frmCommandEditor editor) + //{ + // //seleniumAction_SelectionChangeCommitted(null, null); + //} public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) { From 678cdddb9066e9aa1cb65770d9a9b9b52c79494f Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Wed, 29 May 2019 13:33:51 +0200 Subject: [PATCH 21/38] --- .../Commands/SeleniumBrowserElementActionCommand.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs index 1de19fdb5..35ec34931 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs @@ -112,14 +112,14 @@ public SeleniumBrowserElementActionCommand() ElementsGridViewHelper.DataBindings.Add("DataSource", this, "v_WebActionParameterTable", false, DataSourceUpdateMode.OnPropertyChanged); ElementsGridViewHelper.AllowUserToAddRows = false; ElementsGridViewHelper.AllowUserToDeleteRows = false; - ElementsGridViewHelper.MouseEnter += ElementsGridViewHelper_MouseEnter; + //ElementsGridViewHelper.MouseEnter += ElementsGridViewHelper_MouseEnter; } - private void ElementsGridViewHelper_MouseEnter(object sender, EventArgs e) - { - //seleniumAction_SelectionChangeCommitted(null, null); - } + //private void ElementsGridViewHelper_MouseEnter(object sender, EventArgs e) + //{ + // seleniumAction_SelectionChangeCommitted(null, null); + //} public override void RunCommand(object sender) { @@ -224,7 +224,7 @@ where rw.Field("Parameter Name") == "Clear Element Before Setting Text" clearElement = "No"; } - if (clearElement == "Yes") + if (clearElement.ToLower() == "yes") { element.Clear(); } From 3ba5a3c04b2d2498331d8e57c1f77a7c7ebb3851 Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Tue, 4 Jun 2019 13:55:53 +0200 Subject: [PATCH 22/38] Direct addressing of enumerable objects i.e vElement[3] now works Implemented count property in user variable for enumerable objects i.e. vElements.count now returns array length Fixed a bug that was swapping script statement parameters when editing Run now does Save&Run in old UI too --- taskt/Core/ExtensionMethods.cs | 19 ++++++++++++++----- taskt/Core/Script.cs | 8 +++++++- taskt/UI/CustomControls/CommandControls.cs | 6 +++--- taskt/UI/Forms/frmScriptBuilder.cs | 2 ++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/taskt/Core/ExtensionMethods.cs b/taskt/Core/ExtensionMethods.cs index a0efd04d8..4d174eb04 100644 --- a/taskt/Core/ExtensionMethods.cs +++ b/taskt/Core/ExtensionMethods.cs @@ -115,11 +115,15 @@ public static string ConvertToUserVariable(this String str, object sender) string varcheckname = potentialVariable; string[] aPotentialVariable = potentialVariable.Split(new string[] { "[", "]" }, StringSplitOptions.None); - int ix=0; - if (aPotentialVariable.Length == 3 && int.TryParse(aPotentialVariable[1], out ix)) + int directElementIndex = 0; + if (aPotentialVariable.Length == 3 && int.TryParse(aPotentialVariable[1], out directElementIndex)) { varcheckname = aPotentialVariable[0]; } + else if (potentialVariable.Split('.').Length==2) + { + varcheckname = potentialVariable.Split('.')[0]; + } var varCheck = (from vars in searchList where vars.VariableName == varcheckname @@ -150,13 +154,18 @@ public static string ConvertToUserVariable(this String str, object sender) if (str.Contains(searchVariable)) { - if (ix != 0) + if (directElementIndex != 0) { int savePosition = varCheck.CurrentPosition; - varCheck.CurrentPosition = ix; + varCheck.CurrentPosition = directElementIndex; str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue()); varCheck.CurrentPosition = savePosition; } + else if (potentialVariable.Split('.').Length==2) // This handles vVariable.count + { + string propertyName = potentialVariable.Split('.')[1]; + str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue(propertyName)); + } else { str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue()); @@ -201,7 +210,7 @@ public static string ConvertToUserVariable(this String str, object sender) } } - } + } } diff --git a/taskt/Core/Script.cs b/taskt/Core/Script.cs index 2da498cf6..329db6d9b 100644 --- a/taskt/Core/Script.cs +++ b/taskt/Core/Script.cs @@ -228,7 +228,13 @@ public string GetDisplayValue(string requiredProperty = "") else { List requiredValue = (List)VariableValue; - return requiredValue[CurrentPosition]; + switch(requiredProperty) + { + case "count": + return requiredValue.Count.ToString(); + default: + return requiredValue[CurrentPosition]; + } } } diff --git a/taskt/UI/CustomControls/CommandControls.cs b/taskt/UI/CustomControls/CommandControls.cs index d8c92d38e..62c936c57 100644 --- a/taskt/UI/CustomControls/CommandControls.cs +++ b/taskt/UI/CustomControls/CommandControls.cs @@ -772,10 +772,10 @@ public void Bind(UI.Forms.frmCommandEditor editor) { //preference to preload is false - if (UIControls is null) - { + //if (UIControls is null) + //{ this.RenderUIComponents(); - } + //} foreach (var ctrl in UIControls) { diff --git a/taskt/UI/Forms/frmScriptBuilder.cs b/taskt/UI/Forms/frmScriptBuilder.cs index cd22c4b87..7b2f7599b 100644 --- a/taskt/UI/Forms/frmScriptBuilder.cs +++ b/taskt/UI/Forms/frmScriptBuilder.cs @@ -1603,6 +1603,8 @@ private void uiBtnRunScript_Click(object sender, EventArgs e) //clear selected items ClearSelectedListViewItems(); + SaveToFile(false); // Save & Run! + Notify("Running Script.."); From ba9e766c8dc741f8a30d5d3f4dfceb73cb628aec Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Tue, 4 Jun 2019 23:31:52 -0400 Subject: [PATCH 23/38] Added handling for casing of 'count' property --- taskt/Core/Script.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/taskt/Core/Script.cs b/taskt/Core/Script.cs index 329db6d9b..74a452337 100644 --- a/taskt/Core/Script.cs +++ b/taskt/Core/Script.cs @@ -231,6 +231,8 @@ public string GetDisplayValue(string requiredProperty = "") switch(requiredProperty) { case "count": + case "Count": + case "COUNT": return requiredValue.Count.ToString(); default: return requiredValue[CurrentPosition]; From 4c00cc901533f4fe09101761bd7d7e5940948c9b Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Tue, 4 Jun 2019 23:48:52 -0400 Subject: [PATCH 24/38] Added boolean to help determine if we should use direct element index, otherise {var[0]} will not work --- taskt/Core/ExtensionMethods.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/taskt/Core/ExtensionMethods.cs b/taskt/Core/ExtensionMethods.cs index 4d174eb04..876c39e71 100644 --- a/taskt/Core/ExtensionMethods.cs +++ b/taskt/Core/ExtensionMethods.cs @@ -116,9 +116,11 @@ public static string ConvertToUserVariable(this String str, object sender) string varcheckname = potentialVariable; string[] aPotentialVariable = potentialVariable.Split(new string[] { "[", "]" }, StringSplitOptions.None); int directElementIndex = 0; + bool useDirectElementIndex = false; if (aPotentialVariable.Length == 3 && int.TryParse(aPotentialVariable[1], out directElementIndex)) { varcheckname = aPotentialVariable[0]; + useDirectElementIndex = true; } else if (potentialVariable.Split('.').Length==2) { @@ -154,7 +156,7 @@ public static string ConvertToUserVariable(this String str, object sender) if (str.Contains(searchVariable)) { - if (directElementIndex != 0) + if (useDirectElementIndex) { int savePosition = varCheck.CurrentPosition; varCheck.CurrentPosition = directElementIndex; From 89c6b349dc0f03f070fc7bd8b76d0f9c7ef7758f Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 5 Jun 2019 00:03:10 -0400 Subject: [PATCH 25/38] Added Support for Json and Pipe Delimited Variable Output --- taskt/Core/Script.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/taskt/Core/Script.cs b/taskt/Core/Script.cs index 74a452337..a3dbc2359 100644 --- a/taskt/Core/Script.cs +++ b/taskt/Core/Script.cs @@ -234,6 +234,20 @@ public string GetDisplayValue(string requiredProperty = "") case "Count": case "COUNT": return requiredValue.Count.ToString(); + case "index": + case "Index": + case "INDEX": + return CurrentPosition.ToString(); + case "ToJson": + case "TOJSON": + case "tojson": + case "toJson": + return Newtonsoft.Json.JsonConvert.SerializeObject(requiredValue); + case "toPipe": + case "ToPipe": + case "TOPIPE": + case "topipe": + return String.Join("|", requiredValue); default: return requiredValue[CurrentPosition]; } From 15a3c1ef2a3b9f57e00abb9d5eb5f7c9c8a69f5d Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 5 Jun 2019 00:11:07 -0400 Subject: [PATCH 26/38] Added First and Last properties to access variable --- taskt/Core/Script.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/taskt/Core/Script.cs b/taskt/Core/Script.cs index a3dbc2359..b0e2aff3e 100644 --- a/taskt/Core/Script.cs +++ b/taskt/Core/Script.cs @@ -238,16 +238,24 @@ public string GetDisplayValue(string requiredProperty = "") case "Index": case "INDEX": return CurrentPosition.ToString(); - case "ToJson": - case "TOJSON": case "tojson": + case "ToJson": case "toJson": + case "TOJSON": return Newtonsoft.Json.JsonConvert.SerializeObject(requiredValue); - case "toPipe": + case "topipe": case "ToPipe": + case "toPipe": case "TOPIPE": - case "topipe": return String.Join("|", requiredValue); + case "first": + case "First": + case "FIRST": + return requiredValue.FirstOrDefault(); + case "last": + case "Last": + case "LAST": + return requiredValue.Last(); default: return requiredValue[CurrentPosition]; } From 0bd6d3f5ec3b07799ffef166fc97a8aceca474ed Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 5 Jun 2019 00:22:48 -0400 Subject: [PATCH 27/38] Added Type checking for Variables - BASIC or LIST --- taskt/Core/Script.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/taskt/Core/Script.cs b/taskt/Core/Script.cs index b0e2aff3e..23f8346c2 100644 --- a/taskt/Core/Script.cs +++ b/taskt/Core/Script.cs @@ -221,9 +221,19 @@ public class ScriptVariable /// public string GetDisplayValue(string requiredProperty = "") { + if (VariableValue is string) { - return (string)VariableValue; + switch (requiredProperty) + { + case "type": + case "Type": + case "TYPE": + return "BASIC"; + default: + return (string)VariableValue; + } + } else { @@ -256,6 +266,10 @@ public string GetDisplayValue(string requiredProperty = "") case "Last": case "LAST": return requiredValue.Last(); + case "type": + case "Type": + case "TYPE": + return "LIST"; default: return requiredValue[CurrentPosition]; } From 54f6463ad5bfbae61783997540a34fb11729771c Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 5 Jun 2019 00:39:54 -0400 Subject: [PATCH 28/38] Added Additonal Variable Commands and associated UI assets --- .../Commands/AddToVariableCommand.cs | 127 ++++++++++++++++++ .../Core/Automation/Commands/ScriptCommand.cs | 2 + .../Commands/SetVariableIndexCommand.cs | 109 +++++++++++++++ taskt/UI/CustomControls/CustomControls.cs | 2 + taskt/taskt.csproj | 2 + 5 files changed, 242 insertions(+) create mode 100644 taskt/Core/Automation/Commands/AddToVariableCommand.cs create mode 100644 taskt/Core/Automation/Commands/SetVariableIndexCommand.cs diff --git a/taskt/Core/Automation/Commands/AddToVariableCommand.cs b/taskt/Core/Automation/Commands/AddToVariableCommand.cs new file mode 100644 index 000000000..3c50e1f51 --- /dev/null +++ b/taskt/Core/Automation/Commands/AddToVariableCommand.cs @@ -0,0 +1,127 @@ +using System; +using System.Linq; +using System.Xml.Serialization; +using System.Data; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Drawing; +using taskt.UI.CustomControls; +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("Engine Commands")] + [Attributes.ClassAttributes.Description("This command allows you to modify variables.")] + [Attributes.ClassAttributes.UsesDescription("Use this command when you want to modify the value of variables. You can even use variables to modify other variables.")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements actions against VariableList from the scripting engine.")] + public class AddToVariableCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please select a variable to modify")] + [Attributes.PropertyAttributes.InputSpecification("Select or provide a variable from the variable list")] + [Attributes.PropertyAttributes.SampleUsage("**vSomeVariable**")] + [Attributes.PropertyAttributes.Remarks("If you have enabled the setting **Create Missing Variables at Runtime** then you are not required to pre-define your variables, however, it is highly recommended.")] + public string v_userVariableName { get; set; } + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please define the input to be added to the variable")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + [Attributes.PropertyAttributes.InputSpecification("Enter the input that the variable's value should be set to.")] + [Attributes.PropertyAttributes.SampleUsage("Hello or [vNum]+1")] + [Attributes.PropertyAttributes.Remarks("You can use variables in input if you encase them within brackets [vName]. You can also perform basic math operations.")] + public string v_Input { get; set; } + public AddToVariableCommand() + { + this.CommandName = "AddToVariableCommand"; + this.SelectionName = "Add To Variable"; + this.CommandEnabled = true; + this.CustomRendering = true; + } + + public override void RunCommand(object sender) + { + //get sending instance + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + + var requiredVariable = LookupVariable(engine); + + //if still not found and user has elected option, create variable at runtime + if ((requiredVariable == null) && (engine.engineSettings.CreateMissingVariablesDuringExecution)) + { + engine.VariableList.Add(new Script.ScriptVariable() { VariableName = v_userVariableName }); + requiredVariable = LookupVariable(engine); + } + + var variableInput = v_Input.ConvertToUserVariable(sender); + + + if (requiredVariable != null) + { + + if (requiredVariable.VariableValue is List) + { + var existingList = (List)requiredVariable.VariableValue; + existingList.Add(variableInput); + } + else + { + var itemList = new List(); + + if (requiredVariable.GetDisplayValue() != "") + itemList.Add(requiredVariable.GetDisplayValue()); + + itemList.Add(variableInput); + + requiredVariable.VariableValue = itemList; + + } + + + } + else + { + throw new Exception("Attempted to add data to a variable, but the variable was not found. Enclose variables within brackets, ex. {vVariable}"); + } + } + + private Script.ScriptVariable LookupVariable(Core.Automation.Engine.AutomationEngineInstance sendingInstance) + { + //search for the variable + var requiredVariable = sendingInstance.VariableList.Where(var => var.VariableName == v_userVariableName).FirstOrDefault(); + + //if variable was not found but it starts with variable naming pattern + if ((requiredVariable == null) && (v_userVariableName.StartsWith(sendingInstance.engineSettings.VariableStartMarker)) && (v_userVariableName.EndsWith(sendingInstance.engineSettings.VariableEndMarker))) + { + //reformat and attempt + var reformattedVariable = v_userVariableName.Replace(sendingInstance.engineSettings.VariableStartMarker, "").Replace(sendingInstance.engineSettings.VariableEndMarker, ""); + requiredVariable = sendingInstance.VariableList.Where(var => var.VariableName == reformattedVariable).FirstOrDefault(); + } + + return requiredVariable; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [Apply '" + v_Input + "' to Variable '" + v_userVariableName + "']"; + } + + public override List Render(UI.Forms.frmCommandEditor editor) + { + //custom rendering + base.Render(editor); + + + //create control for variable name + RenderedControls.Add(CommandControls.CreateDefaultLabelFor("v_userVariableName", this)); + var VariableNameControl = CommandControls.CreateStandardComboboxFor("v_userVariableName", this).AddVariableNames(editor); + RenderedControls.AddRange(CommandControls.CreateUIHelpersFor("v_userVariableName", this, new Control[] { VariableNameControl }, editor)); + RenderedControls.Add(VariableNameControl); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_Input", this, editor)); + + + + return RenderedControls; + + + } + } +} \ No newline at end of file diff --git a/taskt/Core/Automation/Commands/ScriptCommand.cs b/taskt/Core/Automation/Commands/ScriptCommand.cs index 49c1db268..b493d4867 100644 --- a/taskt/Core/Automation/Commands/ScriptCommand.cs +++ b/taskt/Core/Automation/Commands/ScriptCommand.cs @@ -114,6 +114,8 @@ namespace taskt.Core.Automation.Commands [XmlInclude(typeof(IEBrowserFindBrowserCommand))] [XmlInclude(typeof(IEBrowserElementActionCommand))] [XmlInclude(typeof(IEBrowserNavigateURLCommand))] + [XmlInclude(typeof(AddToVariableCommand))] + [XmlInclude(typeof(SetVariableIndexCommand))] public abstract class ScriptCommand { [XmlAttribute] diff --git a/taskt/Core/Automation/Commands/SetVariableIndexCommand.cs b/taskt/Core/Automation/Commands/SetVariableIndexCommand.cs new file mode 100644 index 000000000..f4c090c85 --- /dev/null +++ b/taskt/Core/Automation/Commands/SetVariableIndexCommand.cs @@ -0,0 +1,109 @@ +using System; +using System.Linq; +using System.Xml.Serialization; +using System.Data; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Drawing; +using taskt.UI.CustomControls; +namespace taskt.Core.Automation.Commands +{ + [Serializable] + [Attributes.ClassAttributes.Group("Engine Commands")] + [Attributes.ClassAttributes.Description("This command allows you to modify variables.")] + [Attributes.ClassAttributes.UsesDescription("Use this command when you want to modify the value of variables. You can even use variables to modify other variables.")] + [Attributes.ClassAttributes.ImplementationDescription("This command implements actions against VariableList from the scripting engine.")] + public class SetVariableIndexCommand : ScriptCommand + { + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please select a variable to modify")] + [Attributes.PropertyAttributes.InputSpecification("Select or provide a variable from the variable list")] + [Attributes.PropertyAttributes.SampleUsage("**vSomeVariable**")] + [Attributes.PropertyAttributes.Remarks("If you have enabled the setting **Create Missing Variables at Runtime** then you are not required to pre-define your variables, however, it is highly recommended.")] + public string v_userVariableName { get; set; } + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please set the current index of the variable")] + [Attributes.PropertyAttributes.PropertyUIHelper(Attributes.PropertyAttributes.PropertyUIHelper.UIAdditionalHelperType.ShowVariableHelper)] + [Attributes.PropertyAttributes.InputSpecification("Enter the input that the variable's index should be set to.")] + [Attributes.PropertyAttributes.SampleUsage("1, 2, etc.")] + [Attributes.PropertyAttributes.Remarks("You can use variables in input if you encase them within brackets {vName}. You can also perform basic math operations.")] + public string v_Index { get; set; } + public SetVariableIndexCommand() + { + this.CommandName = "SetVariableIndexCommand"; + this.SelectionName = "Set Variable Index"; + this.CommandEnabled = true; + this.CustomRendering = true; + } + + public override void RunCommand(object sender) + { + //get sending instance + var engine = (Core.Automation.Engine.AutomationEngineInstance)sender; + + var requiredVariable = LookupVariable(engine); + + //if still not found and user has elected option, create variable at runtime + if ((requiredVariable == null) && (engine.engineSettings.CreateMissingVariablesDuringExecution)) + { + engine.VariableList.Add(new Script.ScriptVariable() { VariableName = v_userVariableName }); + requiredVariable = LookupVariable(engine); + } + + if (requiredVariable != null) + { + + var index = int.Parse(v_Index.ConvertToUserVariable(sender)); + + requiredVariable.CurrentPosition = index; + + } + else + { + throw new Exception("Attempted to update variable index, but variable was not found. Enclose variables within brackets, ex. {vVariable}"); + } + } + + private Script.ScriptVariable LookupVariable(Core.Automation.Engine.AutomationEngineInstance sendingInstance) + { + //search for the variable + var requiredVariable = sendingInstance.VariableList.Where(var => var.VariableName == v_userVariableName).FirstOrDefault(); + + //if variable was not found but it starts with variable naming pattern + if ((requiredVariable == null) && (v_userVariableName.StartsWith(sendingInstance.engineSettings.VariableStartMarker)) && (v_userVariableName.EndsWith(sendingInstance.engineSettings.VariableEndMarker))) + { + //reformat and attempt + var reformattedVariable = v_userVariableName.Replace(sendingInstance.engineSettings.VariableStartMarker, "").Replace(sendingInstance.engineSettings.VariableEndMarker, ""); + requiredVariable = sendingInstance.VariableList.Where(var => var.VariableName == reformattedVariable).FirstOrDefault(); + } + + return requiredVariable; + } + + public override string GetDisplayValue() + { + return base.GetDisplayValue() + " [Update Variable '" + v_userVariableName + "' index to '" + v_Index + "']"; + } + + public override List Render(UI.Forms.frmCommandEditor editor) + { + //custom rendering + base.Render(editor); + + + //create control for variable name + RenderedControls.Add(CommandControls.CreateDefaultLabelFor("v_userVariableName", this)); + var VariableNameControl = CommandControls.CreateStandardComboboxFor("v_userVariableName", this).AddVariableNames(editor); + RenderedControls.AddRange(CommandControls.CreateUIHelpersFor("v_userVariableName", this, new Control[] { VariableNameControl }, editor)); + RenderedControls.Add(VariableNameControl); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_Index", this, editor)); + + + + return RenderedControls; + + + } + } +} \ No newline at end of file diff --git a/taskt/UI/CustomControls/CustomControls.cs b/taskt/UI/CustomControls/CustomControls.cs index 05c3873c7..20065f7bb 100644 --- a/taskt/UI/CustomControls/CustomControls.cs +++ b/taskt/UI/CustomControls/CustomControls.cs @@ -431,6 +431,8 @@ public static Dictionary UIImageDictionary() uiImages.Add("StopProcessCommand", taskt.Properties.Resources.command_stop_process); uiImages.Add("StartProcessCommand", taskt.Properties.Resources.command_start_process); uiImages.Add("VariableCommand", taskt.Properties.Resources.command_function); + uiImages.Add("AddToVariableCommand", taskt.Properties.Resources.command_function); + uiImages.Add("SetVariableIndexCommand", taskt.Properties.Resources.command_function); uiImages.Add("AddVariableCommand", taskt.Properties.Resources.command_function); uiImages.Add("FormatDataCommand", taskt.Properties.Resources.command_function); uiImages.Add("ModifyVariableCommand", taskt.Properties.Resources.command_function); diff --git a/taskt/taskt.csproj b/taskt/taskt.csproj index 0adcef7a6..e8ef7f91e 100644 --- a/taskt/taskt.csproj +++ b/taskt/taskt.csproj @@ -202,6 +202,8 @@ + + From 826b91b456d32737db6f4e88e51fb9e4f29fea6d Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 5 Jun 2019 00:41:36 -0400 Subject: [PATCH 29/38] Moved Variable Commands to their own category --- taskt/Core/Automation/Commands/AddToVariableCommand.cs | 2 +- taskt/Core/Automation/Commands/AddVariableCommand.cs | 2 +- taskt/Core/Automation/Commands/SetVariableIndexCommand.cs | 2 +- taskt/Core/Automation/Commands/VariableCommand.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/taskt/Core/Automation/Commands/AddToVariableCommand.cs b/taskt/Core/Automation/Commands/AddToVariableCommand.cs index 3c50e1f51..bd1fb0eb3 100644 --- a/taskt/Core/Automation/Commands/AddToVariableCommand.cs +++ b/taskt/Core/Automation/Commands/AddToVariableCommand.cs @@ -9,7 +9,7 @@ namespace taskt.Core.Automation.Commands { [Serializable] - [Attributes.ClassAttributes.Group("Engine Commands")] + [Attributes.ClassAttributes.Group("Variable Commands")] [Attributes.ClassAttributes.Description("This command allows you to modify variables.")] [Attributes.ClassAttributes.UsesDescription("Use this command when you want to modify the value of variables. You can even use variables to modify other variables.")] [Attributes.ClassAttributes.ImplementationDescription("This command implements actions against VariableList from the scripting engine.")] diff --git a/taskt/Core/Automation/Commands/AddVariableCommand.cs b/taskt/Core/Automation/Commands/AddVariableCommand.cs index 1593546b0..db49fd773 100644 --- a/taskt/Core/Automation/Commands/AddVariableCommand.cs +++ b/taskt/Core/Automation/Commands/AddVariableCommand.cs @@ -11,7 +11,7 @@ namespace taskt.Core.Automation.Commands [Serializable] - [Attributes.ClassAttributes.Group("Engine Commands")] + [Attributes.ClassAttributes.Group("Variable Commands")] [Attributes.ClassAttributes.Description("This command allows you to explicitly add a variable if you are not using **Set Variable* with the setting **Create Missing Variables** at runtime.")] [Attributes.ClassAttributes.UsesDescription("Use this command when you want to modify the value of variables. You can even use variables to modify other variables.")] [Attributes.ClassAttributes.ImplementationDescription("This command implements actions against VariableList from the scripting engine.")] diff --git a/taskt/Core/Automation/Commands/SetVariableIndexCommand.cs b/taskt/Core/Automation/Commands/SetVariableIndexCommand.cs index f4c090c85..b5754204f 100644 --- a/taskt/Core/Automation/Commands/SetVariableIndexCommand.cs +++ b/taskt/Core/Automation/Commands/SetVariableIndexCommand.cs @@ -9,7 +9,7 @@ namespace taskt.Core.Automation.Commands { [Serializable] - [Attributes.ClassAttributes.Group("Engine Commands")] + [Attributes.ClassAttributes.Group("Variable Commands")] [Attributes.ClassAttributes.Description("This command allows you to modify variables.")] [Attributes.ClassAttributes.UsesDescription("Use this command when you want to modify the value of variables. You can even use variables to modify other variables.")] [Attributes.ClassAttributes.ImplementationDescription("This command implements actions against VariableList from the scripting engine.")] diff --git a/taskt/Core/Automation/Commands/VariableCommand.cs b/taskt/Core/Automation/Commands/VariableCommand.cs index f4b0ffb32..538574b25 100644 --- a/taskt/Core/Automation/Commands/VariableCommand.cs +++ b/taskt/Core/Automation/Commands/VariableCommand.cs @@ -9,7 +9,7 @@ namespace taskt.Core.Automation.Commands { [Serializable] - [Attributes.ClassAttributes.Group("Engine Commands")] + [Attributes.ClassAttributes.Group("Variable Commands")] [Attributes.ClassAttributes.Description("This command allows you to modify variables.")] [Attributes.ClassAttributes.UsesDescription("Use this command when you want to modify the value of variables. You can even use variables to modify other variables.")] [Attributes.ClassAttributes.ImplementationDescription("This command implements actions against VariableList from the scripting engine.")] From 20e700d75ef20944bf157ba158608d71a1fbaef5 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 5 Jun 2019 00:47:26 -0400 Subject: [PATCH 30/38] Command Name Verbiage Update --- taskt/Core/Automation/Commands/AddVariableCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/taskt/Core/Automation/Commands/AddVariableCommand.cs b/taskt/Core/Automation/Commands/AddVariableCommand.cs index db49fd773..54a543875 100644 --- a/taskt/Core/Automation/Commands/AddVariableCommand.cs +++ b/taskt/Core/Automation/Commands/AddVariableCommand.cs @@ -41,7 +41,7 @@ public class AddVariableCommand : ScriptCommand public AddVariableCommand() { this.CommandName = "AddVariableCommand"; - this.SelectionName = "Add Variable"; + this.SelectionName = "New Variable"; this.CommandEnabled = true; this.CustomRendering = true; } From 720510f88b20f4e7e868a5e265c14c03903d52c6 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 5 Jun 2019 00:47:38 -0400 Subject: [PATCH 31/38] Variable Manipulation Sample File --- .../Variable Manipulation [3.0.0.0].xml | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 taskt/Sample Scripts/3.x Use Case Samples/Variable Manipulation [3.0.0.0].xml diff --git a/taskt/Sample Scripts/3.x Use Case Samples/Variable Manipulation [3.0.0.0].xml b/taskt/Sample Scripts/3.x Use Case Samples/Variable Manipulation [3.0.0.0].xml new file mode 100644 index 000000000..0956e256f --- /dev/null +++ b/taskt/Sample Scripts/3.x Use Case Samples/Variable Manipulation [3.0.0.0].xml @@ -0,0 +1,202 @@ + + \ No newline at end of file From 2091b861fb1aa08694f3236053ed5a85ea721275 Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Wed, 5 Jun 2019 16:20:24 +0200 Subject: [PATCH 32/38] Added editable arguments to Selenium ChromeDriver options --- .../Commands/SeleniumBrowserCreateCommand.cs | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs index afa71788c..16eaa8f71 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs @@ -40,6 +40,13 @@ public class SeleniumBrowserCreateCommand : ScriptCommand [Attributes.PropertyAttributes.Remarks("")] public string v_BrowserWindowOption { get; set; } + [XmlAttribute] + [Attributes.PropertyAttributes.PropertyDescription("Please specify Selenium command line options (optional)")] + [Attributes.PropertyAttributes.InputSpecification("Select optional options to be passed to the Selenium command.")] + [Attributes.PropertyAttributes.SampleUsage("user-data-dir=/user/public/SeleniumTasktProfile")] + [Attributes.PropertyAttributes.Remarks("")] + public string v_SeleniumOptions { get; set; } + [XmlAttribute] [Attributes.PropertyAttributes.PropertyDescription("Please Select a Browser Engine Type")] [Attributes.PropertyAttributes.PropertyUISelectionOption("Chrome")] @@ -71,13 +78,20 @@ public override void RunCommand(object sender) if (seleniumEngine == "Chrome") { + OpenQA.Selenium.Chrome.ChromeOptions options = new OpenQA.Selenium.Chrome.ChromeOptions(); + + if (!string.IsNullOrEmpty(v_SeleniumOptions)) + { + options.AddArguments(v_SeleniumOptions); + } + driverService = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(driverPath); - webDriver = new OpenQA.Selenium.Chrome.ChromeDriver((OpenQA.Selenium.Chrome.ChromeDriverService)driverService, new OpenQA.Selenium.Chrome.ChromeOptions()); + webDriver = new OpenQA.Selenium.Chrome.ChromeDriver((OpenQA.Selenium.Chrome.ChromeDriverService)driverService, options); } else { driverService = OpenQA.Selenium.IE.InternetExplorerDriverService.CreateDefaultService(driverPath); - webDriver = new OpenQA.Selenium.IE.InternetExplorerDriver((OpenQA.Selenium.IE.InternetExplorerDriverService)driverService, new OpenQA.Selenium.IE.InternetExplorerOptions()); + webDriver = new OpenQA.Selenium.IE.InternetExplorerDriver((OpenQA.Selenium.IE.InternetExplorerDriverService)driverService, new OpenQA.Selenium.IE.InternetExplorerOptions()); } @@ -110,13 +124,14 @@ public override void RunCommand(object sender) } public override List Render(frmCommandEditor editor) { - base.Render(editor); - - + base.Render(editor); + + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_InstanceName", this, editor)); RenderedControls.AddRange(CommandControls.CreateDefaultDropdownGroupFor("v_EngineType", this, editor)); RenderedControls.AddRange(CommandControls.CreateDefaultDropdownGroupFor("v_InstanceTracking", this, editor)); RenderedControls.AddRange(CommandControls.CreateDefaultDropdownGroupFor("v_BrowserWindowOption", this, editor)); + RenderedControls.AddRange(CommandControls.CreateDefaultInputGroupFor("v_SeleniumOptions", this, editor)); return RenderedControls; } From daa577c1b144d4b8f6aed9ad58927554bc0e901c Mon Sep 17 00:00:00 2001 From: VirtualFab <49951329+VirtualFab@users.noreply.github.com> Date: Tue, 11 Jun 2019 14:20:37 +0200 Subject: [PATCH 33/38] Fixed a regression in system variables --- .../SeleniumBrowserElementActionCommand.cs | 36 ++++++++++--------- taskt/Core/ExtensionMethods.cs | 7 ++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs index 35ec34931..407d24d97 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserElementActionCommand.cs @@ -99,7 +99,7 @@ public SeleniumBrowserElementActionCommand() this.v_WebActionParameterTable = new System.Data.DataTable { - TableName = DateTime.Now.ToString("WebActionParamTable" + DateTime.Now.ToString("MMddyy.hhmmss")) + TableName = "WebActionParamTable" + DateTime.Now.ToString("MMddyy.hhmmss") }; this.v_WebActionParameterTable.Columns.Add("Parameter Name"); this.v_WebActionParameterTable.Columns.Add("Parameter Value"); @@ -112,6 +112,7 @@ public SeleniumBrowserElementActionCommand() ElementsGridViewHelper.DataBindings.Add("DataSource", this, "v_WebActionParameterTable", false, DataSourceUpdateMode.OnPropertyChanged); ElementsGridViewHelper.AllowUserToAddRows = false; ElementsGridViewHelper.AllowUserToDeleteRows = false; + ElementsGridViewHelper.AllowUserToResizeRows = false; //ElementsGridViewHelper.MouseEnter += ElementsGridViewHelper_MouseEnter; } @@ -312,7 +313,8 @@ where rw.Field("Parameter Name") == "Variable Name" jsonList.Add(json); } - requiredComplexVariable.VariableValue = jsonList; + requiredComplexVariable.VariableValue = jsonList; + requiredComplexVariable.CurrentPosition = 0; break; case "Clear Element": @@ -428,7 +430,7 @@ public override List Render(frmCommandEditor editor) ElementActionDropdown = (ComboBox)CommandControls.CreateDropdownFor("v_SeleniumElementAction", this); RenderedControls.Add(CommandControls.CreateDefaultLabelFor("v_SeleniumElementAction", this)); RenderedControls.AddRange(CommandControls.CreateUIHelpersFor("v_SeleniumElementAction", this, new Control[] { ElementActionDropdown }, editor)); - ElementActionDropdown.SelectionChangeCommitted += seleniumAction_SelectionChangeCommitted; + ElementActionDropdown.SelectionChangeCommitted += seleniumAction_SelectionChangeCommitted; RenderedControls.Add(ElementActionDropdown); @@ -439,7 +441,7 @@ public override List Render(frmCommandEditor editor) RenderedControls.AddRange(ElementParameterControls); - return RenderedControls; + return RenderedControls; } //public override void Refresh(UI.Forms.frmCommandEditor editor) @@ -460,17 +462,17 @@ public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) switch (ElementActionDropdown.SelectedItem) - { + { case "Invoke Click": case "Clear Element": - + foreach (var ctrl in ElementParameterControls) { - //ctrl.Hide(); + ctrl.Hide(); } - + break; - + case "Left Click": case "Middle Click": case "Right Click": @@ -485,7 +487,7 @@ public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) actionParameters.Rows.Add("Y Adjustment", 0); } break; - + case "Set Text": foreach (var ctrl in ElementParameterControls) { @@ -496,21 +498,21 @@ public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) actionParameters.Rows.Add("Text To Set"); actionParameters.Rows.Add("Clear Element Before Setting Text"); } - + DataGridViewComboBoxCell comparisonComboBox = new DataGridViewComboBoxCell(); comparisonComboBox.Items.Add("Yes"); comparisonComboBox.Items.Add("No"); - + //assign cell as a combobox if (sender != null) { ElementsGridViewHelper.Rows[1].Cells[1].Value = "No"; } ElementsGridViewHelper.Rows[1].Cells[1] = comparisonComboBox; - - + + break; - + case "Get Text": case "Get Matching Elements": foreach (var ctrl in ElementParameterControls) @@ -522,7 +524,7 @@ public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) actionParameters.Rows.Add("Variable Name"); } break; - + case "Get Attribute": foreach (var ctrl in ElementParameterControls) { @@ -534,7 +536,7 @@ public void seleniumAction_SelectionChangeCommitted(object sender, EventArgs e) actionParameters.Rows.Add("Variable Name"); } break; - + case "Wait For Element To Exist": foreach (var ctrl in ElementParameterControls) { diff --git a/taskt/Core/ExtensionMethods.cs b/taskt/Core/ExtensionMethods.cs index 876c39e71..ab1be013c 100644 --- a/taskt/Core/ExtensionMethods.cs +++ b/taskt/Core/ExtensionMethods.cs @@ -113,7 +113,8 @@ public static string ConvertToUserVariable(this String str, object sender) } } - string varcheckname = potentialVariable; + string varcheckname = potentialVariable; + bool isSystemVar = systemVariables.Any(vars => vars.VariableName == varcheckname); string[] aPotentialVariable = potentialVariable.Split(new string[] { "[", "]" }, StringSplitOptions.None); int directElementIndex = 0; bool useDirectElementIndex = false; @@ -122,7 +123,7 @@ public static string ConvertToUserVariable(this String str, object sender) varcheckname = aPotentialVariable[0]; useDirectElementIndex = true; } - else if (potentialVariable.Split('.').Length==2) + else if (potentialVariable.Split('.').Length == 2 && !isSystemVar) { varcheckname = potentialVariable.Split('.')[0]; } @@ -163,7 +164,7 @@ public static string ConvertToUserVariable(this String str, object sender) str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue()); varCheck.CurrentPosition = savePosition; } - else if (potentialVariable.Split('.').Length==2) // This handles vVariable.count + else if (potentialVariable.Split('.').Length == 2) // This handles vVariable.count { string propertyName = potentialVariable.Split('.')[1]; str = str.Replace(searchVariable, (string)varCheck.GetDisplayValue(propertyName)); From 6a0ba15d07c0621eb59b8e7f7a9c2a93934e6d27 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Fri, 14 Jun 2019 02:02:22 -0400 Subject: [PATCH 34/38] Added Variable Conversion to Browser Create --- taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs b/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs index 16eaa8f71..45c769848 100644 --- a/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs +++ b/taskt/Core/Automation/Commands/SeleniumBrowserCreateCommand.cs @@ -82,7 +82,8 @@ public override void RunCommand(object sender) if (!string.IsNullOrEmpty(v_SeleniumOptions)) { - options.AddArguments(v_SeleniumOptions); + var convertedOptions = v_SeleniumOptions.ConvertToUserVariable(sender); + options.AddArguments(convertedOptions); } driverService = OpenQA.Selenium.Chrome.ChromeDriverService.CreateDefaultService(driverPath); From dbbc3e5d55a7fbdcaa7ce03818f26243f227c5aa Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Sat, 15 Jun 2019 01:20:12 -0400 Subject: [PATCH 35/38] Added additional handling for updating parameter box https://github.com/saucepleez/taskt/issues/127 --- .../Core/Automation/Commands/UIAutomationCommand.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/taskt/Core/Automation/Commands/UIAutomationCommand.cs b/taskt/Core/Automation/Commands/UIAutomationCommand.cs index 237e34957..be9c8dc3f 100644 --- a/taskt/Core/Automation/Commands/UIAutomationCommand.cs +++ b/taskt/Core/Automation/Commands/UIAutomationCommand.cs @@ -517,15 +517,22 @@ public void UIAType_SelectionChangeCommitted(object sender, EventArgs e) parameterName.Items.Add("NativeWindowHandle"); parameterName.Items.Add("ProcessID"); - if (sender != null) { actionParameters.Rows.Add("Get Value From", ""); actionParameters.Rows.Add("Apply To Variable", ""); + actionParameterView.Refresh(); + try + { + actionParameterView.Rows[0].Cells[1] = parameterName; + } + catch (Exception ex) + { + MessageBox.Show("Unable to select first row, second cell to apply '" + parameterName + "': " + ex.ToString()); + } + } - actionParameterView.Refresh(); - actionParameterView.Rows[0].Cells[1] = parameterName; break; } From 77f1ed29f8e23a06b78a98b490a381507aaba5c3 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Mon, 17 Jun 2019 23:00:55 -0400 Subject: [PATCH 36/38] Downgraded AxRDPClient for Windows 7 Compatibility https://github.com/saucepleez/taskt/issues/129 --- .../frmRemoteDesktopViewer.Designer.cs | 34 +++++++++---------- .../frmRemoteDesktopViewer.cs | 8 ++--- .../frmRemoteDesktopViewer.resx | 6 ++-- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.Designer.cs b/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.Designer.cs index 0120fec75..008dad21b 100644 --- a/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.Designer.cs +++ b/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.Designer.cs @@ -30,26 +30,14 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmRemoteDesktopViewer)); - this.axRDP = new AxMSTSCLib.AxMsRdpClient9NotSafeForScripting(); this.pnlCover = new System.Windows.Forms.Panel(); this.lblLogo = new System.Windows.Forms.Label(); this.tmrLoginFailure = new System.Windows.Forms.Timer(this.components); - ((System.ComponentModel.ISupportInitialize)(this.axRDP)).BeginInit(); + this.axRDP = new AxMSTSCLib.AxMsRdpClient6NotSafeForScripting(); this.pnlCover.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.axRDP)).BeginInit(); this.SuspendLayout(); // - // axRDP - // - this.axRDP.Dock = System.Windows.Forms.DockStyle.Fill; - this.axRDP.Enabled = true; - this.axRDP.Location = new System.Drawing.Point(0, 0); - this.axRDP.Name = "axRDP"; - this.axRDP.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axRDP.OcxState"))); - this.axRDP.Size = new System.Drawing.Size(1904, 1041); - this.axRDP.TabIndex = 0; - this.axRDP.OnLoginComplete += new System.EventHandler(this.axRDP_OnLoginComplete); - this.axRDP.OnDisconnected += new AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEventHandler(this.axRDP_OnDisconnected); - // // pnlCover // this.pnlCover.BackColor = System.Drawing.Color.DimGray; @@ -62,8 +50,8 @@ private void InitializeComponent() // // lblLogo // - this.lblLogo.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.lblLogo.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.lblLogo.AutoSize = true; this.lblLogo.Font = new System.Drawing.Font("Segoe UI", 48F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); @@ -79,6 +67,16 @@ private void InitializeComponent() this.tmrLoginFailure.Interval = 15000; this.tmrLoginFailure.Tick += new System.EventHandler(this.tmrLoginFailure_Tick); // + // axRDP + // + this.axRDP.Dock = System.Windows.Forms.DockStyle.Fill; + this.axRDP.Enabled = true; + this.axRDP.Location = new System.Drawing.Point(0, 0); + this.axRDP.Name = "axRDP"; + this.axRDP.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axRDP.OcxState"))); + this.axRDP.Size = new System.Drawing.Size(1904, 1041); + this.axRDP.TabIndex = 2; + // // frmRemoteDesktopViewer // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -90,9 +88,9 @@ private void InitializeComponent() this.Name = "frmRemoteDesktopViewer"; this.Text = "Remote Desktop"; this.Load += new System.EventHandler(this.frmRemoteDesktopViewer_Load); - ((System.ComponentModel.ISupportInitialize)(this.axRDP)).EndInit(); this.pnlCover.ResumeLayout(false); this.pnlCover.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.axRDP)).EndInit(); this.ResumeLayout(false); } @@ -100,7 +98,7 @@ private void InitializeComponent() #endregion private System.Windows.Forms.Panel pnlCover; private System.Windows.Forms.Label lblLogo; - public AxMSTSCLib.AxMsRdpClient9NotSafeForScripting axRDP; private System.Windows.Forms.Timer tmrLoginFailure; + private AxMSTSCLib.AxMsRdpClient6NotSafeForScripting axRDP; } } \ No newline at end of file diff --git a/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.cs b/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.cs index f2717f4c7..e93eb81a4 100644 --- a/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.cs +++ b/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.cs @@ -35,12 +35,12 @@ public frmRemoteDesktopViewer(string machineName, string userName, string passwo //declare credentials axRDP.Server = machineName; axRDP.UserName = userName; - axRDP.AdvancedSettings8.ClearTextPassword = password; + axRDP.AdvancedSettings7.ClearTextPassword = password; //defaults to false - axRDP.AdvancedSettings8.RedirectDrives = false; - axRDP.AdvancedSettings8.RedirectPrinters = false; - axRDP.AdvancedSettings8.RedirectClipboard = false; + axRDP.AdvancedSettings7.RedirectDrives = false; + axRDP.AdvancedSettings7.RedirectPrinters = false; + axRDP.AdvancedSettings7.RedirectClipboard = false; //initiate connection axRDP.Connect(); diff --git a/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.resx b/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.resx index e95b4fa3e..ccf74a4c0 100644 --- a/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.resx +++ b/taskt/UI/Forms/Supplement Forms/frmRemoteDesktopViewer.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w @@ -125,9 +128,6 @@ AAAAAQAAAAAAAAAAAAAAABQAAAAACAAACAACAAAAAAALAAAACwAAAAs= - - 17, 17 - From c4ae87e7eb2a6fdd82ae1160bec4bc27ec062478 Mon Sep 17 00:00:00 2001 From: Jason Bayldon Date: Wed, 19 Jun 2019 16:40:34 -0400 Subject: [PATCH 37/38] Update to .NET Framework 4.6.1 --- taskt/App.config | 10 +++++----- taskt/taskt.csproj | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/taskt/App.config b/taskt/App.config index baec66804..45e00fea1 100644 --- a/taskt/App.config +++ b/taskt/App.config @@ -1,4 +1,4 @@ - +