From ffcb3ebc3c658cc99877f9cdd22b55194288772d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 1 Jan 2026 19:45:48 +0000 Subject: [PATCH 1/2] Initial plan From 7c492b4552367bd1ee637356a4bd7be7a10f9e87 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 1 Jan 2026 19:55:37 +0000 Subject: [PATCH 2/2] Fix crash when deleting connection between Entry and Return nodes Co-authored-by: snakex64 <39806655+snakex64@users.noreply.github.com> --- .../Components/GraphCanvas.razor.cs | 6 +++- .../Features/NodeManipulation.feature | 7 ++++ src/NodeDev.EndToEndTests/Pages/HomePage.cs | 35 +++++++++++++++++++ .../NodeManipulationStepDefinitions.cs | 18 ++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/NodeDev.Blazor/Components/GraphCanvas.razor.cs b/src/NodeDev.Blazor/Components/GraphCanvas.razor.cs index d248f3a..be3c2c8 100644 --- a/src/NodeDev.Blazor/Components/GraphCanvas.razor.cs +++ b/src/NodeDev.Blazor/Components/GraphCanvas.razor.cs @@ -580,7 +580,11 @@ public void RemoveLinkFromGraphCanvas(Connection source, Connection destination) DisableConnectionUpdate = true; try { - Diagram.Links.Remove(Diagram.Links.First(x => (x.Source.Model as GraphPortModel)?.Connection == source && (x.Target.Model as GraphPortModel)?.Connection == destination)); + var link = Diagram.Links.FirstOrDefault(x => (x.Source.Model as GraphPortModel)?.Connection == source && (x.Target.Model as GraphPortModel)?.Connection == destination); + if (link != null) + { + Diagram.Links.Remove(link); + } } finally { diff --git a/src/NodeDev.EndToEndTests/Features/NodeManipulation.feature b/src/NodeDev.EndToEndTests/Features/NodeManipulation.feature index 7c6efa8..77e50d0 100644 --- a/src/NodeDev.EndToEndTests/Features/NodeManipulation.feature +++ b/src/NodeDev.EndToEndTests/Features/NodeManipulation.feature @@ -34,6 +34,13 @@ Scenario: Disconnect and reconnect nodes When I connect the 'Entry' 'Exec' output to the 'Return' 'Exec' input Then I take a screenshot named 'reconnected' +Scenario: Delete connection between Entry and Return nodes + Given I load the default project + And I open the 'Main' method in the 'Program' class + When I delete the connection between 'Entry' 'Exec' output and 'Return' 'Exec' input + Then There should be no console errors + And I take a screenshot named 'connection-deleted' + Scenario: Open method and check for browser errors Given I load the default project When I check for console errors diff --git a/src/NodeDev.EndToEndTests/Pages/HomePage.cs b/src/NodeDev.EndToEndTests/Pages/HomePage.cs index 049709a..c682ea2 100644 --- a/src/NodeDev.EndToEndTests/Pages/HomePage.cs +++ b/src/NodeDev.EndToEndTests/Pages/HomePage.cs @@ -254,6 +254,41 @@ public async Task ConnectPorts(string sourceNodeName, string sourcePortName, str await Task.Delay(200); // Wait for connection to be established } + public async Task DeleteConnection(string sourceNodeName, string sourcePortName, string targetNodeName, string targetPortName) + { + Console.WriteLine($"Deleting connection: {sourceNodeName}.{sourcePortName} -> {targetNodeName}.{targetPortName}"); + + // In Blazor.Diagrams, connections are rendered as SVG paths + // We need to click on the connection to select it, then press Delete + + // Get source and target port positions + var sourcePort = GetGraphPort(sourceNodeName, sourcePortName, isInput: false); + await sourcePort.WaitForVisible(); + + var targetPort = GetGraphPort(targetNodeName, targetPortName, isInput: true); + await targetPort.WaitForVisible(); + + var sourceBox = await sourcePort.BoundingBoxAsync(); + var targetBox = await targetPort.BoundingBoxAsync(); + + if (sourceBox == null || targetBox == null) + throw new Exception("Could not get bounding boxes for ports"); + + // Calculate midpoint between source and target + var midX = (float)(sourceBox.X + sourceBox.Width / 2 + targetBox.X + targetBox.Width / 2) / 2; + var midY = (float)(sourceBox.Y + sourceBox.Height / 2 + targetBox.Y + targetBox.Height / 2) / 2; + + Console.WriteLine($"Clicking on connection midpoint: ({midX}, {midY})"); + + // Click on the connection to select it + await _user.Mouse.ClickAsync(midX, midY); + await Task.Delay(100); + + // Press Delete key to remove the connection + await _user.Keyboard.PressAsync("Delete"); + await Task.Delay(100); + } + public async Task TakeScreenshot(string fileName) { await _user.ScreenshotAsync(new() { Path = fileName }); diff --git a/src/NodeDev.EndToEndTests/StepDefinitions/NodeManipulationStepDefinitions.cs b/src/NodeDev.EndToEndTests/StepDefinitions/NodeManipulationStepDefinitions.cs index 4f49d85..9481c51 100644 --- a/src/NodeDev.EndToEndTests/StepDefinitions/NodeManipulationStepDefinitions.cs +++ b/src/NodeDev.EndToEndTests/StepDefinitions/NodeManipulationStepDefinitions.cs @@ -205,4 +205,22 @@ public async Task ThenTheGraphCanvasShouldBeVisible() Console.WriteLine("✓ Graph canvas is visible"); } + + [When("I delete the connection between {string} {string} output and {string} {string} input")] + public async Task WhenIDeleteTheConnectionBetweenOutputAndInput(string sourceNode, string sourcePort, string targetNode, string targetPort) + { + Console.WriteLine($"Deleting connection: {sourceNode}.{sourcePort} (output) -> {targetNode}.{targetPort} (input)"); + + // Take screenshot before + await HomePage.TakeScreenshot($"/tmp/before-delete-connection-{Guid.NewGuid()}.png"); + + // Delete the connection + await HomePage.DeleteConnection(sourceNode, sourcePort, targetNode, targetPort); + + // Take screenshot after + await HomePage.TakeScreenshot($"/tmp/after-delete-connection-{Guid.NewGuid()}.png"); + + // Wait for UI to update + await Task.Delay(200); + } }