From 66110f24e22c6c261ce60bdd25e792e952ed11de Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa <72977554+Cristhianzl@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:17:03 -0300 Subject: [PATCH] tests: Add Tests for New Auto-Saving Feature (#3428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ (index.tsx): Add data-testid attribute to the save button for testing purposes ✨ (auto-save-off.spec.ts): Add end-to-end test for manually saving a flow when auto_save is off * ⬆️ (auto-save-off.spec.ts): decrease wait time from 5000ms to 3000ms for improved test efficiency * moving auto-save-off test to scheduled folder --- .../components/menuBar/index.tsx | 1 + .../auto-save-off.spec.ts | 156 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 src/frontend/tests/scheduled-end-to-end/auto-save-off.spec.ts diff --git a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx index d59ee1937..6966832db 100644 --- a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx +++ b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx @@ -259,6 +259,7 @@ export const MenuBar = ({}: {}): JSX.Element => { disabled={autoSaving || !changesNotSaved || isBuilding} className={cn("mr-1 h-9 px-2")} onClick={handleSave} + data-testid="save-flow-button" > diff --git a/src/frontend/tests/scheduled-end-to-end/auto-save-off.spec.ts b/src/frontend/tests/scheduled-end-to-end/auto-save-off.spec.ts new file mode 100644 index 000000000..82979bf03 --- /dev/null +++ b/src/frontend/tests/scheduled-end-to-end/auto-save-off.spec.ts @@ -0,0 +1,156 @@ +import { expect, test } from "@playwright/test"; + +test("user should be able to manually save a flow when the auto_save is off", async ({ + page, +}) => { + // Intercept the request to any base URL ending with /api/v1/config + await page.route("**/api/v1/config", async (route) => { + const response = await route.fetch(); + const responseBody = await response.json(); + responseBody.auto_saving = false; + route.fulfill({ + response, + body: JSON.stringify(responseBody), + headers: { + ...response.headers(), + "content-type": "application/json", + }, + }); + }); + + await page.goto("/"); + await page.locator("span").filter({ hasText: "My Collection" }).isVisible(); + 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(3000); + 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.getByPlaceholder("Search").click(); + await page.getByPlaceholder("Search").fill("NVIDIA"); + + await page.waitForTimeout(1000); + + await page + .getByTestId("modelsNVIDIA") + .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(); + + expect(await page.getByText("Last saved:").isVisible()).toBeTruthy(); + + expect(await page.getByTestId("save-flow-button").isEnabled()).toBeTruthy(); + + await page.waitForSelector("text=loading", { + state: "hidden", + timeout: 100000, + }); + + await page.getByTestId("icon-ChevronLeft").last().click(); + + expect( + await page + .getByText("Unsaved changes will be permanently lost.") + .isVisible(), + ).toBeTruthy(); + + await page.getByText("Exit Anyway", { exact: true }).click(); + + await page.getByText("Untitled document").first().click(); + + await page.waitForSelector('[data-testid="icon-ChevronLeft"]', { + timeout: 100000, + }); + + expect(await page.getByText("NVIDIA").isVisible()).toBeFalsy(); + + await page.getByPlaceholder("Search").click(); + await page.getByPlaceholder("Search").fill("NVIDIA"); + + await page.waitForTimeout(1000); + + await page + .getByTestId("modelsNVIDIA") + .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.getByTestId("icon-ChevronLeft").last().click(); + + await page.getByText("Save And Exit", { exact: true }).click(); + + await page.getByText("Untitled document").first().click(); + + await page.waitForSelector("text=loading", { + state: "hidden", + timeout: 100000, + }); + + await page.waitForTimeout(5000); + + expect(await page.getByTestId("title-NVIDIA").isVisible()).toBeTruthy(); + + await page.getByPlaceholder("Search").click(); + await page.getByPlaceholder("Search").fill("NVIDIA"); + + await page.waitForTimeout(1000); + + await page + .getByTestId("modelsNVIDIA") + .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.getByTestId("save-flow-button").click(); + await page.getByTestId("icon-ChevronLeft").last().click(); + + await page.getByText("Untitled document").first().click(); + + await page.waitForSelector('[data-testid="icon-ChevronLeft"]', { + timeout: 100000, + }); + + await page.waitForTimeout(5000); + + const nvidiaNumber = await page.getByTestId("title-NVIDIA").count(); + expect(nvidiaNumber).toBe(2); +});