bugfix: add returning promises on interceptor errors + tests (#2896)
* 🐛 (generalBugs-shard-5.spec.ts): fix test to wait for elements to be interactable before performing actions to prevent flakiness * 📝 (API/api.tsx): return error in promise rejection to handle errors properly 📝 (codeAreaModal/index.tsx): add data-testid attribute to title element for testing purposes ✨ (generalBugs-shard-6.spec.ts): add end-to-end test for error handling in Code Modal * 📝 (generalBugs-shard-6.spec.ts): update test description for better clarity and grammar
This commit is contained in:
parent
7ffcdd2b68
commit
c83006e066
4 changed files with 95 additions and 2 deletions
1
src/frontend/package-lock.json
generated
1
src/frontend/package-lock.json
generated
|
|
@ -789,7 +789,6 @@
|
||||||
},
|
},
|
||||||
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
|
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"extraneous": true,
|
|
||||||
"inBundle": true,
|
"inBundle": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ function ApiInterceptor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await clearBuildVerticesState(error);
|
await clearBuildVerticesState(error);
|
||||||
|
return Promise.reject(error);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,12 @@ export default function CodeAreaModal({
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="mt-5 h-full max-h-[10rem] w-full overflow-y-auto overflow-x-clip text-left custom-scroll">
|
<div className="mt-5 h-full max-h-[10rem] w-full overflow-y-auto overflow-x-clip text-left custom-scroll">
|
||||||
<h1 className="text-lg text-error">{error?.detail?.error}</h1>
|
<h1
|
||||||
|
data-testid="title_error_code_modal"
|
||||||
|
className="text-lg text-error"
|
||||||
|
>
|
||||||
|
{error?.detail?.error}
|
||||||
|
</h1>
|
||||||
<div className="ml-2 mt-2 w-full text-sm text-destructive word-break-break-word">
|
<div className="ml-2 mt-2 w-full text-sm text-destructive word-break-break-word">
|
||||||
<span className="w-full word-break-break-word">
|
<span className="w-full word-break-break-word">
|
||||||
{error?.detail?.traceback}
|
{error?.detail?.traceback}
|
||||||
|
|
|
||||||
88
src/frontend/tests/end-to-end/generalBugs-shard-6.spec.ts
Normal file
88
src/frontend/tests/end-to-end/generalBugs-shard-6.spec.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
import { expect, test } from "@playwright/test";
|
||||||
|
|
||||||
|
test("should be able to see error when something goes wrong on Code Modal", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await page.goto("/");
|
||||||
|
|
||||||
|
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.waitForSelector('[data-testid="blank-flow"]', {
|
||||||
|
timeout: 30000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.getByTestId("blank-flow").click();
|
||||||
|
await page.waitForSelector('[data-testid="extended-disclosure"]', {
|
||||||
|
timeout: 30000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.getByTestId("extended-disclosure").click();
|
||||||
|
await page.getByPlaceholder("Search").click();
|
||||||
|
await page.getByPlaceholder("Search").fill("custom component");
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
await page
|
||||||
|
.getByTestId("helpersCustom Component")
|
||||||
|
.dragTo(page.locator('//*[@id="react-flow-id"]'));
|
||||||
|
|
||||||
|
await page.getByTitle("zoom out").click();
|
||||||
|
await page.getByTitle("zoom out").click();
|
||||||
|
|
||||||
|
await page.getByTestId("div-generic-node").click();
|
||||||
|
await page.getByTestId("code-button-modal").click();
|
||||||
|
|
||||||
|
const customCodeWithError = `
|
||||||
|
# from langflow.field_typing import Data
|
||||||
|
from langflow.custom import Component
|
||||||
|
from langflow.io import MessageTextInput, Output
|
||||||
|
from langflow.schema import Data
|
||||||
|
import pytorch
|
||||||
|
|
||||||
|
class CustomComponent(Component):
|
||||||
|
display_name = "Custom Component"
|
||||||
|
description = "Use as a template to create your own component."
|
||||||
|
documentation: str = "http://docs.langflow.org/components/custom"
|
||||||
|
icon = "custom_components"
|
||||||
|
name = "CustomComponent"
|
||||||
|
|
||||||
|
inputs = [
|
||||||
|
MessageTextInput(name="input_value", display_name="Input Value", value="Hello, World!"),
|
||||||
|
]
|
||||||
|
|
||||||
|
outputs = [
|
||||||
|
Output(display_name="Output", name="output", method="build_output"),
|
||||||
|
]
|
||||||
|
|
||||||
|
def build_output(self) -> Data:
|
||||||
|
data = Data(value=self.input_value)
|
||||||
|
self.status = data
|
||||||
|
return data
|
||||||
|
`;
|
||||||
|
|
||||||
|
await page.locator("textarea").press("Control+a");
|
||||||
|
await page.locator("textarea").fill(customCodeWithError);
|
||||||
|
|
||||||
|
await page.getByText("Save").click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(1000);
|
||||||
|
|
||||||
|
const error = await page.getByTestId("title_error_code_modal").textContent();
|
||||||
|
|
||||||
|
expect(error!.length).toBeGreaterThan(50);
|
||||||
|
expect(error?.toLowerCase()).toContain("custom component");
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue