From 3889d5ff3b276b9f0ee68ae9d31ec0113b3651fe Mon Sep 17 00:00:00 2001 From: Mike Fortman Date: Wed, 21 May 2025 13:46:46 -0500 Subject: [PATCH] refactor: Improve Reactflow wrapping around toolbars, canvas controls, etc (#8130) * update the wrapping of the reactflow * [autofix.ci] apply automated fixes * test button fix * [autofix.ci] apply automated fixes * selector fix * fix slash --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .../core/canvasControlsComponent/index.tsx | 2 +- .../core/flowToolbarComponent/index.tsx | 2 +- src/frontend/src/modals/IOModal/new-modal.tsx | 66 +++++++++---------- .../PageComponent/MemoizedComponents.tsx | 2 +- .../components/PageComponent/index.tsx | 57 ++++++++-------- .../chatInputOutputUser-shard-0.spec.ts | 3 +- .../tests/core/features/playground.spec.ts | 2 +- .../core/features/saveComponents.spec.ts | 7 +- .../core/integrations/Basic Prompting.spec.ts | 2 +- .../core/integrations/Blog Writer.spec.ts | 2 +- .../core/integrations/Document QA.spec.ts | 2 +- .../core/integrations/Dynamic Agent.spec.ts | 2 +- .../integrations/Hierarchical Agent.spec.ts | 2 +- .../Image Sentiment Analysis.spec.ts | 2 +- .../integrations/Instagram Copywriter.spec.ts | 2 +- .../integrations/Invoice Summarizer.spec.ts | 2 +- .../core/integrations/Market Research.spec.ts | 2 +- .../core/integrations/Memory Chatbot.spec.ts | 2 +- .../core/integrations/Prompt Chaining.spec.ts | 2 +- .../SEO Keyword Generator.spec.ts | 2 +- .../core/integrations/SaaS Pricing.spec.ts | 2 +- .../Sequential Task Agent.spec.ts | 2 +- .../Text Sentiment Analysis.spec.ts | 2 +- .../Travel Planning Agent.spec.ts | 2 +- .../Twitter Thread Generator.spec.ts | 2 +- .../core/integrations/Vector Store.spec.ts | 2 +- .../core/integrations/decisionFlow.spec.ts | 2 +- .../core/integrations/textInputOutput.spec.ts | 4 +- .../regression/generalBugs-shard-9.spec.ts | 2 +- .../core/unit/fileUploadComponent.spec.ts | 6 +- .../features/langflowShortcuts.spec.ts | 2 +- .../features/limit-file-size-upload.spec.ts | 2 +- .../features/stop-button-playground.spec.ts | 2 +- .../chatInputOutputUser-shard-2.spec.ts | 6 +- .../general-bugs-shard-3836.spec.ts | 2 +- .../regression/generalBugs-shard-3.spec.ts | 2 +- 36 files changed, 101 insertions(+), 106 deletions(-) diff --git a/src/frontend/src/components/core/canvasControlsComponent/index.tsx b/src/frontend/src/components/core/canvasControlsComponent/index.tsx index 1c3a9869c..5ec115f0d 100644 --- a/src/frontend/src/components/core/canvasControlsComponent/index.tsx +++ b/src/frontend/src/components/core/canvasControlsComponent/index.tsx @@ -109,7 +109,7 @@ const CanvasControls = ({ children }) => { return ( {/* Zoom In */} diff --git a/src/frontend/src/components/core/flowToolbarComponent/index.tsx b/src/frontend/src/components/core/flowToolbarComponent/index.tsx index 5bdc0d568..5dc24c9f5 100644 --- a/src/frontend/src/components/core/flowToolbarComponent/index.tsx +++ b/src/frontend/src/components/core/flowToolbarComponent/index.tsx @@ -49,7 +49,7 @@ const FlowToolbar = memo(function FlowToolbar(): JSX.Element { return ( <> - +
state.nodes); const setIOModalOpen = useFlowsManagerStore((state) => state.setIOModalOpen); - const inputs = useFlowStore((state) => state.inputs).filter( - (input) => input.type !== "ChatInput", + const inputs = useFlowStore((state) => state.inputs); + const outputs = useFlowStore((state) => state.outputs); + const nodes = useFlowStore((state) => state.nodes); + const buildFlow = useFlowStore((state) => state.buildFlow); + const setIsBuilding = useFlowStore((state) => state.setIsBuilding); + const isBuilding = useFlowStore((state) => state.isBuilding); + const { flowIcon, flowId, flowGradient, flowName } = useFlowStore( + useShallow((state) => ({ + flowIcon: state.currentFlow?.icon, + flowId: state.currentFlow?.id, + flowGradient: state.currentFlow?.gradient, + flowName: state.currentFlow?.name, + })), ); - const chatInput = useFlowStore((state) => state.inputs).find( - (input) => input.type === "ChatInput", - ); - const outputs = useFlowStore((state) => state.outputs).filter( + const filteredInputs = inputs.filter((input) => input.type !== "ChatInput"); + const chatInput = inputs.find((input) => input.type === "ChatInput"); + const filteredOutputs = outputs.filter( (output) => output.type !== "ChatOutput", ); - const chatOutput = useFlowStore((state) => state.outputs).find( - (output) => output.type === "ChatOutput", - ); - const nodes = useFlowStore((state) => state.nodes).filter( + const chatOutput = outputs.find((output) => output.type === "ChatOutput"); + const filteredNodes = nodes.filter( (node) => inputs.some((input) => input.id === node.id) || - outputs.some((output) => output.id === node.id), + filteredOutputs.some((output) => output.id === node.id), ); const haveChat = chatInput || chatOutput; - const [selectedTab, setSelectedTab] = useState( - inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0, - ); const setErrorData = useAlertStore((state) => state.setErrorData); const setSuccessData = useAlertStore((state) => state.setSuccessData); const deleteSession = useMessagesStore((state) => state.deleteSession); @@ -68,14 +74,12 @@ export default function IOModal({ const currentFlowId = playgroundPage ? uuidv5(`${clientId}_${realFlowId}`, uuidv5.DNS) : realFlowId; - const currentFlow = useFlowStore((state) => state.currentFlow); const [sidebarOpen, setSidebarOpen] = useState(true); const { mutate: deleteSessionFunction } = useDeleteMessages(); const [visibleSession, setvisibleSession] = useState( currentFlowId, ); - const flowName = useFlowStore((state) => state.currentFlow?.name); const PlaygroundTitle = playgroundPage && flowName ? flowName : "Playground"; useEffect(() => { @@ -113,10 +117,10 @@ export default function IOModal({ function startView() { if (!chatInput && !chatOutput) { - if (inputs.length > 0) { - return inputs[0]; + if (filteredInputs.length > 0) { + return filteredInputs[0]; } else { - return outputs[0]; + return filteredOutputs[0]; } } else { return undefined; @@ -127,10 +131,6 @@ export default function IOModal({ { type: string; id: string } | undefined >(startView()); - const buildFlow = useFlowStore((state) => state.buildFlow); - const setIsBuilding = useFlowStore((state) => state.setIsBuilding); - - const isBuilding = useFlowStore((state) => state.isBuilding); const messages = useMessagesStore((state) => state.messages); const [sessions, setSessions] = useState( Array.from( @@ -184,10 +184,6 @@ export default function IOModal({ [isBuilding, setIsBuilding, chatValue, chatInput?.id, sessionId, buildFlow], ); - useEffect(() => { - setSelectedTab(inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0); - }, [allNodes.length]); - useEffect(() => { const sessions = new Set(); messages @@ -270,9 +266,9 @@ export default function IOModal({ }, [playgroundPage, messages]); const swatchIndex = - (currentFlow?.gradient && !isNaN(parseInt(currentFlow?.gradient)) - ? parseInt(currentFlow?.gradient) - : getNumberFromString(currentFlow?.gradient ?? currentFlow?.id ?? "")) % + (flowGradient && !isNaN(parseInt(flowGradient)) + ? parseInt(flowGradient) + : getNumberFromString(flowGradient ?? flowId ?? "")) % swatchColors.length; return ( @@ -313,7 +309,7 @@ export default function IOModal({ )} >
@@ -392,11 +388,11 @@ export default function IOModal({ selectedViewField={selectedViewField} setSelectedViewField={setSelectedViewField} haveChat={haveChat} - inputs={inputs} - outputs={outputs} + inputs={filteredInputs} + outputs={filteredOutputs} sessions={sessions} currentFlowId={currentFlowId} - nodes={nodes} + nodes={filteredNodes} /> )} ( button]:border-0 [&>button]:bg-background hover:[&>button]:bg-accent", + "react-flow__controls !top-auto !m-2 flex gap-1.5 rounded-md border border-secondary-hover bg-background fill-foreground stroke-foreground p-1.5 text-primary shadow transition-all duration-300 [&>button]:border-0 [&>button]:bg-background hover:[&>button]:bg-accent", "pointer-events-auto opacity-100 group-data-[open=true]/sidebar-wrapper:pointer-events-none group-data-[open=true]/sidebar-wrapper:-translate-x-full group-data-[open=true]/sidebar-wrapper:opacity-0", )} position="top-left" diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index 22ff6ad48..34e3899d5 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -141,11 +141,12 @@ export default function Page({ const shadowBoxHeight = NOTE_NODE_MIN_HEIGHT * (zoomLevel || 1); const shadowBoxBackgroundColor = COLOR_OPTIONS[Object.keys(COLOR_OPTIONS)[0]]; - function handleGroupNode() { + const handleGroupNode = useCallback(() => { takeSnapshot(); - if (validateSelection(lastSelection!, edges).length === 0) { - const clonedNodes = cloneDeep(nodes); - const clonedEdges = cloneDeep(edges); + const edgesState = useFlowStore.getState().edges; + if (validateSelection(lastSelection!, edgesState).length === 0) { + const clonedNodes = cloneDeep(useFlowStore.getState().nodes); + const clonedEdges = cloneDeep(edgesState); const clonedSelection = cloneDeep(lastSelection); updateIds({ nodes: clonedNodes, edges: clonedEdges }, clonedSelection!); const { newFlow } = generateFlow( @@ -169,10 +170,10 @@ export default function Page({ } else { setErrorData({ title: INVALID_SELECTION_ERROR_ALERT, - list: validateSelection(lastSelection!, edges), + list: validateSelection(lastSelection!, edgesState), }); } - } + }, [lastSelection, setNodes, setErrorData, takeSnapshot]); useEffect(() => { const handleMouseMove = (event) => { @@ -556,6 +557,27 @@ export default function Page({
{showCanvas ? (
+ {!view && ( + <> + + + + )} + +
+ +
+ nodes={nodes} edges={edges} @@ -595,29 +617,6 @@ export default function Page({ onEdgeClick={handleEdgeClick} > - {!view && ( - <> - - - - )} - -
- -
- { - handleGroupNode(); - }} - />
{ // Now dispatch await page.dispatchEvent( - "//*[@id='react-flow-id']/div[1]/div[1]/div", + "//*[@data-testid='rf__wrapper']/div[1]/div", "drop", { dataTransfer, @@ -48,9 +48,8 @@ test.describe("save component tests", () => { expect(true).toBeTruthy(); } - await page - .locator('//*[@id="react-flow-id"]/div[1]/div[2]/button[3]') - .click(); + // Log button element + await page.getByTestId("fit_view").click(); await zoomOut(page, 2); diff --git a/src/frontend/tests/core/integrations/Basic Prompting.spec.ts b/src/frontend/tests/core/integrations/Basic Prompting.spec.ts index 18b2f5da4..ee1e446ac 100644 --- a/src/frontend/tests/core/integrations/Basic Prompting.spec.ts +++ b/src/frontend/tests/core/integrations/Basic Prompting.spec.ts @@ -32,7 +32,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/Blog Writer.spec.ts b/src/frontend/tests/core/integrations/Blog Writer.spec.ts index 58f46fa3b..3272bc94c 100644 --- a/src/frontend/tests/core/integrations/Blog Writer.spec.ts +++ b/src/frontend/tests/core/integrations/Blog Writer.spec.ts @@ -50,7 +50,7 @@ withEventDeliveryModes( timeout: 30000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByPlaceholder( "No chat input variables found. Click to run your flow.", diff --git a/src/frontend/tests/core/integrations/Document QA.spec.ts b/src/frontend/tests/core/integrations/Document QA.spec.ts index c267a5588..fbeb8f29e 100644 --- a/src/frontend/tests/core/integrations/Document QA.spec.ts +++ b/src/frontend/tests/core/integrations/Document QA.spec.ts @@ -38,7 +38,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/Dynamic Agent.spec.ts b/src/frontend/tests/core/integrations/Dynamic Agent.spec.ts index 133e9701a..4120cff3e 100644 --- a/src/frontend/tests/core/integrations/Dynamic Agent.spec.ts +++ b/src/frontend/tests/core/integrations/Dynamic Agent.spec.ts @@ -42,7 +42,7 @@ test.skip( await page.getByText("built successfully").last().click({ timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForTimeout(1000); expect(page.getByText("apple").last()).toBeVisible(); const textContents = await page diff --git a/src/frontend/tests/core/integrations/Hierarchical Agent.spec.ts b/src/frontend/tests/core/integrations/Hierarchical Agent.spec.ts index 299ac3c31..a20a431a8 100644 --- a/src/frontend/tests/core/integrations/Hierarchical Agent.spec.ts +++ b/src/frontend/tests/core/integrations/Hierarchical Agent.spec.ts @@ -48,7 +48,7 @@ test.skip( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); expect(await page.locator(".markdown").count()).toBeGreaterThan(0); diff --git a/src/frontend/tests/core/integrations/Image Sentiment Analysis.spec.ts b/src/frontend/tests/core/integrations/Image Sentiment Analysis.spec.ts index b96d9020f..527422e4a 100644 --- a/src/frontend/tests/core/integrations/Image Sentiment Analysis.spec.ts +++ b/src/frontend/tests/core/integrations/Image Sentiment Analysis.spec.ts @@ -39,7 +39,7 @@ withEventDeliveryModes( await initialGPTsetup(page); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="input-chat-playground"]', { timeout: 100000, diff --git a/src/frontend/tests/core/integrations/Instagram Copywriter.spec.ts b/src/frontend/tests/core/integrations/Instagram Copywriter.spec.ts index ac25fa817..e5dbbb100 100644 --- a/src/frontend/tests/core/integrations/Instagram Copywriter.spec.ts +++ b/src/frontend/tests/core/integrations/Instagram Copywriter.spec.ts @@ -50,7 +50,7 @@ test( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/Invoice Summarizer.spec.ts b/src/frontend/tests/core/integrations/Invoice Summarizer.spec.ts index 971926d0b..9bad23b56 100644 --- a/src/frontend/tests/core/integrations/Invoice Summarizer.spec.ts +++ b/src/frontend/tests/core/integrations/Invoice Summarizer.spec.ts @@ -44,7 +44,7 @@ test( }); // Switch to Playground - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); // Wait for the playground to be ready const inputPlaceholder = page diff --git a/src/frontend/tests/core/integrations/Market Research.spec.ts b/src/frontend/tests/core/integrations/Market Research.spec.ts index 84a9744e7..c0bb97015 100644 --- a/src/frontend/tests/core/integrations/Market Research.spec.ts +++ b/src/frontend/tests/core/integrations/Market Research.spec.ts @@ -50,7 +50,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/Memory Chatbot.spec.ts b/src/frontend/tests/core/integrations/Memory Chatbot.spec.ts index 7a7af1f87..79f809a23 100644 --- a/src/frontend/tests/core/integrations/Memory Chatbot.spec.ts +++ b/src/frontend/tests/core/integrations/Memory Chatbot.spec.ts @@ -31,7 +31,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) diff --git a/src/frontend/tests/core/integrations/Prompt Chaining.spec.ts b/src/frontend/tests/core/integrations/Prompt Chaining.spec.ts index babcf171e..3fcaeb8a4 100644 --- a/src/frontend/tests/core/integrations/Prompt Chaining.spec.ts +++ b/src/frontend/tests/core/integrations/Prompt Chaining.spec.ts @@ -39,7 +39,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/SEO Keyword Generator.spec.ts b/src/frontend/tests/core/integrations/SEO Keyword Generator.spec.ts index adda1fcb5..20328f2bb 100644 --- a/src/frontend/tests/core/integrations/SEO Keyword Generator.spec.ts +++ b/src/frontend/tests/core/integrations/SEO Keyword Generator.spec.ts @@ -39,7 +39,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/SaaS Pricing.spec.ts b/src/frontend/tests/core/integrations/SaaS Pricing.spec.ts index 34265db09..a3465d49a 100644 --- a/src/frontend/tests/core/integrations/SaaS Pricing.spec.ts +++ b/src/frontend/tests/core/integrations/SaaS Pricing.spec.ts @@ -39,7 +39,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/Sequential Task Agent.spec.ts b/src/frontend/tests/core/integrations/Sequential Task Agent.spec.ts index 2d06e8b30..d11998945 100644 --- a/src/frontend/tests/core/integrations/Sequential Task Agent.spec.ts +++ b/src/frontend/tests/core/integrations/Sequential Task Agent.spec.ts @@ -37,7 +37,7 @@ test.skip( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); expect(await page.locator(".markdown").count()).toBeGreaterThan(0); diff --git a/src/frontend/tests/core/integrations/Text Sentiment Analysis.spec.ts b/src/frontend/tests/core/integrations/Text Sentiment Analysis.spec.ts index e7e1c1d28..5f3785137 100644 --- a/src/frontend/tests/core/integrations/Text Sentiment Analysis.spec.ts +++ b/src/frontend/tests/core/integrations/Text Sentiment Analysis.spec.ts @@ -50,7 +50,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("Add a Chat Input component to your flow to send messages.", { exact: true, diff --git a/src/frontend/tests/core/integrations/Travel Planning Agent.spec.ts b/src/frontend/tests/core/integrations/Travel Planning Agent.spec.ts index 9a949029e..ce31f381f 100644 --- a/src/frontend/tests/core/integrations/Travel Planning Agent.spec.ts +++ b/src/frontend/tests/core/integrations/Travel Planning Agent.spec.ts @@ -71,7 +71,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector("text=default session", { timeout: 30000, diff --git a/src/frontend/tests/core/integrations/Twitter Thread Generator.spec.ts b/src/frontend/tests/core/integrations/Twitter Thread Generator.spec.ts index 03edbbd4a..f726f8ee4 100644 --- a/src/frontend/tests/core/integrations/Twitter Thread Generator.spec.ts +++ b/src/frontend/tests/core/integrations/Twitter Thread Generator.spec.ts @@ -41,7 +41,7 @@ withEventDeliveryModes( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page .getByText("No input message provided.", { exact: true }) .last() diff --git a/src/frontend/tests/core/integrations/Vector Store.spec.ts b/src/frontend/tests/core/integrations/Vector Store.spec.ts index 5c1a1f295..901a03311 100644 --- a/src/frontend/tests/core/integrations/Vector Store.spec.ts +++ b/src/frontend/tests/core/integrations/Vector Store.spec.ts @@ -254,7 +254,7 @@ withEventDeliveryModes( timeout: 30000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="input-chat-playground"]', { timeout: 60000, }); diff --git a/src/frontend/tests/core/integrations/decisionFlow.spec.ts b/src/frontend/tests/core/integrations/decisionFlow.spec.ts index 1fef2601e..d34815371 100644 --- a/src/frontend/tests/core/integrations/decisionFlow.spec.ts +++ b/src/frontend/tests/core/integrations/decisionFlow.spec.ts @@ -350,7 +350,7 @@ test( await page.getByTestId("dropdown_str_model_name").click(); await page.getByTestId("gpt-4o-1-option").click(); await page.getByTestId("fit_view").click(); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="input-chat-playground"]', { timeout: 100000, }); diff --git a/src/frontend/tests/core/integrations/textInputOutput.spec.ts b/src/frontend/tests/core/integrations/textInputOutput.spec.ts index a8fa93a0e..199aaa0ba 100644 --- a/src/frontend/tests/core/integrations/textInputOutput.spec.ts +++ b/src/frontend/tests/core/integrations/textInputOutput.spec.ts @@ -144,7 +144,7 @@ test.skip( await page.getByTestId("dropdown_str_model_name").click(); await page.getByTestId("gpt-4o-1-option").click(); await page.waitForTimeout(1000); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.getByTestId("button_run_text_output").click(); await page .getByTestId(/^rf__node-TextOutput-[a-zA-Z0-9]+$/) @@ -167,7 +167,7 @@ test.skip( .getByTestId(/^rf__node-TextInput-[a-zA-Z0-9]+$/) .getByTestId("textarea_str_input_value") .fill("This is a test, again just to be sure!"); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.getByText("Run Flow", { exact: true }).click(); await page.waitForTimeout(5000); textInputContent = await page diff --git a/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts b/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts index 91605ce88..6678abdbe 100644 --- a/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts +++ b/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts @@ -105,7 +105,7 @@ AI: await page.locator('//*[@id="react-flow-id"]').hover(); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="button-send"]', { timeout: 100000, diff --git a/src/frontend/tests/core/unit/fileUploadComponent.spec.ts b/src/frontend/tests/core/unit/fileUploadComponent.spec.ts index 4bf29ea60..3bbc5c384 100644 --- a/src/frontend/tests/core/unit/fileUploadComponent.spec.ts +++ b/src/frontend/tests/core/unit/fileUploadComponent.spec.ts @@ -303,7 +303,7 @@ test( .first() .click(); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector("text=Run Flow", { timeout: 30000, @@ -369,7 +369,9 @@ test( timeout: 1000, }); await page.getByTestId(`remove-file-button-${renamedTxtFile}`).click(); - await page.getByText("Playground", { exact: true }).last().click(); + await page + .getByRole("button", { name: "Playground", exact: true }) + .click(); await page.getByTestId("icon-MoreHorizontal").last().click(); await page.getByText("Delete", { exact: true }).last().click(); diff --git a/src/frontend/tests/extended/features/langflowShortcuts.spec.ts b/src/frontend/tests/extended/features/langflowShortcuts.spec.ts index e3575c843..e152a78cd 100644 --- a/src/frontend/tests/extended/features/langflowShortcuts.spec.ts +++ b/src/frontend/tests/extended/features/langflowShortcuts.spec.ts @@ -26,7 +26,7 @@ test( await page.mouse.up(); await page.mouse.down(); - await page.locator('//*[@id="react-flow-id"]/div/div[2]/button[3]').click(); + await page.getByTestId("fit_view").click(); await adjustScreenView(page); await page.getByTestId("generic-node-title-arrangement").click(); diff --git a/src/frontend/tests/extended/features/limit-file-size-upload.spec.ts b/src/frontend/tests/extended/features/limit-file-size-upload.spec.ts index 4774b4a4d..109d73120 100644 --- a/src/frontend/tests/extended/features/limit-file-size-upload.spec.ts +++ b/src/frontend/tests/extended/features/limit-file-size-upload.spec.ts @@ -44,7 +44,7 @@ test( await page.getByTestId("edit-button-modal").last().click(); await page.getByText("Close").last().click(); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); // Read the image file as a binary string const filePath = "tests/assets/chain.png"; diff --git a/src/frontend/tests/extended/features/stop-button-playground.spec.ts b/src/frontend/tests/extended/features/stop-button-playground.spec.ts index fdfdf774d..b5d40e376 100644 --- a/src/frontend/tests/extended/features/stop-button-playground.spec.ts +++ b/src/frontend/tests/extended/features/stop-button-playground.spec.ts @@ -109,7 +109,7 @@ class CustomComponent(Component): await page.getByTestId("button_run_chat output").click(); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="button-stop"]', { timeout: 30000, diff --git a/src/frontend/tests/extended/integrations/chatInputOutputUser-shard-2.spec.ts b/src/frontend/tests/extended/integrations/chatInputOutputUser-shard-2.spec.ts index aab3c9ba3..88c9a6208 100644 --- a/src/frontend/tests/extended/integrations/chatInputOutputUser-shard-2.spec.ts +++ b/src/frontend/tests/extended/integrations/chatInputOutputUser-shard-2.spec.ts @@ -24,7 +24,7 @@ test( await initialGPTsetup(page); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="input-chat-playground"]', { timeout: 100000, @@ -56,7 +56,7 @@ test( .fill( "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!", ); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="button-send"]', { timeout: 100000, @@ -83,7 +83,7 @@ test( .nth(0) .fill("TestSenderNameAI"); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="button-send"]', { timeout: 100000, diff --git a/src/frontend/tests/extended/regression/general-bugs-shard-3836.spec.ts b/src/frontend/tests/extended/regression/general-bugs-shard-3836.spec.ts index aa84dfd3b..c0a223f9f 100644 --- a/src/frontend/tests/extended/regression/general-bugs-shard-3836.spec.ts +++ b/src/frontend/tests/extended/regression/general-bugs-shard-3836.spec.ts @@ -41,7 +41,7 @@ test( timeout: 15000, }); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="button-send"]', { timeout: 100000, diff --git a/src/frontend/tests/extended/regression/generalBugs-shard-3.spec.ts b/src/frontend/tests/extended/regression/generalBugs-shard-3.spec.ts index f96bd2928..c3d468135 100644 --- a/src/frontend/tests/extended/regression/generalBugs-shard-3.spec.ts +++ b/src/frontend/tests/extended/regression/generalBugs-shard-3.spec.ts @@ -81,7 +81,7 @@ test( .click(); await page.getByTestId("fit_view").click(); - await page.getByText("Playground", { exact: true }).last().click(); + await page.getByRole("button", { name: "Playground", exact: true }).click(); await page.waitForSelector('[data-testid="input-chat-playground"]', { timeout: 100000, });