diff --git a/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx index 7db3b0079..b36b85f4d 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx @@ -357,7 +357,7 @@ function NodeOutputField({ {data.node?.frozen && ( -
+
)} diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx index 4c8632fd7..31646fb16 100644 --- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx @@ -307,6 +307,7 @@ const NodeToolbarComponent = memo( saveComponent(); break; case "freezeAll": + takeSnapshot(); FreezeAllVertices({ flowId: currentFlowId, stopNodeId: data.id }); break; case "code": @@ -454,6 +455,7 @@ const NodeToolbarComponent = memo( { takeSnapshot(); FreezeAllVertices({ @@ -669,7 +671,10 @@ const NodeToolbarComponent = memo( )} {hasToolMode && ( - + diff --git a/src/frontend/tests/core/features/freeze.spec.ts b/src/frontend/tests/core/features/freeze.spec.ts index 8a44c08a0..015859927 100644 --- a/src/frontend/tests/core/features/freeze.spec.ts +++ b/src/frontend/tests/core/features/freeze.spec.ts @@ -2,8 +2,6 @@ import { expect, test } from "@playwright/test"; import { addFlowToTestOnEmptyLangflow } from "../../utils/add-flow-to-test-on-empty-langflow"; import { addLegacyComponents } from "../../utils/add-legacy-components"; import { awaitBootstrapTest } from "../../utils/await-bootstrap-test"; -import { runChatOutput } from "../../utils/run-chat-output"; -import { zoomOut } from "../../utils/zoom-out"; test( "user must be able to freeze a component", @@ -24,279 +22,66 @@ test( await addLegacyComponents(page); - //first component await page.getByTestId("sidebar-search-input").click(); await page.getByTestId("sidebar-search-input").fill("text input"); await page.waitForSelector('[data-testid="input_outputText Input"]', { timeout: 1000, }); - await zoomOut(page, 3); - await page .getByTestId("input_outputText Input") .dragTo(page.locator('//*[@id="react-flow-id"]'), { targetPosition: { x: 100, y: 100 }, }); - await page.getByTestId("sidebar-search-input").click(); - await page.getByTestId("sidebar-search-input").fill("url"); - await page.waitForSelector('[data-testid="dataURL"]', { - timeout: 1000, + await page.getByTestId("textarea_str_input_value").fill("hello world"); + + await page.getByTestId("div-generic-node").getByRole("button").click(); + + await page.waitForSelector('[data-testid="div-generic-node"]', { + timeout: 10000, }); - await page - .getByTestId("dataURL") - .dragTo(page.locator('//*[@id="react-flow-id"]'), { - targetPosition: { x: 300, y: 300 }, - }); + await page.getByTestId("output-inspection-output text-textinput").click(); - //third component + const firstOutputText = await page.getByPlaceholder("Empty").textContent(); - await page.getByTestId("sidebar-search-input").click(); - await page.getByTestId("sidebar-search-input").fill("split text"); - await page.waitForSelector('[data-testid="processingSplit Text"]', { - timeout: 1000, - }); - - await page - .getByTestId("processingSplit Text") - .dragTo(page.locator('//*[@id="react-flow-id"]'), { - targetPosition: { x: 350, y: 100 }, - }); - - //fourth component - - await page.getByTestId("sidebar-search-input").click(); - await page.getByTestId("sidebar-search-input").fill("Parser"); - await page.waitForSelector('[data-testid="processingParser"]', { - timeout: 1000, - }); - - await page - .getByTestId("processingParser") - .dragTo(page.locator('//*[@id="react-flow-id"]'), { - targetPosition: { x: 50, y: 300 }, - }); - - await page.getByTestId("zoom_out").click(); - - //fifth component - - await page.getByTestId("sidebar-search-input").click(); - await page.getByTestId("sidebar-search-input").fill("chat output"); - await page.waitForSelector('[data-testid="input_outputChat Output"]', { - timeout: 1000, - }); - - await page - .getByTestId("input_outputChat Output") - .dragTo(page.locator('//*[@id="react-flow-id"]'), { - targetPosition: { x: 600, y: 200 }, - }); - - await page.getByTestId("div-generic-node").nth(4).click(); - - await page.getByTestId("more-options-modal").click(); - - await page.getByTestId("expand-button-modal").click(); - - await page.getByTestId("fit_view").click(); - - let outdatedComponents = await page.getByTestId("update-button").count(); - - while (outdatedComponents > 0) { - await page.getByTestId("update-button").first().click(); - await page.waitForSelector('[data-testid="update-button"]', { - timeout: 1000, - }); - outdatedComponents = await page.getByTestId("update-button").count(); - } - - let filledApiKey = await page.getByTestId("remove-icon-badge").count(); - while (filledApiKey > 0) { - await page.getByTestId("remove-icon-badge").first().click(); - filledApiKey = await page.getByTestId("remove-icon-badge").count(); - } - - await page.getByTestId("fit_view").click(); - await zoomOut(page, 2); - - //connection 1 - await page - .getByTestId("handle-urlcomponent-shownode-extracted pages-right") - .nth(0) - .click(); - await page - .getByTestId("handle-splittext-shownode-data or dataframe-left") - .click(); - - //connection 2 - await page - .getByTestId("handle-textinput-shownode-output text-right") - .nth(0) - .click(); - await page.getByTestId("handle-splittext-shownode-separator-left").click(); - - //connection 3 - await page - .getByTestId("handle-splittext-shownode-chunks-right") - .nth(0) - .click(); - await page - .getByTestId("handle-parsercomponent-shownode-data or dataframe-left") - .click(); - - //connection 4 - await page - .getByTestId("handle-parsercomponent-shownode-parsed text-right") - .nth(0) - .click(); - await page.getByTestId("handle-chatoutput-shownode-inputs-left").click(); - - await page - .getByTestId("textarea_str_input_value") - .first() - .fill("lorem ipsum"); - - await page - .getByTestId("inputlist_str_urls_0") - .fill("https://www.lipsum.com/feed/html"); - - await runChatOutput(page); - - await page.waitForSelector("text=built successfully", { - timeout: 30000 * 3, - }); - - await page.waitForSelector( - '[data-testid="output-inspection-output message-chatoutput"]', - { - timeout: 1000, - }, - ); - - await page - .getByTestId("output-inspection-output message-chatoutput") - .first() - .click(); - - const firstRunWithoutFreezing = await page - .getByPlaceholder("Empty") - .textContent(); + expect(firstOutputText).toBe("hello world"); await page.getByText("Close").last().click(); - await page.getByTestId("textarea_str_input_value").first().fill(","); + await page.getByTestId("textarea_str_input_value").fill("goodbye world"); - await runChatOutput(page); + await page.getByTestId("div-generic-node").click(); - await page.waitForSelector("text=built successfully", { - timeout: 30000 * 3, - }); - - await page.waitForSelector( - '[data-testid="output-inspection-output message-chatoutput"]', - { - timeout: 1000, - }, - ); - - await page - .getByTestId("output-inspection-output message-chatoutput") - .first() - .click(); - - const secondRunWithoutFreezing = await page - .getByPlaceholder("Empty") - .textContent(); - - await page.getByText("Close").last().click(); - - await page.getByText("Split Text", { exact: true }).last().click(); - - await page.waitForSelector('[data-testid="more-options-modal"]', { + await page.waitForSelector('[data-testid="freeze-all-button-modal"]', { timeout: 1000, }); - await page.getByTestId("more-options-modal").click(); + await page.getByTestId("freeze-all-button-modal").click(); await page.waitForSelector('[data-testid="icon-FreezeAll"]', { timeout: 1000, }); - await page.getByTestId("icon-FreezeAll").last().click(); - - await page.waitForTimeout(3000); + await page.waitForTimeout(5000); + await page.getByTestId("icon-FreezeAll").click(); + await page.waitForSelector('[data-testid="frozen-icon"]', { + timeout: 20000, + }); + await expect(page.getByTestId("frozen-icon")).toBeVisible(); await page.keyboard.press("Escape"); - await page.locator('//*[@id="react-flow-id"]').click(); + await page.getByTestId("div-generic-node").getByRole("button").click(); - await page - .getByTestId("textarea_str_input_value") - .first() - .fill("lorem ipsum"); + await page.waitForTimeout(5000); - await page.waitForTimeout(2000); + await page.getByTestId("output-inspection-output text-textinput").click(); - await runChatOutput(page); + const secondOutputText = await page.getByPlaceholder("Empty").textContent(); - await page.waitForSelector("text=built successfully", { - timeout: 30000 * 3, - }); - - await page.waitForSelector( - '[data-testid="output-inspection-output message-chatoutput"]', - { - timeout: 1000, - }, - ); - - await page - .getByTestId("output-inspection-output message-chatoutput") - .first() - .click(); - - const firstTextFreezed = await page.getByPlaceholder("Empty").textContent(); - - await page.getByText("Close").last().click(); - - await page.getByText("Split Text", { exact: true }).click(); - - await page.getByText("Freeze").first().click(); - - await page.waitForTimeout(3000); - - await page.keyboard.press("Escape"); - - await runChatOutput(page); - - await page.waitForSelector("text=built successfully", { - timeout: 30000 * 3, - }); - - await page.waitForSelector( - '[data-testid="output-inspection-output message-chatoutput"]', - { - timeout: 1000, - }, - ); - - await page - .getByTestId("output-inspection-output message-chatoutput") - .first() - .click(); - - const thirdTextWithoutFreezing = await page - .getByPlaceholder("Empty") - .textContent(); - - expect(firstTextFreezed).toBe(secondRunWithoutFreezing); - - expect(firstTextFreezed).not.toBe(firstRunWithoutFreezing); - expect(firstTextFreezed).not.toBe(thirdTextWithoutFreezing); - expect(firstRunWithoutFreezing).not.toBe(secondRunWithoutFreezing); - expect(thirdTextWithoutFreezing).not.toBe(secondRunWithoutFreezing); + expect(secondOutputText).toBe(firstOutputText); + expect(secondOutputText).toBe("hello world"); }, );