public void TestStarted(TestContext context, TestCase testCase) { lock (sync) { nestedCallback.TestStarted(context, testCase); } }
private void FireErrorOutput(TestContext testContext, ITestMethodRunnerCallback callback, StreamingTestFileContext testFileContext, JsRunnerOutput jsRunnerOutput) { var error = jsRunnerOutput as JsError; error.Error.InputTestFile = testFileContext.ReferencedFile.Path; error.Error.PathFromTestSettingsDirectory = testFileContext.ReferencedFile.PathFromTestSettingsDirectory; callback.FileError(testContext, error.Error); testFileContext.TestFileSummary.Errors.Add(error.Error); if (testFileContext.TestContext.TestFileSettings.CreateFailedTestForFileError.GetValueOrDefault()) { var fileErrorTest = new TestCase(); fileErrorTest.InputTestFile = testFileContext.ReferencedFile.Path; fileErrorTest.PathFromTestSettingsDirectory = testFileContext.ReferencedFile.PathFromTestSettingsDirectory; fileErrorTest.TestName = string.Format("!! File Error #{0} - Error encountered outside of test case execution !!", testFileContext.TestFileSummary.Errors.Count); fileErrorTest.TestResults.Add(new TestResult { Passed = false, StackTrace = error.Error.StackAsString ?? error.Error.FormatStackObject(), Message = error.Error.Message }); callback.TestStarted(testContext, fileErrorTest); callback.TestFinished(testContext, fileErrorTest); testFileContext.TestFileSummary.AddTestCase(fileErrorTest); } ChutzpahTracer.TraceError("Error received from Phantom {0}", error.Error.Message); }
public void TestStarted(TestCase testCase) { lock (sync) { nestedCallback.TestStarted(testCase); } }
private IList <TestFileSummary> ReadFromStream(StreamReader stream, TestContext testContext, TestOptions testOptions, ITestMethodRunnerCallback callback, bool debugEnabled) { var codeCoverageEnabled = (!testContext.TestFileSettings.EnableCodeCoverage.HasValue && testOptions.CoverageOptions.Enabled) || (testContext.TestFileSettings.EnableCodeCoverage.HasValue && testContext.TestFileSettings.EnableCodeCoverage.Value); var testFileContexts = testContext.ReferencedFiles .Where(x => x.IsFileUnderTest) .Select(x => new TestFileContext(x, testContext, codeCoverageEnabled)) .ToList(); var testIndex = 0; string line; TestFileContext currentTestFileContext = null; if (testFileContexts.Count == 1) { currentTestFileContext = testFileContexts.First(); } var deferredEvents = new List <Action <TestFileContext> >(); while ((line = stream.ReadLine()) != null) { if (debugEnabled) { Console.WriteLine(line); } var match = prefixRegex.Match(line); if (!match.Success) { continue; } var type = match.Groups["type"].Value; var json = match.Groups["json"].Value; // Only update last event timestamp if it is an important event. // Log and error could happen even though no test progress is made if (!type.Equals("Log") && !type.Equals("Error")) { lastTestEvent = DateTime.Now; } try { switch (type) { case "FileStart": FireFileStarted(callback, testContext); break; case "CoverageObject": var jsCov = jsonSerializer.Deserialize <JsCoverage>(json); if (currentTestFileContext == null) { deferredEvents.Add((fileContext) => FireCoverageObject(callback, fileContext, jsCov)); } else { FireCoverageObject(callback, currentTestFileContext, jsCov); } break; case "FileDone": var jsFileDone = jsonSerializer.Deserialize <JsFileDone>(json); FireFileFinished(callback, testContext.InputTestFilesString, testFileContexts, jsFileDone); break; case "TestStart": var jsTestCaseStart = jsonSerializer.Deserialize <JsTestCase>(json); TestFileContext newContext = null; var testName = jsTestCaseStart.TestCase.TestName.Trim(); var moduleName = (jsTestCaseStart.TestCase.ModuleName ?? "").Trim(); var fileContexts = GetFileMatches(testName, testFileContexts); if (fileContexts.Count == 0 && currentTestFileContext == null) { // If there are no matches and not file context has been used yet // then just choose the first context newContext = testFileContexts[0]; } else if (fileContexts.Count == 0) { // If there is already a current context and no matches we just keep using that context // unless this test name has been used already in the current context. In that case // move to the next one that hasn't seen this file yet var testAlreadySeenInCurrentContext = currentTestFileContext.HasTestBeenSeen(moduleName, testName); if (testAlreadySeenInCurrentContext) { newContext = testFileContexts.FirstOrDefault(x => !x.HasTestBeenSeen(moduleName, testName)) ?? currentTestFileContext; } } else if (fileContexts.Count > 1) { // If we found the test has more than one file match // try to choose the best match, otherwise just choose the first one // If we have no file context yet take the first one if (currentTestFileContext == null) { newContext = fileContexts.First(); } else { // In this case we have an existing file context so we need to // 1. Check to see if this test has been seen already on that context // if so we need to try the next file context that matches it // 2. If it is not seen yet in the current context and the current context // is one of the matches then keep using it var testAlreadySeenInCurrentContext = currentTestFileContext.HasTestBeenSeen(moduleName, testName); var currentContextInFileMatches = fileContexts.Any(x => x == currentTestFileContext); if (!testAlreadySeenInCurrentContext && currentContextInFileMatches) { // Keep the current context newContext = currentTestFileContext; } else { // Either take first not used context OR the first one newContext = fileContexts.Where(x => !x.IsUsed).FirstOrDefault() ?? fileContexts.First(); } } } else if (fileContexts.Count == 1) { // We found a unique match newContext = fileContexts[0]; } if (newContext != null && newContext != currentTestFileContext) { currentTestFileContext = newContext; testIndex = 0; } currentTestFileContext.IsUsed = true; currentTestFileContext.MarkTestSeen(moduleName, testName); PlayDeferredEvents(currentTestFileContext, deferredEvents); jsTestCaseStart.TestCase.InputTestFile = currentTestFileContext.ReferencedFile.Path; callback.TestStarted(jsTestCaseStart.TestCase); break; case "TestDone": var jsTestCaseDone = jsonSerializer.Deserialize <JsTestCase>(json); var currentTestIndex = testIndex; FireTestFinished(callback, currentTestFileContext, jsTestCaseDone, currentTestIndex); testIndex++; break; case "Log": var log = jsonSerializer.Deserialize <JsLog>(json); if (currentTestFileContext != null) { FireLogOutput(callback, currentTestFileContext, log); } else { deferredEvents.Add((fileContext) => FireLogOutput(callback, fileContext, log)); } break; case "Error": var error = jsonSerializer.Deserialize <JsError>(json); if (currentTestFileContext != null) { FireErrorOutput(callback, currentTestFileContext, error); } else { deferredEvents.Add((fileContext) => FireErrorOutput(callback, fileContext, error)); } break; } } catch (SerializationException e) { // Ignore malformed json and move on ChutzpahTracer.TraceError(e, "Recieved malformed json from Phantom in this line: '{0}'", line); } } return(testFileContexts.Select(x => x.TestFileSummary).ToList()); }
private TestFileSummary ReadFromStream(StreamReader stream, TestContext testContext, TestOptions testOptions, ITestMethodRunnerCallback callback, bool debugEnabled) { var referencedFile = testContext.ReferencedFiles.SingleOrDefault(x => x.IsFileUnderTest); var testIndex = 0; var summary = new TestFileSummary(testContext.InputTestFile); var codeCoverageEnabled = (!testContext.TestFileSettings.EnableCodeCoverage.HasValue && testOptions.CoverageOptions.Enabled) || (testContext.TestFileSettings.EnableCodeCoverage.HasValue && testContext.TestFileSettings.EnableCodeCoverage.Value); if (codeCoverageEnabled) { summary.CoverageObject = new CoverageData(); } string line; while ((line = stream.ReadLine()) != null) { if (debugEnabled) { Console.WriteLine(line); } var match = prefixRegex.Match(line); if (!match.Success) { continue; } var type = match.Groups["type"].Value; var json = match.Groups["json"].Value; // Only update last event timestamp if it is an important event. // Log and error could happen even though no test progress is made if (!type.Equals("Log") && !type.Equals("Error")) { lastTestEvent = DateTime.Now; } try { JsTestCase jsTestCase = null; switch (type) { case "FileStart": callback.FileStarted(testContext.InputTestFile); break; case "CoverageObject": var jsCov = jsonSerializer.Deserialize <JsCoverage>(json); summary.CoverageObject = coverageEngine.DeserializeCoverageObject(jsCov.Object, testContext); break; case "FileDone": var jsFileDone = jsonSerializer.Deserialize <JsFileDone>(json); summary.TimeTaken = jsFileDone.TimeTaken; callback.FileFinished(testContext.InputTestFile, summary); break; case "TestStart": jsTestCase = jsonSerializer.Deserialize <JsTestCase>(json); jsTestCase.TestCase.InputTestFile = testContext.InputTestFile; callback.TestStarted(jsTestCase.TestCase); break; case "TestDone": jsTestCase = jsonSerializer.Deserialize <JsTestCase>(json); jsTestCase.TestCase.InputTestFile = testContext.InputTestFile; AddLineNumber(referencedFile, testIndex, jsTestCase); testIndex++; callback.TestFinished(jsTestCase.TestCase); summary.AddTestCase(jsTestCase.TestCase); break; case "Log": var log = jsonSerializer.Deserialize <JsLog>(json); // This is an internal log message if (log.Log.Message.StartsWith(internalLogPrefix)) { ChutzpahTracer.TraceInformation("Phantom Log - {0}", log.Log.Message.Substring(internalLogPrefix.Length).Trim()); break; } log.Log.InputTestFile = testContext.InputTestFile; callback.FileLog(log.Log); summary.Logs.Add(log.Log); break; case "Error": var error = jsonSerializer.Deserialize <JsError>(json); error.Error.InputTestFile = testContext.InputTestFile; callback.FileError(error.Error); summary.Errors.Add(error.Error); ChutzpahTracer.TraceError("Eror recieved from Phantom {0}", error.Error.Message); break; } } catch (SerializationException e) { // Ignore malformed json and move on ChutzpahTracer.TraceError(e, "Recieved malformed json from Phantom in this line: '{0}'", line); } } return(summary); }
private IList<TestFileSummary> ReadFromStream(StreamReader stream, TestContext testContext, TestOptions testOptions, IList<StreamingTestFileContext> streamingTestFileContexts, IList<Action<StreamingTestFileContext>> deferredEvents, ITestMethodRunnerCallback callback, bool debugEnabled) { var testIndex = 0; string line; StreamingTestFileContext currentTestFileContext = null; if (streamingTestFileContexts.Count == 1) { currentTestFileContext = streamingTestFileContexts.First(); } while ((line = stream.ReadLine()) != null) { if (debugEnabled) Console.WriteLine(line); var match = prefixRegex.Match(line); if (!match.Success) continue; var type = match.Groups["type"].Value; var json = match.Groups["json"].Value; // Only update last event timestamp if it is an important event. // Log and error could happen even though no test progress is made if (!type.Equals("Log") && !type.Equals("Error")) { lastTestEvent = DateTime.Now; } try { switch (type) { case "FileStart": FireFileStarted(callback, testContext); break; case "CoverageObject": var jsCov = jsonSerializer.Deserialize<JsCoverage>(json); if (currentTestFileContext == null) { AddDeferredEvent((fileContext) => FireCoverageObject(callback, fileContext, jsCov), deferredEvents); } else { FireCoverageObject(callback, currentTestFileContext, jsCov); } break; case "FileDone": var jsFileDone = jsonSerializer.Deserialize<JsFileDone>(json); FireFileFinished(callback, testContext.InputTestFilesString, streamingTestFileContexts, jsFileDone); break; case "TestStart": var jsTestCaseStart = jsonSerializer.Deserialize<JsTestCase>(json); StreamingTestFileContext newContext = null; var testName = jsTestCaseStart.TestCase.TestName.Trim(); var moduleName = (jsTestCaseStart.TestCase.ModuleName ?? "").Trim(); var fileContexts = GetFileMatches(testName, streamingTestFileContexts); if (fileContexts.Count == 0 && currentTestFileContext == null) { // If there are no matches and not file context has been used yet // then just choose the first context newContext = streamingTestFileContexts[0]; } else if (fileContexts.Count == 0) { // If there is already a current context and no matches we just keep using that context // unless this test name has been used already in the current context. In that case // move to the next one that hasn't seen this file yet var testAlreadySeenInCurrentContext = currentTestFileContext.HasTestBeenSeen(moduleName, testName); if (testAlreadySeenInCurrentContext) { newContext = streamingTestFileContexts.FirstOrDefault(x => !x.HasTestBeenSeen(moduleName, testName)) ?? currentTestFileContext; } } else if (fileContexts.Count > 1) { // If we found the test has more than one file match // try to choose the best match, otherwise just choose the first one // If we have no file context yet take the first one if (currentTestFileContext == null) { newContext = fileContexts.First(); } else { // In this case we have an existing file context so we need to // 1. Check to see if this test has been seen already on that context // if so we need to try the next file context that matches it // 2. If it is not seen yet in the current context and the current context // is one of the matches then keep using it var testAlreadySeenInCurrentContext = currentTestFileContext.HasTestBeenSeen(moduleName, testName); var currentContextInFileMatches = fileContexts.Any(x => x == currentTestFileContext); if (!testAlreadySeenInCurrentContext && currentContextInFileMatches) { // Keep the current context newContext = currentTestFileContext; } else { // Either take first not used context OR the first one newContext = fileContexts.Where(x => !x.IsUsed).FirstOrDefault() ?? fileContexts.First(); } } } else if (fileContexts.Count == 1) { // We found a unique match newContext = fileContexts[0]; } if (newContext != null && newContext != currentTestFileContext) { currentTestFileContext = newContext; testIndex = 0; } currentTestFileContext.IsUsed = true; currentTestFileContext.MarkTestSeen(moduleName, testName); PlayDeferredEvents(currentTestFileContext, deferredEvents); jsTestCaseStart.TestCase.InputTestFile = currentTestFileContext.ReferencedFile.Path; callback.TestStarted(jsTestCaseStart.TestCase); ChutzpahTracer.TraceInformation("Test Case Started:'{0}'", jsTestCaseStart.TestCase.GetDisplayName()); break; case "TestDone": var jsTestCaseDone = jsonSerializer.Deserialize<JsTestCase>(json); var currentTestIndex = testIndex; FireTestFinished(callback, currentTestFileContext, jsTestCaseDone, currentTestIndex); testIndex++; break; case "Log": var log = jsonSerializer.Deserialize<JsLog>(json); if (currentTestFileContext != null) { FireLogOutput(callback, currentTestFileContext, log); } else { AddDeferredEvent((fileContext) => FireLogOutput(callback, fileContext, log), deferredEvents); } break; case "Error": var error = jsonSerializer.Deserialize<JsError>(json); if (currentTestFileContext != null) { FireErrorOutput(callback, currentTestFileContext, error); } else { AddDeferredEvent((fileContext) => FireErrorOutput(callback, fileContext, error), deferredEvents); } break; } } catch (SerializationException e) { // Ignore malformed json and move on ChutzpahTracer.TraceError(e, "Recieved malformed json from Phantom in this line: '{0}'", line); } } return streamingTestFileContexts.Select(x => x.TestFileSummary).ToList(); }
private TestFileSummary ReadFromStream(StreamReader stream, TestContext testContext, ITestMethodRunnerCallback callback, bool debugEnabled) { var referencedFile = testContext.ReferencedJavaScriptFiles.SingleOrDefault(x => x.IsFileUnderTest); var testIndex = 0; var summary = new TestFileSummary(testContext.InputTestFile); string line; while ((line = stream.ReadLine()) != null) { if (debugEnabled) Console.WriteLine(line); var match = prefixRegex.Match(line); if (!match.Success) continue; var type = match.Groups["type"].Value; var json = match.Groups["json"].Value; // Only update last event timestamp if it is an important event. // Log and error could happen even though no test progress is made if (!type.Equals("Log") && !type.Equals("Error")) { lastTestEvent = DateTime.Now; } try { JsTestCase jsTestCase = null; switch (type) { case "FileStart": callback.FileStarted(testContext.InputTestFile); break; case "CoverageObject": var jsCov = jsonSerializer.Deserialize<JsCoverage>(json); summary.CoverageObject = coverageEngine.DeserializeCoverageObject(jsCov.Object, testContext); break; case "FileDone": var jsFileDone = jsonSerializer.Deserialize<JsFileDone>(json); summary.TimeTaken = jsFileDone.TimeTaken; callback.FileFinished(testContext.InputTestFile, summary); break; case "TestStart": jsTestCase = jsonSerializer.Deserialize<JsTestCase>(json); jsTestCase.TestCase.InputTestFile = testContext.InputTestFile; callback.TestStarted(jsTestCase.TestCase); break; case "TestDone": jsTestCase = jsonSerializer.Deserialize<JsTestCase>(json); jsTestCase.TestCase.InputTestFile = testContext.InputTestFile; AddLineNumber(referencedFile, testIndex, jsTestCase); testIndex++; callback.TestFinished(jsTestCase.TestCase); summary.AddTestCase(jsTestCase.TestCase); break; case "Log": var log = jsonSerializer.Deserialize<JsLog>(json); // This is an internal log message if (log.Log.Message.StartsWith(internalLogPrefix)) { ChutzpahTracer.TraceInformation("Phantom Log - {0}",log.Log.Message.Substring(internalLogPrefix.Length).Trim()); break; } log.Log.InputTestFile = testContext.InputTestFile; callback.FileLog(log.Log); summary.Logs.Add(log.Log); break; case "Error": var error = jsonSerializer.Deserialize<JsError>(json); error.Error.InputTestFile = testContext.InputTestFile; callback.FileError(error.Error); summary.Errors.Add(error.Error); break; } } catch (SerializationException e) { // Ignore malformed json and move on ChutzpahTracer.TraceError(e, "Recieved malformed json from Phantom in this line: '{0}'", line); } } return summary; }