From 595746e797ae190dc3aa7c0791b5eff435b5ef92 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:45:09 -0300 Subject: [PATCH] fix: Fix api_key missing error when adding a flow in ComposIO + tests (#3432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🐛 (ComposioAPI.py): Fix issue where build_config was not being updated correctly when api_key is not empty * 🐛 (GenericNode/index.tsx): Fix potential null pointer exception by adding non-null assertion operator to info property access ✨ (generalBugs-shard-11.spec.ts): Add end-to-end tests to ensure users can use ComposIO without api_key error and connect tools successfully --- .../components/toolkits/ComposioAPI.py | 6 +- .../src/CustomNodes/GenericNode/index.tsx | 2 +- .../generalBugs-shard-11.spec.ts | 127 ++++++++++++++++++ 3 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 src/frontend/tests/scheduled-end-to-end/generalBugs-shard-11.spec.ts diff --git a/src/backend/base/langflow/components/toolkits/ComposioAPI.py b/src/backend/base/langflow/components/toolkits/ComposioAPI.py index cf8dfa2be..7dcebef3b 100644 --- a/src/backend/base/langflow/components/toolkits/ComposioAPI.py +++ b/src/backend/base/langflow/components/toolkits/ComposioAPI.py @@ -147,11 +147,13 @@ class ComposioAPIComponent(LCToolComponent): def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict: if field_name == "api_key": - build_config = self._update_app_names_with_connected_status(build_config) + if hasattr(self, "api_key") and self.api_key != "": + build_config = self._update_app_names_with_connected_status(build_config) return build_config if field_name in {"app_names", "auth_status_config"}: - build_config["auth_status_config"]["value"] = self._check_for_authorization(self._get_normalized_app_name()) + if hasattr(self, "api_key") and self.api_key != "": + build_config = self._update_app_names_with_connected_status(build_config) all_action_names = [action_name for action_name in Action.__annotations__] app_action_names = [ diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 707000c02..bcbd2ce5e 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -263,7 +263,7 @@ export default function GenericNode({ types, )} title={getFieldTitle(data.node?.template!, templateField)} - info={data.node?.template[templateField].info} + info={data.node?.template[templateField].info!} name={templateField} tooltipTitle={ data.node?.template[templateField].input_types?.join("\n") ?? diff --git a/src/frontend/tests/scheduled-end-to-end/generalBugs-shard-11.spec.ts b/src/frontend/tests/scheduled-end-to-end/generalBugs-shard-11.spec.ts new file mode 100644 index 000000000..1d67a5554 --- /dev/null +++ b/src/frontend/tests/scheduled-end-to-end/generalBugs-shard-11.spec.ts @@ -0,0 +1,127 @@ +import { expect, test } from "@playwright/test"; + +test("user should be able to use ComposIO without getting api_key error", async ({ + page, +}) => { + await page.goto("/"); + await page.waitForTimeout(2000); + + let modalCount = 0; + try { + const modalTitleElement = await page.getByTestId("modal-title"); + modalCount = await modalTitleElement.count(); + } catch (error) { + modalCount = 0; + } + + while (modalCount === 0) { + await page.getByText("New Project", { exact: true }).click(); + await page.waitForTimeout(3000); + modalCount = await page.getByTestId("modal-title").count(); + } + + await page.waitForSelector('[data-testid="blank-flow"]', { + timeout: 30000, + }); + await page.getByTestId("blank-flow").click(); + await page.waitForSelector('[data-testid="extended-disclosure"]', { + timeout: 30000, + }); + await page.getByTestId("extended-disclosure").click(); + await page.getByPlaceholder("Search").click(); + await page.getByPlaceholder("Search").fill("composio"); + + await page.waitForTimeout(1000); + + const modelElement = await page.getByTestId("toolkitsComposio Tools"); + const targetElement = await page.locator('//*[@id="react-flow-id"]'); + await modelElement.dragTo(targetElement); + + await page.mouse.up(); + await page.mouse.down(); + + await page.getByTitle("fit view").click(); + await page.getByTitle("zoom out").click(); + await page.getByTitle("zoom out").click(); + + await page.waitForTimeout(1000); + + expect(await page.getByText("api_key").isVisible()).toBe(false); +}); + +test("user should be able to use connect tools", async ({ page }) => { + await page.goto("/"); + await page.waitForTimeout(2000); + + let modalCount = 0; + try { + const modalTitleElement = await page.getByTestId("modal-title"); + modalCount = await modalTitleElement.count(); + } catch (error) { + modalCount = 0; + } + + while (modalCount === 0) { + await page.getByText("New Project", { exact: true }).click(); + await page.waitForTimeout(3000); + modalCount = await page.getByTestId("modal-title").count(); + } + + await page.waitForSelector('[data-testid="blank-flow"]', { + timeout: 30000, + }); + await page.getByTestId("blank-flow").click(); + await page.waitForSelector('[data-testid="extended-disclosure"]', { + timeout: 30000, + }); + await page.getByTestId("extended-disclosure").click(); + await page.getByPlaceholder("Search").click(); + await page.getByPlaceholder("Search").fill("search api"); + + await page.waitForTimeout(1000); + + let modelElement = await page.getByTestId("toolsSearch API"); + let targetElement = await page.locator('//*[@id="react-flow-id"]'); + await modelElement.dragTo(targetElement); + + await page.mouse.up(); + await page.mouse.down(); + + await page.getByTitle("fit view").click(); + await page.getByTitle("zoom out").click(); + await page.getByTitle("zoom out").click(); + + await page.waitForTimeout(1000); + + await page.getByPlaceholder("Search").click(); + await page.getByPlaceholder("Search").fill("tool calling agent"); + + await page.waitForTimeout(1000); + + modelElement = await page.getByTestId("agentsTool Calling Agent"); + targetElement = await page.locator('//*[@id="react-flow-id"]'); + await modelElement.dragTo(targetElement); + + await page.mouse.up(); + await page.mouse.down(); + + await page.getByTitle("fit view").click(); + await page.getByTitle("zoom out").click(); + await page.getByTitle("zoom out").click(); + + //connection + const searchApiOutput = await page + .getByTestId("handle-searchapi-shownode-tool-right") + .nth(0); + await searchApiOutput.hover(); + await page.mouse.down(); + const toolCallingAgentInput = await page + .getByTestId("handle-toolcallingagent-shownode-tools-left") + .nth(0); + await toolCallingAgentInput.hover(); + await page.mouse.up(); + + await page.waitForTimeout(1000); + + expect(await page.locator(".react-flow__edge-interaction").count()).toBe(1); +});