public static ModifiableRecordSession LoadRecordSession(string path) { using var stream = System.IO.File.OpenRead(path); using var doc = JsonDocument.Parse(stream); return(new ModifiableRecordSession(RecordSession.Deserialize(doc.RootElement))); }
private void btnStart_Click(object sender, EventArgs e) { if (!SaveProject()) { return; } var session = new RecordSession() { StartTime = DateTime.Now }; _currentProject.Sessions.Add(session); Process process = null; if (rdbApplicationStart.Checked) { process = StartAndWaitForTargetApplication(_currentProject.Executable, _currentProject.Arguments); _targetProcesStartedByRecorder = process; } else { process = (Process)cboApplicationProcess.SelectedItem; _targetProcesStartedByRecorder = null; } BringProcessToFront(process); _recorderForm = new RecorderForm(); _recorderForm.Initialize(_currentProject.AutomationType, _providerFactory, cboCodeProvider.SelectedItem.ToString(), this, process); _recorderForm.Record(); _recorderForm.ShowInLowerRightCorner(); this.WindowState = FormWindowState.Minimized; }
public void BodyNormalizationRespectsContentType(string body, string contentType) { byte[] bodyBytes = Encoding.UTF8.GetBytes(body); var session = new RecordSession(); RecordEntry recordEntry = new RecordEntry(); if (contentType != null) { recordEntry.Request.Headers.Add("Content-Type", new[] { contentType }); } recordEntry.Request.Body = bodyBytes; recordEntry.RequestUri = "http://localhost/"; recordEntry.RequestMethod = RequestMethod.Delete; RecordEntry.NormalizeJsonBody(recordEntry.Request); if (contentType?.Contains("json") == true) { Assert.NotSame(bodyBytes, recordEntry.Request.Body); } else { Assert.Same(bodyBytes, recordEntry.Request.Body); } }
// iterate through each entry. // if a RESPONSE issues a token with a name we expect, sanitize it. // use it on the next instance of a REQUEST with the same header value present. public override void Sanitize(RecordSession session) { string newValue = ""; // iterate across the entries. looking at responses first for a member that may need to be anonymized, // when one is found, the next REQUEST should have this same key modified. // currently will invoke the creation function once per encounter of response -> request. for (int i = 0; i < session.Entries.Count; i++) { var currentEntry = session.Entries[i]; if (currentEntry.Response.Headers.ContainsKey(_targetKey) && String.IsNullOrWhiteSpace(newValue)) { newValue = (string)_updateMethod[_method].DynamicInvoke(); currentEntry.Response.Headers[_targetKey] = new string[] { newValue }; continue; } if (currentEntry.Request.Headers.ContainsKey(_targetKey) && !String.IsNullOrWhiteSpace(newValue)) { currentEntry.Request.Headers[_targetKey] = new string[] { newValue }; if (_resetAfterFirst) { newValue = ""; } } } }
public void RecordSessionLookupSkipsRequestBodyWhenFilterIsOn() { var request = new MockRequest(); request.Uri.Reset(new Uri("https://mockuri.com")); request.Content = RequestContent.Create(Encoding.UTF8.GetBytes("A nice and long body.")); request.Headers.Add("Content-Type", "text/json"); HttpMessage message = new HttpMessage(request, null); message.Response = new MockResponse(200); var session = new RecordSession(); var recordTransport = new RecordTransport(session, Mock.Of <HttpPipelineTransport>(), entry => EntryRecordModel.RecordWithoutRequestBody, Mock.Of <Random>()); recordTransport.Process(message); request.Content = RequestContent.Create(Encoding.UTF8.GetBytes("A bad and longer body")); var skipRequestBody = true; var playbackTransport = new PlaybackTransport(session, new RecordMatcher(), new RecordedTestSanitizer(), Mock.Of <Random>(), entry => skipRequestBody); playbackTransport.Process(message); skipRequestBody = false; Assert.Throws <InvalidOperationException>(() => playbackTransport.Process(message)); }
public void PlaybackSession(string filename) { CloseActiveProject(); string absFilename = filename; if (!FileHelper.IsAbsolute(absFilename)) { absFilename = Path.Combine(TestDataDir, filename); } string projDir = EditorProject.FindProjectFor(absFilename); EditorProject proj = new EditorProject(); if (projDir == null || !proj.Load(projDir)) { throw new FileNotFoundException("Project file not found for " + absFilename); } EditorManager.Project = proj; RecordSession session = RecordSession.LoadFromFile(proj.MakeRelative(absFilename)); if (session == null) { throw new FileNotFoundException("Session file not found", absFilename); } TestRecordReport report = new TestRecordReport(); if (!session.Playback(report, true)) { throw new Exception("Record session '" + session.Filename + "' failed.\nItem '" + report.CurrentItem + "' triggered the following error:\n\n" + report.LastError + "\n\n" + report.LastErrorDetailed); } }
private void ShowRecordSession(RecordSession recordSession) { using (var form = new CodeForm()) { form.Init(recordSession); form.ShowDialog(this); } }
public void CanRoundtripSessionRecord(string body, string contentType) { byte[] bodyBytes = Encoding.UTF8.GetBytes(body); var session = new RecordSession(); session.Variables["a"] = "value a"; session.Variables["b"] = "value b"; RecordEntry recordEntry = new RecordEntry(); recordEntry.Request.Headers.Add("Content-Type", new[] { contentType }); recordEntry.Request.Headers.Add("Other-Header", new[] { "multi", "value" }); recordEntry.Request.Body = bodyBytes; recordEntry.RequestUri = "url"; recordEntry.RequestMethod = RequestMethod.Delete; recordEntry.Response.Headers.Add("Content-Type", new[] { contentType }); recordEntry.Response.Headers.Add("Other-Response-Header", new[] { "multi", "value" }); recordEntry.Response.Body = bodyBytes; recordEntry.StatusCode = 202; session.Entries.Add(recordEntry); var arrayBufferWriter = new ArrayBufferWriter <byte>(); using var jsonWriter = new Utf8JsonWriter(arrayBufferWriter, new JsonWriterOptions() { Indented = true }); session.Serialize(jsonWriter); jsonWriter.Flush(); TestContext.Out.WriteLine(Encoding.UTF8.GetString(arrayBufferWriter.WrittenMemory.ToArray())); var document = JsonDocument.Parse(arrayBufferWriter.WrittenMemory); var deserializedSession = RecordSession.Deserialize(document.RootElement); Assert.AreEqual("value a", deserializedSession.Variables["a"]); Assert.AreEqual("value b", deserializedSession.Variables["b"]); RecordEntry deserializedRecord = deserializedSession.Entries.Single(); Assert.AreEqual(RequestMethod.Delete, recordEntry.RequestMethod); Assert.AreEqual("url", recordEntry.RequestUri); Assert.AreEqual(202, recordEntry.StatusCode); CollectionAssert.AreEqual(new[] { contentType }, deserializedRecord.Request.Headers["content-type"]); CollectionAssert.AreEqual(new[] { "multi", "value" }, deserializedRecord.Request.Headers["other-header"]); CollectionAssert.AreEqual(new[] { contentType }, deserializedRecord.Response.Headers["content-type"]); CollectionAssert.AreEqual(new[] { "multi", "value" }, deserializedRecord.Response.Headers["other-response-header"]); CollectionAssert.AreEqual(bodyBytes, deserializedRecord.Request.Body); CollectionAssert.AreEqual(bodyBytes, deserializedRecord.Response.Body); }
public static RecordingHandler LoadRecordSessionIntoInMemoryStore(string path) { using var stream = System.IO.File.OpenRead(path); using var doc = JsonDocument.Parse(stream); var guid = Guid.NewGuid().ToString(); var session = new ModifiableRecordSession(RecordSession.Deserialize(doc.RootElement)); RecordingHandler handler = new RecordingHandler(Directory.GetCurrentDirectory()); handler.InMemorySessions.TryAdd(guid, session); return(handler); }
public void RecordingSessionSanitizeSanitizesVariables() { var sanitizer = new TestSanitizer(); var session = new RecordSession(); session.Variables["A"] = "secret"; session.Variables["B"] = "Totally not a secret"; session.Sanitize(sanitizer); Assert.AreEqual("SANITIZED", session.Variables["A"]); Assert.AreEqual("Totally not a SANITIZED", session.Variables["B"]); }
public async Task TestCanSkipRecordingEntireRequestResponse() { var currentPath = Directory.GetCurrentDirectory(); var httpContext = new DefaultHttpContext(); var pathToRecording = "recordings/skip_entry"; var mockClient = new HttpClient(new MockHttpHandler()); var recordingHandler = new RecordingHandler(currentPath) { RedirectableClient = mockClient, RedirectlessClient = mockClient }; var fullPathToRecording = Path.Combine(currentPath, pathToRecording) + ".json"; recordingHandler.StartRecording(pathToRecording, httpContext.Response); var sessionId = httpContext.Response.Headers["x-recording-id"].ToString(); CreateRecordModeRequest(httpContext, "request-response"); await recordingHandler.HandleRecordRequestAsync(sessionId, httpContext.Request, httpContext.Response); httpContext = new DefaultHttpContext(); // send a second request that SHOULD be recorded CreateRecordModeRequest(httpContext); httpContext.Request.Headers.Remove("x-recording-skip"); httpContext.Request.Body = TestHelpers.GenerateStreamRequestBody("{ \"key\": \"value\" }"); await recordingHandler.HandleRecordRequestAsync(sessionId, httpContext.Request, httpContext.Response); recordingHandler.StopRecording(sessionId); try { using var fileStream = File.Open(fullPathToRecording, FileMode.Open); using var doc = JsonDocument.Parse(fileStream); var record = RecordSession.Deserialize(doc.RootElement); Assert.Single(record.Entries); var entry = record.Entries.First(); Assert.Equal("value", JsonDocument.Parse(entry.Request.Body).RootElement.GetProperty("key").GetString()); Assert.Equal(MockHttpHandler.DefaultResponse, Encoding.UTF8.GetString(entry.Response.Body)); } finally { File.Delete(fullPathToRecording); } }
public async Task StartPlaybackAsync(string sessionId, HttpResponse outgoingResponse, RecordingType mode = RecordingType.FilePersisted) { var id = Guid.NewGuid().ToString(); ModifiableRecordSession session; if (mode == RecordingType.InMemory) { if (!InMemorySessions.TryGetValue(sessionId, out session)) { throw new HttpException(HttpStatusCode.BadRequest, $"There is no in-memory session with id {sessionId} available for playback retrieval."); } session.SourceRecordingId = sessionId; } else { var path = GetRecordingPath(sessionId); if (!File.Exists(path)) { throw new TestRecordingMismatchException($"Recording file path {path} does not exist."); } using var stream = System.IO.File.OpenRead(path); using var doc = await JsonDocument.ParseAsync(stream).ConfigureAwait(false); session = new ModifiableRecordSession(RecordSession.Deserialize(doc.RootElement)) { Path = path }; } if (!PlaybackSessions.TryAdd(id, session)) { throw new HttpException(HttpStatusCode.InternalServerError, $"Unexpectedly failed to add new playback session under id {id}."); } outgoingResponse.Headers.Add("x-recording-id", id); var json = JsonSerializer.Serialize(session.Session.Variables); outgoingResponse.Headers.Add("Content-Type", "application/json"); // Write to the response await outgoingResponse.WriteAsync(json); }
private void Bootstrap() { InputEvents inputEvents = _container.Resolve <InputEvents>(); //_container.RegisterType<ILogger, DebugOutputLogger>(new ContainerControlledLifetimeManager()); _container.RegisterType <ILogger, NullLogger>(new ContainerControlledLifetimeManager()); var logger = _container.Resolve <ILogger>(); logger.LogLevel = LogLevel.Debug; var midiInput = _container.Resolve <MidiInput>(); var midiOutput = _container.Resolve <MidiOutput>(); //var mediaServiceHost = _container.Resolve<MediaServiceHost>(); //Try and initialise the midi input/output try { midiInput.Initialise(); } catch (Exception ex) { MessageBox.Show("Failed to initialise Input: " + ex.Message); } try { midiOutput.Initialise(); } catch (Exception ex) { MessageBox.Show("Failed to initialise Output: " + ex.Message); } //Wire midi inputs through central the input events, could do this with OIC but the //midi input shouldn't need to know about this centralised routing midiInput.MessageReceived += inputEvents.HandleInputEvent; inputEvents.MessageReceived += (o, e) => midiOutput.Send(o, e); _container.RegisterType <IVirtualKeyBoard, VirtualKeyBoard>(new ContainerControlledLifetimeManager()); _container.RegisterInstance <IInputEvents>(inputEvents); _container.RegisterInstance <IMidiInput>(midiInput); _container.RegisterInstance <IOutput>(midiOutput); //Register some basic services to be used by child views later... RecordSession recordSession = _container.Resolve <RecordSession>(); _container.RegisterType <IDialogService, ModalDialogService>(new ContainerControlledLifetimeManager()); _container.RegisterType <MediaControlViewModel, MediaControlViewModel>(); _container.RegisterType <IMediaServiceHost, MediaServiceHost>(new ContainerControlledLifetimeManager()); _container.RegisterInstance <IInputDeviceStatusService>(midiInput); _container.RegisterInstance <IOutputDeviceStatusService>(midiOutput); _container.RegisterType <ITestControlService, BasicTestControl>(new ContainerControlledLifetimeManager()); }
/// <summary> /// Sanitizes all headers, variables, and body content of a <see cref="RecordSession"/>. /// </summary> /// <param name="session">The <see cref="RecordSession"/> to sanitize.</param> public override void Sanitize(RecordSession session) { HashSet <string> secrets = new HashSet <string>(); foreach (KeyValuePair <string, string> variable in session.Variables.ToArray()) { session.Variables[variable.Key] = SanitizeVariable(secrets, variable.Key, variable.Value); } foreach (RecordEntry entry in session.Entries) { if (secrets.Count > 0) { SanitizeBody(secrets, entry.Request); SanitizeBody(secrets, entry.Response); } } base.Sanitize(session); }
public void PlaybackSessionsInProject(string projectDir, string subdir) { CloseActiveProject(); string absFilename = projectDir; if (!FileHelper.IsAbsolute(absFilename)) { absFilename = Path.Combine(TestDataDir, projectDir); } string projDir = EditorProject.FindProjectFor(Path.Combine(absFilename, "dummy.xyz")); EditorProject proj = new EditorProject(); if (projDir == null) { throw new FileNotFoundException("Project file not found for " + absFilename); } proj.Load(projDir); EditorManager.Project = proj; DirectoryInfo folder = new DirectoryInfo(proj.MakeAbsolute(subdir)); FileInfo[] files = folder.GetFiles("*.record"); foreach (FileInfo file in files) { RecordSession session = RecordSession.LoadFromFile(Path.Combine(subdir, file.Name)); if (session == null) { throw new FileNotFoundException("Session file not found", absFilename); } TestRecordReport report = new TestRecordReport(); if (!session.Playback(report, true)) { throw new Exception("Record session '" + session.Filename + "' failed.\nItem '" + report.CurrentItem + "' triggered the following error:\n\n" + report.LastError + "\n\n" + report.LastErrorDetailed); } } }
public void BodyNormalizationWorksWhenMatching(string body, string contentType) { byte[] bodyBytes = Encoding.UTF8.GetBytes(body); var session = new RecordSession(); session.Variables["a"] = "value a"; session.Variables["b"] = "value b"; RecordEntry recordEntry = new RecordEntry(); recordEntry.Request.Headers.Add("Content-Type", new[] { contentType }); recordEntry.Request.Headers.Add("Other-Header", new[] { "multi", "value" }); recordEntry.Request.Body = bodyBytes; recordEntry.RequestUri = "http://localhost/"; recordEntry.RequestMethod = RequestMethod.Delete; recordEntry.Response.Headers.Add("Content-Type", new[] { contentType }); recordEntry.Response.Headers.Add("Other-Response-Header", new[] { "multi", "value" }); recordEntry.Response.Body = bodyBytes; recordEntry.StatusCode = 202; session.Entries.Add(recordEntry); var arrayBufferWriter = new ArrayBufferWriter <byte>(); using var jsonWriter = new Utf8JsonWriter(arrayBufferWriter, new JsonWriterOptions() { Indented = true }); session.Serialize(jsonWriter); jsonWriter.Flush(); var document = JsonDocument.Parse(arrayBufferWriter.WrittenMemory); var deserializedSession = RecordSession.Deserialize(document.RootElement); var matcher = new RecordMatcher(); Assert.NotNull(deserializedSession.Lookup(recordEntry, matcher, new[] { new RecordedTestSanitizer() })); }
public async Task TestCanSkipRecordingRequestBody() { var currentPath = Directory.GetCurrentDirectory(); var httpContext = new DefaultHttpContext(); var pathToRecording = "recordings/skip_body"; var mockClient = new HttpClient(new MockHttpHandler()); var recordingHandler = new RecordingHandler(currentPath) { RedirectableClient = mockClient, RedirectlessClient = mockClient }; var fullPathToRecording = Path.Combine(currentPath, pathToRecording) + ".json"; recordingHandler.StartRecording(pathToRecording, httpContext.Response); var sessionId = httpContext.Response.Headers["x-recording-id"].ToString(); CreateRecordModeRequest(httpContext, "request-body"); await recordingHandler.HandleRecordRequestAsync(sessionId, httpContext.Request, httpContext.Response); recordingHandler.StopRecording(sessionId); try { using var fileStream = File.Open(fullPathToRecording, FileMode.Open); using var doc = JsonDocument.Parse(fileStream); var record = RecordSession.Deserialize(doc.RootElement); var entry = record.Entries.First(); Assert.Null(entry.Request.Body); Assert.Equal(MockHttpHandler.DefaultResponse, Encoding.UTF8.GetString(entry.Response.Body)); } finally { File.Delete(fullPathToRecording); } }
public override void Sanitize(RecordSession session) { session.Entries.RemoveAll(x => rx.IsMatch(x.RequestUri)); }
internal void Init(RecordSession recordSession) { txtCode.Text = recordSession.Code; Text = "Session " + recordSession.StartTime.ToString("g"); }