public void DoSomething() { SignalX sx = SignalX.Instance; sx.Settings.ReceiveErrorMessagesFromClient = true; sx.Settings.ReceiveDebugMessagesFromClient = true; sx.Settings.ManageUserConnections = true; sx.Settings.LogAgentMessagesOnClient = true; sx.Settings.ClientLogScriptFunction = @" (function(html){ var appendHtml= function (el, str) { var div = document.createElement('div'); div.innerHTML = str; while (div.children.length > 0) { el.appendChild(div.children[0]); } } appendHtml(document.body,html); })"; sx.SetUpClientErrorMessageHandler( (error, request) => { throw new Exception($"Failed because an error has occurred on the client side script during a test '{this.TestName.Replace("_", " ")}' {error}"); }); var exceptionTracker = new ExceptionTracker { Exception = null }; sx.OnException( (m, e) => { exceptionTracker.Exception = new Exception(m, e); exceptionTracker.Context = m; }); if (this.MethodBody != null) { SignalXTester.Run(exceptionTracker, sx, this.MethodBody?.Invoke(sx, new SignalXAssertionLib())); } if (this.MethodBody2 != null) { SignalXTester.Run(exceptionTracker, sx, this.MethodBody2?.Invoke(sx)); } }
internal static void CheckExpectations(ExceptionTracker exceptionTracker, SignalX signalX, int numberOfClients, Action operation, string url, List <TestObject> testObjects, BrowserType browserType = BrowserType.Default, TestEventHandler events = null) { Thread thread = null; var browserProcess = new List <Process>(); /* * */ //https://stackoverflow.com/questions/22538457/put-a-string-with-html-javascript-into-selenium-webdriver //https://www.automatetheplanet.com/selenium-webdriver-csharp-cheat-sheet/ var option = new FirefoxOptions(); option.AddArgument("--headless"); var _drivers = new List <IWebDriver>(); if (browserType == BrowserType.HeadlessBrowser) { for (int i = 0; i < testObjects.Count; i++) { _drivers.Add( new FirefoxDriver( option // Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), )); } } try { using (WebApp.Start <Startup>(url)) { events?.OnAppStarted?.Invoke(); thread = new Thread( () => { try { for (int i = 0; i < testObjects.Count; i++) { TestObject testObject = testObjects[i]; if (browserType == BrowserType.SystemBrowser) { browserProcess.Add(Process.Start(url + testObject.FileName)); } if (browserType == BrowserType.Default || browserType == BrowserType.HeadlessBrowser) { _drivers[i].Navigate().GoToUrl(url); ((IJavaScriptExecutor)_drivers[i]).ExecuteScript($"arguments[0].innerHTML = '{testObject.PageHtml}'"); } } } catch (Exception e) { events?.OnClientError?.Invoke(new AggregateException(e, exceptionTracker.Exception)); } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); // SpinWait.SpinUntil(() => (!SignalX.Settings.HasOneOrMoreConnections || SignalX.CurrentNumberOfConnections < (ulong)numberOfClients), MaxTestWaitTimeBeforeChecks); AwaitAssert( () => { if (!signalX.Settings.HasOneOrMoreConnections) { throw new Exception("No connection received from any client.This may also be caused by a slow connection " + exceptionTracker?.Exception?.Message); } if (signalX.ConnectionCount < (ulong)numberOfClients) { throw new Exception($"Wait timeout for expected number of clients {numberOfClients} to show up.This may also be caused by a slow connection " + exceptionTracker?.Exception?.Message); } }, () => { if (exceptionTracker.Exception != null) { throw exceptionTracker.Exception; } }, MaxWaitTimeForAllExpectedConnectionsToArrive); new SignalXAssertionLib().WaitForSomeTime(MaxTestWaitTimeBeforeChecks); events?.OnClientLoaded?.Invoke(); //wait for some time before checks to allow side effects to occur AwaitAssert( () => { operation(); //if we got this far, then we made it events?.OnCheckSucceeded?.Invoke(); }, () => { if (exceptionTracker.Exception != null) { throw exceptionTracker.Exception; } }, MaxTestTimeSpan, null, ex => { //to handle both exceptions if (exceptionTracker.Exception != null) { events?.OnFinally?.Invoke(exceptionTracker.Exception); } else { events?.OnFinally?.Invoke(ex); } }, events?.OnCheckFailures); } } finally { QuitAllBrowsers(_drivers, browserProcess, thread, testObjects, browserType); signalX.Dispose(); } }
internal static void Run(ExceptionTracker exceptionTracker, SignalX signalX, SignalXTestDefinition scenarioDefinition) { // SetSignalXInstance(signalX); //setup var testObjects = new List <TestObject>(); // script string scriptTags = ""; if (EmbedeLibraryScripts) { JQueryScriptDownload = JQueryScriptDownload ?? ScriptDownLoadFunction(ScriptLibraries.JQUERY, CDNjQuery); signalRScriptDownload = signalRScriptDownload ?? ScriptDownLoadFunction(ScriptLibraries.SIGNALR, CDNSignalR); signalxScriptDownload = signalxScriptDownload ?? ScriptDownLoadFunction(ScriptLibraries.SIGNALX, CDNSignalX); scriptTags = @" <script>" + JQueryScriptDownload + @"</script> <script>" + signalRScriptDownload + @"</script> <script>" + signalxScriptDownload + @"</script> "; } else { scriptTags = @" <script src='" + CDNjQuery + @"'></script> <script src='" + CDNSignalR + @"'></script> <script src='" + CDNSignalX + @"'></script> "; } scriptTags += "<script>" + signalX.ClientErrorSnippet + @"</script>"; //todo this ovverides settings. so use jquery events on clients scriptTags += @"<script>signalx.debug(function(ev,e){ " + signalX.Settings.ClientLogScriptFunction + @"('<div style=\' color:green\'>'+JSON.stringify(e)+'</div>'); });</script>"; scriptTags += @"<script>signalx.error(function(ev,e){ " + signalX.Settings.ClientLogScriptFunction + @"('<div style=\' color:red\'>'+JSON.stringify(e)+'</div>'); });</script>"; for (int i = 0; i < scenarioDefinition.NumberOfClients; i++) { string script = scenarioDefinition.Script.Count == 1 ? scenarioDefinition.Script[0] : scenarioDefinition.Script[i]; var testObject = new TestObject(); testObject.BaseDirectory = AppDomain.CurrentDomain.BaseDirectory; testObject.FileName = "\\index" + TestFileNameGenerator() + ".html"; testObject.PageHtml = WrapScriptInHtml(scriptTags, script, "<h1>Signalx tests running ....</h1>"); testObject = scenarioDefinition.OnClientPrepared == null ? testObject : scenarioDefinition.OnClientPrepared.Invoke(testObject); string FilePath = testObject.BaseDirectory + testObject.FileName; File.WriteAllText(FilePath, testObject.PageHtml); testObjects.Add(testObject); } scenarioDefinition.TestEvents = scenarioDefinition.TestEvents ?? new TestEventHandler(); scenarioDefinition.TestEvents.OnAppStarted = () => { scenarioDefinition?.OnAppStarted?.Invoke(); }; int port = TcpPortNumberGenerator(); if (!IsPortIsAvailable(port)) { throw new Exception($"The specified tcp port {port} is already in use"); } CheckExpectations( exceptionTracker, signalX, scenarioDefinition.NumberOfClients, () => { scenarioDefinition?.Checks?.Invoke(); }, "http://localhost:" + port, testObjects, scenarioDefinition.BrowserType, scenarioDefinition.TestEvents); }