Merge remote-tracking branch 'origin/dev' into fixList

This commit is contained in:
anovazzi1 2024-06-27 16:43:29 -03:00
commit c0a464f8e2
58 changed files with 1176 additions and 789 deletions

View file

@ -50,7 +50,7 @@ jobs:
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
- name: Get Playwright version
run: echo "PLAYWRIGHT_VERSION=$(jq '.devDependencies["@playwright/test"]' src/frontend/package.json -r)" >> $GITHUB_ENV
- name: Cache Playwright binaries
- name: Cache Playwright binaries
id: playwright-cache
uses: actions/cache@v4
with:

View file

@ -1950,12 +1950,12 @@
}
},
"node_modules/braces": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
"fill-range": "^7.0.1"
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@ -2763,9 +2763,9 @@
}
},
"node_modules/fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"

View file

@ -83,7 +83,7 @@ class CustomComponent(BaseComponent):
_flows_data: Optional[List[Data]] = None
_outputs: List[OutputLog] = []
_logs: List[Log] = []
_tracing_service: "TracingService"
tracing_service: Optional["TracingService"] = None
def update_state(self, name: str, value: Any):
if not self.vertex:
@ -488,14 +488,14 @@ class CustomComponent(BaseComponent):
Args:
message (LoggableType | list[LoggableType]): The message to log.
"""
if name is None:
name = self.display_name if self.display_name else self.__class__.__name__
if hasattr(message, "model_dump") and isinstance(message, BaseModel):
message = message.model_dump()
if name is None and self.display_name:
name = self.display_name
else:
name = self.__class__.__name__
log = Log(message=message, type=get_artifact_type(message), name=name)
self._logs.append(log)
if self.vertex:
self._tracing_service.add_log(trace_name=self.vertex.id, log=log)
if self.tracing_service and self.vertex:
self.tracing_service.add_log(trace_name=self.vertex.id, log=log)
def post_code_processing(self, new_build_config: dict, current_build_config: dict):
"""

View file

@ -18,8 +18,12 @@ def migrate_messages_from_monitor_service_to_database(session: Session) -> bool:
from langflow.schema.message import Message
from langflow.services.database.models.message import MessageTable
monitor_service = get_monitor_service()
messages_df = monitor_service.get_messages()
try:
monitor_service = get_monitor_service()
messages_df = monitor_service.get_messages()
except Exception as e:
logger.error(f"Error retrieving messages from monitor service: {e}")
return False
if messages_df.empty:
logger.info("No messages to migrate.")

View file

@ -0,0 +1,33 @@
from abc import ABC, abstractmethod
from typing import Any, Dict
from uuid import UUID
class BaseTracer(ABC):
@abstractmethod
def __init__(self, trace_name: str, trace_type: str, project_name: str, trace_id: UUID):
raise NotImplementedError
@abstractmethod
def ready(self):
raise NotImplementedError
@abstractmethod
def add_trace(
self, trace_name: str, trace_type: str, inputs: Dict[str, Any], metadata: Dict[str, Any] | None = None
):
raise NotImplementedError
@abstractmethod
def end_trace(self, trace_name: str, outputs: Dict[str, Any] | None = None, error: str | None = None):
raise NotImplementedError
@abstractmethod
def end(
self,
inputs: dict[str, Any],
outputs: Dict[str, Any],
error: str | None = None,
metadata: dict[str, Any] | None = None,
):
raise NotImplementedError

View file

@ -12,6 +12,7 @@ from loguru import logger
from langflow.schema.data import Data
from langflow.services.base import Service
from langflow.services.tracing.base import BaseTracer
from langflow.services.tracing.schema import Log
if TYPE_CHECKING:
@ -180,7 +181,7 @@ class TracingService(Service):
self.outputs_metadata[trace_name] |= output_metadata or {}
class LangSmithTracer:
class LangSmithTracer(BaseTracer):
def __init__(self, trace_name: str, trace_type: str, project_name: str, trace_id: UUID):
from langsmith.run_trees import RunTree
@ -292,7 +293,7 @@ class LangSmithTracer:
inputs: dict[str, Any],
outputs: Dict[str, Any],
error: str | None = None,
metadata: Optional[dict[str, Any]] = None,
metadata: dict[str, Any] | None = None,
):
self._run_tree.add_metadata({"inputs": inputs, "metadata": metadata or {}})
self._run_tree.end(outputs=outputs, error=error)

View file

@ -0,0 +1,34 @@
from typing import Any, Dict
from langflow.schema.data import Data
def convert_to_langchain_type(value):
from langflow.schema.message import Message
if isinstance(value, dict):
for key, _value in value.copy().items():
_value = convert_to_langchain_type(_value)
value[key] = _value
elif isinstance(value, list):
value = [convert_to_langchain_type(v) for v in value]
elif isinstance(value, Message):
if "prompt" in value:
value = value.load_lc_prompt()
elif value.sender:
value = value.to_lc_message()
else:
value = value.to_lc_document()
elif isinstance(value, Data):
if "text" in value.data:
value = value.to_lc_document()
else:
value = value.data
return value
def convert_to_langchain_types(io_dict: Dict[str, Any]):
converted = {}
for key, value in io_dict.items():
converted[key] = convert_to_langchain_type(value)
return converted

View file

@ -21,6 +21,7 @@ export default function HandleRenderComponent({
colors,
setFilterEdge,
showNode,
testIdComplement,
}: {
left: boolean;
nodes: any;
@ -33,6 +34,7 @@ export default function HandleRenderComponent({
colors: string[];
setFilterEdge: any;
showNode: any;
testIdComplement?: string;
}) {
return (
<Button
@ -52,7 +54,7 @@ export default function HandleRenderComponent({
side={left ? "left" : "right"}
>
<Handle
data-testid={`handle-${title.toLowerCase()}-${
data-testid={`handle-${testIdComplement}-${title.toLowerCase()}-${
!showNode ? (left ? "target" : "source") : left ? "left" : "right"
}`}
type={left ? "target" : "source"}

View file

@ -264,6 +264,7 @@ export default function ParameterComponent({
colors={colors}
setFilterEdge={setFilterEdge}
showNode={showNode}
testIdComplement={`${data?.type?.toLowerCase()}-noshownode`}
/>
)
) : (
@ -390,6 +391,7 @@ export default function ParameterComponent({
colors={colors}
setFilterEdge={setFilterEdge}
showNode={showNode}
testIdComplement={`${data?.type?.toLowerCase()}-shownode`}
/>
)}

View file

@ -863,3 +863,11 @@ export const TITLE_ERROR_UPDATING_COMPONENT =
"Error while updating the Component";
export const EMPTY_INPUT_SEND_MESSAGE = "No input message provided.";
export const TABS_ORDER = [
"run curl",
"python api",
"js api",
"python code",
"chat widget html",
];

View file

@ -43,10 +43,6 @@ export const FolderForms = ({
if (folderToEdit) {
setValue("name", folderToEdit.name);
setValue("description", folderToEdit.description);
console.log(folderToEdit);
// setSelectedComponents(folderToEdit.components);
// setSelectedFlows(folderToEdit.flows);
return;
}
setValue("name", "");

View file

@ -63,8 +63,6 @@ export default function ChatView({
)
.map((output, index) => {
try {
console.log("output:", output);
const messageOutput = output.data.message;
const hasMessageValue =
messageOutput?.message ||

View file

@ -18,11 +18,13 @@ import { buildContent } from "./utils/build-content";
import { buildTweaks } from "./utils/build-tweaks";
import { checkCanBuildTweakObject } from "./utils/check-can-build-tweak-object";
import { getChangesType } from "./utils/get-changes-types";
import getCodesObj from "./utils/get-codes-obj";
import { getCurlRunCode, getCurlWebhookCode } from "./utils/get-curl-code";
import getJsApiCode from "./utils/get-js-api-code";
import { getNodesWithDefaultValue } from "./utils/get-nodes-with-default-value";
import getPythonApiCode from "./utils/get-python-api-code";
import getPythonCode from "./utils/get-python-code";
import getTabsOrder from "./utils/get-tabs-order";
import { getValue } from "./utils/get-value";
import getWidgetCode from "./utils/get-widget-code";
import { createTabsArray } from "./utils/tabs-array";
@ -213,21 +215,26 @@ const ApiModal = forwardRef(
);
const pythonCode = getPythonCode(flow?.name, cloneTweak);
const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin);
const isThereTweaks = Object.keys(tweaksCode).length > 0;
const codesObj = getCodesObj({
runCurlCode,
webhookCurlCode,
pythonApiCode,
jsApiCode,
pythonCode,
widgetCode,
});
const tabsOrder = getTabsOrder(includeWebhook, isThereTweaks);
if (tabs && tabs?.length > 0) {
let i = 0;
tabs![i].code = runCurlCode;
i++;
if (includeWebhook) {
tabs![i].code = webhookCurlCode;
i++;
}
tabs![i].code = pythonApiCode;
i++;
tabs![i].code = jsApiCode;
i++;
tabs![i].code = pythonCode;
i++;
tabs![i].code = widgetCode;
tabs.forEach((tab, idx) => {
const order = tabsOrder[idx];
if (order && order.toLowerCase() === tab.name.toLowerCase()) {
const codeToFind = codesObj.find(
(c) => c.name.toLowerCase() === tab.name.toLowerCase(),
);
tab.code = codeToFind?.code;
}
});
}
};

View file

@ -0,0 +1,40 @@
import {
getCodesObjProps,
getCodesObjReturn,
} from "../../../types/utils/functions";
export default function getCodesObj({
runCurlCode,
webhookCurlCode,
pythonApiCode,
jsApiCode,
pythonCode,
widgetCode,
}: getCodesObjProps): getCodesObjReturn {
return [
{
name: "run curl",
code: runCurlCode,
},
{
name: "webhook curl",
code: webhookCurlCode,
},
{
name: "python api",
code: pythonApiCode,
},
{
name: "js api",
code: jsApiCode,
},
{
name: "python code",
code: pythonCode,
},
{
name: "chat widget html",
code: widgetCode,
},
];
}

View file

@ -8,7 +8,7 @@ export function getCurlRunCode(
flowId: string,
isAuth: boolean,
tweaksBuildedObject,
endpointName?: string,
endpointName?: string | null,
): string {
const tweaksObject = tweaksBuildedObject[0];
// show the endpoint name in the curl command if it exists
@ -35,7 +35,11 @@ export function getCurlRunCode(
* @param {string} options.endpointName - The name of the webhook endpoint.
* @returns {string} The cURL command.
*/
export function getCurlWebhookCode(flowId, isAuth, endpointName?: string) {
export function getCurlWebhookCode(
flowId,
isAuth,
endpointName?: string | null,
) {
return `curl -X POST \\
"${window.location.protocol}//${window.location.host}/api/v1/webhook/${
endpointName || flowId

View file

@ -10,7 +10,7 @@ export default function getJsApiCode(
flowId: string,
isAuth: boolean,
tweaksBuildedObject: any[],
endpointName?: string,
endpointName?: string | null,
): string {
let tweaksString = "{}";
if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {

View file

@ -10,7 +10,7 @@ export default function getPythonApiCode(
flowId: string,
isAuth: boolean,
tweaksBuildedObject: any[],
endpointName?: string,
endpointName?: string | null,
): string {
let tweaksString = "{}";
if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {

View file

@ -0,0 +1,15 @@
import { TABS_ORDER } from "../../../constants/constants";
export default function getTabsOrder(
isThereWH: boolean = false,
isThereTweaks: boolean = false,
): string[] {
const defaultOrder = TABS_ORDER;
if (isThereTweaks) {
defaultOrder.push("tweaks");
}
if (isThereWH) {
defaultOrder.splice(1, 0, "webhook curl");
}
return defaultOrder;
}

View file

@ -3,6 +3,8 @@ export function createTabsArray(
includeWebhookCurl = false,
includeTweaks = false,
) {
// console.log(includeTweaks)
console.log(includeWebhookCurl);
const tabs = [
{
name: "Run cURL",

View file

@ -0,0 +1,10 @@
export type getCodesObjProps = {
runCurlCode: string;
webhookCurlCode: string;
pythonApiCode: string;
jsApiCode: string;
pythonCode: string;
widgetCode: string;
};
export type getCodesObjReturn = Array<{ name: string; code: string }>;

View file

@ -0,0 +1,134 @@
import { test } from "@playwright/test";
test("user should be able to download a flow or a component", async ({
page,
}) => {
await page.goto("/");
await page.waitForTimeout(2000);
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.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("icon-SaveAll").first().click();
await page.waitForTimeout(3000);
if (await page.getByTestId("replace-button").isVisible()) {
await page.getByTestId("replace-button").click();
}
await page.waitForTimeout(3000);
await page.getByTestId("icon-ChevronLeft").last().click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-FileDown").last().click();
await page.waitForTimeout(1000);
await page.getByText("Items exported successfully").isVisible();
await page.getByText("Flows", { exact: true }).click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-FileDown").last().click();
await page.waitForTimeout(1000);
await page.getByText("Items exported successfully").isVisible();
await page.getByText("Components", { exact: true }).click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-FileDown").last().click();
await page.waitForTimeout(1000);
await page.getByText("Components exported successfully").isVisible();
});
test("user should be able to upload a flow or a component", async ({
page,
}) => {
await page.goto("/");
await page.waitForTimeout(2000);
let modalCount = 0;
try {
const modalTitleElement = await page?.getByTestId("modal-title");
if (modalTitleElement) {
modalCount = await modalTitleElement.count();
}
} catch (error) {
modalCount = 0;
}
await page.getByTestId("upload-folder-button").last().click();
});
test("user should be able to duplicate a flow or a component", async ({
page,
}) => {
await page.goto("/");
await page.waitForTimeout(2000);
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.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("icon-SaveAll").first().click();
await page.waitForTimeout(3000);
if (await page.getByTestId("replace-button").isVisible()) {
await page.getByTestId("replace-button").click();
}
await page.waitForTimeout(3000);
await page.getByTestId("icon-ChevronLeft").last().click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-Copy").last().click();
await page.waitForTimeout(1000);
await page.getByText("Items duplicated successfully").isVisible();
});

View file

@ -137,136 +137,3 @@ test("search components", async ({ page }) => {
await page.getByText("Prompt", { exact: true }).isHidden();
await page.getByText("OpenAI", { exact: true }).isHidden();
});
test("user should be able to download a flow or a component", async ({
page,
}) => {
await page.goto("/");
await page.waitForTimeout(2000);
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.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("icon-SaveAll").first().click();
await page.waitForTimeout(3000);
if (await page.getByTestId("replace-button").isVisible()) {
await page.getByTestId("replace-button").click();
}
await page.waitForTimeout(3000);
await page.getByTestId("icon-ChevronLeft").last().click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-FileDown").last().click();
await page.waitForTimeout(1000);
await page.getByText("Items exported successfully").isVisible();
await page.getByText("Flows", { exact: true }).click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-FileDown").last().click();
await page.waitForTimeout(1000);
await page.getByText("Items exported successfully").isVisible();
await page.getByText("Components", { exact: true }).click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-FileDown").last().click();
await page.waitForTimeout(1000);
await page.getByText("Components exported successfully").isVisible();
});
test("user should be able to upload a flow or a component", async ({
page,
}) => {
await page.goto("/");
await page.waitForTimeout(2000);
let modalCount = 0;
try {
const modalTitleElement = await page?.getByTestId("modal-title");
if (modalTitleElement) {
modalCount = await modalTitleElement.count();
}
} catch (error) {
modalCount = 0;
}
await page.getByTestId("upload-folder-button").last().click();
});
test("user should be able to duplicate a flow or a component", async ({
page,
}) => {
await page.goto("/");
await page.waitForTimeout(2000);
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.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("icon-SaveAll").first().click();
await page.waitForTimeout(3000);
if (await page.getByTestId("replace-button").isVisible()) {
await page.getByTestId("replace-button").click();
}
await page.waitForTimeout(3000);
await page.getByTestId("icon-ChevronLeft").last().click();
await page.getByRole("checkbox").nth(1).click();
await page.getByTestId("icon-Copy").last().click();
await page.waitForTimeout(1000);
await page.getByText("Items duplicated successfully").isVisible();
});

View file

@ -1,5 +1,4 @@
import { expect, test } from "@playwright/test";
import { readFileSync } from "fs";
test("chat_io_teste", async ({ page }) => {
await page.goto("/");
@ -22,17 +21,14 @@ test("chat_io_teste", async ({ page }) => {
modalCount = await page.getByTestId("modal-title")?.count();
}
const jsonContent = readFileSync(
"tests/end-to-end/assets/ChatTest.json",
"utf-8",
);
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
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("chat output");
@ -67,20 +63,37 @@ test("chat_io_teste", async ({ page }) => {
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
const elementsChatInput = await page
.locator('[data-testid="handle-chatinput-shownode-message-right"]')
.all();
let visibleElementHandle;
for (const element of elementsChatInput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
// Click and hold on the first element
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[2]/div/div[2]/div[9]/button/div[1]',
)
.hover();
await visibleElementHandle.hover();
await page.mouse.down();
// Move to the second element
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]/div/div[2]/div[3]/div/button/div[1]',
)
.hover();
const elementsChatOutput = await page
.getByTestId("handle-chatoutput-shownode-text-left")
.all();
for (const element of elementsChatOutput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover();
// Release the mouse
await page.mouse.up();

View file

@ -20,14 +20,14 @@ test("CodeAreaModalComponent", async ({ page }) => {
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
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("python function");

View file

@ -1,18 +1,37 @@
import { test } from "@playwright/test";
test("should add API-KEY", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("api-key-button-store").click();
await page
.getByPlaceholder("Insert your API Key")
.fill("testtesttesttesttesttest");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page
.getByPlaceholder("Insert your API Key")
.fill(process.env.STORE_API_KEY ?? "");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isHidden();
});
test("should delete a flow", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(2000);
await page.getByText("Store").nth(0).click();
await page.getByText("API Key", { exact: true }).click();
await page
.getByPlaceholder("Insert your API Key", { exact: true })
.fill(process.env.STORE_API_KEY ?? "");
await page.waitForSelector("text=Save", { timeout: 30000 });
await page.getByText("Save").last().click();
await page.waitForSelector("text=Store", { timeout: 30000 });

View file

@ -19,12 +19,15 @@ test("dropDownComponent", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("amazon");

View file

@ -20,11 +20,12 @@ test("should be able to upload a file", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
@ -77,38 +78,70 @@ test("should be able to upload a file", async ({ page }) => {
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
let visibleElementHandle;
const elementsFile = await page
.getByTestId("handle-file-shownode-data-right")
.all();
for (const element of elementsFile) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
// Click and hold on the first element
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[6]/button/div[1]',
)
.hover();
await visibleElementHandle.hover();
await page.mouse.down();
// Move to the second element
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[3]/div/div[2]/div[4]/div/button/div[1]',
)
.hover();
const parseDataElement = await page
.getByTestId("handle-parsedata-shownode-data-left")
.all();
for (const element of parseDataElement) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover();
// Release the mouse
await page.mouse.up();
// Click and hold on the first element
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[3]/div/div[2]/div[7]/button/div[1]',
)
.hover();
const parseDataOutputElement = await page
.getByTestId("handle-parsedata-shownode-text-right")
.all();
for (const element of parseDataOutputElement) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover();
await page.mouse.down();
// Move to the second element
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[3]/div/button/div[1]',
)
.hover();
const textOutputElement = await page
.getByTestId("handle-textoutput-shownode-text-left")
.all();
for (const element of textOutputElement) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover();
// Release the mouse
await page.mouse.up();

View file

@ -0,0 +1,175 @@
import { expect, test } from "@playwright/test";
test("LLMChain - Tooltip", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
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.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("llmchain");
await page.waitForTimeout(1000);
await page
.getByTestId("chainsLLMChain")
.dragTo(page.locator('//*[@id="react-flow-id"]'));
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.getByTitle("zoom out").click();
const llmChainOutputElements = await page
.getByTestId("handle-llmchain-shownode-text-right")
.all();
let visibleElementHandle;
for (const element of llmChainOutputElements) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover().then(async () => {
await expect(
page.getByTestId("available-output-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-textsplitters").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-retrievers").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-prototypes").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-tools").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-memories").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-toolkits").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-agents").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-helpers").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-langchain_utilities").first(),
).toBeVisible();
await page.getByTestId("icon-X").click();
await page.waitForTimeout(500);
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
const llmChainInputElements1 = await page
.getByTestId("handle-llmchain-shownode-llm-left")
.all();
for (const element of llmChainInputElements1) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover().then(async () => {
await expect(
page.getByTestId("available-input-models").first(),
).toBeVisible();
await page.waitForTimeout(2000);
await page.getByTestId("icon-Search").click();
await page.waitForTimeout(500);
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
const llmChainInputElements0 = await page
.getByTestId("handle-llmchain-shownode-template-left")
.all();
for (const element of llmChainInputElements0) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover().then(async () => {
await page.waitForTimeout(2000);
await expect(
page.getByTestId("available-input-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-prototypes").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-agents").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-helpers").first(),
).toBeVisible();
await page.waitForTimeout(500);
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
const llmChainInputElements2 = await page
.getByTestId("handle-llmchain-shownode-memory-left")
.all();
for (const element of llmChainInputElements2) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.hover().then(async () => {
await expect(
page.getByTestId("empty-tooltip-filter").first(),
).toBeVisible();
});
});

View file

@ -21,13 +21,14 @@ test("LLMChain - Filter", async ({ page }) => {
}
await page.waitForTimeout(1000);
await page.getByTestId(
"input-list-plus-btn-edit_metadata_indexing_include-2",
);
await page.getByTestId("blank-flow").click();
await page.waitForTimeout(3000);
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("llmchain");
@ -44,13 +45,33 @@ test("LLMChain - Filter", async ({ page }) => {
await page.getByTitle("zoom out").click();
await page.waitForTimeout(500);
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div[1]',
)
.click();
let visibleElementHandle;
const llmChainOutputElements = await page
.getByTestId("handle-llmchain-shownode-text-right")
.all();
for (const element of llmChainOutputElements) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.click({
force: true,
});
await expect(page.getByTestId("disclosure-helpers")).toBeVisible();
await expect(page.getByTestId("disclosure-agents")).toBeVisible();
await expect(page.getByTestId("disclosure-chains")).toBeVisible();
await expect(page.getByTestId("disclosure-utilities")).toBeVisible();
await expect(page.getByTestId("disclosure-memories")).toBeVisible();
await expect(page.getByTestId("disclosure-prototypes")).toBeVisible();
await expect(page.getByTestId("disclosure-retrievers")).toBeVisible();
await expect(page.getByTestId("disclosure-text splitters")).toBeVisible();
await expect(page.getByTestId("disclosure-toolkits")).toBeVisible();
await expect(page.getByTestId("disclosure-tools")).toBeVisible();
await expect(page.getByTestId("chainsLLMChain").first()).toBeVisible();
await expect(
@ -88,19 +109,37 @@ test("LLMChain - Filter", async ({ page }) => {
await expect(page.getByTestId("model_specsChatOpenAI")).not.toBeVisible();
await expect(page.getByTestId("model_specsChatVertexAI")).not.toBeVisible();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[4]/div/button/div[1]',
)
.click();
const llmChainInputElements1 = await page
.getByTestId("handle-llmchain-shownode-llm-left")
.all();
for (const element of llmChainInputElements1) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.blur();
await visibleElementHandle.click({
force: true,
});
await expect(page.getByTestId("disclosure-models")).toBeVisible();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[3]/div/button/div[1]',
)
.click();
const llmChainInputElements0 = await page
.getByTestId("handle-llmchain-shownode-template-left")
.all();
for (const element of llmChainInputElements0) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.click();
await expect(page.getByTestId("disclosure-helpers")).toBeVisible();
await expect(page.getByTestId("disclosure-agents")).toBeVisible();

View file

@ -19,11 +19,12 @@ test("FloatComponent", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -23,7 +23,7 @@ test.describe("Flow Page tests", () => {
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -19,8 +19,9 @@ test("flowSettings", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForTimeout(1000);

View file

@ -23,7 +23,7 @@ test("should interact with api request", async ({ page }) => {
}
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -19,11 +19,12 @@ test("GlobalVariables", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -1,159 +0,0 @@
import { expect, test } from "@playwright/test";
test("LLMChain - Tooltip", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
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.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("llmchain");
await page.waitForTimeout(1000);
await page
.getByTestId("chainsLLMChain")
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up();
await page.mouse.down();
await page.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div[1]',
)
.hover()
.then(async () => {
await expect(
page.getByTestId("available-output-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-textsplitters").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-retrievers").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-prototypes").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-tools").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-memories").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-toolkits").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-agents").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-helpers").first(),
).toBeVisible();
await expect(
page.getByTestId("available-output-langchain_utilities").first(),
).toBeVisible();
await page.getByTestId("icon-X").click();
await page.waitForTimeout(500);
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[4]/div/button/div[1]',
)
.hover()
.then(async () => {
await expect(
page.getByTestId("available-input-models").first(),
).toBeVisible();
await page.waitForTimeout(2000);
await page.getByTestId("icon-Search").click();
await page.waitForTimeout(500);
});
await page.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div/div/div[2]/div[3]/div/button/div[1]',
)
.hover()
.then(async () => {
await page.waitForTimeout(2000);
await expect(
page.getByTestId("available-input-chains").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-prototypes").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-agents").first(),
).toBeVisible();
await expect(
page.getByTestId("available-input-helpers").first(),
).toBeVisible();
await page.waitForTimeout(500);
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page
.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[5]/div/button/div[1]',
)
.hover()
.then(async () => {
await expect(
page.getByTestId("empty-tooltip-filter").first(),
).toBeVisible();
});
});

View file

@ -19,11 +19,12 @@ test("InputComponent", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -22,7 +22,7 @@ test("InputListComponent", async ({ page }) => {
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -19,11 +19,12 @@ test("IntComponent", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -19,10 +19,13 @@ test("KeypairListComponent", async ({ page }) => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForTimeout(3000);
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("amazon bedrock");

View file

@ -3,8 +3,6 @@ import uaParser from "ua-parser-js";
test("LangflowShortcuts", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
let modalCount = 0;
try {
const modalTitleElement = await page?.getByTestId("modal-title");
@ -29,10 +27,15 @@ test("LangflowShortcuts", async ({ page }) => {
control = "Meta";
}
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
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("ollama");
@ -67,11 +70,9 @@ test("LangflowShortcuts", async ({ page }) => {
expect(false).toBeTruthy();
}
await page
.locator(
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]',
)
.click();
const ollamaTitleElement = await page.getByTestId("title-Ollama").last();
await ollamaTitleElement.click();
await page.keyboard.press("Backspace");
numberOfNodes = await page.getByTestId("title-Ollama")?.count();
@ -90,11 +91,7 @@ test("LangflowShortcuts", async ({ page }) => {
expect(false).toBeTruthy();
}
await page
.locator(
'//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]',
)
.click();
await ollamaTitleElement.click();
await page.keyboard.press("Backspace");
await page.getByTestId("title-Ollama").click();

View file

@ -19,10 +19,12 @@ test("NestedComponent", async ({ page }) => {
await page.waitForTimeout(5000);
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: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -19,10 +19,12 @@ test("PromptTemplateComponent", async ({ page }) => {
await page.waitForTimeout(5000);
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: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -20,7 +20,9 @@ test.describe("save component tests", () => {
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForTimeout(1000);
@ -94,7 +96,7 @@ test.describe("save component tests", () => {
await page.getByTestId("replace-button").click();
}
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -0,0 +1,19 @@
import { test } from "@playwright/test";
test("should exists Store", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").isVisible();
await page.getByTestId("button-store").isEnabled();
});
test("should not have an API key", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isVisible();
});

View file

@ -0,0 +1,119 @@
import { expect, test } from "@playwright/test";
test("should add API-KEY", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("api-key-button-store").click();
await page
.getByPlaceholder("Insert your API Key")
.fill("testtesttesttesttesttest");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page
.getByPlaceholder("Insert your API Key")
.fill(process.env.STORE_API_KEY ?? "");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isHidden();
});
test("should like and add components and flows", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("api-key-button-store").click();
await page
.getByPlaceholder("Insert your API Key")
.fill(process.env.STORE_API_KEY ?? "");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isHidden();
await page.waitForTimeout(2000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(5000);
const likedValue = await page
.getByTestId("likes-Website Content QA")
.innerText();
await page.getByTestId("like-Website Content QA").click();
await page.waitForTimeout(5000);
const likedValueAfter = await page
.getByTestId("likes-Website Content QA")
.innerText();
if (Number(likedValue) === Number(likedValueAfter)) {
expect(false).toBe(true);
}
const downloadValue = await page
.getByTestId("downloads-Website Content QA")
.innerText();
await page.getByTestId("install-Website Content QA").click();
await page.waitForTimeout(2000);
await page.getByText("Flow Installed Successfully").isVisible();
await page.waitForTimeout(5000);
const downloadValueAfter = await page
.getByTestId("downloads-Website Content QA")
.innerText();
if (Number(downloadValue) === Number(downloadValueAfter)) {
expect(false).toBe(true);
}
await page.getByTestId("install-Basic RAG").click();
await page.waitForTimeout(2000);
await page.getByText("Component Installed Successfully").isVisible();
await page.waitForTimeout(5000);
await page.getByText("My Collection").click();
await page.getByText("Website Content QA").first().isVisible();
await page.getByText("Components").first().click();
await page.getByText("Basic RAG").first().isVisible();
});
test("should find a searched Component on Store", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("search-store-input").fill("File Loader");
await page.getByTestId("search-store-button").click();
await page.getByText("File Loader").isVisible();
await page.getByTestId("search-store-input").fill("Basic RAG");
await page.getByTestId("search-store-button").click();
await page.getByText("Basic RAG").isVisible();
await page.getByTestId("search-store-input").fill("YouTube QA");
await page.getByTestId("search-store-button").click();
await page.getByText("YouTube QA").isVisible();
});

View file

@ -0,0 +1,122 @@
import { expect, test } from "@playwright/test";
test("should add API-KEY", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("api-key-button-store").click();
await page
.getByPlaceholder("Insert your API Key")
.fill("testtesttesttesttesttest");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page
.getByPlaceholder("Insert your API Key")
.fill(process.env.STORE_API_KEY ?? "");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isHidden();
});
test("should filter by tag", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("tag-selector-Agent").click();
await page.getByText("File Loader").isVisible();
await page.getByTestId("tag-selector-Agent").click();
await page.getByText("Album Cover Builder").isVisible();
await page.getByTestId("tag-selector-Memory").click();
await page.getByText("MP3 QA12").isVisible();
await page.getByTestId("tag-selector-Chain").click();
await page.getByText("There are no").isVisible();
await page.getByTestId("tag-selector-Chain").click();
await page.getByTestId("tag-selector-Vector Store").click();
await page.getByText("MP3 QA12").isVisible();
await page.getByTestId("tag-selector-Vector Store").click();
await page.getByTestId("tag-selector-Memory").click();
await page.getByText("Basic RAG").isVisible();
});
test("should share component with share button", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(2000);
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.waitForTimeout(1000);
const randomName = Math.random().toString(36).substring(2);
await page.getByRole("heading", { name: "Basic Prompting" }).click();
await page.waitForTimeout(1000);
const flowName = await page.getByTestId("flow_name").innerText();
await page.getByTestId("flow_name").click();
await page.getByText("Settings").click();
const flowDescription = await page
.getByPlaceholder("Flow description")
.inputValue();
await page.getByPlaceholder("Flow name").fill(randomName);
await page.getByText("Save").last().click();
await page.getByText("Close").last().click();
await page.waitForSelector('[data-testid="shared-button-flow"]', {
timeout: 100000,
});
await page.getByTestId("shared-button-flow").first().click();
await page.getByText("Name:").isVisible();
await page.getByText("Description:").isVisible();
await page.getByText("Set workflow status to public").isVisible();
await page
.getByText(
"Attention: API keys in specified fields are automatically removed upon sharing.",
)
.isVisible();
await page.getByText("Export").first().isVisible();
await page.getByText("Share Flow").first().isVisible();
await page.waitForTimeout(5000);
await page.getByText("Agent").first().isVisible();
await page.getByText("Memory").first().isVisible();
await page.getByText("Chain").first().isVisible();
await page.getByText("Vector Store").first().isVisible();
await page.getByText("Prompt").last().isVisible();
await page.getByTestId("public-checkbox").isChecked();
await page.getByText(flowName).last().isVisible();
await page.getByText(flowDescription).last().isVisible();
await page.waitForTimeout(1000);
await page.getByText("Flow shared successfully").last().isVisible();
});

View file

@ -0,0 +1,88 @@
import { expect, test } from "@playwright/test";
test("should add API-KEY", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("api-key-button-store").click();
await page
.getByPlaceholder("Insert your API Key")
.fill("testtesttesttesttesttest");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page
.getByPlaceholder("Insert your API Key")
.fill(process.env.STORE_API_KEY ?? "");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isHidden();
});
test("should order the visualization", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByText("Basic RAG").isVisible();
await page.getByTestId("select-order-store").click();
await page.waitForTimeout(2000);
await page.getByText("Alphabetical").click();
await page.getByText("Album Cover Builder").isVisible();
await page.getByTestId("select-order-store").click();
await page.getByText("Popular").click();
await page.getByText("Basic RAG").isVisible();
});
test("should filter by type", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByText("Website Content QA").isVisible();
await page.getByTestId("flows-button-store").click();
await page.waitForTimeout(8000);
let iconGroup = await page.getByTestId("icon-Group")?.count();
expect(iconGroup).not.toBe(0);
await page.getByText("icon-ToyBrick").last().isHidden();
await page.getByTestId("components-button-store").click();
await page.waitForTimeout(8000);
await page.getByTestId("icon-Group").last().isHidden();
let toyBrick = await page.getByTestId("icon-ToyBrick")?.count();
expect(toyBrick).not.toBe(0);
await page.getByTestId("all-button-store").click();
await page.waitForTimeout(8000);
let iconGroupAllCount = await page.getByTestId("icon-Group")?.count();
await page.waitForTimeout(2000);
let toyBrickAllCount = await page.getByTestId("icon-ToyBrick")?.count();
await page.waitForTimeout(2000);
if (iconGroupAllCount === 0 || toyBrickAllCount === 0) {
expect(false).toBe(true);
}
});

View file

@ -1,287 +0,0 @@
import { expect, test } from "@playwright/test";
test("should exists Store", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").isVisible();
await page.getByTestId("button-store").isEnabled();
});
test("should not have an API key", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isVisible();
});
test("should add API-KEY", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("api-key-button-store").click();
await page
.getByPlaceholder("Insert your API Key")
.fill("testtesttesttesttesttest");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page
.getByPlaceholder("Insert your API Key")
.fill(process.env.STORE_API_KEY ?? "");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isHidden();
});
test("should like and add components and flows", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("api-key-button-store").click();
await page
.getByPlaceholder("Insert your API Key")
.fill(process.env.STORE_API_KEY ?? "");
await page.getByTestId("api-key-save-button-store").click();
await page.waitForTimeout(2000);
await page.getByText("Success! Your API Key has been saved.").isVisible();
await page.waitForTimeout(2000);
await page.getByText("API Key Error").isHidden();
await page.waitForTimeout(2000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(5000);
const likedValue = await page
.getByTestId("likes-Website Content QA")
.innerText();
await page.getByTestId("like-Website Content QA").click();
await page.waitForTimeout(5000);
const likedValueAfter = await page
.getByTestId("likes-Website Content QA")
.innerText();
if (Number(likedValue) === Number(likedValueAfter)) {
expect(false).toBe(true);
}
const downloadValue = await page
.getByTestId("downloads-Website Content QA")
.innerText();
await page.getByTestId("install-Website Content QA").click();
await page.waitForTimeout(2000);
await page.getByText("Flow Installed Successfully").isVisible();
await page.waitForTimeout(5000);
const downloadValueAfter = await page
.getByTestId("downloads-Website Content QA")
.innerText();
if (Number(downloadValue) === Number(downloadValueAfter)) {
expect(false).toBe(true);
}
await page.getByTestId("install-Basic RAG").click();
await page.waitForTimeout(2000);
await page.getByText("Component Installed Successfully").isVisible();
await page.waitForTimeout(5000);
await page.getByText("My Collection").click();
await page.getByText("Website Content QA").first().isVisible();
await page.getByText("Components").first().click();
await page.getByText("Basic RAG").first().isVisible();
});
test("should find a searched Component on Store", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("search-store-input").fill("File Loader");
await page.getByTestId("search-store-button").click();
await page.getByText("File Loader").isVisible();
await page.getByTestId("search-store-input").fill("Basic RAG");
await page.getByTestId("search-store-button").click();
await page.getByText("Basic RAG").isVisible();
await page.getByTestId("search-store-input").fill("YouTube QA");
await page.getByTestId("search-store-button").click();
await page.getByText("YouTube QA").isVisible();
});
test("should filter by tag", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByTestId("tag-selector-Agent").click();
await page.getByText("File Loader").isVisible();
await page.getByTestId("tag-selector-Agent").click();
await page.getByText("Album Cover Builder").isVisible();
await page.getByTestId("tag-selector-Memory").click();
await page.getByText("MP3 QA12").isVisible();
await page.getByTestId("tag-selector-Chain").click();
await page.getByText("There are no").isVisible();
await page.getByTestId("tag-selector-Chain").click();
await page.getByTestId("tag-selector-Vector Store").click();
await page.getByText("MP3 QA12").isVisible();
await page.getByTestId("tag-selector-Vector Store").click();
await page.getByTestId("tag-selector-Memory").click();
await page.getByText("Basic RAG").isVisible();
});
test("should share component with share button", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(2000);
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.waitForTimeout(1000);
const randomName = Math.random().toString(36).substring(2);
await page.getByRole("heading", { name: "Basic Prompting" }).click();
await page.waitForTimeout(1000);
const flowName = await page.getByTestId("flow_name").innerText();
await page.getByTestId("flow_name").click();
await page.getByText("Settings").click();
const flowDescription = await page
.getByPlaceholder("Flow description")
.inputValue();
await page.getByPlaceholder("Flow name").fill(randomName);
await page.getByText("Save").last().click();
await page.getByText("Close").last().click();
await page.waitForSelector('[data-testid="shared-button-flow"]', {
timeout: 100000,
});
await page.getByTestId("shared-button-flow").first().click();
await page.getByText("Name:").isVisible();
await page.getByText("Description:").isVisible();
await page.getByText("Set workflow status to public").isVisible();
await page
.getByText(
"Attention: API keys in specified fields are automatically removed upon sharing.",
)
.isVisible();
await page.getByText("Export").first().isVisible();
await page.getByText("Share Flow").first().isVisible();
await page.waitForTimeout(5000);
await page.getByText("Agent").first().isVisible();
await page.getByText("Memory").first().isVisible();
await page.getByText("Chain").first().isVisible();
await page.getByText("Vector Store").first().isVisible();
await page.getByText("Prompt").last().isVisible();
await page.getByTestId("public-checkbox").isChecked();
await page.getByText(flowName).last().isVisible();
await page.getByText(flowDescription).last().isVisible();
await page.waitForTimeout(1000);
await page.getByText("Flow shared successfully").last().isVisible();
});
test("should order the visualization", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByText("Basic RAG").isVisible();
await page.getByTestId("select-order-store").click();
await page.waitForTimeout(2000);
await page.getByText("Alphabetical").click();
await page.getByText("Album Cover Builder").isVisible();
await page.getByTestId("select-order-store").click();
await page.getByText("Popular").click();
await page.getByText("Basic RAG").isVisible();
});
test("should filter by type", async ({ page }) => {
await page.goto("/");
await page.waitForTimeout(1000);
await page.getByTestId("button-store").click();
await page.waitForTimeout(1000);
await page.getByText("Website Content QA").isVisible();
await page.getByTestId("flows-button-store").click();
await page.waitForTimeout(8000);
let iconGroup = await page.getByTestId("icon-Group")?.count();
expect(iconGroup).not.toBe(0);
await page.getByText("icon-ToyBrick").last().isHidden();
await page.getByTestId("components-button-store").click();
await page.waitForTimeout(8000);
await page.getByTestId("icon-Group").last().isHidden();
let toyBrick = await page.getByTestId("icon-ToyBrick")?.count();
expect(toyBrick).not.toBe(0);
await page.getByTestId("all-button-store").click();
await page.waitForTimeout(8000);
let iconGroupAllCount = await page.getByTestId("icon-Group")?.count();
await page.waitForTimeout(2000);
let toyBrickAllCount = await page.getByTestId("icon-ToyBrick")?.count();
await page.waitForTimeout(2000);
if (iconGroupAllCount === 0 || toyBrickAllCount === 0) {
expect(false).toBe(true);
}
});

View file

@ -19,7 +19,9 @@ test("TextAreaModalComponent", async ({ page }) => {
await page.waitForTimeout(5000);
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"]', {

View file

@ -26,8 +26,9 @@ test("TextInputOutputComponent", async ({ page }) => {
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 30000,
@ -69,33 +70,45 @@ test("TextInputOutputComponent", async ({ page }) => {
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
const component1 = await page.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]',
);
let visibleElementHandle;
const element1 = await page.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[1]/div/div[2]/div[5]/button/div[1]',
);
const elementsTextInputOutput = await page
.getByTestId("handle-textinput-shownode-text-right")
.all();
const component2 = await page.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[2]',
);
for (const element of elementsTextInputOutput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
const element2 = await page.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[2]/div/div[2]/div[3]/div/button/div[1]',
);
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
// ensure elements popups are not blocking
component1.blur();
component2.blur();
await page.mouse.up();
await element1.hover();
await visibleElementHandle.hover();
await page.mouse.down();
const elementsOpenAiInput = await page.getByTestId(
"handle-openaimodel-shownode-input-left",
);
for (const element of elementsTextInputOutput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
// Move to the second element
await element2.hover();
await visibleElementHandle.hover();
// Release the mouse
await page.mouse.up();
@ -120,29 +133,44 @@ test("TextInputOutputComponent", async ({ page }) => {
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
const component3 = await page.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[3]',
);
const elementsOpenAiOutput = await page
.getByTestId("handle-openaimodel-shownode-text-right")
.all();
const element3 = await page.locator(
'//*[@id="react-flow-id"]/div/div[1]/div/div/div[2]/div[3]/div/div[2]/div[3]/div/button/div[1]',
);
for (const element of elementsOpenAiOutput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
const element4 = await page.locator(
'//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[16]/button/div[1]',
);
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
// ensure elements popups are not blocking
component2.blur();
component3.blur();
await page.mouse.up();
await element4.hover();
// Click and hold on the first element
await visibleElementHandle.hover();
await page.mouse.down();
const elementTextOutputInput = await page
.getByTestId("handle-textoutput-shownode-text-left")
.all();
for (const element of elementTextOutputInput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
// Move to the second element
await element3.hover();
await visibleElementHandle.hover();
// Release the mouse
await page.mouse.up();

View file

@ -19,7 +19,9 @@ test("ToggleComponent", async ({ page }) => {
await page.waitForTimeout(5000);
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"]', {

View file

@ -79,11 +79,14 @@ test("check if tweaks are updating when someothing on the flow changes", async (
await page.waitForTimeout(5000);
modalCount = await page.getByTestId("modal-title")?.count();
}
await page.waitForTimeout(1000);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.waitForSelector('[data-testid="extended-disclosure"]', {
timeout: 100000,
timeout: 30000,
});
await page.getByTestId("extended-disclosure").click();
await page.getByPlaceholder("Search").click();

View file

@ -20,10 +20,10 @@
"include": [
"src",
"tests/end-to-end/saveComponents.spec.ts",
"tests/end-to-end/actionsMainPage.spec.ts",
"tests/end-to-end/actionsMainPage-shard-1.spec.ts",
"tests/end-to-end/auto_login.spec.ts",
"tests/end-to-end/chatInputOutput.spec.ts",
"tests/end-to-end/chatInputOutputUser - Interact.spec.ts",
"tests/end-to-end/chatInputOutputUser-shard-2.spec.ts",
"tests/end-to-end/codeAreaModalComponent.spec.ts",
"tests/end-to-end/curlApiGeneration.spec.ts",
"tests/end-to-end/deleteComponentFlows.spec.ts",