langflow/src/frontend/tests/core/integrations/textInputOutput.spec.ts
Cristhian Zanforlin Lousa 9dc6c24180
feat: change Text to Message type with backend and frontend support (#5652)
*  (inputs.py): Update default prompt input types to include "MessageTextInput" for improved user experience
📝 (styleUtils.ts): Add color definition for "MessageTextInput" node to enhance visual representation in the frontend

* 📝 (text.py): Update input_types for "Value" to include "Message" for better clarity
📝 (memory.py): Update input_types for "Session ID" to include "Message" for consistency
📝 (message.py): Update input_types for "Session ID" to include "Message" for uniformity
📝 (self_query.py): Update input_types for "Query" to only include "Message" for consistency
📝 (create_data.py): Update input_types for fields to only include "Message" for consistency
📝 (update_data.py): Update input_types for fields to only include "Message" for consistency
📝 (inputs.py): Update DEFAULT_PROMPT_INTUT_TYPES to only include "Message" for consistency
📝 (styleUtils.ts): Remove "MessageTextInput" from nodeColors and nodeColorsName for consistency

* 📝 (model.py): update display name from "Text" to "Message" for better clarity
📝 (url.py): update display name from "Text" to "Message" for better consistency
📝 (memory.py): update display name from "Text" to "Message" for better understanding
📝 (text.py): update display name from "Text" to "Message" for better semantics
📝 (llm_math.py): update display name from "Text" to "Message" for improved readability
📝 (runnable_executor.py): update display name from "Text" to "Message" for better context
📝 (sql_generator.py): update display name from "Text" to "Message" for clearer communication
📝 (text.py): update display name from "Text" to "Message" for better consistency
📝 (parse_data.py): update display name from "Text" to "Message" for enhanced understanding
📝 (wikidata_api.py): update display name from "Text" to "Message" for improved semantics
📝 (test_cycles.py): update display name from "Text" to "Message" for better clarity

* [autofix.ci] apply automated fixes

* 🔧 (App.css): change width property value to fit-content to improve layout responsiveness

* fix: resolve merge conflicts and clean up URLComponent implementation in starter projects

- Removed conflicting sections in the JSON files for 'Custom Component Maker' and 'Graph Vector Store RAG'.
- Ensured the URLComponent class is correctly defined with methods for URL validation and content fetching.
- Updated input and output definitions for better clarity and functionality.

* 🐛 (freeze.spec.ts): fix incorrect test selectors for handle-textinput-shownode and handle-parsedata-shownode elements to match updated element IDs

* 📝 (NodeOutputfield/index.tsx): Add id prop to InspectButton component for better identification
🔧 (freeze-path.spec.ts, freeze.spec.ts, stop-building.spec.ts, decisionFlow.spec.ts, similarity.spec.ts, textInputOutput.spec.ts, generalBugs-shard-5.spec.ts, fileUploadComponent.spec.ts): Update test selectors to match changes in UI components for better test accuracy

*  (duckduckgo.spec.ts): update the test to click on a specific element with the test ID "output-inspection-data-duckduckgosearch" instead of "output-inspection-data" to match the updated frontend implementation.

*  (youtube-transcripts.spec.ts): update selector for clicking on transcript element to match changes in the frontend code, ensuring the test remains accurate

---------

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-01-20 20:36:46 +00:00

182 lines
6.7 KiB
TypeScript

import { expect, test } from "@playwright/test";
import * as dotenv from "dotenv";
import path from "path";
import { adjustScreenView } from "../../utils/adjust-screen-view";
import { awaitBootstrapTest } from "../../utils/await-bootstrap-test";
test.skip(
"TextInputOutputComponent",
{ tag: ["@release", "@components"] },
async ({ page }) => {
// commented out because new playground does not support text io yet
test.skip(
!process?.env?.OPENAI_API_KEY,
"OPENAI_API_KEY required to run this test",
);
if (!process.env.CI) {
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
}
await awaitBootstrapTest(page);
await page.waitForSelector('[data-testid="blank-flow"]', {
timeout: 30000,
});
await page.getByTestId("blank-flow").click();
await page.getByTestId("sidebar-search-input").click();
await page.getByTestId("sidebar-search-input").fill("text input");
await page.waitForTimeout(1000);
await page
.getByTestId("inputsText Input")
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up();
await page.mouse.down();
await page.getByTestId("sidebar-search-input").click();
await page.getByTestId("sidebar-search-input").fill("openai");
await page.waitForTimeout(1000);
await page
.getByTestId("modelsOpenAI")
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up();
await page.mouse.down();
await adjustScreenView(page);
let visibleElementHandle;
const elementsTextInputOutput = await page
.getByTestId("handle-textinput-shownode-text-right")
.all();
for (const element of elementsTextInputOutput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
await visibleElementHandle.hover();
await page.mouse.down();
for (const element of elementsTextInputOutput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
// Move to the second element
await visibleElementHandle.hover();
// Release the mouse
await page.mouse.up();
await page.getByTestId("sidebar-search-input").click();
await page.getByTestId("sidebar-search-input").fill("text output");
await page
.getByTestId("outputsText Output")
.dragTo(page.locator('//*[@id="react-flow-id"]'));
await page.mouse.up();
await page.mouse.down();
await page.waitForSelector('[data-testid="fit_view"]', {
timeout: 100000,
});
await page.getByTestId("zoom_out").click();
await page.getByTestId("zoom_out").click();
await page.getByTestId("zoom_out").click();
await page.getByTestId("zoom_out").click();
await page.getByTestId("zoom_out").click();
await page.getByTestId("zoom_out").click();
const elementsOpenAiOutput = await page
.getByTestId("handle-openaimodel-shownode-text-right")
.all();
for (const element of elementsOpenAiOutput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
// Click and hold on the first element
await visibleElementHandle.hover();
await page.mouse.down();
const elementTextOutputInput = await page
.getByTestId("handle-textoutput-shownode-text-left")
.all();
for (const element of elementTextOutputInput) {
if (await element.isVisible()) {
visibleElementHandle = element;
break;
}
}
await visibleElementHandle.waitFor({
state: "visible",
timeout: 30000,
});
// Move to the second element
await visibleElementHandle.hover();
// Release the mouse
await page.mouse.up();
await page
.getByTestId(/^rf__node-TextInput-[a-zA-Z0-9]+$/)
.getByTestId("textarea_str_input_value")
.fill("This is a test!");
let outdatedComponents = await page
.getByTestId("icon-AlertTriangle")
.count();
while (outdatedComponents > 0) {
await page.getByTestId("icon-AlertTriangle").first().click();
await page.waitForTimeout(1000);
outdatedComponents = await page.getByTestId("icon-AlertTriangle").count();
}
let filledApiKey = await page.getByTestId("remove-icon-badge").count();
while (filledApiKey > 0) {
await page.getByTestId("remove-icon-badge").first().click();
await page.waitForTimeout(1000);
filledApiKey = await page.getByTestId("remove-icon-badge").count();
}
const apiKeyInput = page.getByTestId("popover-anchor-input-api_key");
const isApiKeyInputVisible = await apiKeyInput.isVisible();
if (isApiKeyInputVisible) {
await apiKeyInput.fill(process.env.OPENAI_API_KEY ?? "");
}
await page.getByTestId("dropdown_str_model_name").click();
await page.getByTestId("gpt-4o-1-option").click();
await page.waitForTimeout(1000);
await page.getByText("Playground", { exact: true }).last().click();
await page.getByTestId("button_run_text_output").click();
await page
.getByTestId(/^rf__node-TextOutput-[a-zA-Z0-9]+$/)
.getByTestId("output-inspection-message-chatoutput")
.click();
await page.getByText("Run Flow", { exact: true }).click();
await page.waitForTimeout(5000);
let textInputContent = await page
.getByPlaceholder("Enter text...")
.textContent();
expect(textInputContent).toBe("This is a test!");
await page.getByText("Outputs", { exact: true }).nth(1).click();
await page.getByText("Text Output", { exact: true }).nth(2).click();
let contentOutput = await page
.getByPlaceholder("Enter text...")
.inputValue();
expect(contentOutput).not.toBe(null);
await page.keyboard.press("Escape");
await page
.getByTestId(/^rf__node-TextInput-[a-zA-Z0-9]+$/)
.getByTestId("textarea_str_input_value")
.fill("This is a test, again just to be sure!");
await page.getByText("Playground", { exact: true }).last().click();
await page.getByText("Run Flow", { exact: true }).click();
await page.waitForTimeout(5000);
textInputContent = await page
.getByPlaceholder("Enter text...")
.textContent();
expect(textInputContent).toBe("This is a test, again just to be sure!");
await page.getByText("Outputs", { exact: true }).nth(1).click();
await page.getByText("Text Output", { exact: true }).nth(2).click();
contentOutput = await page.getByPlaceholder("Enter text...").inputValue();
expect(contentOutput).not.toBe(null);
},
);