Beispiel #1
0
		public static string GetTextResource(FileResource file, string extendableResourceName = "") {

			if(!isSet) {
				
				Set();

			}

			if(!knownTrilleonResourceFiles.FindAll(x => x.Key == file).Any()) {
				
				AutoConsole.PostMessage("The supplied file is not an expected Trilleon resource. Make sure you are referencing a file declared in the FileBroker.cs Set() logic."); //No usage of string.Format with file name data. Using Enum.GetName here causes exceptions on compile "Recursive Serialization is not supported. You can't dereference a PPtr while loading.".
                return string.Empty;

			}

			TextAsset txt = (TextAsset)Resources.Load(knownTrilleonResourceFiles.Find(x => x.Key == file && (file == FileResource.ExtendableResource ? x.Value == extendableResourceName : true)).Value, typeof(TextAsset));

			if(txt != null) {
				
				return txt.text;

			}

			return string.Empty;

		}
Beispiel #2
0
		/// <summary>
		/// Returns the text resource by the resource enumeration name, or by the provided string name if it is an extendable resource.
		/// </summary>
		public static string GetNonUnityTextResource(FileResource file, string extendableResourceName = "") {

			if(!isSet) {
				Set();
			}

			if(!knownEditorResourceFiles.FindAll(x => x.Key == file && (file == FileResource.ExtendableResource ? x.Value == extendableResourceName : true)).Any()) {
				
                AutoConsole.PostMessage("The supplied file is not an expected Trilleon resource. Make sure you are referencing a file declared in the FileBroker.cs Set() logic."); //No usage of string.Format with file name data. Using Enum.GetName here causes exceptions on compile "Recursive Serialization is not supported. You can't dereference a PPtr while loading.".
                return string.Empty;

            }

			string directory = string.Format("{0}{1}{2}", RESOURCES_DIRECTORY, FILE_PATH_SPLIT, knownEditorResourceFiles.Find(x => x.Key == file).Value);
			string fileText = string.Empty;
			if(!Exists(directory)) {

				Set();

			} 
			fileText = File.ReadAllText(directory);

			return fileText;

		}
Beispiel #3
0
        public IEnumerator SendRequest(string endpoint, RequestType requestType, List <KeyValuePair <string, string> > args, List <KeyValuePair <string, string> > headers)
        {
            WWWForm form = new WWWForm();

            for (int x = 0; x < args.Count; x++)
            {
                form.AddField(args[x].Key, args[x].Value);
            }

            Dictionary <string, string> _headers = form.headers;

            for (int x = 0; x < headers.Count; x++)
            {
                _headers[headers[x].Key] = headers[x].Value;
            }

            string url = Endpoints.Find(x => x.Key == endpoint).Value;
            WWW    www = new WWW(url, form.data, _headers);

            yield return(www);

            string message = string.Empty;

            if (www.error == null)
            {
                message = string.Format("API Call Success: {0}", url);
            }
            else
            {
                message = string.Format("API Call Failure: {0} Message: {1}", url, www.error);
                yield return(StartCoroutine(Q.assert.Fail(message)));
            }
            AutoConsole.PostMessage(message);
            yield return(null);
        }
Beispiel #4
0
		public static void SaveTextResource(FileResource file, string value) {

			if(!isSet) {
				
				Set();

			}

			#if UNITY_EDITOR

			if(!knownTrilleonResourceFiles.FindAll(x => x.Key == file).Any()) {
				
				AutoConsole.PostMessage("The supplied file could not be found. Make sure you are referencing a file stored outside of the Unity project."); //No usage of string.Format with file name data. Using Enum.GetName here causes exceptions on compile "Recursive Serialization is not supported. You can't dereference a PPtr while loading.".
                return;
                 
			}

			string filePath = string.Format("{0}{1}{2}.txt", Application.dataPath.Replace("/", FILE_PATH_SPLIT), AutomationMaster.ConfigReader.GetString("UNITY_RESOURCES_FILE_PATH").Replace("/", FILE_PATH_SPLIT), knownTrilleonResourceFiles.Find(x => x.Key == file).Value);
			File.WriteAllText(filePath, value);

			AssetDatabase.Refresh();
			if(file == FileResource.TrilleonConfig) {

				AutomationMaster.ConfigReader.Refresh();

			}

			#endif

		}
Beispiel #5
0
        void SendCommunicationActual(List <KeyValuePair <string, string> > parameters)
        {
            //Generally no need to communicate with a server if we are in the Editor. Else, just comment out.
            if (!Application.isEditor || AutomationMaster.ConfigReader.GetBool("SEND_COMMUNICATIONS_IN_EDITOR"))
            {
                StringBuilder json = new StringBuilder();
                json.Append("[");

                //--Required Identifiers--
                json.Append(string.Format("{{\"grid_identity\":\"{0}\"}},", GridIdentity));
                json.Append(string.Format("{{\"grid_identity_buddy\":\"{0}\"}},", BuddyHandler.BuddyName));
                json.Append("{{\"grid_source\":\"client\"}},");
                json.Append(string.Format("{{\"test_run_id\":\"{0}\"}},", TestRunId));
                json.Append(string.Format("{{\"device_udid\":\"{0}\"}},", DeviceUdid));
                json.Append(string.Format("{{\"test_run_time\":\"{0}\"}},", AutomationMaster.Busy ? AutomationReport.TestSuiteRunTime.ToString() : "0 "));
                json.Append(string.Format("{{\"game\":\"{0}\"}},", GameMaster.GAME_NAME));
                //--End Required Params--

                for (int x = 0; x < parameters.Count; x++)
                {
                    json.Append(string.Format("{{\"{0}\":\"{1}\"}}", parameters[x].Key.ToLower(), parameters[x].Value.Replace("\"", "@APOS@").Replace("'", "@QUOT@")));
                    if (x + 1 < parameters.Count)
                    {
                        json.Append(",");
                    }
                }
                json.Append("]");
                ConnectionStrategy.SendCommunication(json.ToString());
                AutoConsole.PostMessage(json.ToString(), ConsoleMessageType.Pubsub);
            }
        }
Beispiel #6
0
        public static void SendJsonInPieces(string jsonAttributePrefix, string json)
        {
            //Break this message into pieces.
            List <string> pieces  = new List <string>();
            int           charPos = 0;

            while (charPos < json.Length)
            {
                if (charPos + ConnectionStrategy.MaxMessageLength <= json.Length)
                {
                    pieces.Add(json.Substring(charPos, ConnectionStrategy.MaxMessageLength));
                    charPos += ConnectionStrategy.MaxMessageLength;
                }
                else
                {
                    pieces.Add(json.Substring(charPos, json.Length - charPos - 1));
                    break;
                }
            }

            for (int x = 0; x < pieces.Count; x++)
            {
                AutoConsole.PostMessage(string.Format("{0}_MULTI_PART|{1}{2}{3}|", jsonAttributePrefix, x, AutomationMaster.PARTIAL_DELIMITER, pieces[x]), MessageLevel.Abridged);
            }
        }
Beispiel #7
0
        /// <summary>
        /// Grant current account all requested values.
        /// </summary>
        /// <param name="grant">Grant.</param>
        public IEnumerator GrantPlayer(Grant grant)
        {
            for (int i = 0; i < ALL_FIELDS.Length; i++)
            {
                switch (ALL_FIELDS[i])
                {
                case "Gold":
                    if (grant.Gold >= 0)
                    {
                        AutoConsole.PostMessage(string.Format("Granting Gold: {0}", grant.Gold));
                        yield return(StartCoroutine(Grant("GRANT GOLD", grant.Gold)));

                        yield return(StartCoroutine(Q.driver.WaitRealTime(4)));
                    }
                    break;

                case "Silver":
                    if (grant.Silver >= 0)
                    {
                        AutoConsole.PostMessage(string.Format("Granting Silver: {0}", grant.Silver));
                        yield return(StartCoroutine(Grant("GRANT SILVER", grant.Silver)));

                        yield return(StartCoroutine(Q.driver.WaitRealTime(4)));
                    }
                    break;

                default:
                    throw new UnityException("Grant Command not recognized.");
                }
            }
        }
Beispiel #8
0
 public void Add(string test)
 {
     if (!_tests.Contains(test))
     {
         Tests.Add(test);
         string message = string.Format("[{0}] {1}", test, "#Ignore#");
         AutoConsole.PostMessage(message);
     }
 }
        static string ResetTestRailsTestStatuses(List <string> args)
        {
            if (args.First().ToInt() > 0)
            {
                TestRailsAPIClient client = new TestRailsAPIClient(GameMaster.BASE_TEST_RAILS_URL);
                if (client == null)
                {
                    string message = "COULD NOT RESET RAILS! New API Client could not be instantiated.";
                    AutoConsole.PostMessage(message, MessageLevel.Abridged);
                    return(message);
                }
                string               json        = client.SendGet(string.Format("get_tests/{0}", args.First()));
                System.Object        jsonObj     = Json.Deserialize(json);
                List <System.Object> list        = (List <System.Object>)jsonObj;
                StringBuilder        jsonUpdates = new StringBuilder();
                jsonUpdates.Append("{\"results\": [");

                for (int i = 0; i < list.Count; i++)
                {
                    Dictionary <string, object> item = (Dictionary <string, object>)list[i];
                    int id       = item["id"].ToString().ToInt();
                    int statusId = item["status_id"].ToString().ToInt();

                    //If test is not marked as Blocked.
                    if (statusId != 2)
                    {
                        jsonUpdates.AppendLine("{");
                        jsonUpdates.Append(string.Format("\"test_id\":{0},", id));
                        jsonUpdates.Append("\"status_id\":4,");
                        jsonUpdates.Append("\"comment\":\"Resetting test for next run.\"");
                        jsonUpdates.Append("}");
                        if (i + 1 < list.Count)
                        {
                            jsonUpdates.Append(",");
                        }
                    }
                }

                jsonUpdates.Append("]");
                jsonUpdates.Append("}");
                string jsonFinal = jsonUpdates.ToString().Replace("},]", "}]");
                client.SendPost(string.Format("add_results/{0}", args.First()), jsonFinal);

                return("Test statuses set to Untested. Please check the test run in your browser to confirm.");
            }
            else
            {
                return("The provided TestRails TestRunID must be a valid integer.");
            }
        }
Beispiel #10
0
        //Report test results to TestRails.
        private static void SendResultForAllCasesToTestRails(string status, int testRunId, List <int> testCaseIds)
        {
            StringBuilder json = new StringBuilder();

            json.Append("{\"results\": [");
            int idStatus = TEST_RAILS_STATUSES[status];

            for (int x = 0; x < testCaseIds.Count; x++)
            {
                string comment       = string.Empty;
                string deviceDetails = AutomationMaster.GameMaster.GetDeviceDetails();
                if (status == FAILED_NAME)
                {
                    comment = string.Format("FROM TEST METHOD - {0} - FAILED! Details: {1} [{2}]", AutomationMaster.CurrentTestContext.TestName, AutomationMaster.CurrentTestContext.ErrorDetails, deviceDetails);
                }
                else
                {
                    comment = string.Format("FROM TEST METHOD - {0} - {1} [{2}]", AutomationMaster.CurrentTestContext.TestName, status.ToUpper(), deviceDetails);
                }
                json.AppendLine("{");
                json.Append(string.Format("\"test_id\":{0},", testCaseIds[x]));
                json.Append(string.Format("\"status_id\":{0},", idStatus));
                json.Append(string.Format("\"comment\":\"{0}\"", comment));
                json.Append("}");
                if (x + 1 < testCaseIds.Count)
                {
                    json.Append(",");
                }
            }
            json.Append("]");
            json.Append("}");

            TestRailsAPIClient client = new TestRailsAPIClient(GameMaster.BASE_TEST_RAILS_URL);

            AutoConsole.PostMessage(client.SendPost(string.Format("add_results/{0}", testRunId), json.ToString()));

            for (int t = 0; t < testCaseIds.Count; t++)
            {
                string jsonResult = client.GetTestName(testCaseIds[t]);
                //Only report as failure if assertion has not already failed, leading to these test cases being marked as fails.
                if (!Q.assert.IsFailing)
                {
                    AutomationMaster.CurrentTestContext.AddAssertion(string.Format("<a href='{0}{1}'>{2}</a>", TestRailsAPIClient.GetUrl(), testCaseIds[t], jsonResult));
                }
                else
                {
                    AutomationMaster.CurrentTestContext.AddTestCaseAssertionOnFailure(string.Format("**TRY_FAIL**<a href='{0}{1}'>{2}</a>", TestRailsAPIClient.GetUrl(), testCaseIds[t], jsonResult));
                }
            }
        }
Beispiel #11
0
		public static void CopyFile(string copyThis, string destination) {

			if(!Exists(copyThis)) {
				
				AutoConsole.PostMessage(string.Format("Could not copy \"{0}\" to \"{1}\". File to copy does not currently exist.", copyThis.Replace("/", FILE_PATH_SPLIT), destination.Replace("/", FILE_PATH_SPLIT)), MessageLevel.Abridged);

			}
			if(Exists(destination)) {

				File.Delete(destination);

			}
			File.Copy(copyThis, destination);
			AutoConsole.PostMessage(string.Format("Copied \"{0}\" to \"{1}\"", copyThis, destination), MessageLevel.Verbose);

		}
Beispiel #12
0
 public void UpdateKey(string key, string newValue)
 {
     if (_requiredConfigs.FindAll(x => x.Key == key).Any())
     {
         _requiredConfigs.RemoveAt(_requiredConfigs.FindIndex(x => x.Key == key));
         _requiredConfigs.Add(new KeyValuePair <string, string>(key, newValue));
     }
     else if (_customConfigs.FindAll(x => x.Key == key).Any())
     {
         _customConfigs.RemoveAt(_customConfigs.FindIndex(x => x.Key == key));
         _customConfigs.Add(new KeyValuePair <string, string>(key, newValue));
     }
     else
     {
         AutoConsole.PostMessage(string.Format("ConfigReader.UpdateKey() called for key \"{0}\" with value \"{1}\", but key does not exist in the \"{2}\" config!", key, newValue, System.Enum.GetName(typeof(FileResource), ResourceOrigin)), MessageLevel.Abridged);
     }
 }
Beispiel #13
0
		public static void SaveNonUnityTextResource(FileResource file, string value, bool overwrite = true){

			if(!isSet) {
				
				Set();

			}

			#if UNITY_EDITOR

			if(!knownEditorResourceFiles.FindAll(x => x.Key == file).Any()) {
				
				AutoConsole.PostMessage("The supplied file could not be found. Make sure you are referencing a file stored outside of the Unity project."); //No usage of string.Format with file name data. Using Enum.GetName here causes exceptions on compile "Recursive Serialization is not supported. You can't dereference a PPtr while loading.".
                return;

			}

			string directory = string.Format("{0}{1}{2}", RESOURCES_DIRECTORY, FILE_PATH_SPLIT, knownEditorResourceFiles.Find(x => x.Key == file).Value);
			if(!Directory.Exists(Path.GetDirectoryName(directory))) {
				
				Set();

			}

			if(!Exists(directory)) {

				Set();

			}

			if(overwrite) {

				File.WriteAllText(directory, value);

			} else {

				File.AppendAllText(directory, value);

			}

			#endif

		}
Beispiel #14
0
        public IEnumerator HandleCommand(string command)
        {
            if (!commands.Any())
            {
                SetCommands();
            }

            List <KeyValuePair <string, IEnumerator> > match = commands.FindAll(x => x.Key == command);

            if (match.Any())
            {
                AutoConsole.PostMessage(string.Format("Running Buddy command \"{0}\"", command), MessageLevel.Abridged);
                yield return(StartCoroutine(match.First().Value));
            }
            else
            {
                AutoConsole.PostMessage(string.Format("Cannot find Buddy command \"{0}\"", command), MessageLevel.Abridged);
                //TODO: Auto fail test if its pre-run commands cannot be accomodated.
            }

            yield return(null);
        }
Beispiel #15
0
        public static void SendJsonInPieces(string jsonAttributePrefix, string json, int orderRan = -1)
        {
            //Break this message into pieces.
            List <string> pieces  = new List <string>();
            int           charPos = 0;

            if (ConnectionStrategy.MaxMessageLength <= 0)
            {
                throw new UnityException("ConnectionStrategy.MaxMessageLength must be a positive number. This would cause an infinite loop and hard crash. Please fix the source of this value and rerun automation.");
            }

            while (charPos < json.Length)
            {
                if (charPos + ConnectionStrategy.MaxMessageLength <= json.Length)
                {
                    pieces.Add(json.Substring(charPos, ConnectionStrategy.MaxMessageLength));
                    charPos += ConnectionStrategy.MaxMessageLength;
                }
                else
                {
                    pieces.Add(json.Substring(charPos, json.Length - charPos - 1));
                    break;
                }
            }

            for (int x = 0; x < pieces.Count; x++)
            {
                if (orderRan >= 0)
                {
                    AutoConsole.PostMessage(string.Format("{5}_MULTI_PART|{1}{0}{2}{0}{3}{0}{4}|", AutomationMaster.PARTIAL_DELIMITER, x, pieces.Count, orderIndex, pieces[x], jsonAttributePrefix), MessageLevel.Abridged);
                }
                else
                {
                    AutoConsole.PostMessage(string.Format("{0}_MULTI_PART|{1}{2}{3}|", jsonAttributePrefix, x, AutomationMaster.PARTIAL_DELIMITER, pieces[x]), MessageLevel.Abridged);
                }
            }
        }
Beispiel #16
0
        IEnumerator SendCommand(ServerCommand command)
        {
            if (AutomationMaster.Arbiter.TestRunId.Length == 0 || Application.isEditor)
            {
                AutoConsole.PostMessage(string.Format("Ignoring command \"{0}\" as no server is involved in this test run.", Enum.GetName(typeof(ServerCommand), command)), MessageLevel.Verbose);
                yield break;
            }

            switch (command)
            {
            case ServerCommand.AcceptDeviceAlert:
                //AutomationMaster.Arbiter.SendCommunication("SERVER_BROKER_COMMAND|HANDLE_DEVICE_ALERT|", "SERVER_BROKER_VALUE|1|"); // 1 or true, accept alert.
                yield break;

            case ServerCommand.DeclineDeviceAlert:
                //AutomationMaster.Arbiter.SendCommunication("SERVER_BROKER_COMMAND|HANDLE_DEVICE_ALERT|", "SERVER_BROKER_VALUE|0|"); // 0 or false, decline alert.
                yield break;
            }

            /*
             * float timer = 0f;
             * _awaitingResponse = true;
             * while(_awaitingResponse && timer <= _responseTimeout) {
             *
             *      timer += 1;
             *      yield return StartCoroutine(Q.driver.WaitRealTime(1f));
             *
             * }
             * if(timer > _responseTimeout) {
             *
             *      yield return StartCoroutine(Q.assert.Fail("Response timeout occurred waiting for server to complete and respond to a ServerBroker command."));
             *
             * }
             */
            yield return(null);
        }
Beispiel #17
0
		//Record logs from Unity console.
		public static void GetLog(string message, string stackTrace, LogType type) {

			Log newLog = new Log() {
				message = message,
				stackTrace = stackTrace,
				type = type,
			};
			Logs.Add(newLog);
			//If we exceed the maximum storage space.
			if(Logs.Count >= MAX_LOG_COUNT_HISTORY) {
				
				Logs.RemoveAt(0); //Remove oldest log.

			}

			//If an unhandled exception has occurred in the Trilleon Framework during a test run, handle it!
			if(type == LogType.Exception) {

				#if UNITY_EDITOR
				EditorApplication.UnlockReloadAssemblies();
				#endif

				//If this error occurred directly in the Trilleon Framework (not editor), then stop all tests and report on the exception.
				if(AutomationMaster.Busy &&  AutomationMaster.Initialized && stackTrace.Contains("TrilleonAutomation.") && !stackTrace.Contains("/Editor/") && !ReportOnce) {

					ReportOnce = true;
					AutomationMaster.Arbiter.SendCommunication("An unhandled exception occurred in the Trilleon Framework, disrupting the test run execution");
					string stack = string.Format("The unhandled exception was: {0} {1}", message, stackTrace);
					if(stack.Length > ConnectionStrategy.MaxMessageLength) {
						
						stack = stack.Substring(0, ConnectionStrategy.MaxMessageLength - 50);

					}
					AutomationMaster.Arbiter.SendCommunication(stack);
					string assertionData = string.Join("**", AutomationMaster.CurrentTestContext.Assertions.ToArray());
					if(assertionData.Length > ConnectionStrategy.MaxMessageLength) {

						int startingIndex = assertionData.Length - ConnectionStrategy.MaxMessageLength - 50;
						assertionData = stack.Substring(startingIndex, stack.Length - startingIndex - 1);

					}
					AutomationMaster.Arbiter.SendCommunication(string.Format("ASSERTION DATA:[{0}]", assertionData));
					AutomationMaster.AutomationReport.ReportUnhandledException(message, stackTrace);

					#if UNITY_EDITOR
					//Reset test runner
					GameObject helper = GameObject.Find(TestMonitorHelpers.NAME);
					if(helper != null)
						AutomationMaster.Destroy(helper);
					#endif

					AutomationMaster.Destroy(AutomationMaster.StaticSelf);
					AutomationMaster.Initialize();
					AutomationMaster.StaticSelfComponent.ResetTestRunner();
					AutoConsole.PostMessage("Exception in framework killed TestRunner. Framework reset and ready for new commands.", MessageLevel.Abridged);

				} else if(AutomationMaster.Busy && AutomationMaster.Initialized && !stackTrace.Contains("/Editor/")) {

					AutomationMaster.TestRunContext.Exceptions.Add(newLog);

				}

				#if UNITY_EDITOR
				if(!AutomationMaster.Initialized && stackTrace.Contains("TrilleonAutomation.") && message.ToLower().Contains("object reference")) {

					//Without AutomationMaster.Initialize(), a null reference error will occur trying to use most functionality in the Trilleon framework.
					string missingRefError = "Object reference error in Trilleon framework without initialization. This is most often caused when TrilleonAutomation.Initialize() is not called. This method is required in your Game's startup logic to activate Trilleon.";
					Debug.LogError(missingRefError);
					AutoConsole.PostMessage(missingRefError, MessageLevel.Abridged);

				}
				#endif
				if(ConnectionStrategy.TrilleonConnectionStrategy == ConnectionStrategyType.Socket) {

					AutomationMaster.StaticSelf.GetComponent<SocketConnectionStrategy>().Stop();

				}

			}

		}
Beispiel #18
0
		static void Set() {

			isSet = true;
			string basePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
			if(Application.platform == RuntimePlatform.WindowsEditor) {
				
				if(basePath.Contains(@"\\")) {
					
					FILE_PATH_SPLIT = @"\\";

				} else {
					
					FILE_PATH_SPLIT = @"\";

				}

			} else {
				
				FILE_PATH_SPLIT = "/";

			}
			BASE_RESOURCE_PATH = string.Format("{0}{1}Automation{1}Engine{1}Xtra{1}Resources{1}", Application.dataPath.Replace("/", FILE_PATH_SPLIT), FILE_PATH_SPLIT);

			knownTrilleonResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.TrilleonConfig, "TrilleonConfig"));
			knownTrilleonResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.ReportJavascript, ConfigReader.GetString("AUTOMATION_RESULTS_REPORT_JAVASCRIPT_USE").Replace("/", FILE_PATH_SPLIT)));
			knownTrilleonResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.ReportCss, ConfigReader.GetString("AUTOMATION_RESULTS_REPORT_CSS_USE").Replace("/", FILE_PATH_SPLIT)));

			#if UNITY_EDITOR

			AssetDatabase.Refresh();

			knownEditorResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.LatestTestResults, "nexus_test_manifest_latest_test_results.txt"));
			knownEditorResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.LaunchInstructions, "nexus_test_manifest_launch_instructions.txt"));
			knownEditorResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.ManifestGUISettings, "nexus_test_manifest_categories_foldout_bools.txt"));
			knownEditorResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.BuddyHistory, "nexus_buddy_data_history.txt"));
			knownEditorResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.NexusTabs, "nexus_tab_preferences.txt"));
			knownEditorResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.Favorites, "nexus_manifest_favorites.txt"));
			knownEditorResourceFiles.Add(new KeyValuePair<FileResource,string>(FileResource.FavoritesUnit, "nexus_manifest_favorites_unit.txt"));

			BASE_NON_UNITY_PATH = string.Empty;
			if(Application.platform == RuntimePlatform.WindowsEditor) {

				BASE_NON_UNITY_PATH = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);

			} else {

				string[] pathPieces = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Split(new string[] { FILE_PATH_SPLIT }, StringSplitOptions.None);
				if(pathPieces.Length <= 2) {

					string error = string.Format("Unrecognized file path encountered. Trilleon cannot interact with local files, and will not be fully functional until the issue is corrected. Path [{0}]", basePath);
					AutoConsole.PostMessage(error);
					Debug.Log(error);
					return;

				}
				BASE_NON_UNITY_PATH = string.Format("/{0}/{1}", pathPieces[1], pathPieces[2]);

			}

			RESOURCES_DIRECTORY = string.Format("{0}{4}{1}{4}{2}{3}", BASE_NON_UNITY_PATH, TOP_LEVEL_FOLDER_NAME, GameMaster.GAME_NAME, ConfigReader.GetString("EDITOR_RESOURCE_FILES_DIRECTORY").Replace("/", FILE_PATH_SPLIT), FILE_PATH_SPLIT);
			if(!Directory.Exists(RESOURCES_DIRECTORY)) {
				
				Directory.CreateDirectory(Path.GetDirectoryName(RESOURCES_DIRECTORY));

			}

			CONSOLE_LOG_DIRECTORY = string.Format("{0}{4}{1}{4}{2}{3}", BASE_NON_UNITY_PATH, TOP_LEVEL_FOLDER_NAME, GameMaster.GAME_NAME, ConfigReader.GetString("EDITOR_RESOURCE_CONSOLE_LOG_DIRECTORY").Replace("/", FILE_PATH_SPLIT), FILE_PATH_SPLIT);
			if(!Directory.Exists(CONSOLE_LOG_DIRECTORY)) {
				
				Directory.CreateDirectory(Path.GetDirectoryName(CONSOLE_LOG_DIRECTORY));

			}

			REPORTS_DIRECTORY = string.Format("{0}{4}{1}{4}{2}{3}", BASE_NON_UNITY_PATH, TOP_LEVEL_FOLDER_NAME, GameMaster.GAME_NAME, ConfigReader.GetString("EDITOR_RESOURCE_TEST_REPORTS_DIRECTORY").Replace("/", FILE_PATH_SPLIT), FILE_PATH_SPLIT);
			if(!Directory.Exists(REPORTS_DIRECTORY)) {
				
				Directory.CreateDirectory(Path.GetDirectoryName(REPORTS_DIRECTORY));

			}

			SCREENSHOTS_DIRECTORY = string.Format("{0}screenshots{1}", RESOURCES_DIRECTORY, FILE_PATH_SPLIT);
			if(!Directory.Exists(SCREENSHOTS_DIRECTORY)) {
				
				//This is the single report screenshot storage directory.
				Directory.CreateDirectory(Path.GetDirectoryName(SCREENSHOTS_DIRECTORY));

			}

			string file = string.Format("{0}TrilleonConfig.txt", BASE_RESOURCE_PATH);
			FileInfo fileInfo = new FileInfo(file);
			fileInfo.IsReadOnly = false;
			file = string.Format("{0}{1}.txt",  BASE_RESOURCE_PATH, ConfigReader.GetString("AUTOMATION_RESULTS_REPORT_JAVASCRIPT_USE").Replace("/", FILE_PATH_SPLIT), FILE_PATH_SPLIT);
			fileInfo = new FileInfo(file);
			fileInfo.IsReadOnly = false;
			file = string.Format("{0}{1}.txt", BASE_RESOURCE_PATH, ConfigReader.GetString("AUTOMATION_RESULTS_REPORT_CSS_USE").Replace("/", FILE_PATH_SPLIT));
			fileInfo = new FileInfo(file);
			fileInfo.IsReadOnly = false;

			//Create any missing required files.
			for(int k = 0; k < knownEditorResourceFiles.Count; k++) {
				
				string fileName = string.Format("{0}{1}{2}", RESOURCES_DIRECTORY, FILE_PATH_SPLIT, knownEditorResourceFiles[k].Value);
				if(!Exists(fileName)) {
					
					File.WriteAllText(fileName, string.Empty);

				}

			}

			#endif

		}
Beispiel #19
0
        /// <summary>
        /// Handles incoming pubsub messages. Expects JSON format.
        /// </summary>
        public IEnumerator HandleMessage(string result)
        {
            //Ignore duplicate or empty messages. Ignore messages not meant for this client.
            if (lastMessageReceived == result || string.IsNullOrEmpty(result.Trim()))
            {
                yield break;
            }

            lastMessageReceived = result;

            List <KeyValuePair <string, string> > parameters = DeserializeJsonString(result);

            if (!LocalRunLaunch)
            {
                //If no context or identity is provided, then this is not a valid command. If the DeviceUdid is not valid, then ignore the command.
                if (!parameters.FindAll(x => x.Key.ToLower() == "grid_source").Any() || !parameters.FindAll(x => x.Key.ToLower() == "grid_identity").Any())
                {
                    yield break;
                }

                string source   = parameters.Find(x => x.Key == "grid_source").Value;
                string identity = parameters.Find(x => x.Key == "grid_identity").Value;
                string buddy    = parameters.Find(x => x.Key == "grid_identity_buddy").Value;

                //If message simply contains no reference to this GridIdentity OR the identity is self, then it is chatter and can be ignored.
                bool isChatter = !result.Contains(GridIdentity);
                bool isInvalid = string.IsNullOrEmpty(TestRunId) ? !parameters.FindAll(x => x.Key == "set_test_run_id").Any() : parameters.FindAll(x => x.Key == "test_run_id").Any() && TestRunId != parameters.Find(x => x.Key == "test_run_id").Value;
                bool isEcho    = identity == GridIdentity && source == "client";

                //If message is from a client source where the identity is not that of this client, but contains this client's identity, then this it is a BuddySystem message.
                bool isBuddyMessage = source != "server" && parameters.FindAll(x => x.Key.StartsWith("buddy_")).Any() && buddy == GridIdentity && identity == BuddyHandler.BuddyName;

                //If this message is meant for a different client, or is an echo from the current client, simply ignore the message.
                if (!isBuddyMessage && (isChatter || isEcho || isInvalid))
                {
                    yield break;
                }
            }
            else if (!LocalRunLaunch && parameters.FindAll(x => x.Key.ToLower() == "grid_identity").Any() ? parameters.Find(x => x.Key == "grid_identity").Value != GridIdentity : false)
            {
                yield break;
            }

            LastMessage = DateTime.Now;

            if (parameters.Count > 0)
            {
                //Process each command.
                for (int c = 0; c < parameters.Count; c++)
                {
                    string command             = parameters[c].Key.ToLower();
                    string message             = parameters[c].Value.TrimEnd(',');
                    bool   isRecognizedCommand = true;

                    switch (command.ToLower())
                    {
                    case "change_connection_strategy":
                        AutomationMaster.ConnectionStrategy.ChangeConnectionStrategy(message);
                        break;

                    case "change_communications_identity":
                        AutomationMaster.ConnectionStrategy.UpdateChannelIdentity(message);
                        break;

                    case "no_interval_screenshots":
                        AutomationMaster.NoIntervalScreenshots = true;
                        break;

                    case "ignore_memory_tracking":
                        AutomationMaster.IgnoreMemoryTracking = true;
                        break;

                    case "health_check":
                        SendCommunication(string.Format("heartbeat_{0}", (++AutomationMaster.HeartBeatIndex).ToString(), "0"));
                        break;

                    case "buddy_ignore_all":
                        AutomationMaster.IgnoreAllBuddyTests      = true;
                        AutomationMaster.LockIgnoreBuddyTestsFlag = true;     //Prevents Test editor window from implicitly updating the Ignore flag.
                        break;

                    case "buddy_ready_for_tests":
                        //TODO: Refactor and re-add GRIDLOCK logic. Without it, BuddySystem will not informatively report that both buddies are reporting as the same role.
                        //if((BuddyHandler.IsPrimary && message == "primary") || (!BuddyHandler.IsPrimary && message == "secondary")) {

                        //Gridlock. One client must be the primary, and one must be the secondary.
                        //SendCommunication("buddy_gridlock_detected", "0");
                        //BuddyHandler.RoleGridLock = true;

                        //} else {

                        SendCommunication("buddy_ready_for_tests_acknowledged", BuddyHandler.IsPrimary ? "primary" : "secondary");
                        BuddyHandler.IsBuddyReadyForBuddyTests = true;

                        //}
                        break;

                    case "buddy_ready_for_tests_acknowledged":
                        BuddyHandler.HasBuddyAcknowledgedOurReadiness = true;
                        break;

                    case "buddy_switching_roles":
                        BuddyHandler.BuddyHasSuccessfullySwitchRoles = true;
                        break;

                    case "buddy_requesting_required_details":
                        //Send/Resend details required by Primary Buddy.
                        BuddyHandler.SendBasicBuddyDetails();
                        break;

                    case "buddy_starting_reaction":
                        BuddyHandler.SecondaryReactionsStarted = true;
                        break;

                    case "buddy_tearing_down":
                        BuddyHandler.BuddyTearingDown = true;
                        break;

                    case "buddy_data_update":
                        BuddyHandler.SetCurrentBuddyRequiredDetails(message);
                        break;

                    case "buddy_primary_test_complete":
                        BuddyHandler.CurrentPrimaryTest    = message;
                        BuddyHandler.ReadyForReactionTests = true;
                        BuddyHandler.SendBuddyCommunication("buddy_xyz", string.Format("Buddy Primary Test Completion ({0}) Acknowledged ({1}) %%%%", BuddyHandler.CurrentPrimaryTest, BuddyHandler.ReadyForReactionTests));
                        break;

                    case "buddy_primary_pretest_commands":
                        AutomationMaster.BuddyHandler.PreTestCommandReceived(message);
                        break;

                    case "buddy_secondary_pretest_commands_complete":
                        BuddyHandler.BuddyProcessingCommands = false;
                        break;

                    case "buddy_secondary_pretest_commands_failure":
                        BuddyHandler.BuddyCommandExecutionFailure = true;
                        BuddyHandler.BuddyProcessingCommands      = false;
                        BuddyHandler.BuddyCommandFailure          = message;
                        break;

                    case "buddy_secondary_tests_complete":
                        BuddyHandler.WaitingForBuddyToCompleteReactionTests = false;
                        break;

                    case "buddy_primary_test_failed":
                        BuddyHandler.PrimaryFailed = true;
                        break;

                    case "buddy_primary_complete_action_tests":
                        BuddyHandler.IsPrimaryFinishedWithActionTests = true;
                        break;

                    case "loop_tests":
                        //This command should be sent before or at the same time as the run command. Sending it after may result in failing to have the desired effect.
                        List <KeyValuePair <string, int> > loopTests = new List <KeyValuePair <string, int> >();
                        List <string> RawRequests = message.Split(AutomationMaster.DELIMITER).ToList();
                        for (int x = 0; x < RawRequests.Count; x++)
                        {
                            string testName = RawRequests[x].Split('@').First();
                            string count    = RawRequests[x].Split('@').Last();
                            if (RawRequests[x].Split('@').ToList().Count != 2 || count.ToInt() == 0)
                            {
                                AutoConsole.PostMessage("Provided loop_tests command is invalid. The value must be a string and then integer, separated by an @ symbol.");
                                continue;
                            }
                            loopTests.Add(new KeyValuePair <string, int>(testName, count.ToInt()));
                        }
                        AutomationMaster.LoopTests = loopTests;
                        break;

                    case "request_response":
                        switch (message)
                        {
                        case "screenshot":
                            AutomationMaster.AwaitingScreenshot = false;
                            break;

                        default:
                            break;
                        }
                        break;

                    case "request_buddy":
                        //AutomationMaster.BuddyRequest(message, "newbuddy");
                        break;

                    case "set_test_run_id":
                        TestRunId = message;
                        break;

                    case "manual_set_buddy_primary":
                        BuddyHandler.BuddyName = message;
                        BuddyHandler.IsPrimary = true;
                        BuddyHandler.SendBasicBuddyDetails();
                        BuddyIdentity = message;
                        break;

                    case "manual_set_buddy_secondary":
                        BuddyHandler.BuddyName = message;
                        BuddyHandler.IsPrimary = false;
                        BuddyHandler.SendBasicBuddyDetails();
                        BuddyIdentity = message;
                        break;

                    case "no_test_rails_reporting":
                        AutomationReport.IgnoreTestRailsReporting = true;
                        break;

                    case "server_heartbeat":
                        AutomationMaster.ServerHeartbeatReceived();
                        break;

                    case "console_command":
                        List <string> commands = message.Trim().Split('|').ToList();
                        for (int co = 0; co < commands.Count; co++)
                        {
                            string com = string.Format("{0} {1}", commands[co].Split('$').First(), commands[co].Split('$').Last());
                            Q.SendConsoleCommand(com);
                            AutoConsole.PostMessage(string.Format("Ran Command: {0}", com), MessageLevel.Abridged);
                        }
                        break;

                    case "server_broker_response":
                        Q.request.CommandResponseReceived(message);
                        break;

                    case "automation_command":
                        if (AutomationMaster.Busy)
                        {
                            SendCommunication("Notification", "Busy completing previous test run.");
                            break;
                        }
                        SendCommunication("Notification", "Beginning pre-run checks.");

                        if (parameters.Find(x => x.Key == "grid_source").Value == "server")
                        {
                            AutomationMaster.IsServerListening = true;
                        }

                        //Incoming server-based runs will require the carrot before "rt all", for example, to run unit tests instead of automation.
                        if (message.StartsWith("^"))
                        {
                            AutomationMaster.UnitTestMode = true;
                        }

                        yield return(StartCoroutine(Q.driver.WaitRealTime(1)));

                        AutomationMaster.Busy = true;
                        AutomationMaster.LockIgnoreBuddyTestsFlag = true;

                        //Split string and discard only command prefix. Also allows for spaces in test Category names.
                        message = message.TrimStart().TrimEnd().Replace(", ", ",").Split(new char[] { ' ' }, 2)[1].Trim().ToLower();
                        if (message == "all")
                        {
                            AutomationMaster.LaunchType = LaunchType.All;
                        }
                        else if (message.StartsWith("*") && message.Contains(","))
                        {
                            message = message.Replace("*", string.Empty);
                            AutomationMaster.LaunchType = LaunchType.MultipleMethodNames;
                        }
                        else if (message.StartsWith("*"))
                        {
                            message = message.Replace("*", string.Empty);
                            AutomationMaster.LaunchType = LaunchType.MethodName;
                        }
                        else if (message.StartsWith("&&"))
                        {
                            message = message.Replace("&&", string.Empty);
                            AutomationMaster.LaunchType = LaunchType.Mix;
                        }
                        else if (message.Contains(","))
                        {
                            AutomationMaster.LaunchType = LaunchType.MultipleCategoryNames;
                        }
                        else
                        {
                            AutomationMaster.LaunchType = LaunchType.CategoryName;
                        }

                        //Wait until loading of game is complete to attempt a launch of the automation suite
                        yield return(StartCoroutine(Q.game.WaitForGameLoadingComplete()));

                        StartCoroutine(AutomationMaster.StaticSelfComponent.BeginTestLaunch(message));

                        break;

                    case "buddy_secondary_test_complete":
                    case "buddy_requesting_value_ready":
                    case "buddy_setting_ready_to":
                        //Commands that do not require any action, but should be considered valid for logging purposes (isRecognizedCommand).
                        break;

                    default:
                        isRecognizedCommand = false;
                        break;
                    }

                    Arbiter.LocalRunLaunch = false;
                    if (isRecognizedCommand && !string.IsNullOrEmpty(message))
                    {
                        AutoConsole.PostMessage(string.Format("SENDER [{0}] - COMMAND [{1}] - MESSAGE [{2}]", parameters.Find(x => x.Key == "grid_identity").Value, command, message), ConsoleMessageType.Pubsub);
                    }
                }
            }
        }
Beispiel #20
0
        private string SendRequest(string method, string uri, string json)
        {
            try {
                string url = this.m_url + uri;

                // Create the request object and set the required HTTP method
                // (GET/POST) and headers (content type and basic auth).
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.ContentType = "application/json";
                request.Method      = method;

                string auth = Convert.ToBase64String(
                    Encoding.ASCII.GetBytes(
                        String.Format(
                            "{0}:{1}",
                            this.m_user,
                            this.m_password
                            )
                        )
                    );

                request.Headers.Add("Authorization", "Basic " + auth);

                if (method == "POST")
                {
                    // Add the POST arguments, if any. We just serialize the passed
                    // data object (i.e. a dictionary) and then add it to the request
                    // body.
                    using (var streamWriter = new StreamWriter(request.GetRequestStream())) {
                        streamWriter.Write(json);
                        streamWriter.Flush();
                        streamWriter.Close();
                    }

                    /*if (!string.IsNullOrEmpty(json))
                     * {
                     * byte[] block = Encoding.UTF8.GetBytes(
                     * json
                     * );
                     * request.GetRequestStream().Write(block, 0, block.Length);
                     * }*/
                }

                // Execute the actual web request (GET or POST) and record any
                // occurred errors.
                Exception       ex       = null;
                HttpWebResponse response = null;
                try {
                    response = (HttpWebResponse)request.GetResponse();
                } catch (WebException e) {
                    if (e.Response != null)
                    {
                        response = (HttpWebResponse)e.Response;
                        ex       = e;
                    }
                }

                // Read the response body, if any, and deserialize it from JSON.
                string text = "";
                if (response != null)
                {
                    var reader = new StreamReader(
                        response.GetResponseStream(),
                        Encoding.UTF8
                        );

                    using (reader){
                        text = reader.ReadToEnd();
                    }
                }

                // Check for any occurred errors and add additional details to
                // the exception message, if any (e.g. the error message returned
                // by TestRail).
                if (ex != null)
                {
                    string error = text;
                    if (error != null)
                    {
                        error = '"' + error + '"';
                    }
                    else
                    {
                        error = "No additional error message received";
                    }
                    AutoConsole.PostMessage(String.Format("TestRail API returned HTTP {0} ({1}) for IdTest {2} with JSON [{3}]", (int)response.StatusCode, error, uri, json), MessageLevel.Abridged);
                }

                return(text);
            } catch (Exception e) {
                return(e.Message);
            }
        }
Beispiel #21
0
        /// <summary>
        /// Create x
        /// </summary>
        public static void AddToReport(bool isSuccess, double runTime, bool skipped = false)
        {
            if (AutomationMaster.ValidationRun)
            {
                return;
            }

            string             testName = AutomationMaster.CurrentTestContext.TestName;
            ConsoleMessageType type;
            string             status     = string.Empty;
            List <string>      assertions = AutomationMaster.CurrentTestContext.Assertions;

            if (skipped && isSuccess)
            {
                testName = AutomationMaster.TestRunContext.Ignored.Tests[AutomationMaster.TestRunContext.Ignored.Tests.Count - 1];
                xmlBody.Append(string.Format("<testcase classname=\"{0}\" name=\"{1}\" time=\"{2}\" status=\"ignored\"></testcase>", AutomationMaster.CurrentTestContext.ClassName, testName, 0));
                status = IGNORED_NAME;
                type   = ConsoleMessageType.AssertionIgnore;
            }
            else if (skipped && !isSuccess)
            {
                xmlBody.Append(string.Format("<testcase classname=\"{0}\" name=\"{1}\" time=\"{2}\" status=\"skipped\">", AutomationMaster.CurrentTestContext.ClassName, testName, 0));
                xmlBody.Append(string.Format("<skipped message=\"{0}\" type=\"Test Failure\"></skipped></testcase>", assertions.Any() ? assertions.Last() : "Error occurred before any test assertions were made."));
                status = SKIPPED_NAME;
                type   = ConsoleMessageType.AssertionSkip;
                SkipFailCount++;
            }
            else if (AutomationMaster.CurrentTestContext.IsSuccess)
            {
                xmlBody.Append(string.Format("<testcase classname=\"{0}\" name=\"{1}\" time=\"{2}\"></testcase>", AutomationMaster.CurrentTestContext.ClassName, testName, runTime));
                status = PASSED_NAME;
                type   = ConsoleMessageType.AssertionPass;
            }
            else
            {
                xmlBody.Append(string.Format("<testcase classname=\"{0}\" name=\"{1}\" time=\"{2}\">", AutomationMaster.CurrentTestContext.ClassName, testName, runTime));
                xmlBody.Append(string.Format("<failure message=\"{0}\" type=\"Test Failure\"></failure></testcase>", assertions.Any() ? assertions.Last() : "Error occurred before any test assertions were made."));
                status = FAILED_NAME;
                type   = ConsoleMessageType.AssertionFail;
            }

            TestSuiteRunTime += runTime;
            AutoConsole.PostMessage(string.Format("{0}     {1}", status, AutomationMaster.CurrentTestContext.TestName), MessageLevel.Abridged, type, AutomationMaster.CurrentTestContext.TestName);

                        #if UNITY_EDITOR
            SaveMostRecentsResults(status);
                        #endif

            StringBuilder assertionsJson = new StringBuilder();
            for (int a = 0; a < AutomationMaster.CurrentTestContext.Assertions.Count; a++)
            {
                //Note; Replace "[{" to prevent the reading of any encoded json as actual JSON, which may cause a parsing failure in the html report.
                assertionsJson.Append(string.Format("{{\"assertion\":\"{0}\"}}{1}", AutomationMaster.CurrentTestContext.Assertions[a].Replace("[{", "||"), (AutomationMaster.CurrentTestContext.Assertions.Count - 1) == a ? string.Empty : ","));
            }

            orderIndex++;
            string error_details = AutomationMaster.CurrentTestContext.Notices.Any() ? string.Join(", ", AutomationMaster.CurrentTestContext.Notices.ToArray()) : string.Empty;
            error_details += AutomationMaster.CurrentTestContext.ErrorDetails.Replace("[{", "||");
            error_details  = error_details ?? "No Error Details Were Reported For This Failure!";
            string json = string.Format("{{\"order_ran\":\"{0}\", \"status\":\"{1}\", \"name\":\"{2}\", \"class\":\"{3}\", \"test_categories\":\"{4}\", \"result_details\":\"{5}\", \"assertions\":[{6}]}},",
                                        orderIndex, status, AutomationMaster.CurrentTestContext.TestName, AutomationMaster.CurrentTestContext.ClassName, string.Join(", ", AutomationMaster.CurrentTestContext.Categories.ToArray()),
                                        error_details, assertionsJson.ToString());

            if (json.Length > ConnectionStrategy.MaxMessageLength)
            {
                SendJsonInPieces("SINGLE_TEST_RESULTS_JSON", json, orderIndex);
                jsonBody.Append(json);
            }
            else
            {
                jsonBody.Append(json);
                AutoConsole.PostMessage(string.Format("SINGLE_TEST_RESULTS_JSON|{0}|", json), MessageLevel.Abridged);
            }
        }
Beispiel #22
0
 private void Error(PubnubClientError pubnubError)
 {
     AutoConsole.PostMessage(pubnubError.Description, MessageLevel.Verbose);
 }
Beispiel #23
0
        public override void Render()
        {
            GUIStyle horizontal = new GUIStyle();

            horizontal.margin = new RectOffset(10, 11, 0, 0);

            GUIStyle statusColor = new GUIStyle(GUI.skin.label);

            statusColor.margin           = new RectOffset(0, 0, 3, 0);
            statusColor.normal.textColor = AutoConsole.Paused ? Color.red : Nexus.TextGreen;
            statusColor.fixedWidth       = 125;
            statusColor.fontStyle        = FontStyle.Bold;

            GUILayout.Space(15);
            EditorGUILayout.BeginHorizontal(horizontal);             //For "Running" notification and FPS counter.

            if (Application.isPlaying && AutomationMaster.Busy)
            {
                EditorGUILayout.LabelField("Running Test(s)", statusColor);
            }
            else
            {
                AutomationMaster.Busy = false;
                EditorGUILayout.LabelField(string.Empty, statusColor);
            }

            if (Application.isPlaying)
            {
                if (renderPasses == FPS_SAMPLE_RATE && Application.isPlaying)
                {
                    fpsSample    = Math.Round(1 / Time.deltaTime, 0);
                    renderPasses = 0;
                }
                GUIStyle fps = new GUIStyle(GUI.skin.label);
                fps.fontSize         = 26;
                fps.padding          = new RectOffset(0, 0, -8, 0);
                fps.normal.textColor = GetFpsColor(fpsSample);

                GUILayout.FlexibleSpace();
                EditorGUILayout.LabelField(string.Format("FPS   {0}", fpsSample), new GUILayoutOption[] { GUILayout.Width(50) });
                EditorGUILayout.LabelField(string.Format("◈", fpsSample), fps, new GUILayoutOption[] { GUILayout.Width(35) });
                GUILayout.Space(-18);

                renderPasses++;
            }
            EditorGUILayout.EndHorizontal();             //End for "Running" notification and FPS counter.

            GUIStyle scrollStatus = new GUIStyle(GUI.skin.button);

            scrollStatus.margin            = new RectOffset(0, 0, 0, 0);
            scrollStatus.fontStyle         = _autoScroll ? FontStyle.Bold : FontStyle.Normal;
            scrollStatus.normal.background = Swat.ToggleButtonBackgroundSelectedTexture;
            scrollStatus.normal.textColor  = _pubsubMode ? Nexus.TextGreen : Swat.WindowDefaultTextColor;
            EditorGUILayout.Space();

            GUILayout.BeginHorizontal(horizontal);
            EditorGUILayout.LabelField(string.Format("{0}  -  {1}", AutoConsole.Paused ? "Paused" : "Active", AutoConsole.FilterLevel == MessageLevel.Verbose ? "Verbose" : "Abridged"), statusColor);
            EditorGUILayout.Space();
            GUILayout.Space(-100);
            Nexus.Self.Button("Pubsub", "Show received Pubsub messages.",
                              new Nexus.SwatDelegate(delegate() {
                _pubsubMode = !_pubsubMode;
            }), scrollStatus, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });
            GUILayout.Space(0.65f);
            scrollStatus.normal.textColor = _autoScroll ? Nexus.TextGreen : Color.red;
            Nexus.Self.Button("Auto Scroll", "Remove all messages in the console.",
                              new Nexus.SwatDelegate(delegate() {
                _autoScroll = !_autoScroll;
            }), scrollStatus, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });
            GUILayout.EndHorizontal();

            EditorGUILayout.Space();

            GUILayout.BeginHorizontal(horizontal);
            GUIStyle button = new GUIStyle(GUI.skin.button);

            button.margin            = new RectOffset(0, 0, 0, 0);
            button.normal.textColor  = Swat.ToggleButtonTextColor;
            button.normal.background = Swat.ToggleButtonBackgroundTexture;

            Nexus.Self.Button("Clear", "Remove all messages in the console.",
                              new Nexus.SwatDelegate(delegate() {
                FileBroker.SaveUnboundFile(string.Format("{0}{1}{2}/console_before_start.txt", FileBroker.BASE_NON_UNITY_PATH, ConfigReader.GetString("EDITOR_RESOURCE_CONSOLE_LOG_DIRECTORY"), GameMaster.GAME_NAME), string.Empty);
                AutoConsole.messageListDisplayed = new List <AutoConsoleMessage>();
                AutoConsole.messageListQueued    = new List <AutoConsoleMessage>();
                _selectedConsoleMessage          = null;
            }), button, new GUILayoutOption[] { GUILayout.Width(60), GUILayout.Height(22) });

            GUILayout.Space(0.5f);

            Nexus.Self.Button(AutoConsole.Paused ? "Resume" : "Pause", "Pause/Continue rendering of new messages in the console. Messages are still received and stored when paused, and will appear immediately when resuming.",
                              new Nexus.SwatDelegate(delegate() {
                AutoConsole.Paused = !AutoConsole.Paused;
            }), button, new GUILayoutOption[] { GUILayout.Width(60), GUILayout.Height(22) });

            EditorGUILayout.Space();

            Nexus.Self.Button("Verbose", "Post ALL messages from the automation framework in the console.",
                              new Nexus.SwatDelegate(delegate() {
                AutoConsole.FilterLevel = MessageLevel.Verbose;
                if (_autoScroll)
                {
                    _scroll.y = 99999;
                    _scroll.x = 0;
                }
            }), button, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });

            GUILayout.Space(0.65f);

            GUIStyle abridged = new GUIStyle(GUI.skin.button);

            abridged.margin            = new RectOffset(0, 0, 0, 0);
            abridged.normal.textColor  = Swat.ToggleButtonTextColor;
            abridged.normal.background = Swat.ToggleButtonBackgroundTexture;
            Nexus.Self.Button("Abridged", "Post only automation messages marked as high priority in the console.",
                              new Nexus.SwatDelegate(delegate() {
                AutoConsole.FilterLevel = MessageLevel.Abridged;
                if (_autoScroll)
                {
                    _scroll.y = 99999;
                    _scroll.x = 0;
                }
            }), abridged, new GUILayoutOption[] { GUILayout.Width(75), GUILayout.Height(22) });

            GUILayout.EndHorizontal();

            float messageHeight = 15;

            GUIStyle consoleBox = new GUIStyle(GUI.skin.box);

            consoleBox.fixedHeight       = Nexus.Self.position.height - (Application.isPlaying ? 125 : 105);
            consoleBox.fixedWidth        = Nexus.Self.position.width - 20;
            consoleBox.margin            = new RectOffset(10, 0, 0, 10);
            consoleBox.normal.background = Swat.TabButtonBackgroundTexture;

            GUILayout.BeginVertical(consoleBox);             //Begin box border around console.
            _scroll = GUILayout.BeginScrollView(_scroll);

            GUIStyle messageBox = new GUIStyle(GUI.skin.box);

            messageBox.normal.background = Swat.TabButtonBackgroundSelectedTexture;
            messageBox.margin            = new RectOffset(2, 2, 1, 1);
            GUIStyle messageBoxText = new GUIStyle(GUI.skin.label);

            messageBoxText.normal.textColor = Swat.WindowDefaultTextColor;
            messageBox.fixedWidth           = consoleBox.fixedWidth - 10;
            messageBoxText.fixedWidth       = messageBox.fixedWidth - 5;

            string lastConsoleMessage = string.Empty;
            int    duplicateCount     = 0;
            List <AutoConsoleMessage> consoleMessages = AutoConsole.messageListDisplayed;

            for (int m = 0; m < consoleMessages.Count; m++)
            {
                if ((_pubsubMode && consoleMessages[m].messageType != ConsoleMessageType.Pubsub) || (!_pubsubMode && consoleMessages[m].messageType == ConsoleMessageType.Pubsub))
                {
                    continue;
                }

                //If this is a new console message, and auto scroll is on, scroll down automatically.
                if (_autoScroll && m == _lastPassConsoleMessageCount)
                {
                    _scroll.y = 99999;
                    _scroll.x = 0;
                }

                //Render only messages of the requested filter level.
                if (_pubsubMode || (AutoConsole.FilterLevel == MessageLevel.Abridged && consoleMessages[m].level == MessageLevel.Abridged) || AutoConsole.FilterLevel == MessageLevel.Verbose)
                {
                    messageBoxText.normal.textColor = AutoConsole.MessageColor(consoleMessages[m].messageType);
                    GUILayout.BeginHorizontal(messageBox, new GUILayoutOption[] {
                        GUILayout.MinWidth(225),
                        GUILayout.MaxHeight(messageHeight)
                    });

                    if (lastConsoleMessage == consoleMessages[m].message)
                    {
                        duplicateCount++;
                        consoleMessages.RemoveAt(m - 1);
                    }
                    else
                    {
                        lastConsoleMessage = consoleMessages[m].message;
                        duplicateCount     = 0;
                    }

                    if (consoleMessages.Count > m)
                    {
                        if (GUILayout.Button(string.Format("{0} {1}", duplicateCount > 0 ?(duplicateCount + 1).ToString() : string.Empty, consoleMessages[m].message), messageBoxText))
                        {
                            if (_selectedConsoleMessage == consoleMessages[m])
                            {
                                //If the message has been double-clicked, open this test failure as a single-test, temporary report.
                                if (DateTime.Now.Subtract(_lastConsoleMessageButtonClick).TotalSeconds < 0.75d && !string.IsNullOrEmpty(consoleMessages[m].testMethod))
                                {
                                    if (_consoleAbridgedReportTypes.Contains(consoleMessages[m].messageType))
                                    {
                                        _selectedConsoleMessage = null;                                         //Prevents details panel from appearing. We only want it to appear for a single click, not a double click.
                                        AutomationReport.BuildTemporaryReportForSingleConsoleFailure(consoleMessages[m].testMethod);
                                        System.Diagnostics.Process.Start(string.Format("{0}SingleTestAsReportTemp.html", FileBroker.RESOURCES_DIRECTORY));
                                        OpenedTestReport = DateTime.UtcNow;
                                    }
                                }
                                else
                                {
                                    ConsoleMessage.Pop(_selectedConsoleMessage.message, Enum.GetName(typeof(ConsoleMessageType), _selectedConsoleMessage.messageType), Enum.GetName(typeof(MessageLevel), _selectedConsoleMessage.level), _selectedConsoleMessage.timestamp.ToString());
                                    _selectedConsoleMessage = null;
                                }
                            }

                            _selectedConsoleMessage        = consoleMessages[m];
                            _lastConsoleMessageButtonClick = DateTime.Now;
                        }
                    }
                    GUILayout.EndHorizontal();
                }
            }

            _lastPassConsoleMessageCount = consoleMessages.Count;

            GUILayout.EndScrollView();
            GUILayout.EndVertical();
        }
Beispiel #24
0
        public IEnumerator RunBuddySystemTests()
        {
            //If a relationship has not yet been established, then cancel BuddySystem execution. This is not used if IgnoreAllBuddyTests flag set.
            BuddySystemHandlingStarted = true;
            _isBuddySystemFailure      = string.IsNullOrEmpty(BuddyName);

            if (!AutomationMaster.IgnoreAllBuddyTests)
            {
                //If allowed, and Buddy is not yet set, then set Buddy to last-used Buddy.
            #if UNITY_EDITOR
                if (AutomationMaster.ConfigReader.GetBool("EDITOR_DEFAULT_BUDDY_TO_LAST"))
                {
                    string mostRecentBuddy = AutomationReport.GetMostRecentBuddy();
                    if (!string.IsNullOrEmpty(mostRecentBuddy))
                    {
                        BuddyName = mostRecentBuddy;
                    }
                }
            #endif

                if (_isBuddySystemFailure)
                {
                    _failureReason = "Buddy was not set before BuddySystem test execution started.";
                }

                if (!_isBuddySystemFailure)
                {
                    AutoConsole.PostMessage("Establishing Connection With Buddy", MessageLevel.Abridged);
                    do
                    {
                        if (RoleGridLock)
                        {
                            _isBuddySystemFailure = true;
                            _failureReason        = "This client and the associated Buddy client share the same role (primary/secondary). One must be a primary Buddy, and the other a secondary Buddy.";
                            break;
                        }

                        SendBuddyCommunication("buddy_ready_for_tests", IsPrimary ? "primary" : "secondary");
                        yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                        time += 5;
                    } while((!_isBuddyReadyForBuddyTests || !HasBuddyAcknowledgedOurReadiness) && time <= timeout);
                    AutoConsole.PostMessage(time > timeout ? "Buddy Connection Failure": "Buddy Connection Established", MessageLevel.Abridged);

                    if (IsPrimary && !BuddyTestRequiredDetails.Any())
                    {
                        //If this client is the Primary, and has not yet recieved its required information from the Secondary, request it.
                        for (int limit = 30; limit >= 0; limit--)
                        {
                            if (!BuddyTestRequiredDetails.Any())
                            {
                                break;
                            }

                            SendBuddyCommunication("buddy_requesting_required_details", "0");
                            yield return(StartCoroutine(Q.driver.WaitRealTime(1)));
                        }
                    }

                    if (time >= timeout || (IsPrimary && !BuddyTestRequiredDetails.Any()))
                    {
                        _isBuddySystemFailure = true;
                        _failureReason        = "Timed out waiting for Buddy to be ready for multi-client testing.";
                    }

                    if (!_isBuddySystemFailure)
                    {
                        SendBasicBuddyDetails();

                        if (_isPrimary)
                        {
                            yield return(StartCoroutine(PrimaryBuddyTestRun()));

                            if (!_isBuddySystemFailure)
                            {
                                ResetBuddySystemValues();
                                yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                SendBuddyCommunication("buddy_switching_roles", "0");

                                timeout = 300;
                                time    = 0;
                                while (!BuddyHasSuccessfullySwitchRoles && time <= timeout)
                                {
                                    yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                    SendBuddyCommunication("buddy_primary_complete_action_tests", "0");
                                    time += 5;
                                }
                                if (time > timeout)
                                {
                                    _isBuddySystemFailure = true;
                                    _failureReason        = "Timed out waiting for Buddy to switch roles from Secondary to Primary.";
                                }
                                else
                                {
                                    AutoConsole.PostMessage("Switching Roles With Buddy", MessageLevel.Abridged);
                                    yield return(StartCoroutine(SecondaryBuddyTestRun()));
                                }
                            }
                        }
                        else
                        {
                            yield return(StartCoroutine(SecondaryBuddyTestRun()));

                            if (!_isBuddySystemFailure)
                            {
                                ResetBuddySystemValues();
                                yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                SendBuddyCommunication("buddy_switching_roles", "0");

                                timeout = 300;
                                time    = 0;
                                while (!BuddyHasSuccessfullySwitchRoles && time <= timeout)
                                {
                                    yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                                    SendBuddyCommunication("buddy_secondary_tests_complete", "0");
                                    time += 5;
                                }
                                if (time > timeout)
                                {
                                    _isBuddySystemFailure = true;
                                    _failureReason        = "Timed out waiting for Buddy to switch roles from Primary to Secondary.";
                                }
                                else
                                {
                                    AutoConsole.PostMessage("Switching Roles With Buddy", MessageLevel.Abridged);
                                    yield return(StartCoroutine(PrimaryBuddyTestRun()));
                                }
                            }
                        }

                        SendBuddyCommunication("buddy_tearing_down", "0");
                        yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                        SendBuddyCommunication("buddy_tearing_down", "0");
                    }
                }
            }

            if (_isBuddySystemFailure || AutomationMaster.IgnoreAllBuddyTests)
            {
                //Fail all remaining tests.
                string errorMessage = string.Format("BuddySystem failure. Reason: {0} Skipping BuddySystem tests.", _failureReason);
                AutoConsole.PostMessage(errorMessage, MessageLevel.Abridged);
                for (int f = 0; f < _buddies.Count; f++)
                {
                    if (!HandledBuddyTests.Contains(_buddies[f].Key.Key))
                    {
                        AutomationMaster.CurrentTestContext = new TestContext();
                        if (!AutomationMaster.Methods.KeyValListContainsKey(_buddies[f].Key.Key))
                        {
                            AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(_buddies[f].Key.Key, Buddies[f].Key.Value));
                        }
                    }

                    yield return(StartCoroutine(Master.LaunchSingleTest(_buddies[f].Key, AutomationMaster.Methods.Count - 1, AutomationMaster.IgnoreAllBuddyTests ? TestStatus.Ignore : TestStatus.Fail, errorMessage)));

                    for (int fr = 0; fr < _buddies[f].Value.Count; fr++)
                    {
                        if (HandledBuddyTests.Contains(Buddies[f].Value[fr].Value.Name))
                        {
                            continue;
                        }
                        AutomationMaster.CurrentTestContext = new TestContext();
                        if (!AutomationMaster.Methods.KeyValListContainsKey(_buddies[f].Value[fr].Key))
                        {
                            AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(_buddies[f].Value[fr].Key, Buddies[f].Value[fr].Value));
                        }
                        yield return(StartCoroutine(Master.LaunchSingleTest(_buddies[f].Value[fr], AutomationMaster.Methods.Count - 1, AutomationMaster.IgnoreAllBuddyTests ? TestStatus.Ignore : TestStatus.Fail, errorMessage)));
                    }
                }
            }

            HandledBuddyTests = new List <string>();
            ResetBuddySystemValues();

            yield return(null);
        }
Beispiel #25
0
        /// <summary>
        /// While this client is in the Primary Buddy role, run Action tests, and await completion of Secondary Buddy's Reaction tests.
        /// </summary>
        /// <returns>The buddy test run.</returns>
        public IEnumerator PrimaryBuddyTestRun()
        {
            for (int b = 0; b < _buddies.Count; b++)
            {
                //Skip this method if it has already been handled.
                if (HandledBuddyTests.Contains(Buddies[b].Key.Key))
                {
                    continue;
                }

                SecondaryReactionsStarted = false; //Reset for next reaction.

                timeout = 180;
                time    = 0;

                //Retrieve any BuddyCommands for this Action test, and send them to Buddy for execution.
                BuddyCommand command = _buddies[b].Key.Value.GetCustomAttributes(typeof(BuddyCommand), false).ToList().First() as BuddyCommand;
                if (command != null)
                {
                    SendBuddyCommunication("buddy_primary_pretest_commands", string.Join("|", command.Commands.ToArray()));
                    BuddyProcessingCommands = true;
                    while (BuddyProcessingCommands && time <= timeout)
                    {
                        if (BuddyCommandExecutionFailure)
                        {
                            break;
                        }
                        //Every 50 seconds, report still waiting.
                        if (time % 50 == 0)
                        {
                            AutoConsole.PostMessage(string.Format("Primary waiting for Secondary to complete pretest commands ({0}) seconds", time.ToString()), MessageLevel.Abridged);
                        }

                        yield return(StartCoroutine(Q.driver.WaitRealTime(5)));

                        time += 5;
                    }
                }

                string errorMessage = string.Empty;
                HandledBuddyTests.Add(_buddies[b].Key.Key);
                if (!AutomationMaster.Methods.KeyValListContainsKey(Buddies[b].Key.Key))
                {
                    AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(Buddies[b].Key.Key, Buddies[b].Key.Value));
                }

                if (!BuddyCommandExecutionFailure && time <= timeout)
                {
                    //Launch Action test.
                    yield return(StartCoroutine(Master.LaunchSingleTest(Buddies[b].Key, AutomationMaster.Methods.Count - 1)));
                }
                else
                {
                    AutomationMaster.CurrentTestContext.TestInitialize(_buddies[b].Key.Value);
                    if (BuddyCommandExecutionFailure)
                    {
                        errorMessage = string.Format("The Secondary Buddy of this client failed to successfully handle the command(s) {0} required by this Action test. Commands: {1}.", BuddyCommandFailure, string.Join("|", command.Commands.ToArray()));
                    }
                    else
                    {
                        errorMessage = "Timout occurred waiting for primary buddy to complete its pretest commands.";
                    }
                    yield return(StartCoroutine(Q.assert.Fail(errorMessage, FailureContext.TestMethod)));

                    AutomationReport.AddToReport(false, 0, true); //Save results to test run's XML file.
                    Master.ReportOnTest();
                }
                ResendAllInfoForBuddyTests();
                yield return(StartCoroutine(Q.driver.WaitRealTime(2f)));

                bool actionSuccessful = AutomationMaster.CurrentTestContext.IsSuccess;
                if (actionSuccessful)
                {
                    SendBuddyCommunication("buddy_primary_test_complete", _buddies[b].Key.Value.Name);
                }
                else
                {
                    SendBuddyCommunication("buddy_primary_test_failed", _buddies[b].Key.Value.Name);
                }

                //When the buddy has completed all reaction tests, we can then move on to the next.
                timeout = 300;
                time    = 0;
                _waitingForBuddyToCompleteReactionTests = true;
                int resendCount = 4;
                while (_waitingForBuddyToCompleteReactionTests && time <= timeout)
                {
                    //Check if buddy has declared that it is running its secondary tests. If not, resend the command once.
                    if (resendCount > 0 && time > 10 && !SecondaryReactionsStarted)
                    {
                        resendCount--;
                        if (actionSuccessful)
                        {
                            SendBuddyCommunication("buddy_primary_test_complete", _buddies[b].Key.Value.Name);
                        }
                        else
                        {
                            SendBuddyCommunication("buddy_primary_test_failed", _buddies[b].Key.Value.Name);
                        }
                    }

                    //Every 50 seconds, report still waiting.
                    if (time % 50 == 0)
                    {
                        AutoConsole.PostMessage(string.Format("Primary waiting for Secondary ({0}) seconds", time.ToString()), MessageLevel.Abridged);
                    }

                    yield return(StartCoroutine(Q.driver.WaitRealTime(5f)));

                    time += 5;
                }

                //If we time out, stop the run and break out of execution.
                _isBuddySystemFailure = time >= timeout;
                if (_isBuddySystemFailure)
                {
                    _failureReason = errorMessage;
                    AutoConsole.PostMessage(_failureReason, MessageLevel.Abridged);
                    break;
                }

                //Run all CounterReaction tests for this Action.
                List <KeyValuePair <string, MethodInfo> > counterReactions = _buddies.FindAll(x => x.Key.Value.Name == _buddies[b].Key.Value.Name).First().Value.FindAll(x => {
                    BuddySystem bs = (BuddySystem)Attribute.GetCustomAttribute(x.Value, typeof(BuddySystem));
                    return(bs.buddy == Buddy.CounterReaction);
                });

                for (int c = 0; c < counterReactions.Count; c++)
                {
                    HandledBuddyTests.Add(counterReactions[c].Key);
                    if (!AutomationMaster.Methods.KeyValListContainsKey(counterReactions[c].Key))
                    {
                        AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(counterReactions[c].Key, counterReactions[c].Value));
                    }
                    yield return(StartCoroutine(Master.LaunchSingleTest(counterReactions[c], AutomationMaster.Methods.Count - 1, actionSuccessful ? TestStatus.Pass : TestStatus.Fail)));
                }
            }

            SendBuddyCommunication("buddy_primary_complete_action_tests", "0");

            yield return(null);
        }
Beispiel #26
0
        public IEnumerator SecondaryBuddyTestRun()
        {
            do
            {
                int timeout = 300;
                int time    = 0;
                while (!ReadyForReactionTests && time <= timeout)
                {
                    if (ReadyForReactionTests || IsPrimaryFinishedWithActionTests || PrimaryFailed || BuddyTearingDown)
                    {
                        break;
                    }

                    //Every 50 seconds, report still waiting.
                    if (time % 50 == 0)
                    {
                        AutoConsole.PostMessage(string.Format("Secondary waiting for Primary ({0}) seconds", time.ToString()), MessageLevel.Abridged);
                    }

                    yield return(StartCoroutine(Q.driver.WaitRealTime(5f)));

                    time += 5;
                }

                //If there is no primary test, then we are complete the secondary run.
                if (string.IsNullOrEmpty(CurrentPrimaryTest) || BuddyTearingDown)
                {
                    break;
                }

                SendBuddyCommunication("buddy_starting_reaction", "0");

                List <KeyValuePair <string, MethodInfo> > reactionTests = _buddies.FindAll(x => x.Key.Value.Name == CurrentPrimaryTest).First().Value.FindAll(x => {
                    BuddySystem bs = (BuddySystem)Attribute.GetCustomAttribute(x.Value, typeof(BuddySystem));
                    return(bs.buddy == Buddy.Reaction);
                });

                for (int r = 0; r < reactionTests.Count; r++)
                {
                    if (_primaryFailed)
                    {
                        //Add each test and "start" them with auto fail.
                        if (!AutomationMaster.Methods.KeyValListContainsKey(reactionTests[r].Key))
                        {
                            AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(reactionTests[r].Key, reactionTests[r].Value));
                        }
                        string errorMessage = string.Format("This BuddySystem Reaction test was skipped because its primary Action \"{0}\" failed.", CurrentPrimaryTest);
                        yield return(StartCoroutine(Master.LaunchSingleTest(reactionTests[r], AutomationMaster.Methods.Count - 1, TestStatus.Fail, errorMessage)));
                    }
                    else
                    {
                        if (HandledBuddyTests.Contains(reactionTests[r].Key))
                        {
                            continue;
                        }
                        HandledBuddyTests.Add(reactionTests[r].Key);
                        if (!AutomationMaster.Methods.KeyValListContainsKey(reactionTests[r].Key))
                        {
                            AutomationMaster.Methods.Add(new KeyValuePair <string, MethodInfo>(reactionTests[r].Key, reactionTests[r].Value));
                        }
                        yield return(StartCoroutine(Master.LaunchSingleTest(reactionTests[r], AutomationMaster.Methods.Count - 1)));

                        SendBuddyCommunication("buddy_secondary_test_complete", reactionTests[r].Key);
                    }
                }

                ReadyForReactionTests = false;
                CurrentPrimaryTest    = string.Empty;

                //Alert buddy that reaction tests are complete.
                SendBuddyCommunication("buddy_secondary_tests_complete", "0");
                ResendAllInfoForBuddyTests();
            } while(!_isPrimaryFinishedWithActionTests);


            yield return(null);
        }
Beispiel #27
0
 public IEnumerator Warn(string message, FailureContext failureContext = FailureContext.Default)
 {
     AutoConsole.PostMessage(string.Format("{0} {1}", AutomationMaster.WARNING_FLAG, message), MessageLevel.Abridged);
     yield return(StartCoroutine(Unifier(true, false, message, failureContext)));
 }
Beispiel #28
0
        protected IEnumerator Unifier(bool b, bool inverse, string message, FailureContext newFailureContext, params int[] testRailsId)
        {
            //If test was already marked as a failure, and test has flag indicating that it should continue despite failure, ignore.
            if (!AutomationMaster.CurrentTestContext.IsSuccess || ((AutomationMaster.TryContinueOnFailure || MideExecution_MarkTestToTryContinueAfterFail) && IsFailing))
            {
                UnitTestStepFailure = isSoft = isTry = quiet = false;                 //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
                yield break;
            }

            //Automatically label this assertion as quiet if the previous assertion is identical to this one.
            quiet = quiet ? true : AutomationMaster.CurrentTestContext.Assertions.Last() == message;

            _failureContext = newFailureContext;
            if ((!b && inverse) || (b && !inverse))
            {
                if (isTry && !quiet)
                {
                    AutomationMaster.CurrentTestContext.AddAssertion(string.Format("**TRY_SUCCESS**{0}", message));
                    UnitTestStepFailure = isSoft = isTry = quiet = false;                     //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
                    yield break;
                }

                ConcurrentFailures = 0;
                AutomationMaster.CurrentTestContext.IsSuccess = true;
                if (!string.IsNullOrEmpty(message) && !isTry && !quiet)
                {
                    AutomationMaster.CurrentTestContext.AddAssertion(message);
                }
            }
            else
            {
                //TODO: UnitTestStepFailure - Determine if an assertion has failed within the context of a TestObject "steps" method. If so, set this to true. Used to disabled certain TestRunner reactive logic, such as screenshots.

                if (isTry)
                {
                    if (!quiet)
                    {
                        AutomationMaster.CurrentTestContext.AddAssertion(string.Format("**TRY_FAIL**{0}", message));
                    }
                    UnitTestStepFailure = isSoft = isTry = quiet = false;                     //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
                    yield break;
                }

                IsFailing = true;
                bool recordLogDetails = newFailureContext != FailureContext.Skipped;

                SetReflectedTestData();
                string recentLogs = AutomationReport.EncodeCharactersForJson(AutoConsole.ReturnLatestLogs(5));

                if (newFailureContext == FailureContext.Skipped)
                {
                    AutomationMaster.TestRunContext.Skipped.Add(AutomationMaster.CurrentTestContext.TestName);
                }
                else
                {
                    AutomationMaster.TestRunContext.Failed.Add(AutomationMaster.CurrentTestContext.TestName, new string[] {
                        message,
                        recentLogs.ToString(),
                        lineNumber
                    });
                }

                AutomationMaster.CurrentTestContext.IsSuccess = false;
                AutomationMaster.CurrentTestContext.AddAssertion(message);
                AutomationMaster.CurrentTestContext.ErrorDetails += string.Format("Error Message [{0}] : Test Line [{1}] : Debug Logs [{2}] ", message, string.Format("Line [{0}] Call [{1}]", lineNumber, lineCall), (recordLogDetails ? recentLogs : string.Format("#SKIPPED#{0}", message)));
                AutomationMaster.CurrentTestContext.ErrorDetails += string.Format(" FULL STACK: [{0}]", Environment.StackTrace.Replace(" at", string.Format(" {0} at", AutomationMaster.NEW_LINE_INDICATOR)));
                if (failureContext != FailureContext.Skipped)
                {
                    //Take screenshot if a failure is not a "Skip" failure (In which case a test does not run at all, and there is no value in taking a screenshot as the current screen has no relevance to the reason it failed).
                    yield return(StartCoroutine(AutomationMaster.StaticSelfComponent.TakeScreenshot()));

                    screenshotRequestTime = DateTime.UtcNow;
                }

                //Handle errors occurring outside of the context of the current test's execution. Only certain contexts require additional handling over what is offered by default.
                switch (AutomationMaster.ExecutionContext)
                {
                case AutomationMaster.CurrentExecutionContext.SetUpClass:
                    AutomationMaster.AutoSkips.Add(new KeyValuePair <string[], string>(new string[] { "class", AutomationMaster.CurrentTestContext.ClassName }, string.Format("FAILURE OCCURRED IN SETUPCLASS:", message)));
                    break;

                case AutomationMaster.CurrentExecutionContext.SetUp:
                    AutomationMaster.AutoSkips.Add(new KeyValuePair <string[], string>(new string[] { "test", AutomationMaster.CurrentTestContext.TestName }, string.Format("FAILURE OCCURRED IN SETUP:", message)));
                    break;

                case AutomationMaster.CurrentExecutionContext.TearDownClass:
                    yield return(StartCoroutine(Q.assert.Warn(string.Format("A failure occurred in the TearDownClass logic for  the test \"{0}.{1}\". This fails the last-run test, and may cause other undesirable behavior for downstream test execution.", AutomationMaster.CurrentTestContext.ClassName, AutomationMaster.CurrentTestContext.TestName))));

                    //Will automatically handle the failure of this test.
                    break;

                case AutomationMaster.CurrentExecutionContext.TearDown:
                //Will automatically handle the failure of this test.
                case AutomationMaster.CurrentExecutionContext.Test:
                //Will automatically handle the failure of this test.
                default:
                    break;
                }

                if ((AutomationMaster.TryContinueOnFailure || MideExecution_MarkTestToTryContinueAfterFail) && ConcurrentFailures > 5)
                {
                    AutomationMaster.OverrideContinueOnFailureAfterTooManyConcurrentFailures = true;
                }

                                #if UNITY_EDITOR
                AutomationMaster.PauseEditorOnFailure();
                                #endif

                //Any FailureContext beyond TestMethod will not have an instantiated test method.
                if (!AutomationMaster.TryContinueOnFailure)
                {
                    if ((!isSoft && AutomationMaster.OverrideContinueOnFailureAfterTooManyConcurrentFailures) || (!MideExecution_MarkTestToTryContinueAfterFail && (_failureContext == FailureContext.TestMethod || _failureContext == FailureContext.Default) && failureContext != FailureContext.Skipped))
                    {
                        try {
                            AutomationMaster.CurrentTestMethod.Stop();                //Kill current test, only if the currently queued test has been initialized.
                        } catch { }
                        yield return(new WaitForEndOfFrame());                        //Allow all Coroutines to be stopped before returning control. In reality, the coroutine calling this will be stopped, so control will never be returned anyway.
                    }
                }

                if (!isSoft && (AutomationMaster.TryContinueOnFailure || MideExecution_MarkTestToTryContinueAfterFail))
                {
                    ConcurrentFailures++;
                }
            }

            if (testRailsId.Length > 0)
            {
                AutomationReport.MarkTestRailsTestCase(AutomationMaster.CurrentTestContext.IsSuccess ? "Passed" : "Failed", testRailsId);
            }

            AutoConsole.PostMessage(string.Format("Assert [{0}] |{1}| {2}", AutomationMaster.CurrentTestContext.TestName, AutomationMaster.CurrentTestContext.IsSuccess ? "Success" : "Failure", message), MessageLevel.Verbose, ConsoleMessageType.TestRunnerUpdate);
            UnitTestStepFailure = isSoft = isTry = quiet = false;             //Reset the UnitTestStepFailure, Soft, Try, and Quiet flags.
            yield return(null);
        }