diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index ac85a7f7f..f4b0314a7 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -217,18 +217,22 @@ export default function GenericNode({ useEffect(() => { if (buildStatus === BuildStatus.BUILT && !isBuilding) { - setNode(data.id, (old) => { - return { - ...old, - data: { - ...old.data, - node: { - ...old.data.node, - lf_version: version, + setNode( + data.id, + (old) => { + return { + ...old, + data: { + ...old.data, + node: { + ...old.data.node, + lf_version: version, + }, }, - }, - }; - }); + }; + }, + false, + ); } }, [buildStatus, isBuilding]); diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 6c963458b..7f0c68040 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -245,7 +245,11 @@ const useFlowStore = create((set, get) => ({ ); } }, - setNode: (id: string, change: Node | ((oldState: Node) => Node)) => { + setNode: ( + id: string, + change: Node | ((oldState: Node) => Node), + isUserChange: boolean = true, + ) => { let newChange = typeof change === "function" ? change(get().nodes.find((node) => node.id === id)!) @@ -253,8 +257,10 @@ const useFlowStore = create((set, get) => ({ get().setNodes((oldNodes) => oldNodes.map((node) => { if (node.id === id) { - if ((node.data as NodeDataType).node?.frozen) { - (newChange.data as NodeDataType).node!.frozen = false; + if (isUserChange) { + if ((node.data as NodeDataType).node?.frozen) { + (newChange.data as NodeDataType).node!.frozen = false; + } } return newChange; } diff --git a/src/frontend/src/types/zustand/flow/index.ts b/src/frontend/src/types/zustand/flow/index.ts index 500a5aeb8..927638b65 100644 --- a/src/frontend/src/types/zustand/flow/index.ts +++ b/src/frontend/src/types/zustand/flow/index.ts @@ -109,7 +109,11 @@ export type FlowStoreType = { update: Edge[] | ((oldState: Edge[]) => Edge[]), skipSave?: boolean, ) => void; - setNode: (id: string, update: Node | ((oldState: Node) => Node)) => void; + setNode: ( + id: string, + update: Node | ((oldState: Node) => Node), + isUserChange: boolean, + ) => void; getNode: (id: string) => Node | undefined; deleteNode: (nodeId: string | Array) => void; deleteEdge: (edgeId: string | Array) => void; diff --git a/src/frontend/tests/end-to-end/generalBugs-shard-10.spec.ts b/src/frontend/tests/end-to-end/generalBugs-shard-10.spec.ts new file mode 100644 index 000000000..d78b9d60a --- /dev/null +++ b/src/frontend/tests/end-to-end/generalBugs-shard-10.spec.ts @@ -0,0 +1,140 @@ +import { expect, test } from "@playwright/test"; +import * as dotenv from "dotenv"; +import path from "path"; + +test("freeze must work correctly", async ({ page }) => { + test.skip( + !process?.env?.OPENAI_API_KEY, + "OPENAI_API_KEY required to run this test", + ); + + if (!process.env.CI) { + dotenv.config({ path: path.resolve(__dirname, "../../.env") }); + } + + await page.goto("/"); + await page.waitForTimeout(1000); + + const promptText = "THIS IS A TEST PROMPT"; + const newPromptText = "TEST TEST TEST TEST TEST"; + + let modalCount = 0; + try { + const modalTitleElement = await page?.getByTestId("modal-title"); + if (modalTitleElement) { + modalCount = await modalTitleElement.count(); + } + } catch (error) { + modalCount = 0; + } + + while (modalCount === 0) { + await page.getByText("New Project", { exact: true }).click(); + await page.waitForTimeout(5000); + modalCount = await page.getByTestId("modal-title")?.count(); + } + + await page.getByRole("heading", { name: "Basic Prompting" }).click(); + await page.waitForTimeout(1000); + + await page.getByTitle("fit view").click(); + + await page.getByText("openai").first().click(); + await page.keyboard.press("Delete"); + + //connection 1 + + const elementPrompt = await page + .getByTestId("handle-prompt-shownode-prompt message-right") + .first(); + await elementPrompt.hover(); + await page.mouse.down(); + + await page.locator('//*[@id="react-flow-id"]').hover(); + + const elementChatOutput = await page + .getByTestId("handle-chatoutput-shownode-text-left") + .first(); + await elementChatOutput.hover(); + await page.mouse.up(); + + await page.locator('//*[@id="react-flow-id"]').hover(); + + await page.getByTestId("promptarea_prompt_template-ExternalLink").click(); + + await page.getByTestId("modal-promptarea_prompt_template").fill(promptText); + + let promptValue = await page + .getByTestId("modal-promptarea_prompt_template") + .inputValue(); + + await page.getByText("Check & Save").click(); + + await page.waitForTimeout(3000); + + await page.getByTestId("button_run_chat output").click(); + + await page.waitForTimeout(3000); + + await page.getByTestId("button_run_chat output").click(); + + await page.waitForTimeout(3000); + + await page.getByTestId("playground-btn-flow-io").click(); + + const textContents = await page + .getByTestId("div-chat-message") + .allTextContents(); + + const concatAllText = textContents.join(" "); + + expect(concatAllText).toContain(promptValue); + + await page.waitForTimeout(1000); + await page.getByText("Close").last().click(); + + await page.getByText("Prompt", { exact: true }).click(); + await page.getByTestId("more-options-modal").click(); + + await page.getByText("Freeze", { exact: true }).last().click(); + + await page.waitForTimeout(1000); + await page.locator('//*[@id="react-flow-id"]').click(); + + expect(page.getByTestId("icon-Snowflake").first()).toBeVisible(); + + await page.locator('//*[@id="react-flow-id"]').click(); + + await page.getByTestId("promptarea_prompt_template-ExternalLink").click(); + + await page.getByTestId("edit-prompt-sanitized").first().click(); + + await page + .getByTestId("modal-promptarea_prompt_template") + .fill(newPromptText); + + promptValue = await page + .getByTestId("modal-promptarea_prompt_template") + .inputValue(); + + await page.getByText("Check & Save").click(); + + await page.getByTestId("button_run_chat output").click(); + + await page.waitForTimeout(3000); + + await page.getByTestId("button_run_chat output").click(); + + await page.waitForTimeout(3000); + + await page.getByTestId("playground-btn-flow-io").click(); + + const textContents2 = await page + .getByTestId("div-chat-message") + .allTextContents(); + + const concatAllText2 = textContents2.join(" "); + + expect(concatAllText2).toContain(promptText); + expect(concatAllText2).not.toContain(newPromptText); +});