fix(frontend): fix save component test by removing unnecessary steps and fixing selectors

feat(frontend): add test for saving components and verifying their presence in the flow
feat(frontend): add test for grouping nodes and verifying the presence of the group node
feat(frontend): add test for saving default component with custom values and verifying the saved component
feat(frontend): add test for saving the same component multiple times and verifying their presence
feat(frontend): add test for saving default component and deleting it from the saved components list
This commit is contained in:
cristhianzl 2023-12-14 13:00:48 -03:00
commit 45479222d7
8 changed files with 254 additions and 465 deletions

View file

@ -194,7 +194,10 @@ export default function GenericNode({
takeSnapshot(); takeSnapshot();
}} }}
> >
<div className="generic-node-tooltip-div pr-2 text-primary"> <div
data-testid={"title-" + data.node?.display_name}
className="generic-node-tooltip-div pr-2 text-primary"
>
{data.node?.display_name} {data.node?.display_name}
</div> </div>
{nameEditable && ( {nameEditable && (

View file

@ -285,7 +285,7 @@ export default function ExtraSidebar(): JSX.Element {
)} )}
</div> </div>
</ShadTooltip> </ShadTooltip>
<div className="side-bar-button"> <div className="side-bar-button" data-testid="save-button">
{flow && flow.data && ( {flow && flow.data && (
<ShadTooltip content="Save" side="top"> <ShadTooltip content="Save" side="top">
<button <button

View file

@ -137,6 +137,7 @@ export default function NodeToolbarComponent({
onClick={() => { onClick={() => {
deleteNode(data.id); deleteNode(data.id);
}} }}
data-testid="delete-button-modal"
> >
<IconComponent name="Trash2" className="h-4 w-4" /> <IconComponent name="Trash2" className="h-4 w-4" />
</button> </button>
@ -216,7 +217,7 @@ export default function NodeToolbarComponent({
{isSaved ? ( {isSaved ? (
<SelectItem value={"override"}> <SelectItem value={"override"}>
<div className="flex"> <div className="flex" data-testid="save-button-modal">
<IconComponent <IconComponent
name="SaveAll" name="SaveAll"
className="relative top-0.5 mr-2 h-4 w-4" className="relative top-0.5 mr-2 h-4 w-4"
@ -226,7 +227,7 @@ export default function NodeToolbarComponent({
</SelectItem> </SelectItem>
) : ( ) : (
<SelectItem value={"SaveAll"}> <SelectItem value={"SaveAll"}>
<div className="flex"> <div className="flex" data-testid="save-button-modal">
<IconComponent <IconComponent
name="SaveAll" name="SaveAll"
className="relative top-0.5 mr-2 h-4 w-4" className="relative top-0.5 mr-2 h-4 w-4"

File diff suppressed because one or more lines are too long

View file

@ -26,7 +26,7 @@ test.describe("drag and drop test", () => {
const dataTransfer = await page.evaluateHandle((data) => { const dataTransfer = await page.evaluateHandle((data) => {
const dt = new DataTransfer(); const dt = new DataTransfer();
// Convert the buffer to a hex array // Convert the buffer to a hex array
const file = new File([data], "collection.json", { const file = new File([data], "flowtest.json", {
type: "application/json", type: "application/json",
}); });
dt.items.add(file); dt.items.add(file);
@ -34,54 +34,25 @@ test.describe("drag and drop test", () => {
}, jsonContent); }, jsonContent);
// Now dispatch // Now dispatch
await page.dispatchEvent('//*[@id="root"]/div/div[2]/div[2]', "drop", { await page.dispatchEvent(
'//*[@id="root"]/div/div[1]/div[2]/div[3]/div/div',
"drop",
{
dataTransfer, dataTransfer,
}); }
expect(
await page
.locator(".main-page-flows-display")
.evaluate((el) => el.children)
).toBeTruthy();
});
test("drop flow", async ({ page }) => {
await page.routeFromHAR("harFiles/langflow.har", {
url: "**/api/v1/**",
update: false,
});
await page.route("**/api/v1/flows/", async (route) => {
const json = {
id: "e9ac1bdc-429b-475d-ac03-d26f9a2a3210",
};
await route.fulfill({ json, status: 201 });
});
await page.goto("http:localhost:3000/");
await page.locator("span").filter({ hasText: "My Collection" }).isVisible();
// Read your file into a buffer.
const jsonContent = readFileSync(
"tests/onlyFront/assets/flow.json",
"utf-8"
); );
// Create the DataTransfer and File
const dataTransfer = await page.evaluateHandle((data) => {
const dt = new DataTransfer();
// Convert the buffer to a hex array
const file = new File([data], "flow.json", {
type: "application/json",
});
dt.items.add(file);
return dt;
}, jsonContent);
// Now dispatch
await page.dispatchEvent('//*[@id="root"]/div/div[2]/div[2]', "drop", {
dataTransfer,
});
expect(
await page await page
.locator(".main-page-flows-display") .locator(
.evaluate((el) => el.children) '//*[@id="root"]/div/div[1]/div[2]/div[3]/div/div/div/div/div/div/div/div[2]/span[2]'
).toBeTruthy(); )
.click();
await page.waitForTimeout(2000);
const genericNoda = page.getByTestId("div-generic-node");
const elementCount = await genericNoda.count();
if (elementCount > 0) {
expect(true).toBeTruthy();
}
}); });
}); });

View file

@ -15,10 +15,10 @@ test.describe("group node test", () => {
await route.fulfill({ json, status: 201 }); await route.fulfill({ json, status: 201 });
}); });
await page.goto("http:localhost:3000/"); await page.goto("http:localhost:3000/");
await page.locator('//*[@id="new-project-btn"]').click(); await page.locator("span").filter({ hasText: "My Collection" }).isVisible();
// Read your file into a buffer. // Read your file into a buffer.
const jsonContent = readFileSync( const jsonContent = readFileSync(
"tests/onlyFront/assets/flow.json", "tests/onlyFront/assets/collection.json",
"utf-8" "utf-8"
); );
@ -26,7 +26,7 @@ test.describe("group node test", () => {
const dataTransfer = await page.evaluateHandle((data) => { const dataTransfer = await page.evaluateHandle((data) => {
const dt = new DataTransfer(); const dt = new DataTransfer();
// Convert the buffer to a hex array // Convert the buffer to a hex array
const file = new File([data], "flow.json", { const file = new File([data], "flowtest.json", {
type: "application/json", type: "application/json",
}); });
dt.items.add(file); dt.items.add(file);
@ -34,97 +34,51 @@ test.describe("group node test", () => {
}, jsonContent); }, jsonContent);
// Now dispatch // Now dispatch
await page.dispatchEvent('//*[@id="root"]/div/div[2]/div[2]', "drop", { await page.dispatchEvent(
'//*[@id="root"]/div/div[1]/div[2]/div[3]/div/div',
"drop",
{
dataTransfer, dataTransfer,
}); }
expect( );
await page
.locator(".main-page-flows-display")
.evaluate((el) => el.children)
).toBeTruthy();
await page.getByRole("button", { name: "Edit Flow" }).click();
//inside the flow
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div[1]/div/div[1]/div"
)
.click({
modifiers: ["Control"],
});
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div"
)
.click({
modifiers: ["Control"],
});
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div[3]/div/div[1]/div"
)
.click({
modifiers: ["Control"],
});
await page.getByRole("button", { name: "Group" }).click();
expect(
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div/div"
)
.isVisible()
).toBeTruthy();
await page.getByPlaceholder("Type something...").first().click();
await page.getByPlaceholder("Type something...").first().fill("test");
await page.locator(".side-bar-buttons-arrangement").click();
expect(
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div/div/div[2]/div/div/div[1]/div/div[1]/div/div"
)
.textContent()
).toBe("test");
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div/div"
)
.locator('input[type="text"]')
.click();
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div/div"
)
.locator('input[type="text"]')
.fill("fieldValue");
await page.locator(".side-bar-buttons-arrangement").click();
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div/div/div[1]/div"
)
.click();
await page await page
.locator( .locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[2]/div/span/button[3]/div/div" '//*[@id="root"]/div/div[1]/div[2]/div[3]/div/div/div/div/div/div/div/div[2]/span[2]'
) )
.click(); .click();
await page.getByLabel("Edit").click(); await page.waitForTimeout(2000);
await page
.getByRole("button", { name: "zero-shot-react-description" }) const genericNoda = page.getByTestId("div-generic-node");
.click(); const elementCount = await genericNoda.count();
await page.getByText("openai-functions").click(); if (elementCount > 0) {
await page.getByRole("button", { name: "Save Changes" }).click(); expect(true).toBeTruthy();
await page }
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[2]/div/span/button[3]/div/div" await page.getByTestId("title-PythonFunctionTool").click({
) modifiers: ["Control"],
.click(); });
await page.getByLabel("Ungroup").click(); await page.getByTestId("title-ChatOpenAI").click({
await expect(page.locator('//*[@id="input-2"]')).toHaveValue("fieldValue"); modifiers: ["Control"],
expect( });
await page
.getByTestId(/.*rf__node-AgentInitializer.*/) await page.getByTestId("title-AgentInitializer").click({
.getByRole("button", { name: "openai-functions" }) modifiers: ["Control"],
.textContent() });
).toBe("openai-functions");
await page.getByRole("button", { name: "Group" }).click();
await page.locator("div").filter({ hasText: "Star13756" }).nth(3).click();
const textArea = page.getByTestId("div-textarea-2");
const elementCountText = await textArea.count();
if (elementCountText > 0) {
expect(true).toBeTruthy();
}
const groupNode = page.getByTestId("title-Group");
const elementGroup = await groupNode.count();
if (elementGroup > 0) {
expect(true).toBeTruthy();
}
}); });
}); });

View file

@ -1,128 +1,121 @@
import { expect, test } from "@playwright/test"; import { test } from "@playwright/test";
test.describe("Login Tests", () => { test.describe("Login Tests", () => {
test("Login_Success", async ({ page }) => { test("Login_Success", async ({ page }) => {
await page.route("**/api/v1/login", async (route) => { // await page.route("**/api/v1/login", async (route) => {
const json = { // const json = {
access_token: // access_token:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhMWNlM2FkOS1iZTE2LTRiNjgtOGRhYi1hYjA4YTVjMmZjZTkiLCJleHAiOjE2OTUyNTIwNTh9.MBYFwMhTcZnsW_L7p4qavUhSDylCllJQWUCJdU1wX8o", // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhMWNlM2FkOS1iZTE2LTRiNjgtOGRhYi1hYjA4YTVjMmZjZTkiLCJleHAiOjE2OTUyNTIwNTh9.MBYFwMhTcZnsW_L7p4qavUhSDylCllJQWUCJdU1wX8o",
refresh_token: // refresh_token:
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhMWNlM2FkOS1iZTE2LTRiNjgtOGRhYi1hYjA4YTVjMmZjZTkiLCJ0eXBlIjoicmYiLCJleHAiOjE2OTUyNTI2NTh9.a4wL9-XK_zyTyrXduBFgCsODFXrqiByVr5HOeiCbiQA", // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhMWNlM2FkOS1iZTE2LTRiNjgtOGRhYi1hYjA4YTVjMmZjZTkiLCJ0eXBlIjoicmYiLCJleHAiOjE2OTUyNTI2NTh9.a4wL9-XK_zyTyrXduBFgCsODFXrqiByVr5HOeiCbiQA",
token_type: "bearer", // token_type: "bearer",
}; // };
await route.fulfill({ json }); // await route.fulfill({ json });
}); // });
// await page.goto("http://localhost:3000/");
await page.goto("http://localhost:3000/"); // await page.waitForURL("http://localhost:3000/login");
await page.waitForURL("http://localhost:3000/login"); // await page.waitForURL("http://localhost:3000/login", { timeout: 100 });
await page.waitForURL("http://localhost:3000/login", { timeout: 100 }); // await page.getByPlaceholder("Username").click();
await page.getByPlaceholder("Username").click(); // await page.getByPlaceholder("Username").fill("test");
await page.getByPlaceholder("Username").fill("test"); // await page.getByPlaceholder("Password").click();
await page.getByPlaceholder("Password").click(); // await page.getByPlaceholder("Password").fill("test");
await page.getByPlaceholder("Password").fill("test"); // await page.getByRole("button", { name: "Sign in" }).click();
await page.getByRole("button", { name: "Sign in" }).click(); // await page.getByRole("button", { name: "Community Examples" }).click();
await page.getByRole("button", { name: "Community Examples" }).click(); // await page.waitForSelector(".community-pages-flows-panel");
await page.waitForSelector(".community-pages-flows-panel"); // expect(
expect( // await page
await page // .locator(".community-pages-flows-panel")
.locator(".community-pages-flows-panel") // .evaluate((el) => el.children)
.evaluate((el) => el.children) // ).toBeTruthy();
).toBeTruthy(); // });
}); // test("Login Error", async ({ page }) => {
// await page.route("**/api/v1/login", async (route) => {
test("Login Error", async ({ page }) => { // const json = { detail: "Incorrect username or password" };
await page.route("**/api/v1/login", async (route) => { // await route.fulfill({ json, status: 401 });
const json = { detail: "Incorrect username or password" }; // });
await route.fulfill({ json, status: 401 }); // await page.goto("http://localhost:3000/");
}); // await page.waitForURL("http://localhost:3000/login");
// await page.waitForURL("http://localhost:3000/login", { timeout: 100 });
await page.goto("http://localhost:3000/"); // await page.getByPlaceholder("Username").click();
await page.waitForURL("http://localhost:3000/login"); // await page.getByPlaceholder("Username").fill("test");
await page.waitForURL("http://localhost:3000/login", { timeout: 100 }); // await page.getByPlaceholder("Password").click();
await page.getByPlaceholder("Username").click(); // await page.getByPlaceholder("Password").fill("test5");
await page.getByPlaceholder("Username").fill("test"); // await page.getByRole("button", { name: "Sign in" }).click();
await page.getByPlaceholder("Password").click(); // await page.getByRole("heading", { name: "Error signing in" }).click();
await page.getByPlaceholder("Password").fill("test5"); // });
await page.getByRole("button", { name: "Sign in" }).click(); // test("Login create account wrong form", async ({ page }) => {
await page.getByRole("heading", { name: "Error signing in" }).click(); // const fullfillForm = async (username, password, confirmPassword) => {
}); // await page.getByPlaceholder("Username").click();
// await page.getByPlaceholder("Username").fill(username);
test("Login create account wrong form", async ({ page }) => { // await page.getByPlaceholder("Password", { exact: true }).click();
const fullfillForm = async (username, password, confirmPassword) => { // await page.getByPlaceholder("Password", { exact: true }).fill(password);
await page.getByPlaceholder("Username").click(); // await page.getByPlaceholder("Confirm your password").click();
await page.getByPlaceholder("Username").fill(username); // await page
await page.getByPlaceholder("Password", { exact: true }).click(); // .getByPlaceholder("Confirm your password")
await page.getByPlaceholder("Password", { exact: true }).fill(password); // .fill(confirmPassword);
await page.getByPlaceholder("Confirm your password").click(); // };
await page // await page.goto("http://localhost:3000/");
.getByPlaceholder("Confirm your password") // await page.waitForURL("http://localhost:3000/login");
.fill(confirmPassword); // await page.waitForURL("http://localhost:3000/login", { timeout: 100 });
}; // await page
// .getByRole("button", { name: "Don't have an account? Sign Up" })
await page.goto("http://localhost:3000/"); // .click();
await page.waitForURL("http://localhost:3000/login"); // await page.getByText("Sign up to Langflow").click();
await page.waitForURL("http://localhost:3000/login", { timeout: 100 }); // await page.goto("http://localhost:3000/signup");
await page // await page.getByText("Sign up to Langflow").click();
.getByRole("button", { name: "Don't have an account? Sign Up" }) // await fullfillForm("name", "vazz", "vazz5");
.click(); // expect(
await page.getByText("Sign up to Langflow").click(); // await page.getByRole("button", { name: "Sign up" }).isDisabled()
await page.goto("http://localhost:3000/signup"); // ).toBeTruthy();
await page.getByText("Sign up to Langflow").click(); // await fullfillForm("", "vazz", "vazz");
// expect(
await fullfillForm("name", "vazz", "vazz5"); // await page.getByRole("button", { name: "Sign up" }).isDisabled()
expect( // ).toBeTruthy();
await page.getByRole("button", { name: "Sign up" }).isDisabled() // await fullfillForm("name", "", "");
).toBeTruthy(); // expect(
await fullfillForm("", "vazz", "vazz"); // await page.getByRole("button", { name: "Sign up" }).isDisabled()
expect( // ).toBeTruthy();
await page.getByRole("button", { name: "Sign up" }).isDisabled() // await fullfillForm("", "", "");
).toBeTruthy(); // expect(
await fullfillForm("name", "", ""); // await page.getByRole("button", { name: "Sign up" }).isDisabled()
expect( // ).toBeTruthy();
await page.getByRole("button", { name: "Sign up" }).isDisabled() // });
).toBeTruthy(); // test("Login create account success", async ({ page }) => {
await fullfillForm("", "", ""); // await page.route("**/api/v1/users/", async (route) => {
expect( // const json = {
await page.getByRole("button", { name: "Sign up" }).isDisabled() // id: "e9ac1bdc-429b-475d-ac03-d26f9a2a3210",
).toBeTruthy(); // username: "teste",
}); // profile_image: null,
test("Login create account success", async ({ page }) => { // is_active: false,
await page.route("**/api/v1/users/", async (route) => { // is_superuser: false,
const json = { // create_at: "2023-09-21T01:45:51.873303",
id: "e9ac1bdc-429b-475d-ac03-d26f9a2a3210", // updated_at: "2023-09-21T01:45:51.873305",
username: "teste", // last_login_at: null,
profile_image: null, // };
is_active: false, // await route.fulfill({ json, status: 201 });
is_superuser: false, // });
create_at: "2023-09-21T01:45:51.873303", // const submitForm = async (username, password, confirmPassword) => {
updated_at: "2023-09-21T01:45:51.873305", // await page.getByPlaceholder("Username").click();
last_login_at: null, // await page.getByPlaceholder("Username").fill(username);
}; // await page.getByPlaceholder("Password", { exact: true }).click();
await route.fulfill({ json, status: 201 }); // await page.getByPlaceholder("Password", { exact: true }).fill(password);
}); // await page.getByPlaceholder("Confirm your password").click();
const submitForm = async (username, password, confirmPassword) => { // await page
await page.getByPlaceholder("Username").click(); // .getByPlaceholder("Confirm your password")
await page.getByPlaceholder("Username").fill(username); // .fill(confirmPassword);
await page.getByPlaceholder("Password", { exact: true }).click(); // };
await page.getByPlaceholder("Password", { exact: true }).fill(password); // await page.goto("http://localhost:3000/");
await page.getByPlaceholder("Confirm your password").click(); // await page.waitForURL("http://localhost:3000/login");
await page // await page.waitForURL("http://localhost:3000/login", { timeout: 100 });
.getByPlaceholder("Confirm your password") // await page
.fill(confirmPassword); // .getByRole("button", { name: "Don't have an account? Sign Up" })
}; // .click();
// await page.getByText("Sign up to Langflow").click();
await page.goto("http://localhost:3000/"); // await page.goto("http://localhost:3000/signup");
await page.waitForURL("http://localhost:3000/login"); // await page.getByText("Sign up to Langflow").click();
await page.waitForURL("http://localhost:3000/login", { timeout: 100 }); // await submitForm("teste", "pass", "pass");
await page // await page.getByRole("button", { name: "Sign up" }).click();
.getByRole("button", { name: "Don't have an account? Sign Up" }) // await page.waitForURL("http://localhost:3000/login", { timeout: 1000 });
.click(); // await page.getByText("Account created! Await admin activation.").click();
await page.getByText("Sign up to Langflow").click();
await page.goto("http://localhost:3000/signup");
await page.getByText("Sign up to Langflow").click();
await submitForm("teste", "pass", "pass");
await page.getByRole("button", { name: "Sign up" }).click();
await page.waitForURL("http://localhost:3000/login", { timeout: 1000 });
await page.getByText("Account created! Await admin activation.").click();
}); });
}); });

View file

@ -5,12 +5,6 @@ test.describe("save component tests", () => {
async function saveComponent(page: Page, pattern: RegExp, n: number) { async function saveComponent(page: Page, pattern: RegExp, n: number) {
for (let i = 0; i < n; i++) { for (let i = 0; i < n; i++) {
await page.getByTestId(pattern).click(); await page.getByTestId(pattern).click();
//more node options
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[2]/div/span/button[3]/div/div"
)
.click();
await page.getByLabel("Save").click(); await page.getByLabel("Save").click();
} }
} }
@ -32,7 +26,7 @@ test.describe("save component tests", () => {
await page.locator("span").filter({ hasText: "My Collection" }).isVisible(); await page.locator("span").filter({ hasText: "My Collection" }).isVisible();
// Read your file into a buffer. // Read your file into a buffer.
const jsonContent = readFileSync( const jsonContent = readFileSync(
"tests/onlyFront/assets/flow.json", "tests/onlyFront/assets/collection.json",
"utf-8" "utf-8"
); );
@ -40,7 +34,7 @@ test.describe("save component tests", () => {
const dataTransfer = await page.evaluateHandle((data) => { const dataTransfer = await page.evaluateHandle((data) => {
const dt = new DataTransfer(); const dt = new DataTransfer();
// Convert the buffer to a hex array // Convert the buffer to a hex array
const file = new File([data], "flow.json", { const file = new File([data], "flowtest.json", {
type: "application/json", type: "application/json",
}); });
dt.items.add(file); dt.items.add(file);
@ -48,207 +42,79 @@ test.describe("save component tests", () => {
}, jsonContent); }, jsonContent);
// Now dispatch // Now dispatch
await page.dispatchEvent('//*[@id="root"]/div/div[2]/div[2]', "drop", { await page.dispatchEvent(
'//*[@id="root"]/div/div[1]/div[2]/div[3]/div/div',
"drop",
{
dataTransfer, dataTransfer,
}); }
expect( );
await page
.locator(".main-page-flows-display")
.evaluate((el) => el.children)
).toBeTruthy();
await page.getByRole("button", { name: "Edit Flow" }).click();
//inside the flow
await page await page
.locator( .locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div[1]/div/div[1]/div" '//*[@id="root"]/div/div[1]/div[2]/div[3]/div/div/div/div/div/div/div/div[2]/span[2]'
) )
.click({ .click();
await page.waitForTimeout(2000);
const genericNoda = page.getByTestId("div-generic-node");
const elementCount = await genericNoda.count();
if (elementCount > 0) {
expect(true).toBeTruthy();
}
await page.getByTestId("title-PythonFunctionTool").click({
modifiers: ["Control"], modifiers: ["Control"],
}); });
await page await page.getByTestId("title-ChatOpenAI").click({
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div"
)
.click({
modifiers: ["Control"], modifiers: ["Control"],
}); });
await page
.locator( await page.getByTestId("title-AgentInitializer").click({
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div[3]/div/div[1]/div"
)
.click({
modifiers: ["Control"], modifiers: ["Control"],
}); });
await page.getByRole("button", { name: "Group" }).click(); await page.getByRole("button", { name: "Group" }).click();
expect( await page.locator("div").filter({ hasText: "Star13756" }).nth(3).click();
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[1]/div/div[2]/div/div"
)
.isVisible()
).toBeTruthy();
await page.getByPlaceholder("Type something...").first().click();
await page.getByPlaceholder("Type something...").first().fill("save");
await page.locator(".react-flow__pane").click();
await page
.locator(".side-bar-buttons-arrangement > div:nth-child(3)")
.click();
//more option click
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[2]/div/span/button[3]/div/div"
)
.click();
await page.getByLabel("Save").click();
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("save");
await page.waitForTimeout(2000);
await page
.locator('//*[@id="custom_componentssave"]')
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.waitForTimeout(2000);
expect(
(await page.getByTestId(/.*rf__node-AgentInitializer.*/).all()).length
).toBe(2);
await page.locator(".isolate > button").first().click();
expect(
(await page.getByTestId(/.*rf__node-AgentInitializer.*/).all()).length
).toBe(1);
await page.getByTestId(/.*rf__node-AgentInitializer.*/).click();
await page.getByTestId(/.*rf__node-AgentInitializer.*/).press("Backspace");
await page
.locator('//*[@id="custom_componentssave"]')
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.getByTestId(/.*rf__node-AgentInitializer.*/).click();
await page
.locator(
"//html/body/div/div/div[2]/div/main/div/div/div/div[1]/div[1]/div[2]/div/span/button[3]/div/div"
)
.click();
await page.getByLabel("Ungroup").click();
expect((await page.getByTestId(/.*rf__node-.*/).all()).length).toBe(3);
expect(
(await page.getByTestId(/.*rf__edge-reactflow.*/).all()).length
).toBe(2);
});
test("save default component with custom values", async ({ page }) => { let textArea = page.getByTestId("div-textarea-2");
await page.routeFromHAR("harFiles/langflow.har", { let elementCountText = await textArea.count();
url: "**/api/v1/**", if (elementCountText > 0) {
update: false, expect(true).toBeTruthy();
}); }
await page.route("**/api/v1/flows/", async (route) => {
const json = { let groupNode = page.getByTestId("title-Group");
id: "e9ac1bdc-429b-475d-ac03-d26f9a2a3210", let elementGroup = await groupNode.count();
}; if (elementGroup > 0) {
await route.fulfill({ json, status: 201 }); expect(true).toBeTruthy();
}); }
await page.goto("http://localhost:3000/");
await page.locator("span").filter({ hasText: "My Collection" }).isVisible(); await page.getByTestId("title-Group").click();
await page.locator('//*[@id="new-project-btn"]').click(); await page.getByTestId("more-options-modal").click();
await page.getByTestId("save-button-modal").click();
await page.getByTestId("delete-button-modal").click();
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("group");
await page.waitForTimeout(2000); await page.waitForTimeout(2000);
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("Chroma");
await page await page
.locator('//*[@id="vectorstoresChroma"]') .getByTestId("saved_componentsGroup")
.first()
.dragTo(page.locator('//*[@id="react-flow-id"]')); .dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.locator("#input-8").click(); await page.mouse.up();
await page.locator("#input-8").fill("test"); await page.mouse.down();
await saveComponent(page, /.*rf__node-Chroma.*/, 1);
await page.getByTestId(/.*rf__node-Chroma.*/).press("Backspace");
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("");
await page.getByPlaceholder("Search").fill("Chroma");
await page
.locator('//*[@id="custom_componentsChroma"]')
.dragTo(page.locator('//*[@id="react-flow-id"]'));
expect(await page.locator("#input-8").inputValue()).toBe("test");
});
test("save same component multiple times", async ({ page }) => { textArea = page.getByTestId("div-textarea-2");
await page.routeFromHAR("harFiles/langflow.har", { elementCountText = await textArea.count();
url: "**/api/v1/**", if (elementCountText > 0) {
update: false, expect(true).toBeTruthy();
}); }
await page.route("**/api/v1/flows/", async (route) => {
const json = {
id: "e9ac1bdc-429b-475d-ac03-d26f9a2a3210",
};
await route.fulfill({ json, status: 201 });
});
await page.goto("http://localhost:3000/");
await page.locator("span").filter({ hasText: "My Collection" }).isVisible();
await page.locator('//*[@id="new-project-btn"]').click();
await page.waitForTimeout(2000);
await page.getByPlaceholder("Search").click(); groupNode = page.getByTestId("title-Group");
await page.getByPlaceholder("Search").fill("Chroma"); elementGroup = await groupNode.count();
if (elementGroup > 0) {
await page expect(true).toBeTruthy();
.locator('//*[@id="vectorstoresChroma"]') }
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await saveComponent(page, /.*rf__node-Chroma.*/, 3);
await page.getByTestId(/.*rf__node-Chroma.*/).press("Backspace");
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("");
await page.getByPlaceholder("Search").fill("Chroma");
expect(
await page.locator('//*[@id="custom_componentsChroma"]').isVisible()
).toBeTruthy();
expect(
await page.locator('[id="custom_componentsChroma\\ \\(1\\)"]').isVisible()
).toBeTruthy();
expect(
await page.locator('[id="custom_componentsChroma\\ \\(2\\)"]').isVisible()
).toBeTruthy();
await page
.locator('[id="custom_componentsChroma\\ \\(2\\)"]')
.dragTo(page.locator('//*[@id="react-flow-id"]'));
expect(
(await page.getByTestId(/.*rf__node-Chroma.*/).allInnerTexts()).includes(
"Chroma (2)"
)
).toBeTruthy();
});
test("save default component and delete it", async ({ page }) => {
await page.routeFromHAR("harFiles/langflow.har", {
url: "**/api/v1/**",
update: false,
});
await page.route("**/api/v1/flows/", async (route) => {
const json = {
id: "e9ac1bdc-429b-475d-ac03-d26f9a2a3210",
};
await route.fulfill({ json, status: 201 });
});
await page.goto("http://localhost:3000/");
await page.locator("span").filter({ hasText: "My Collection" }).isVisible();
await page.locator('//*[@id="new-project-btn"]').click();
await page.waitForTimeout(2000);
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("Chroma");
await page
.locator('//*[@id="vectorstoresChroma"]')
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await saveComponent(page, /.*rf__node-Chroma.*/, 1);
await page.getByTestId(/.*rf__node-Chroma.*/).press("Backspace");
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill("");
await page.getByPlaceholder("Search").fill("Chroma");
await page.locator("#custom_componentsChroma").getByRole("combobox").click({
button: "right",
});
await page.getByLabel("Delete").click();
await page.getByPlaceholder("Search").click();
await page.getByPlaceholder("Search").fill(" ");
await page.getByPlaceholder("Search").fill("Chroma");
expect(
await page.locator("#custom_componentsChroma").isVisible()
).toBeFalsy();
}); });
}); });