fix: prompt template not being saved on advanced modal (#2488)

* Fixed dbvalue on table node cell renderer

* Added Change Advanced hook

* Added Handle New Value hook

* Added Handle Node Class hook

* Added Node Class handler to TableNodeCellRender

* Removed internal state of EditNode, added internal state for NodeClass and made the rows and columns be updated when NodeClass changes

* Added NodeClass as dependencies on useMemo to update columns when NodeClass changes

* Fixed advanced not changing the node

* feat: updating tests without save btn

* Added Close button on editNode

---------

Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
Co-authored-by: anovazzi1 <otavio2204@gmail.com>
This commit is contained in:
Lucas Oliveira 2024-07-03 14:55:52 -03:00 • committed by GitHub
commit fe21f90aec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 262 additions and 88 deletions

View file

@ -2,6 +2,7 @@ import { CustomCellRendererProps } from "ag-grid-react";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { useState } from "react"; import { useState } from "react";
import useFlowStore from "../../../../stores/flowStore"; import useFlowStore from "../../../../stores/flowStore";
import { APIClassType } from "../../../../types/api";
import { import {
convertObjToArray, convertObjToArray,
convertValuesToNumbers, convertValuesToNumbers,
@ -24,24 +25,31 @@ import ToggleShadComponent from "../../../toggleShadComponent";
export default function TableNodeCellRender({ export default function TableNodeCellRender({
node: { data }, node: { data },
value: { value, nodeClass, handleOnNewValue: handleOnNewValueNode }, value: {
value,
nodeClass,
handleOnNewValue: handleOnNewValueNode,
handleNodeClass,
},
}: CustomCellRendererProps) { }: CustomCellRendererProps) {
const handleOnNewValue = (newValue: any, name: string, dbValue?: boolean) => { const handleOnNewValue = (newValue: any, name: string, dbValue?: boolean) => {
handleOnNewValueNode(newValue, name, dbValue); handleOnNewValueNode(newValue, name, dbValue);
setTemplateData((old) => { setTemplateData((old) => {
let newData = cloneDeep(old); let newData = cloneDeep(old);
newData.value = newValue; newData.value = newValue;
if (dbValue) { if (dbValue !== undefined) {
newData.load_from_db = newValue; newData.load_from_db = newValue;
} }
return newData; return newData;
}); });
setTemplateValue(newValue); setTemplateValue(newValue);
}; };
const setNodeClass = (value: APIClassType, code?: string, type?: string) => {
handleNodeClass(value, templateData.key, code, type);
};
const [templateValue, setTemplateValue] = useState(value); const [templateValue, setTemplateValue] = useState(value);
const [templateData, setTemplateData] = useState(data); const [templateData, setTemplateData] = useState(data);
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false); const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
const edges = useFlowStore((state) => state.edges); const edges = useFlowStore((state) => state.edges);
@ -220,9 +228,7 @@ export default function TableNodeCellRender({
editNode={true} editNode={true}
disabled={disabled} disabled={disabled}
nodeClass={nodeClass} nodeClass={nodeClass}
setNodeClass={(value) => { setNodeClass={setNodeClass}
nodeClass = value;
}}
value={templateValue ?? ""} value={templateValue ?? ""}
onChange={(value: string | string[]) => { onChange={(value: string | string[]) => {
handleOnNewValue(value, templateData.key); handleOnNewValue(value, templateData.key);
@ -237,9 +243,7 @@ export default function TableNodeCellRender({
<CodeAreaComponent <CodeAreaComponent
readonly={nodeClass.flow && templateData.dynamic ? true : false} readonly={nodeClass.flow && templateData.dynamic ? true : false}
dynamic={templateData.dynamic ?? false} dynamic={templateData.dynamic ?? false}
setNodeClass={(value) => { setNodeClass={setNodeClass}
nodeClass = value;
}}
nodeClass={nodeClass} nodeClass={nodeClass}
disabled={disabled} disabled={disabled}
editNode={true} editNode={true}

View file

@ -1,12 +1,19 @@
import { ColDef, ValueGetterParams } from "ag-grid-community"; import { ColDef, ValueGetterParams } from "ag-grid-community";
import { useMemo } from "react"; import { useMemo, useState } from "react";
import TableNodeCellRender from "../../../components/tableComponent/components/tableNodeCellRender"; import TableNodeCellRender from "../../../components/tableComponent/components/tableNodeCellRender";
import TableToggleCellRender from "../../../components/tableComponent/components/tableToggleCellRender"; import TableToggleCellRender from "../../../components/tableComponent/components/tableToggleCellRender";
import { APIClassType } from "../../../types/api";
import { NodeDataType } from "../../../types/flow"; import { NodeDataType } from "../../../types/flow";
const useColumnDefs = ( const useColumnDefs = (
myData: NodeDataType, nodeClass: APIClassType,
handleOnNewValue: (newValue: any, name: string, setDb?: boolean) => void, handleOnNewValue: (newValue: any, name: string, setDb?: boolean) => void,
handleNodeClass: (
newNodeClass: APIClassType,
name: string,
code: string,
type?: string,
) => void,
changeAdvanced: (n: string) => void, changeAdvanced: (n: string) => void,
open: boolean, open: boolean,
) => { ) => {
@ -46,8 +53,9 @@ const useColumnDefs = (
valueGetter: (params: ValueGetterParams) => { valueGetter: (params: ValueGetterParams) => {
return { return {
value: params.data.value, value: params.data.value,
nodeClass: myData.node, nodeClass: nodeClass,
handleOnNewValue: handleOnNewValue, handleOnNewValue: handleOnNewValue,
handleNodeClass: handleNodeClass,
}; };
}, },
minWidth: 340, minWidth: 340,
@ -75,7 +83,7 @@ const useColumnDefs = (
cellClass: "no-border", cellClass: "no-border",
}, },
], ],
[open, myData], [open, nodeClass],
); );
return columnDefs; return columnDefs;

View file

@ -0,0 +1,29 @@
import { cloneDeep } from "lodash";
import { NodeDataType } from "../../../types/flow";
const useHandleChangeAdvanced = (
data: NodeDataType,
takeSnapshot: () => void,
setNode: (id: string, callback: (oldNode: any) => any) => void,
updateNodeInternals: (id: string) => void,
) => {
const handleChangeAdvanced = (name) => {
if (!data.node) return;
takeSnapshot();
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data.node.template[name].advanced =
!newNode.data.node.template[name].advanced;
return newNode;
});
updateNodeInternals(data.id);
};
return { handleChangeAdvanced };
};
export default useHandleChangeAdvanced;

View file

@ -0,0 +1,84 @@
import { cloneDeep } from "lodash";
import {
ERROR_UPDATING_COMPONENT,
TITLE_ERROR_UPDATING_COMPONENT,
} from "../../../constants/constants";
import useAlertStore from "../../../stores/alertStore";
import { ResponseErrorTypeAPI } from "../../../types/api";
import { NodeDataType } from "../../../types/flow";
const useHandleOnNewValue = (
data: NodeDataType,
takeSnapshot: () => void,
handleUpdateValues: (name: string, data: NodeDataType) => Promise<any>,
debouncedHandleUpdateValues: any,
setNode: (id: string, callback: (oldNode: any) => any) => void,
) => {
const setErrorData = useAlertStore((state) => state.setErrorData);
const handleOnNewValue = async (
newValue,
name,
dbValue,
skipSnapshot = false,
) => {
const nodeTemplate = data.node!.template[name];
const currentValue = nodeTemplate.value;
if (currentValue !== newValue && !skipSnapshot) {
takeSnapshot();
}
const shouldUpdate =
data.node?.template[name].real_time_refresh &&
!data.node?.template[name].refresh_button &&
currentValue !== newValue;
const typeToDebounce = nodeTemplate.type;
nodeTemplate.value = newValue;
let newTemplate;
if (shouldUpdate) {
try {
if (["int"].includes(typeToDebounce)) {
newTemplate = await handleUpdateValues(name, data);
} else {
newTemplate = await debouncedHandleUpdateValues(name, data);
}
} catch (error) {
let responseError = error as ResponseErrorTypeAPI;
setErrorData({
title: TITLE_ERROR_UPDATING_COMPONENT,
list: [
responseError?.response?.data?.detail.error ??
ERROR_UPDATING_COMPONENT,
],
});
}
}
setNode(data.id, (oldNode) => {
const newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
};
if (dbValue !== undefined) {
newNode.data.node.template[name].load_from_db = dbValue;
}
if (data.node?.template[name].real_time_refresh && newTemplate) {
newNode.data.node.template = newTemplate;
} else {
newNode.data.node.template[name].value = newValue;
}
return newNode;
});
};
return { handleOnNewValue };
};
export default useHandleOnNewValue;

View file

@ -0,0 +1,39 @@
import { cloneDeep } from "lodash";
import { NodeDataType } from "../../../types/flow";
const useHandleNodeClass = (
data: NodeDataType,
takeSnapshot: () => void,
setNode: (id: string, callback: (oldNode: any) => any) => void,
updateNodeInternals: (id: string) => void,
) => {
const handleNodeClass = (newNodeClass, name, code, type?: string) => {
if (!data.node) return;
if (data.node!.template[name].value !== code) {
takeSnapshot();
}
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
node: newNodeClass,
description: newNodeClass.description ?? data.node!.description,
display_name: newNodeClass.display_name ?? data.node!.display_name,
};
if (type) {
newNode.data.node.template[name].type = type;
}
newNode.data.node.template[name].value = code;
return newNode;
});
updateNodeInternals(data.id);
};
return { handleNodeClass };
};
export default useHandleNodeClass;

View file

@ -1,8 +1,13 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { LANGFLOW_SUPPORTED_TYPES } from "../../../constants/constants"; import { LANGFLOW_SUPPORTED_TYPES } from "../../../constants/constants";
import { APIClassType } from "../../../types/api";
import { NodeDataType } from "../../../types/flow"; import { NodeDataType } from "../../../types/flow";
const useRowData = (myData: NodeDataType, open: boolean) => { const useRowData = (
myData: NodeDataType,
nodeClass: APIClassType,
open: boolean,
) => {
const rowData = useMemo(() => { const rowData = useMemo(() => {
return Object.keys(myData.node!.template) return Object.keys(myData.node!.template)
.filter((key: string) => { .filter((key: string) => {
@ -25,7 +30,7 @@ const useRowData = (myData: NodeDataType, open: boolean) => {
id: key, id: key,
}; };
}); });
}, [open, myData]); }, [open, nodeClass]);
return rowData; return rowData;
}; };

View file

@ -1,13 +1,23 @@
import { ColDef, GridApi } from "ag-grid-community"; import { ColDef } from "ag-grid-community";
import { cloneDeep } from "lodash"; import { forwardRef, useState } from "react";
import { forwardRef, useEffect, useRef, useState } from "react"; import { useUpdateNodeInternals } from "reactflow";
import TableComponent from "../../components/tableComponent"; import TableComponent from "../../components/tableComponent";
import { Badge } from "../../components/ui/badge"; import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import { useDarkStore } from "../../stores/darkStore"; import { useDarkStore } from "../../stores/darkStore";
import useFlowStore from "../../stores/flowStore"; import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { APIClassType } from "../../types/api";
import { NodeDataType } from "../../types/flow"; import { NodeDataType } from "../../types/flow";
import {
debouncedHandleUpdateValues,
handleUpdateValues,
} from "../../utils/parameterUtils";
import BaseModal from "../baseModal"; import BaseModal from "../baseModal";
import useColumnDefs from "./hooks/use-column-defs"; import useColumnDefs from "./hooks/use-column-defs";
import useHandleChangeAdvanced from "./hooks/use-handle-change-advanced";
import useHandleOnNewValue from "./hooks/use-handle-new-value";
import useHandleNodeClass from "./hooks/use-handle-node-class";
import useRowData from "./hooks/use-row-data"; import useRowData from "./hooks/use-row-data";
const EditNodeModal = forwardRef( const EditNodeModal = forwardRef(
@ -25,41 +35,50 @@ const EditNodeModal = forwardRef(
}, },
ref, ref,
) => { ) => {
const myData = useRef(cloneDeep(data));
const isDark = useDarkStore((state) => state.dark); const isDark = useDarkStore((state) => state.dark);
const setNode = useFlowStore((state) => state.setNode); const setNode = useFlowStore((state) => state.setNode);
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
const updateNodeInternals = useUpdateNodeInternals();
function changeAdvanced(n) { const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue(
myData.current.node!.template[n].advanced =
!myData.current.node!.template[n]?.advanced;
}
const handleOnNewValue = (newValue: any, key: string, setDb?: boolean) => {
myData.current.node!.template[key].value = newValue;
if (setDb) {
myData.current.node!.template[key].load_from_db = newValue;
}
};
const rowData = useRowData(data, open);
const columnDefs: ColDef[] = useColumnDefs(
data, data,
handleOnNewValue, takeSnapshot,
changeAdvanced, handleUpdateValues,
open, debouncedHandleUpdateValues,
setNode,
); );
const [gridApi, setGridApi] = useState<GridApi | null>(null); const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass(
data,
takeSnapshot,
setNode,
updateNodeInternals,
);
useEffect(() => { const [nodeClass, setNodeClass] = useState<APIClassType>(data.node!);
if (gridApi && open) {
myData.current = cloneDeep(data); const handleNodeClass = (
gridApi.refreshCells(); newNodeClass: APIClassType,
} name: string,
}, [gridApi, open]); code: string,
type?: string,
) => {
handleNodeClassHook(newNodeClass, name, code, type);
setNodeClass(newNodeClass);
};
const { handleChangeAdvanced: handleChangeAdvancedHook } =
useHandleChangeAdvanced(data, takeSnapshot, setNode, updateNodeInternals);
const rowData = useRowData(data, nodeClass, open);
const columnDefs: ColDef[] = useColumnDefs(
nodeClass,
handleOnNewValueHook,
handleNodeClass,
handleChangeAdvancedHook,
open,
);
return ( return (
<BaseModal key={data.id} open={open} setOpen={setOpen}> <BaseModal key={data.id} open={open} setOpen={setOpen}>
@ -80,9 +99,6 @@ const EditNodeModal = forwardRef(
{nodeLength > 0 && ( {nodeLength > 0 && (
<TableComponent <TableComponent
key={"editNode"} key={"editNode"}
onGridReady={(params) => {
setGridApi(params.api);
}}
tooltipShowDelay={0.5} tooltipShowDelay={0.5}
columnDefs={columnDefs} columnDefs={columnDefs}
rowData={rowData} rowData={rowData}
@ -91,22 +107,11 @@ const EditNodeModal = forwardRef(
</div> </div>
</div> </div>
</BaseModal.Content> </BaseModal.Content>
<BaseModal.Footer>
<BaseModal.Footer <div className="flex w-full justify-end gap-2 pt-2">
submit={{ <Button onClick={() => setOpen(false)}>Close</Button>
label: "Save Changes", </div>
onClick: () => { </BaseModal.Footer>
setNode(data.id, (old) => ({
...old,
data: {
...old.data,
node: myData.current.node,
},
}));
setOpen(false);
},
}}
/>
</BaseModal> </BaseModal>
); );
}, },

View file

@ -54,7 +54,7 @@ test("user must be able to send an image on chat", async ({ page }) => {
await page.getByText("Chat Input", { exact: true }).click(); await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("more-options-modal").click(); await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click(); await page.getByTestId("edit-button-modal").click();
await page.getByText("Save Changes").click(); await page.getByText("Close").last().click();
await page.getByText("Playground", { exact: true }).click(); await page.getByText("Playground", { exact: true }).click();

View file

@ -93,12 +93,12 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
await page.getByText("Chat Input", { exact: true }).click(); await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("advanced-button-modal").click(); await page.getByTestId("advanced-button-modal").click();
await page.getByTestId("showsender_name").click(); await page.getByTestId("showsender_name").click();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByText("Chat Output", { exact: true }).click(); await page.getByText("Chat Output", { exact: true }).click();
await page.getByTestId("advanced-button-modal").click(); await page.getByTestId("advanced-button-modal").click();
await page.getByTestId("showsender_name").click(); await page.getByTestId("showsender_name").click();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page await page
.getByTestId("popover-anchor-input-sender_name") .getByTestId("popover-anchor-input-sender_name")

View file

@ -472,7 +472,7 @@ AI:
.getByTestId("popover-anchor-input-input_message-edit") .getByTestId("popover-anchor-input-input_message-edit")
.nth(0) .nth(0)
.fill("You're Happy! 🤪"); .fill("You're Happy! 🤪");
await page.getByText("Save Changes").click(); await page.getByText("Close").last().click();
await page.getByTitle("zoom in").click(); await page.getByTitle("zoom in").click();
await page.getByTitle("zoom in").click(); await page.getByTitle("zoom in").click();
@ -495,7 +495,7 @@ AI:
.getByTestId("popover-anchor-input-input_message-edit") .getByTestId("popover-anchor-input-input_message-edit")
.nth(0) .nth(0)
.fill("You're Sad! 🥲"); .fill("You're Sad! 🥲");
await page.getByText("Save Changes").click(); await page.getByText("Close").last().click();
await page.getByTitle("fit view").click({ await page.getByTitle("fit view").click({
force: true, force: true,

View file

@ -144,7 +144,7 @@ test("dropDownComponent", async ({ page }) => {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
value = await page.getByTestId("dropdown-model_id").innerText(); value = await page.getByTestId("dropdown-model_id").innerText();
if (value !== "cohere.embed-multilingual-v3") { if (value !== "cohere.embed-multilingual-v3") {

View file

@ -99,7 +99,7 @@ test("FloatComponent", async ({ page }) => {
await page.locator('//*[@id="showmirostat_tau"]').isChecked(), await page.locator('//*[@id="showmirostat_tau"]').isChecked(),
).toBeFalsy(); ).toBeFalsy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
const plusButtonLocator = page.locator('//*[@id="float-input"]'); const plusButtonLocator = page.locator('//*[@id="float-input"]');
const elementCount = await plusButtonLocator?.count(); const elementCount = await plusButtonLocator?.count();
@ -115,7 +115,7 @@ test("FloatComponent", async ({ page }) => {
await page.locator('//*[@id="showtemperature"]').isChecked(), await page.locator('//*[@id="showtemperature"]').isChecked(),
).toBeTruthy(); ).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.locator('//*[@id="float-input"]').click(); await page.locator('//*[@id="float-input"]').click();
await page.locator('//*[@id="float-input"]').fill("3"); await page.locator('//*[@id="float-input"]').fill("3");

View file

@ -135,7 +135,7 @@ test("InputComponent", async ({ page }) => {
.getByTestId("popover-anchor-input-collection_name-edit") .getByTestId("popover-anchor-input-collection_name-edit")
.fill("NEW_collection_name_test_123123123!@#$&*(&%$@ÇÇÇÀõe"); .fill("NEW_collection_name_test_123123123!@#$&*(&%$@ÇÇÇÀõe");
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
const plusButtonLocator = page.getByTestId("input-collection_name"); const plusButtonLocator = page.getByTestId("input-collection_name");
const elementCount = await plusButtonLocator?.count(); const elementCount = await plusButtonLocator?.count();
@ -152,7 +152,7 @@ test("InputComponent", async ({ page }) => {
await page.locator('//*[@id="showcollection_name"]').isChecked(), await page.locator('//*[@id="showcollection_name"]').isChecked(),
).toBeTruthy(); ).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
let value = await page let value = await page
.getByTestId("popover-anchor-input-collection_name") .getByTestId("popover-anchor-input-collection_name")

View file

@ -87,7 +87,7 @@ test("InputListComponent", async ({ page }) => {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByTestId("input-list-minus-btn_urls-2").isHidden(); await page.getByTestId("input-list-minus-btn_urls-2").isHidden();

View file

@ -51,7 +51,7 @@ test("IntComponent", async ({ page }) => {
await page.getByTestId("edit-button-modal").click(); await page.getByTestId("edit-button-modal").click();
await page.getByTestId("showmax_tokens").click(); await page.getByTestId("showmax_tokens").click();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByTestId("int-input-max_tokens").click(); await page.getByTestId("int-input-max_tokens").click();
await page await page
.getByTestId("int-input-max_tokens") .getByTestId("int-input-max_tokens")
@ -172,7 +172,7 @@ test("IntComponent", async ({ page }) => {
await page.locator('//*[@id="showtemperature"]').isChecked(), await page.locator('//*[@id="showtemperature"]').isChecked(),
).toBeFalsy(); ).toBeFalsy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
const plusButtonLocator = page.getByTestId("int-input-max_tokens"); const plusButtonLocator = page.getByTestId("int-input-max_tokens");
const elementCount = await plusButtonLocator?.count(); const elementCount = await plusButtonLocator?.count();
@ -195,7 +195,7 @@ test("IntComponent", async ({ page }) => {
expect(false).toBeTruthy(); expect(false).toBeTruthy();
} }
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByTestId("int-input-max_tokens").click(); await page.getByTestId("int-input-max_tokens").click();
await page.getByTestId("int-input-max_tokens").fill("3"); await page.getByTestId("int-input-max_tokens").fill("3");

View file

@ -47,7 +47,7 @@ test("KeypairListComponent", async ({ page }) => {
await page.getByTestId("showmodel_kwargs").click(); await page.getByTestId("showmodel_kwargs").click();
expect(await page.getByTestId("showmodel_kwargs").isChecked()).toBeTruthy(); expect(await page.getByTestId("showmodel_kwargs").isChecked()).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.locator('//*[@id="keypair0"]').click(); await page.locator('//*[@id="keypair0"]').click();
await page.locator('//*[@id="keypair0"]').fill("testtesttesttest"); await page.locator('//*[@id="keypair0"]').fill("testtesttesttest");
@ -92,7 +92,7 @@ test("KeypairListComponent", async ({ page }) => {
expect( expect(
await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(), await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(),
).toBeFalsy(); ).toBeFalsy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
const plusButtonLocator = page.locator('//*[@id="plusbtn0"]'); const plusButtonLocator = page.locator('//*[@id="plusbtn0"]');
const elementCount = await plusButtonLocator?.count(); const elementCount = await plusButtonLocator?.count();
@ -115,7 +115,7 @@ test("KeypairListComponent", async ({ page }) => {
const elementKeyCount = await keyPairVerification?.count(); const elementKeyCount = await keyPairVerification?.count();
if (elementKeyCount === 1) { if (elementKeyCount === 1) {
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByTestId("div-generic-node").click(); await page.getByTestId("div-generic-node").click();

View file

@ -60,7 +60,7 @@ test("LangflowShortcuts", async ({ page }) => {
await page.getByTitle("zoom out").click(); await page.getByTitle("zoom out").click();
await page.getByTestId("generic-node-title-arrangement").click(); await page.getByTestId("generic-node-title-arrangement").click();
await page.keyboard.press(`${control}+Shift+A`); await page.keyboard.press(`${control}+Shift+A`);
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByTestId("generic-node-title-arrangement").click(); await page.getByTestId("generic-node-title-arrangement").click();
await page.keyboard.press(`${control}+d`); await page.keyboard.press(`${control}+d`);

View file

@ -174,5 +174,5 @@ test("NestedComponent", async ({ page }) => {
await page.locator('//*[@id="showtext_key"]').isChecked(), await page.locator('//*[@id="showtext_key"]').isChecked(),
).toBeTruthy(); ).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
}); });

View file

@ -182,7 +182,7 @@ test("PromptTemplateComponent", async ({ page }) => {
await page.locator('//*[@id="showprompt"]').click(); await page.locator('//*[@id="showprompt"]').click();
expect(await page.locator('//*[@id="showprompt"]').isChecked()).toBeTruthy(); expect(await page.locator('//*[@id="showprompt"]').isChecked()).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByTestId("more-options-modal").click(); await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click(); await page.getByTestId("edit-button-modal").click();

View file

@ -62,7 +62,7 @@ test("ToggleComponent", async ({ page }) => {
await page.locator('//*[@id="showload_hidden"]').isChecked(), await page.locator('//*[@id="showload_hidden"]').isChecked(),
).toBeTruthy(); ).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.waitForSelector('[title="fit view"]', { await page.waitForSelector('[title="fit view"]', {
timeout: 100000, timeout: 100000,
@ -152,7 +152,7 @@ test("ToggleComponent", async ({ page }) => {
await page.locator('//*[@id="showuse_multithreading"]').isChecked(), await page.locator('//*[@id="showuse_multithreading"]').isChecked(),
).toBeFalsy(); ).toBeFalsy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
const plusButtonLocator = page.getByTestId("toggle-load_hidden"); const plusButtonLocator = page.getByTestId("toggle-load_hidden");
const elementCount = await plusButtonLocator?.count(); const elementCount = await plusButtonLocator?.count();
@ -173,7 +173,7 @@ test("ToggleComponent", async ({ page }) => {
await page.getByTestId("toggle-edit-load_hidden").isChecked(), await page.getByTestId("toggle-edit-load_hidden").isChecked(),
).toBeTruthy(); ).toBeTruthy();
await page.getByText("Save Changes", { exact: true }).click(); await page.getByText("Close").last().click();
await page.getByTestId("toggle-load_hidden").click(); await page.getByTestId("toggle-load_hidden").click();
expect( expect(