merge dev into branch

This commit is contained in:
cristhianzl 2024-06-27 15:16:21 -03:00
commit 04277fae7e
39 changed files with 1189 additions and 785 deletions

View file

@ -1,16 +1,11 @@
name: Run Frontend Tests
on:
workflow_dispatch:
inputs:
branch:
description: "Branch to run tests on"
required: true
type: string
pull_request:
merge_group:
env:
POETRY_VERSION: "1.8.2"
POETRY_VERSION: "1.8.3"
NODE_VERSION: "21"
PYTHON_VERSION: "3.12"
# Define the directory where Playwright browsers will be installed.
@ -19,18 +14,19 @@ env:
jobs:
setup-and-test:
name: Run Frontend Tests on branch ${{ inputs.branch }}
name: Run Playwright Tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shardIndex: [1, 2, 3, 4]
shardTotal: [4]
shardIndex: [1, 2, 3, 4, 5, 6, 7, 8]
shardTotal: [8]
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
STORE_API_KEY: ${{ secrets.STORE_API_KEY }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.branch }}
- name: Setup Node.js
uses: actions/setup-node@v4
@ -52,14 +48,15 @@ jobs:
cd src/frontend
npm ci
if: ${{ steps.setup-node.outputs.cache-hit != 'true' }}
- name: Cache playwright binaries
uses: actions/cache@v4
- name: Get Playwright version
run: echo "PLAYWRIGHT_VERSION=$(jq '.devDependencies["@playwright/test"]' src/frontend/package.json -r)" >> $GITHUB_ENV
- name: Cache Playwright binaries
id: playwright-cache
uses: actions/cache@v4
with:
path: |
~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('src/frontend/package-lock.json') }}
path: ~/.cache/ms-playwright
key: playwright-browsers-${{ runner.os }}-${{ env.PLAYWRIGHT_VERSION }}
- name: Install Frontend dependencies
run: |
cd src/frontend

View file

@ -15,11 +15,11 @@ dotenv.config({ path: path.resolve(__dirname, "../../.env") });
export default defineConfig({
testDir: "./tests",
/* Run tests in files in parallel */
fullyParallel: true,
fullyParallel: false,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
retries: process.env.CI ? 2 : 3,
/* Opt out of parallel tests on CI. */
workers: 2,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */

View file

@ -229,6 +229,7 @@ export default function CollectionCardComponent({
render={({ field }) => (
<FormControl>
<Checkbox
data-testid={`checkbox-component`}
aria-label="checkbox-component"
checked={field.value}
onCheckedChange={field.onChange}

View file

@ -67,6 +67,7 @@ export default function FlowToolbar(): JSX.Element {
? "button-disable text-muted-foreground"
: "",
)}
data-testid="shared-button-flow"
>
<ForwardedIconComponent
name="Share3"

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

@ -33,6 +33,11 @@ test("should able to see and interact with logs", async ({ page }) => {
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page.getByTestId("button_run_chat output").first().click();
await page.waitForTimeout(2000);

View file

@ -45,6 +45,7 @@ const TextAreaWrapper = ({
return (
<Textarea
data-testid="input-chat-playground"
onFocus={(e) => {
setInputFocus(true);
e.target.style.borderTopWidth = "0";

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,90 @@
import { expect, test } from "@playwright/test";
import path from "path";
test("Basic Prompting (Hello, World)", async ({ page }) => {
if (!process?.env?.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
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
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page.getByTestId("button_run_chat output").click();
await page.waitForSelector("text=built successfully", { timeout: 30000 });
await page.getByText("built successfully").last().click({
timeout: 15000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByText("No input message provided.", { exact: true })
.last()
.isVisible();
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page
.getByTestId("input-chat-playground")
.last()
.fill("Say hello as a pirate");
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForTimeout(3000);
await page.getByText("Ahoy").last().isVisible();
await page.getByText("Default Session").last().click();
await page.getByText("timestamp", { exact: true }).last().isVisible();
await page.getByText("text", { exact: true }).last().isVisible();
await page.getByText("sender", { exact: true }).last().isVisible();
await page.getByText("sender_name", { exact: true }).last().isVisible();
await page.getByText("session_id", { exact: true }).last().isVisible();
await page.getByText("files", { exact: true }).last().isVisible();
await page.getByRole("gridcell").last().isVisible();
await page.getByTestId("icon-Trash2").first().click();
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page.getByTestId("input-chat-playground").last().isVisible();
});

View file

@ -0,0 +1,109 @@
import { expect, test } from "@playwright/test";
import path from "path";
test("Blog Writer", async ({ page }) => {
if (!process?.env?.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
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: "Blog Writer" }).click();
await page.waitForTimeout(1000);
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
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page
.getByTestId("input-list-input_urls-0")
.nth(0)
.fill(
"https://www.natgeokids.com/uk/discover/animals/sea-life/turtle-facts/",
);
await page
.getByTestId("input-list-input_urls-1")
.nth(0)
.fill("https://www.originaldiving.com/blog/top-ten-turtle-facts");
await page
.getByTestId("popover-anchor-input-input_value")
.nth(0)
.fill(
"Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.",
);
await page.getByTestId("button_run_chat output").click();
await page.waitForTimeout(5000);
await page.waitForSelector("text=built successfully", { timeout: 30000 });
await page.getByText("built successfully").last().click({
timeout: 30000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByPlaceholder(
"No chat input variables found. Click to run your flow.",
{ exact: true },
)
.last()
.isVisible();
await page.waitForTimeout(3000);
await page.getByText("turtles").last().isVisible();
await page.getByText("sea").last().isVisible();
await page.getByText("survival").last().isVisible();
await page.getByText("Instructions").last().click();
const value = await page
.getByPlaceholder("Enter text...")
.last()
.inputValue();
expect(value).toBe(
"Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.",
);
await page.getByTestId("icon-ExternalLink").last().click();
const count = await page
.getByText(
"Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.",
)
.count();
if (count <= 1) {
expect(false).toBe(true);
}
});

View file

@ -0,0 +1,96 @@
import { expect, test } from "@playwright/test";
import path from "path";
test("Document QA", async ({ page }) => {
if (!process?.env?.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
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: "Document QA" }).click();
await page.waitForTimeout(1000);
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
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
const fileChooserPromise = page.waitForEvent("filechooser");
await page.getByTestId("icon-FileSearch2").click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, "/assets/test_file.txt"));
await page.getByText("test_file.txt").isVisible();
await page.waitForTimeout(2000);
await page.getByTestId("button_run_chat output").click();
await page.waitForSelector("text=built successfully", { timeout: 30000 });
await page.getByText("built successfully").last().click({
timeout: 15000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByText("No input message provided.", { exact: true })
.last()
.isVisible();
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page
.getByTestId("input-chat-playground")
.last()
.fill("whats the text in the file?");
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForTimeout(3000);
await page.getByText("this is a test file").last().isVisible();
await page.getByText("Default Session").last().click();
await page.getByText("timestamp", { exact: true }).last().isVisible();
await page.getByText("text", { exact: true }).last().isVisible();
await page.getByText("sender", { exact: true }).last().isVisible();
await page.getByText("sender_name", { exact: true }).last().isVisible();
await page.getByText("session_id", { exact: true }).last().isVisible();
await page.getByText("files", { exact: true }).last().isVisible();
await page.getByRole("gridcell").last().isVisible();
await page.getByTestId("icon-Trash2").first().click();
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page.getByTestId("input-chat-playground").last().isVisible();
});

View file

@ -0,0 +1,102 @@
import { expect, test } from "@playwright/test";
import path from "path";
test("Memory Chatbot", async ({ page }) => {
if (!process?.env?.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
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: "Memory Chatbot" }).click();
await page.waitForTimeout(1000);
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
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page.getByTestId("button_run_chat output").click();
await page.waitForSelector("text=built successfully", { timeout: 30000 });
await page.getByText("built successfully").last().click({
timeout: 15000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByText("No input message provided.", { exact: true })
.last()
.isVisible();
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page
.getByTestId("input-chat-playground")
.last()
.fill("Remember that I'm a lion");
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page
.getByTestId("input-chat-playground")
.last()
.fill("try reproduce the sound I made in words");
await page.waitForSelector('[data-testid="icon-LucideSend"]', {
timeout: 100000,
});
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForSelector("text=roar", { timeout: 30000 });
await page.getByText("roar").last().isVisible();
await page.getByText("Default Session").last().click();
await page.getByText("timestamp", { exact: true }).last().isVisible();
await page.getByText("text", { exact: true }).last().isVisible();
await page.getByText("sender", { exact: true }).last().isVisible();
await page.getByText("sender_name", { exact: true }).last().isVisible();
await page.getByText("session_id", { exact: true }).last().isVisible();
await page.getByText("files", { exact: true }).last().isVisible();
await page.getByRole("gridcell").last().isVisible();
await page.getByTestId("icon-Trash2").first().click();
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page.getByTestId("input-chat-playground").last().isVisible();
});

View file

@ -0,0 +1,129 @@
import { expect, test } from "@playwright/test";
import path from "path";
test("Vector Store RAG", 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: "Vector Store RAG" }).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();
// if (
// !process.env.OPENAI_API_KEY ||
// !process.env.ASTRA_DB_API_ENDPOINT ||
// !process.env.ASTRA_DB_APPLICATION_TOKEN
// ) {
// //You must set the OPENAI_API_KEY, ASTRA_DB_API_ENDPOINT and ASTRA_DB_APPLICATION_TOKEN on .env file to run this test
// expect(false).toBe(true);
// }
// await page
// .getByTestId("popover-anchor-input-openai_api_key")
// .nth(0)
// .fill(process.env.OPENAI_API_KEY ?? "");
// await page
// .getByTestId("popover-anchor-input-openai_api_key")
// .nth(1)
// .fill(process.env.OPENAI_API_KEY ?? "");
// await page
// .getByTestId("popover-anchor-input-openai_api_key")
// .nth(2)
// .fill(process.env.OPENAI_API_KEY ?? "");
// await page
// .getByTestId("popover-anchor-input-token")
// .nth(0)
// .fill(process.env.ASTRA_DB_APPLICATION_TOKEN ?? "");
// await page
// .getByTestId("popover-anchor-input-token")
// .nth(1)
// .fill(process.env.ASTRA_DB_APPLICATION_TOKEN ?? "");
// await page
// .getByTestId("popover-anchor-input-api_endpoint")
// .nth(0)
// .fill(process.env.ASTRA_DB_API_ENDPOINT ?? "");
// await page
// .getByTestId("popover-anchor-input-api_endpoint")
// .nth(1)
// .fill(process.env.ASTRA_DB_API_ENDPOINT ?? "");
const fileChooserPromise = page.waitForEvent("filechooser");
await page.getByTestId("icon-FileSearch2").last().click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, "/assets/test_file.txt"));
await page.getByText("test_file.txt").isVisible();
// await page.getByTestId("button_run_astra db").first().click();
// await page.waitForSelector("text=built successfully", { timeout: 30000 });
// await page.getByText("built successfully").last().click({
// timeout: 30000,
// });
// await page.getByTestId("button_run_chat output").click();
// await page.waitForSelector("text=built successfully", { timeout: 30000 });
// await page.getByText("built successfully").last().click({
// timeout: 30000,
// });
// await page.getByText("Playground", { exact: true }).click();
// await page.waitForSelector('[data-testid="input-chat-playground"]', {
// timeout: 100000,
// });
// await page.getByTestId("input-chat-playground").last().fill("hello");
// await page.getByTestId("icon-LucideSend").last().click();
// await page
// .getByText("This is a test file.", { exact: true })
// .last()
// .isVisible();
// await page.getByText("Memories", { exact: true }).last().click();
// await page.getByText("Default Session").last().click();
// await page.getByText("timestamp", { exact: true }).last().isVisible();
// await page.getByText("text", { exact: true }).last().isVisible();
// await page.getByText("sender", { exact: true }).last().isVisible();
// await page.getByText("sender_name", { exact: true }).last().isVisible();
// await page.getByText("session_id", { exact: true }).last().isVisible();
// await page.getByText("files", { exact: true }).last().isVisible();
// await page.getByRole("gridcell").last().isVisible();
// await page.getByTestId("icon-Trash2").first().click();
// await page.waitForSelector('[data-testid="input-chat-playground"]', {
// timeout: 100000,
// });
// await page.getByTestId("input-chat-playground").last().isVisible();
});

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

@ -89,6 +89,10 @@ test("search components", async ({ page }) => {
}
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();
@ -133,128 +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.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.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,440 +0,0 @@
import { expect, test } from "@playwright/test";
import path from "path";
test("Basic Prompting (Hello, World)", 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.waitForTimeout(1000);
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("button_run_chat output").click();
await page.waitForTimeout(1000);
await page.getByText("built successfully").last().click({
timeout: 15000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByText("No input message provided.", { exact: true })
.last()
.isVisible();
await page
.getByPlaceholder("Send a message...")
.last()
.fill("Say hello as a pirate");
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForTimeout(3000);
await page.getByText("Ahoy").last().isVisible();
await page.getByText("Default Session").last().click();
await page.getByText("timestamp", { exact: true }).last().isVisible();
await page.getByText("text", { exact: true }).last().isVisible();
await page.getByText("sender", { exact: true }).last().isVisible();
await page.getByText("sender_name", { exact: true }).last().isVisible();
await page.getByText("session_id", { exact: true }).last().isVisible();
await page.getByText("files", { exact: true }).last().isVisible();
await page.getByRole("gridcell").last().isVisible();
await page.getByTestId("icon-Trash2").first().click();
await page.getByPlaceholder("Send a message...").last().isVisible();
});
test("Memory Chatbot", 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: "Memory Chatbot" }).click();
await page.waitForTimeout(1000);
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("button_run_chat output").click();
await page.waitForTimeout(1000);
await page.getByText("built successfully").last().click({
timeout: 15000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByText("No input message provided.", { exact: true })
.last()
.isVisible();
await page
.getByPlaceholder("Send a message...")
.last()
.fill("Remember that I'm a lion");
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForTimeout(3000);
await page
.getByPlaceholder("Send a message...")
.last()
.fill("try reproduce the sound I made in words");
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForTimeout(3000);
await page.getByText("roar").last().isVisible();
await page.getByText("Default Session").last().click();
await page.getByText("timestamp", { exact: true }).last().isVisible();
await page.getByText("text", { exact: true }).last().isVisible();
await page.getByText("sender", { exact: true }).last().isVisible();
await page.getByText("sender_name", { exact: true }).last().isVisible();
await page.getByText("session_id", { exact: true }).last().isVisible();
await page.getByText("files", { exact: true }).last().isVisible();
await page.getByRole("gridcell").last().isVisible();
await page.getByTestId("icon-Trash2").first().click();
await page.getByPlaceholder("Send a message...").last().isVisible();
});
test("Document QA", 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: "Document QA" }).click();
await page.waitForTimeout(1000);
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
const fileChooserPromise = page.waitForEvent("filechooser");
await page.getByTestId("icon-FileSearch2").click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, "/assets/test_file.txt"));
await page.getByText("test_file.txt").isVisible();
await page.waitForTimeout(2000);
await page.getByTestId("button_run_chat output").click();
await page.getByText("built successfully").last().click({
timeout: 15000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByText("No input message provided.", { exact: true })
.last()
.isVisible();
await page
.getByPlaceholder("Send a message...")
.last()
.fill("whats the text in the file?");
await page.getByTestId("icon-LucideSend").last().click();
await page.waitForTimeout(3000);
await page.getByText("this is a test file").last().isVisible();
await page.getByText("Default Session").last().click();
await page.getByText("timestamp", { exact: true }).last().isVisible();
await page.getByText("text", { exact: true }).last().isVisible();
await page.getByText("sender", { exact: true }).last().isVisible();
await page.getByText("sender_name", { exact: true }).last().isVisible();
await page.getByText("session_id", { exact: true }).last().isVisible();
await page.getByText("files", { exact: true }).last().isVisible();
await page.getByRole("gridcell").last().isVisible();
await page.getByTestId("icon-Trash2").first().click();
await page.getByPlaceholder("Send a message...").last().isVisible();
});
test("Blog Writer", 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: "Blog Writer" }).click();
await page.waitForTimeout(1000);
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page
.getByTestId("input-list-input_urls-0")
.nth(0)
.fill(
"https://www.natgeokids.com/uk/discover/animals/sea-life/turtle-facts/",
);
await page
.getByTestId("input-list-input_urls-1")
.nth(0)
.fill("https://www.originaldiving.com/blog/top-ten-turtle-facts");
await page
.getByTestId("popover-anchor-input-input_value")
.nth(0)
.fill(
"Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.",
);
await page.getByTestId("button_run_chat output").click();
await page.waitForTimeout(5000);
await page.getByText("built successfully").last().click({
timeout: 30000,
});
await page.getByText("Playground", { exact: true }).click();
await page
.getByPlaceholder(
"No chat input variables found. Click to run your flow.",
{ exact: true },
)
.last()
.isVisible();
await page.waitForTimeout(3000);
await page.getByText("turtles").last().isVisible();
await page.getByText("sea").last().isVisible();
await page.getByText("survival").last().isVisible();
await page.getByText("Instructions").last().click();
const value = await page
.getByPlaceholder("Enter text...")
.last()
.inputValue();
expect(value).toBe(
"Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.",
);
await page.getByTestId("icon-ExternalLink").last().click();
const count = await page
.getByText(
"Use the references above for style to write a new blog/tutorial about turtles. Suggest non-covered topics.",
)
.count();
if (count <= 1) {
expect(false).toBe(true);
}
});
test("Vector Store RAG", 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: "Vector Store RAG" }).click();
await page.waitForTimeout(1000);
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
if (
!process.env.OPENAI_API_KEY ||
!process.env.ASTRA_DB_API_ENDPOINT ||
!process.env.ASTRA_DB_APPLICATION_TOKEN
) {
//You must set the OPENAI_API_KEY, ASTRA_DB_API_ENDPOINT and ASTRA_DB_APPLICATION_TOKEN on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.nth(0)
.fill(process.env.OPENAI_API_KEY ?? "");
await page
.getByTestId("popover-anchor-input-openai_api_key")
.nth(1)
.fill(process.env.OPENAI_API_KEY ?? "");
await page
.getByTestId("popover-anchor-input-openai_api_key")
.nth(2)
.fill(process.env.OPENAI_API_KEY ?? "");
await page
.getByTestId("popover-anchor-input-token")
.nth(0)
.fill(process.env.ASTRA_DB_APPLICATION_TOKEN ?? "");
await page
.getByTestId("popover-anchor-input-token")
.nth(1)
.fill(process.env.ASTRA_DB_APPLICATION_TOKEN ?? "");
await page
.getByTestId("popover-anchor-input-api_endpoint")
.nth(0)
.fill(process.env.ASTRA_DB_API_ENDPOINT ?? "");
await page
.getByTestId("popover-anchor-input-api_endpoint")
.nth(1)
.fill(process.env.ASTRA_DB_API_ENDPOINT ?? "");
const fileChooserPromise = page.waitForEvent("filechooser");
await page.getByTestId("icon-FileSearch2").last().click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, "/assets/test_file.txt"));
await page.getByText("test_file.txt").isVisible();
await page.waitForTimeout(2000);
await page.getByTestId("button_run_astra db").first().click();
await page.getByText("built successfully").last().click({
timeout: 30000,
});
await page.getByTestId("button_run_chat output").click();
await page.getByText("built successfully").last().click({
timeout: 30000,
});
await page.getByText("Playground", { exact: true }).click();
await page.getByPlaceholder("Send a message...").last().fill("hello");
await page.getByTestId("icon-LucideSend").last().click();
await page
.getByText("This is a test file.", { exact: true })
.last()
.isVisible();
await page.getByText("Memories", { exact: true }).last().click();
await page.getByText("Default Session").last().click();
await page.getByText("timestamp", { exact: true }).last().isVisible();
await page.getByText("text", { exact: true }).last().isVisible();
await page.getByText("sender", { exact: true }).last().isVisible();
await page.getByText("sender_name", { exact: true }).last().isVisible();
await page.getByText("session_id", { exact: true }).last().isVisible();
await page.getByText("files", { exact: true }).last().isVisible();
await page.getByRole("gridcell").last().isVisible();
await page.getByTestId("icon-Trash2").first().click();
await page.getByPlaceholder("Send a message...").last().isVisible();
});

View file

@ -50,6 +50,10 @@ test("chat_io_teste", async ({ page }) => {
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();
@ -96,8 +100,11 @@ test("chat_io_teste", async ({ page }) => {
await page.getByLabel("fit view").click();
await page.getByText("Playground", { exact: true }).click();
await page.getByPlaceholder("Send a message...").click();
await page.getByPlaceholder("Send a message...").fill("teste");
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page.getByTestId("input-chat-playground").click();
await page.getByTestId("input-chat-playground").fill("teste");
await page.getByRole("button").nth(1).click();
const chat_output = page.getByTestId("chat-message-AI-teste");
const chat_input = page.getByTestId("chat-message-User-teste");

View file

@ -0,0 +1,108 @@
import { expect, test } from "@playwright/test";
import * as dotenv from "dotenv";
import { readFileSync } from "fs";
import path from "path";
test("user must be able to send an image on chat", async ({ page }) => {
if (!process.env.CI) {
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
}
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.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();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForSelector("text=Chat Input", { timeout: 30000 });
await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click();
await page.getByText("Save Changes").click();
await page.getByText("Playground", { exact: true }).click();
// Read the image file as a binary string
const filePath = "tests/end-to-end/assets/chain.png";
const fileContent = readFileSync(filePath, "base64");
// Create the DataTransfer and File objects within the browser context
const dataTransfer = await page.evaluateHandle(
({ fileContent }) => {
const dt = new DataTransfer();
const byteCharacters = atob(fileContent);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const file = new File([byteArray], "chain.png", { type: "image/png" });
dt.items.add(file);
return dt;
},
{ fileContent },
);
// Locate the target element
const element = await page.getByTestId("input-chat-playground");
// Dispatch the drop event on the target element
await element.dispatchEvent("drop", { dataTransfer });
await page.waitForSelector('[data-testid="icon-LucideSend"]', {
timeout: 100000,
});
await page.getByTestId("icon-LucideSend").click();
await page.waitForSelector("text=chain.png", { timeout: 30000 });
await page.getByText("chain.png").isVisible();
await page.getByText("Close", { exact: true }).click();
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
timeout: 30000,
});
await page.getByTestId("icon-ScanEye").nth(4).click();
await page.getByText("Restart").isHidden();
});

View file

@ -0,0 +1,67 @@
import { expect, test } from "@playwright/test";
import * as dotenv from "dotenv";
import { readFileSync } from "fs";
import path from "path";
test("user must be able to see output inspection", async ({ page }) => {
if (!process.env.CI) {
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
}
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.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();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page.getByTestId("button_run_chat output").last().click();
await page.waitForTimeout(5000);
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
timeout: 30000,
});
await page.getByTestId("icon-ScanEye").nth(4).click();
await page.getByText("Sender", { exact: true }).isVisible();
await page.getByText("Type", { exact: true }).isVisible();
await page.getByText("User", { exact: true }).last().isVisible();
});

View file

@ -29,7 +29,9 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
}
await page.getByRole("heading", { name: "Basic Prompting" }).click();
await page.waitForTimeout(1000);
await page.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
@ -44,8 +46,23 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page.getByText("Playground", { exact: true }).click();
await page.getByPlaceholder("Send a message...").fill("Hello, how are you?");
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page.getByTestId("input-chat-playground").fill("Hello, how are you?");
await page.waitForSelector('[data-testid="icon-LucideSend"]', {
timeout: 100000,
});
await page.getByTestId("icon-LucideSend").click();
let valueUser = await page.getByTestId("sender_name_user").textContent();
@ -67,6 +84,11 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
"testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!",
);
await page.getByText("Playground", { exact: true }).last().click();
await page.waitForSelector('[data-testid="icon-LucideSend"]', {
timeout: 100000,
});
await page.getByTestId("icon-LucideSend").click();
await page.getByText("Close", { exact: true }).click();
await page.getByText("Chat Input", { exact: true }).click();
@ -89,6 +111,11 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
.fill("TestSenderNameAI");
await page.getByText("Playground", { exact: true }).last().click();
await page.waitForSelector('[data-testid="icon-LucideSend"]', {
timeout: 100000,
});
await page.getByTestId("icon-LucideSend").click();
valueUser = await page
@ -110,153 +137,3 @@ test("user must interact with chat with Input/Output", async ({ page }) => {
.isVisible(),
);
});
test("user must be able to see output inspection", async ({ page }) => {
if (!process.env.CI) {
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
}
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.getByRole("heading", { name: "Basic Prompting" }).click();
await page.waitForTimeout(1000);
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("button_run_chat output").last().click();
await page.waitForTimeout(5000);
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
timeout: 30000,
});
await page.getByTestId("icon-ScanEye").nth(4).click();
await page.getByText("Sender", { exact: true }).isVisible();
await page.getByText("Type", { exact: true }).isVisible();
await page.getByText("User", { exact: true }).last().isVisible();
});
test("user must be able to send an image on chat", async ({ page }) => {
if (!process.env.CI) {
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
}
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.getByRole("heading", { name: "Basic Prompting" }).click();
await page.waitForTimeout(1000);
await page.getByTitle("fit view").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
if (!process.env.OPENAI_API_KEY) {
//You must set the OPENAI_API_KEY on .env file to run this test
expect(false).toBe(true);
}
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByText("Chat Input", { exact: true }).click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click();
await page.getByText("Save Changes").click();
await page.getByText("Playground", { exact: true }).click();
// Read the image file as a binary string
const filePath = "tests/end-to-end/assets/chain.png";
const fileContent = readFileSync(filePath, "base64");
// Create the DataTransfer and File objects within the browser context
const dataTransfer = await page.evaluateHandle(
({ fileContent }) => {
const dt = new DataTransfer();
const byteCharacters = atob(fileContent);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const file = new File([byteArray], "chain.png", { type: "image/png" });
dt.items.add(file);
return dt;
},
{ fileContent },
);
// Locate the target element
const element = await page.getByPlaceholder("Send a message...");
// Dispatch the drop event on the target element
await element.dispatchEvent("drop", { dataTransfer });
await page.waitForTimeout(4000);
await page.getByText("chain.png").isVisible();
await page.getByTestId("icon-LucideSend").click();
await page.waitForTimeout(2000);
await page.getByText("chain.png").isVisible();
await page.getByText("Close", { exact: true }).click();
await page.waitForSelector('[data-testid="icon-ScanEye"]', {
timeout: 30000,
});
await page.getByTestId("icon-ScanEye").nth(4).click();
await page.getByText("Restart").isHidden();
});

View file

@ -1,29 +1,61 @@
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.waitForSelector("text=Store", { timeout: 30000 });
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.getByText("Save").last().click();
await page.waitForTimeout(8000);
await page.getByText("Store").nth(0).click();
await page.getByTestId("install-Website Content QA").click();
await page.waitForTimeout(5000);
await page.getByText("My Collection").nth(0).click();
await page.getByText("Website Content QA").first().isVisible();
await page.getByLabel("checkbox-component").last().waitFor({
state: "visible",
timeout: 30000, // Timeout of 30 seconds
await page.waitForSelector('[data-testid="install-Website Content QA"]', {
timeout: 100000,
});
await page.getByLabel("checkbox-component").first().click();
await page.getByTestId("install-Website Content QA").click();
await page.waitForSelector("text=My Collection", { timeout: 30000 });
await page.getByText("My Collection").nth(0).click();
await page.waitForSelector("text=Website Content QA", { timeout: 30000 });
await page.getByText("Website Content QA").first().isVisible();
await page.waitForSelector('[data-testid="checkbox-component"]', {
timeout: 100000,
});
await page.getByTestId("checkbox-component").first().click();
await page.getByTestId("icon-Trash2").click();
await page
@ -44,12 +76,12 @@ test("should delete a component", async ({ page }) => {
await page.getByText("Components").first().click();
await page.getByText("Basic RAG").first().isVisible();
await page.getByLabel("checkbox-component").last().waitFor({
state: "visible",
timeout: 30000, // Timeout of 30 seconds
await page.waitForSelector('[data-testid="checkbox-component"]', {
timeout: 100000,
});
await page.getByLabel("checkbox-component").first().click();
await page.getByTestId("checkbox-component").first().click();
await page.getByTestId("icon-Trash2").click();
await page
.getByText("Are you sure you want to delete the selected component?")

View file

@ -22,6 +22,10 @@ test("CRUD folders", async ({ page }) => {
}
await page.getByRole("heading", { name: "Basic Prompting" }).click();
await page.waitForSelector('[data-testid="icon-ChevronLeft"]', {
timeout: 100000,
});
await page.getByTestId("icon-ChevronLeft").first().click();
await page.getByText("My Collection").nth(2).isVisible();
@ -35,9 +39,18 @@ test("CRUD folders", async ({ page }) => {
await page.getByText("New Folder").last().isVisible();
await page.waitForTimeout(1000);
await page.getByText("New Folder").last().dblclick();
await page.getByTestId("input-folder").fill("new folder test name");
await page.keyboard.press("Enter");
await page.getByText("new folder test name").last().isVisible();
const element = await page.getByTestId("input-folder");
await element.fill("new folder test name");
await page.getByText("My Projects").last().click({
force: true,
});
await page.getByText("new folder test name").last().waitFor({
state: "visible",
timeout: 30000,
});
await page
.getByText("new folder test name")

View file

@ -83,8 +83,23 @@ test("erase button should clear the chat messages", async ({ page }) => {
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page.getByText("Playground", { exact: true }).click();
await page.getByPlaceholder("Send a message...").fill("Hello, how are you?");
await page.waitForSelector('[data-testid="input-chat-playground"]', {
timeout: 100000,
});
await page.getByTestId("input-chat-playground").fill("Hello, how are you?");
await page.waitForSelector('[data-testid="icon-LucideSend"]', {
timeout: 100000,
});
await page.getByTestId("icon-LucideSend").click();
let valueUser = await page.getByTestId("sender_name_user").textContent();

View file

@ -38,6 +38,10 @@ test("GlobalVariables", async ({ page }) => {
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();

View file

@ -37,6 +37,10 @@ test("InputComponent", async ({ page }) => {
.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();

View file

@ -38,6 +38,10 @@ test("IntComponent", async ({ page }) => {
.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();
@ -69,6 +73,11 @@ test("IntComponent", async ({ page }) => {
}
await page.getByTestId("title-OpenAI").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();

View file

@ -2,6 +2,7 @@ import { expect, test } from "@playwright/test";
import uaParser from "ua-parser-js";
test("LangflowShortcuts", async ({ page }) => {
await page.goto("/");
const getUA = await page.evaluate(() => navigator.userAgent);
const userAgentInfo = uaParser(getUA);
let control = "Control";
@ -49,6 +50,11 @@ test("LangflowShortcuts", async ({ page }) => {
await page.mouse.down();
await page.locator('//*[@id="react-flow-id"]/div/div[2]/button[3]').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();

View file

@ -44,6 +44,10 @@ test("TextAreaModalComponent", async ({ page }) => {
.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();

View file

@ -61,6 +61,10 @@ test("TextInputOutputComponent", async ({ page }) => {
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();
@ -118,7 +122,13 @@ test("TextInputOutputComponent", async ({ page }) => {
await page.mouse.up();
await page.mouse.down();
await page.getByTitle("fit view").click();
await page.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
await page.getByTitle("zoom out").click();
@ -178,6 +188,11 @@ test("TextInputOutputComponent", async ({ page }) => {
await page
.getByTestId("popover-anchor-input-openai_api_key")
.fill(process.env.OPENAI_API_KEY ?? "");
await page.getByTestId("dropdown-model_name").click();
await page.getByTestId("gpt-4o-0-option").click();
await page.waitForTimeout(2000);
await page.getByText("Playground", { exact: true }).click();
await page.getByText("Run Flow", { exact: true }).click();

View file

@ -43,6 +43,10 @@ test("ToggleComponent", async ({ page }) => {
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();
@ -60,6 +64,10 @@ test("ToggleComponent", async ({ page }) => {
await page.getByText("Save Changes", { exact: true }).click();
await page.waitForSelector('[title="fit view"]', {
timeout: 100000,
});
await page.getByTitle("fit view").click();
await page.getByTestId("toggle-load_hidden").click();
@ -79,6 +87,10 @@ test("ToggleComponent", async ({ page }) => {
await page.getByTestId("div-generic-node").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();

View file

@ -99,6 +99,11 @@ test("check if tweaks are updating when someothing on the flow changes", async (
.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();

View file

@ -17,5 +17,41 @@
"jsx": "react-jsx",
"noImplicitAny": false
},
"include": ["src"]
"include": [
"src",
"tests/end-to-end/saveComponents.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-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",
"tests/end-to-end/dragAndDrop.spec.ts",
"tests/end-to-end/dropdownComponent.spec.ts",
"tests/end-to-end/fileUploadComponent.spec.ts",
"tests/end-to-end/filterEdge.spec.ts",
"tests/end-to-end/floatComponent.spec.ts",
"tests/end-to-end/flowPage.spec.ts",
"tests/end-to-end/flowSettings.spec.ts",
"tests/end-to-end/generalBugs.spec.ts",
"tests/end-to-end/globalVariables.spec.ts",
"tests/end-to-end/group.spec.ts",
"tests/end-to-end/folders.spec.ts",
"tests/end-to-end/inputComponent.spec.ts",
"tests/end-to-end/inputListComponent.spec.ts",
"tests/end-to-end/intComponent.spec.ts",
"tests/end-to-end/keyPairListComponent.spec.ts",
"tests/end-to-end/langflowShortcuts.spec.ts",
"tests/end-to-end/nestedComponent.spec.ts",
"tests/end-to-end/promptModalComponent.spec.ts",
"tests/end-to-end/python_api_generation.spec.ts",
"tests/end-to-end/textAreaModalComponent.spec.ts",
"tests/end-to-end/textInputOutput.spec.ts",
"tests/end-to-end/toggleComponent.spec.ts",
"tests/end-to-end/tweaks_test.spec.ts",
"tests/end-to-end/twoEdges.spec.ts",
"tests/end-to-end/userSettings.spec.ts",
"tests/end-to-end/store.spec.ts"
]
}