From 86d6fea8f487168a821d93a682383ddbdeab4797 Mon Sep 17 00:00:00 2001 From: Anchel135 Date: Mon, 20 Jan 2025 12:11:34 +0200 Subject: [PATCH 01/26] commit --- app/components/ForceGraph.tsx | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/app/components/ForceGraph.tsx b/app/components/ForceGraph.tsx index 10144fe..e6a16b8 100644 --- a/app/components/ForceGraph.tsx +++ b/app/components/ForceGraph.tsx @@ -50,34 +50,26 @@ export default function ForceGraph({ const parentRef = useRef(null) const toast = useToast() - useEffect(() => { - if (!chartRef.current || data.nodes.length === 0 || data.links.length === 0) return - chartRef.current.d3Force('link').id((link: any) => link.id).distance(50) - chartRef.current.d3Force('charge').strength(-300) - chartRef.current.d3Force('center').strength(0.05) - }, [chartRef, data.links.length, data.nodes.length]) - - useEffect(() => { + useEffect(() => { const handleResize = () => { if (!parentRef.current) return setParentWidth(parentRef.current.clientWidth) setParentHeight(parentRef.current.clientHeight) } - handleResize() + window.addEventListener('resize', handleResize) + + const observer = new ResizeObserver(handleResize) - const resizeObserver = new ResizeObserver(handleResize) if (parentRef.current) { - resizeObserver.observe(parentRef.current) + observer.observe(parentRef.current) } - window.addEventListener('resize', handleResize) - return () => { - resizeObserver.disconnect() window.removeEventListener('resize', handleResize) + observer.disconnect() } - }, []) + }, [parentRef]) const onFetchNode = async (node: Node) => { const result = await securedFetch(`/api/graph/${graph.Id}/${node.id}`, { From c019e8256159a8d372445a73516981c1b8672149 Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Tue, 21 Jan 2025 16:21:19 +0200 Subject: [PATCH 02/26] upgrade to node22 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index db11d29..dfd3740 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine AS base +FROM node:22-alpine AS base # Install dependencies only when needed FROM base AS deps @@ -68,4 +68,4 @@ ENV HOSTNAME "0.0.0.0" # server.js is created by next build from the standalone output # https://nextjs.org/docs/pages/api-reference/next-config-js/output -CMD ["node", "server.js"] \ No newline at end of file +CMD ["node", "server.js"] From 97206a44022a38b576f5a5edf3f45da0f0b70250 Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Tue, 21 Jan 2025 16:23:28 +0200 Subject: [PATCH 03/26] upgrade to node22 --- .github/workflows/nextjs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml index e86401d..0bffc7d 100644 --- a/.github/workflows/nextjs.yml +++ b/.github/workflows/nextjs.yml @@ -36,7 +36,7 @@ jobs: - name: Setup Node uses: actions/setup-node@v3 with: - node-version: "18" + node-version: "22" cache: ${{ steps.detect-package-manager.outputs.manager }} - name: Restore cache From ecf24d7c431e4d335a0efd1a7296b40ce2a41617 Mon Sep 17 00:00:00 2001 From: Anchel135 Date: Wed, 22 Jan 2025 10:17:31 +0200 Subject: [PATCH 04/26] commit --- app/components/ForceGraph.tsx | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/components/ForceGraph.tsx b/app/components/ForceGraph.tsx index 10144fe..2cd19bd 100644 --- a/app/components/ForceGraph.tsx +++ b/app/components/ForceGraph.tsx @@ -48,6 +48,7 @@ export default function ForceGraph({ const [parentHeight, setParentHeight] = useState(0) const [hoverElement, setHoverElement] = useState() const parentRef = useRef(null) + const lastClick = useRef<{ date: Date, name: string }>({ date: new Date(), name: "" }) const toast = useToast() useEffect(() => { @@ -119,19 +120,29 @@ export default function ForceGraph({ graph.removeLinks() } - const handleNodeRightClick = async (node: Node) => { + const handleNodeClick = async (node: Node) => { + + const now = new Date() + const { date, name } = lastClick.current + + if (now.getTime() - date.getTime() < 1000 && name === (node.data.name || node.id.toString())) { + return + } + if (!node.expand) { await onFetchNode(node) } else { deleteNeighbors([node]) } + + lastClick.current = { date: new Date(), name: node.data.name || node.id.toString() } } const handleHover = (element: Node | Link | null) => { setHoverElement(element === null ? undefined : element) } - const handleClick = (element: Node | Link, evt: MouseEvent) => { + const handleRightClick = (element: Node | Link, evt: MouseEvent) => { if (!("source" in element) && isAddElement) { if (setSelectedNodes) { setSelectedNodes(prev => { @@ -263,11 +274,11 @@ export default function ForceGraph({ ctx.fillText(link.label, 0, 0); ctx.restore() }} - onNodeClick={handleClick} - onLinkClick={handleClick} + onNodeClick={handleNodeClick} onNodeHover={handleHover} onLinkHover={handleHover} - onNodeRightClick={handleNodeRightClick} + onNodeRightClick={handleRightClick} + onLinkRightClick={handleRightClick} onBackgroundClick={handleUnselected} onBackgroundRightClick={handleUnselected} onEngineStop={() => { From a63aef2988cb2ef24457eab75be559451e7a9117 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:25:19 +0200 Subject: [PATCH 05/26] Update auth.setup.ts --- e2e/tests/auth.setup.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/e2e/tests/auth.setup.ts b/e2e/tests/auth.setup.ts index 97c8549..f516bc5 100644 --- a/e2e/tests/auth.setup.ts +++ b/e2e/tests/auth.setup.ts @@ -13,6 +13,7 @@ setup("admin authentication", async () => { try { const browserWrapper = new BrowserWrapper(); const loginPage = await browserWrapper.createNewPage(LoginPage, urls.loginUrl); + await browserWrapper.setPageToFullScreen(); await loginPage.clickOnConnect(); await loginPage.dismissDialogAtStart(); const context = browserWrapper.getContext(); @@ -37,6 +38,7 @@ userRoles.forEach(({ name, file, userName }) => { try { const browserWrapper = new BrowserWrapper(); const loginPage = await browserWrapper.createNewPage(LoginPage, urls.loginUrl); + await browserWrapper.setPageToFullScreen(); await loginPage.connectWithCredentials(userName, user.password); await loginPage.dismissDialogAtStart(); const context = browserWrapper.getContext(); From ac6baf6918bf7307a4e846bc452c21dbae2ae71d Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:51:13 +0200 Subject: [PATCH 06/26] update config settings tests --- e2e/config/settingsConfigData.json | 2 +- e2e/tests/settingsConfig.spec.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/e2e/config/settingsConfigData.json b/e2e/config/settingsConfigData.json index ae70e25..3616177 100644 --- a/e2e/config/settingsConfigData.json +++ b/e2e/config/settingsConfigData.json @@ -35,7 +35,7 @@ {"role": "QUERY_MEM_CAPACITY", "description": "modify queryMemCapacity", "input": "20", "expected": true}, {"role": "VKEY_MAX_ENTITY_COUNT", "description": "modify vKeyMaxEntityCount", "input": "20", "expected": true}, {"role": "CMD_INFO", "description": "modify cmdInfo", "input": "yes", "expected": true}, - {"role": "MAX_INFO_QUERIES", "description": "modify maxInfoQueries", "input": "20", "expected": true} + {"role": "MAX_INFO_QUERIES", "description": "modify maxInfoQueries", "input": "999", "expected": true} ] } \ No newline at end of file diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 9b36bb4..30417fd 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -25,6 +25,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.maxQueuedQueries, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.maxQueuedQueries) + await apiCall.modifySettingsRole(roles.maxTimeOut, "25") expect(value === input).toBe(expected) }); }) @@ -36,6 +37,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.maxTimeOut, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.maxTimeOut) + await apiCall.modifySettingsRole(roles.maxTimeOut, "0") expect(value === input).toBe(expected) }); }) @@ -47,6 +49,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.defaultTimeOut, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.defaultTimeOut) + await apiCall.modifySettingsRole(roles.maxTimeOut, "0") expect(value === input).toBe(expected) }); }) @@ -58,6 +61,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.resultSetSize, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.resultSetSize) + await apiCall.modifySettingsRole(roles.maxTimeOut, "1000") expect(value === input).toBe(expected) }); }) @@ -81,6 +85,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.vKeyMaxEntityCount) + await apiCall.modifySettingsRole(roles.queryMemCapacity, "100000") expect(value === input).toBe(expected) }); }) @@ -92,6 +97,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.cmdInfo, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.cmdInfo) + await apiCall.modifySettingsRole(roles.queryMemCapacity, "yes") expect(value === input).toBe(expected) }); }) @@ -103,6 +109,7 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.maxInfoQueries, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.maxInfoQueries) + await apiCall.modifySettingsRole(roles.queryMemCapacity, "1000") expect(value === input).toBe(expected) }); }) From 9bd266a6e83746dc19e303109d207ea34fbc1f72 Mon Sep 17 00:00:00 2001 From: Anchel135 Date: Thu, 23 Jan 2025 14:36:01 +0200 Subject: [PATCH 07/26] change bg and display logo, version and copy rights --- app/components/Header.tsx | 2 +- app/globals.css | 6 +----- app/layout.tsx | 2 +- app/page.tsx | 14 +++++++++++--- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/components/Header.tsx b/app/components/Header.tsx index 66c0591..3dec72a 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -97,7 +97,7 @@ export default function Header({ onSetGraphName }: Props) { -
+
) } diff --git a/app/globals.css b/app/globals.css index 830ec07..28ca906 100644 --- a/app/globals.css +++ b/app/globals.css @@ -60,11 +60,7 @@ @apply h-full w-full flex flex-col bg-background; } - .LandingPage { - background: linear-gradient(180deg, #EC806C 0%, #B66EBD 43.41%, #7568F2 100%); - } - - .Top { + .Gradient { background: linear-gradient(90deg, #EC806C 0%, #B66EBD 43.41%, #7568F2 100%); } diff --git a/app/layout.tsx b/app/layout.tsx index 141d0f5..185eaa8 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -24,7 +24,7 @@ export default function RootLayout({ // caused by mismatched client/server content caused by next-themes return ( - + {children} diff --git a/app/page.tsx b/app/page.tsx index 2fd5e7c..4c6b09f 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,13 +1,21 @@ "use client"; import Spinning from "@/app/components/ui/spinning"; +import Image from "next/image"; +import pkg from '@/package.json'; export default function Home() { return ( -
-
- +
+
+ FalkorDB Logo +
+
+

Version: {`{${pkg.version}}`}

+

All Rights Reserved © 2024 - {new Date().getFullYear()} falkordb.com

+
+
) } From e509ef446d5847ac280fa924fbe80e4dc851ff4f Mon Sep 17 00:00:00 2001 From: Anchel135 Date: Thu, 23 Jan 2025 14:39:18 +0200 Subject: [PATCH 08/26] adjust the bg better and fix interaction with the dropzone --- app/components/ui/Dropzone.tsx | 2 +- app/login/LoginForm.tsx | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/components/ui/Dropzone.tsx b/app/components/ui/Dropzone.tsx index 9342631..1ab97cb 100644 --- a/app/components/ui/Dropzone.tsx +++ b/app/components/ui/Dropzone.tsx @@ -56,7 +56,7 @@ function Dropzone({ filesCount = false, className = "", withTable = false, disab Or Browse
- :

Upload Certificate

+ :

Upload Certificate

}
{ diff --git a/app/login/LoginForm.tsx b/app/login/LoginForm.tsx index be315cb..3c8458b 100644 --- a/app/login/LoginForm.tsx +++ b/app/login/LoginForm.tsx @@ -118,12 +118,10 @@ export default function LoginForm() { } return ( -
+
-
- Loading... -
+ Loading...
-
+
); } From 7d70e910f1f669f523f006c4dec094d631f97e30 Mon Sep 17 00:00:00 2001 From: Anchel135 Date: Thu, 23 Jan 2025 15:11:24 +0200 Subject: [PATCH 09/26] Enhance Header component with new help features - Added a Sheet component for displaying additional information about the application. --- app/components/Header.tsx | 118 ++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 44 deletions(-) diff --git a/app/components/Header.tsx b/app/components/Header.tsx index 66c0591..ed08c08 100644 --- a/app/components/Header.tsx +++ b/app/components/Header.tsx @@ -9,6 +9,9 @@ import { cn } from "@/lib/utils"; import { useRouter, usePathname } from "next/navigation"; import { signOut, useSession } from "next-auth/react"; import { NavigationMenu, NavigationMenuContent, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger } from "@/components/ui/navigation-menu"; +import { Sheet, SheetContent, SheetDescription, SheetTitle, SheetTrigger } from "@/components/ui/sheet"; +import pkg from '@/package.json'; +import { VisuallyHidden } from "@radix-ui/react-visually-hidden"; import Button from "./ui/Button"; import CreateGraph from "./CreateGraph"; @@ -22,7 +25,7 @@ export default function Header({ onSetGraphName }: Props) { const type = pathname.includes("/schema") ? "Schema" : "Graph" const inCreate = pathname.includes("/create") const { data: session } = useSession() - + return (
@@ -49,52 +52,79 @@ export default function Header({ onSetGraphName }: Props) {
- - - + + + + + + + + + +

Help

+
+ + + +
+ { + !inCreate && + + } -
- - - -

Help

-
- - - -
- { - !inCreate && - - } - -
-
+ + + + + +
+ Loading... +

We Make AI Reliable

+

+ Delivering a scalable, + low-latency graph database designed for development teams managing + structured and unstructured interconnected data in real-time or interactive environments. +

+
+
+

Version: {`{${pkg.version}}`}

+

All Rights Reserved © 2024 - {new Date().getFullYear()} falkordb.com

+
+
+
From 72b96e9dac11f3aa2011296743d40e947209a3e1 Mon Sep 17 00:00:00 2001 From: Anchel135 Date: Thu, 23 Jan 2025 16:11:43 +0200 Subject: [PATCH 10/26] remove blur on input to be able to click on submit --- app/graph/GraphDataPanel.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/app/graph/GraphDataPanel.tsx b/app/graph/GraphDataPanel.tsx index abe0c40..30f106f 100644 --- a/app/graph/GraphDataPanel.tsx +++ b/app/graph/GraphDataPanel.tsx @@ -294,7 +294,6 @@ export default function GraphDataPanel({ obj, setObj, onExpand, onDeleteElement, value={newVal} onChange={(e) => setNewVal(e.target.value)} onKeyDown={handleSetKeyDown} - onBlur={() => handleSetEditable("", "")} /> :
) diff --git a/lib/utils.ts b/lib/utils.ts index 059aa9d..a5256ea 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -41,4 +41,19 @@ export function prepareArg(arg: string) { return encodeURIComponent(arg.trim()) } -export const defaultQuery = (q?: string) => q || "MATCH (n) OPTIONAL MATCH (n)-[e]-(m) return n,e,m LIMIT 100" \ No newline at end of file +export const defaultQuery = (q?: string) => q || "MATCH (n) OPTIONAL MATCH (n)-[e]-(m) return n,e,m LIMIT 100" + +export const lightenColor = (hex: string): string => { + // Remove the # if present + const color = hex.replace('#', ''); + // Convert to RGB + const r = parseInt(color.slice(0, 2), 16); + const g = parseInt(color.slice(2, 4), 16); + const b = parseInt(color.slice(4, 6), 16); + // Mix with white (add 20% of the remaining distance to white) + const lightR = Math.min(255, r + Math.floor((255 - r) * 0.2)); + const lightG = Math.min(255, g + Math.floor((255 - g) * 0.2)); + const lightB = Math.min(255, b + Math.floor((255 - b) * 0.2)); + // Convert back to hex + return `#${lightR.toString(16).padStart(2, '0')}${lightG.toString(16).padStart(2, '0')}${lightB.toString(16).padStart(2, '0')}`; +} \ No newline at end of file From a70a6cd2d29978a92875b4945bf518852317bf50 Mon Sep 17 00:00:00 2001 From: Anchel135 Date: Sun, 26 Jan 2025 12:02:40 +0200 Subject: [PATCH 13/26] commit --- app/graph/labels.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/graph/labels.tsx b/app/graph/labels.tsx index 0a11645..e2d245b 100644 --- a/app/graph/labels.tsx +++ b/app/graph/labels.tsx @@ -1,5 +1,5 @@ import { useRef, useState } from "react"; -import { cn } from "@/lib/utils"; +import { cn, lightenColor } from "@/lib/utils"; import { ChevronDown, ChevronUp } from "lucide-react"; import { Category, Graph } from "../api/graph/model"; import Button from "../components/ui/Button"; @@ -57,7 +57,7 @@ export default function Labels({ graph, categories, onClick, label, className = setReload(prev => !prev) }} > -
+
)) From 5a75ad85b39e0b3b1be5f11c1efad9ad3f5d05c8 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 12:27:27 +0200 Subject: [PATCH 14/26] update config tests --- e2e/config/settingsConfigData.json | 14 ++--- e2e/tests/settingsConfig.spec.ts | 87 +++++++++++++++++++----------- 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/e2e/config/settingsConfigData.json b/e2e/config/settingsConfigData.json index 3616177..69d7c96 100644 --- a/e2e/config/settingsConfigData.json +++ b/e2e/config/settingsConfigData.json @@ -28,13 +28,13 @@ { "input": "yes", "description": "valid input - yes value", "expected": true } ], "roleModificationData": [ - {"role": "MAX_QUEUED_QUERIES", "description": "modify maxQueuedQueries", "input": "20", "expected": true}, - {"role": "TIMEOUT_MAX", "description": "modify maxTimeOut", "input": "25", "expected": true}, - {"role": "TIMEOUT_DEFAULT", "description": "modify defaultTimeOut", "input": "10", "expected": true}, - {"role": "RESULTSET_SIZE", "description": "modify resultSetSize", "input": "20", "expected": true}, - {"role": "QUERY_MEM_CAPACITY", "description": "modify queryMemCapacity", "input": "20", "expected": true}, - {"role": "VKEY_MAX_ENTITY_COUNT", "description": "modify vKeyMaxEntityCount", "input": "20", "expected": true}, - {"role": "CMD_INFO", "description": "modify cmdInfo", "input": "yes", "expected": true}, + {"role": "MAX_QUEUED_QUERIES", "description": "modify maxQueuedQueries", "input": "24", "expected": true}, + {"role": "TIMEOUT_MAX", "description": "modify maxTimeOut", "input": "1", "expected": true}, + {"role": "TIMEOUT_DEFAULT", "description": "modify defaultTimeOut", "input": "1", "expected": true}, + {"role": "RESULTSET_SIZE", "description": "modify resultSetSize", "input": "10001", "expected": true}, + {"role": "QUERY_MEM_CAPACITY", "description": "modify queryMemCapacity", "input": "1", "expected": true}, + {"role": "VKEY_MAX_ENTITY_COUNT", "description": "modify vKeyMaxEntityCount", "input": "100001", "expected": true}, + {"role": "CMD_INFO", "description": "modify cmdInfo", "input": "no", "expected": true}, {"role": "MAX_INFO_QUERIES", "description": "modify maxInfoQueries", "input": "999", "expected": true} ] } diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 30417fd..a8d1551 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -17,7 +17,7 @@ test.describe('Settings Tests', () => { await browser.closeBrowser(); }) - Data.inputDataRejectsZero.forEach(({ input, description, expected }) => { + Data.inputDataRejectsZero.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.maxQueuedQueries} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() @@ -25,109 +25,134 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.maxQueuedQueries, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.maxQueuedQueries) - await apiCall.modifySettingsRole(roles.maxTimeOut, "25") - expect(value === input).toBe(expected) + expect(value === input).toBe(expected); + if (index === Data.inputDataRejectsZero.length - 1) { + await apiCall.modifySettingsRole(roles.maxQueuedQueries, "25") + } }); }) - Data.maxTimeOut.forEach(({ input, description, expected }) => { + Data.maxTimeOut.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.maxTimeOut} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.maxTimeOut, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.maxTimeOut) - await apiCall.modifySettingsRole(roles.maxTimeOut, "0") - expect(value === input).toBe(expected) + expect(value === input).toBe(expected); + if (index === Data.maxTimeOut.length - 1) { + await apiCall.modifySettingsRole(roles.maxTimeOut, "0") + } }); }) - Data.inputDataAcceptsZero.forEach(({ input, description, expected }) => { + Data.inputDataAcceptsZero.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.defaultTimeOut} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.defaultTimeOut, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.defaultTimeOut) - await apiCall.modifySettingsRole(roles.maxTimeOut, "0") - expect(value === input).toBe(expected) + expect(value === input).toBe(expected); + if (index === Data.inputDataAcceptsZero.length - 1) { + await apiCall.modifySettingsRole(roles.defaultTimeOut, "0") + } }); }) - Data.inputDataAcceptsZero.forEach(({ input, description, expected }) => { + Data.inputDataAcceptsZero.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.resultSetSize} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.resultSetSize, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.resultSetSize) - await apiCall.modifySettingsRole(roles.maxTimeOut, "1000") - expect(value === input).toBe(expected) + expect(value === input).toBe(expected); + if (index === Data.inputDataAcceptsZero.length - 1) { + await apiCall.modifySettingsRole(roles.resultSetSize, "10000") + } }); }) - Data.inputDataAcceptsZero.forEach(({ input, description, expected }) => { + Data.inputDataAcceptsZero.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.queryMemCapacity} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.queryMemCapacity, input) await settingsConfigPage.refreshPage() - const value = await settingsConfigPage.getRoleContentValue(roles.queryMemCapacity) - await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") // update to default values - expect(value === input).toBe(expected) + const value = await settingsConfigPage.getRoleContentValue(roles.queryMemCapacity) + expect(value === input).toBe(expected); + if (index === Data.inputDataAcceptsZero.length - 1) { + await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") + } }); }) - Data.inputDataAcceptsZero.forEach(({ input, description, expected }) => { + Data.inputDataAcceptsZero.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.vKeyMaxEntityCount} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.vKeyMaxEntityCount) - await apiCall.modifySettingsRole(roles.queryMemCapacity, "100000") expect(value === input).toBe(expected) + if (index === Data.inputDataAcceptsZero.length - 1) { + await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, "100000") + } }); }) - Data.CMDData.forEach(({ input, description, expected }) => { + Data.CMDData.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.cmdInfo} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.cmdInfo, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.cmdInfo) - await apiCall.modifySettingsRole(roles.queryMemCapacity, "yes") expect(value === input).toBe(expected) + if (index === Data.CMDData.length - 1) { + await apiCall.modifySettingsRole(roles.cmdInfo, "yes") + } }); }) - Data.inputDataAcceptsZero.forEach(({ input, description, expected }) => { + Data.inputDataAcceptsZero.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.maxInfoQueries} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await apiCall.modifySettingsRole(roles.maxInfoQueries, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.maxInfoQueries) - await apiCall.modifySettingsRole(roles.queryMemCapacity, "1000") - expect(value === input).toBe(expected) + expect(value === input).toBe(expected); + if (index === Data.inputDataAcceptsZero.length - 1) { + await apiCall.modifySettingsRole(roles.queryMemCapacity, "1000"); + } }); }) - Data.roleModificationData.forEach(({ role, input, description, expected }) => { + Data.roleModificationData.forEach(({ role, input, description, expected }, index) => { test(`@admin Modify ${role} via UI validation via API: Input value: ${input} description: ${description}`, async () => { + const apiCall = new ApiCalls() + console.log("before: ",String((await apiCall.getSettingsRoleValue(role)).config[1])); const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) await settingsConfigPage.modifyRoleValue(role, input) - const apiCall = new ApiCalls() let value = String((await apiCall.getSettingsRoleValue(role)).config[1]); + console.log("after: ",value); // Convert numeric values to yes/no for boolean settings - if (value === '1') { - value = 'yes'; - } else if (value === '0') { - value = 'no'; + value = value === '1' ? 'yes' : value === '0' ? 'no' : value; + expect(value === input).toBe(expected); + if (index === Data.roleModificationData.length - 1) { + await apiCall.modifySettingsRole(roles.maxQueuedQueries, "25") + await apiCall.modifySettingsRole(roles.maxTimeOut, "0") + await apiCall.modifySettingsRole(roles.defaultTimeOut, "0") + await apiCall.modifySettingsRole(roles.resultSetSize, "10000") + await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") + await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, "100000") + await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") + await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, "100000") + await apiCall.modifySettingsRole(roles.cmdInfo, "yes") + await apiCall.modifySettingsRole(roles.queryMemCapacity, "1000") } - await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") // update to default values - expect(value === input).toBe(expected) }); }) From e734415fec018d94683b4cd6735dfec13b6b6f84 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 12:50:46 +0200 Subject: [PATCH 15/26] update tests --- e2e/config/settingsConfigData.json | 1 + e2e/tests/settingsConfig.spec.ts | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/e2e/config/settingsConfigData.json b/e2e/config/settingsConfigData.json index 69d7c96..069a86a 100644 --- a/e2e/config/settingsConfigData.json +++ b/e2e/config/settingsConfigData.json @@ -29,6 +29,7 @@ ], "roleModificationData": [ {"role": "MAX_QUEUED_QUERIES", "description": "modify maxQueuedQueries", "input": "24", "expected": true}, + {"role": "TIMEOUT", "description": "modify timeOut", "input": "1001", "expected": true}, {"role": "TIMEOUT_MAX", "description": "modify maxTimeOut", "input": "1", "expected": true}, {"role": "TIMEOUT_DEFAULT", "description": "modify defaultTimeOut", "input": "1", "expected": true}, {"role": "RESULTSET_SIZE", "description": "modify resultSetSize", "input": "10001", "expected": true}, diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index a8d1551..c8bf952 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -32,6 +32,21 @@ test.describe('Settings Tests', () => { }); }) + Data.inputDataAcceptsZero.forEach(({ input, description, expected }, index) => { + test(`@admin Modify ${roles.maxQueuedQueries} via API validation via UI: Input value: ${input} description: ${description}`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + const apiCall = new ApiCalls() + await new Promise(resolve => { setTimeout(resolve, 1000) }); + await apiCall.modifySettingsRole(roles.TimeOut, input) + await settingsConfigPage.refreshPage() + const value = await settingsConfigPage.getRoleContentValue(roles.TimeOut) + expect(value === input).toBe(expected); + if (index === Data.inputDataAcceptsZero.length - 1) { + await apiCall.modifySettingsRole(roles.TimeOut, "1000") + } + }); + }) + Data.maxTimeOut.forEach(({ input, description, expected }, index) => { test(`@admin Modify ${roles.maxTimeOut} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) @@ -143,13 +158,12 @@ test.describe('Settings Tests', () => { expect(value === input).toBe(expected); if (index === Data.roleModificationData.length - 1) { await apiCall.modifySettingsRole(roles.maxQueuedQueries, "25") + await apiCall.modifySettingsRole(roles.TimeOut, "1000") await apiCall.modifySettingsRole(roles.maxTimeOut, "0") await apiCall.modifySettingsRole(roles.defaultTimeOut, "0") await apiCall.modifySettingsRole(roles.resultSetSize, "10000") await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, "100000") - await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") - await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, "100000") await apiCall.modifySettingsRole(roles.cmdInfo, "yes") await apiCall.modifySettingsRole(roles.queryMemCapacity, "1000") } From 1e7b07501ef35258caa3c9d1a98759f19dc2afc4 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 13:51:50 +0200 Subject: [PATCH 16/26] Update settingsConfig.spec.ts --- e2e/tests/settingsConfig.spec.ts | 107 +++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 25 deletions(-) diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index c8bf952..4fdc959 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -33,7 +33,7 @@ test.describe('Settings Tests', () => { }) Data.inputDataAcceptsZero.forEach(({ input, description, expected }, index) => { - test(`@admin Modify ${roles.maxQueuedQueries} via API validation via UI: Input value: ${input} description: ${description}`, async () => { + test(`@admin Modify ${roles.TimeOut} via API validation via UI: Input value: ${input} description: ${description}`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) const apiCall = new ApiCalls() await new Promise(resolve => { setTimeout(resolve, 1000) }); @@ -145,30 +145,87 @@ test.describe('Settings Tests', () => { }); }) - Data.roleModificationData.forEach(({ role, input, description, expected }, index) => { - test(`@admin Modify ${role} via UI validation via API: Input value: ${input} description: ${description}`, async () => { - const apiCall = new ApiCalls() - console.log("before: ",String((await apiCall.getSettingsRoleValue(role)).config[1])); - const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) - await settingsConfigPage.modifyRoleValue(role, input) - let value = String((await apiCall.getSettingsRoleValue(role)).config[1]); - console.log("after: ",value); - // Convert numeric values to yes/no for boolean settings - value = value === '1' ? 'yes' : value === '0' ? 'no' : value; - expect(value === input).toBe(expected); - if (index === Data.roleModificationData.length - 1) { - await apiCall.modifySettingsRole(roles.maxQueuedQueries, "25") - await apiCall.modifySettingsRole(roles.TimeOut, "1000") - await apiCall.modifySettingsRole(roles.maxTimeOut, "0") - await apiCall.modifySettingsRole(roles.defaultTimeOut, "0") - await apiCall.modifySettingsRole(roles.resultSetSize, "10000") - await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") - await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, "100000") - await apiCall.modifySettingsRole(roles.cmdInfo, "yes") - await apiCall.modifySettingsRole(roles.queryMemCapacity, "1000") - } - }); - }) + test(`@admin Modify maxQueuedQueries via UI validation via API: Input value: 24`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.maxQueuedQueries, "24") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.maxQueuedQueries)).config[1]); + expect(value === "24").toBe(true); + await apiCall.modifySettingsRole(roles.maxQueuedQueries, "25") + }); + + test(`@admin Modify TimeOut via UI validation via API: Input value: 1001`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.TimeOut, "1001") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.TimeOut)).config[1]); + expect(value === "1001").toBe(true); + await apiCall.modifySettingsRole(roles.TimeOut, "1000") + }); + + test(`@admin Modify maxTimeOut via UI validation via API: Input value: 1`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.maxTimeOut, "1") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.maxTimeOut)).config[1]); + expect(value === "1").toBe(true); + await apiCall.modifySettingsRole(roles.maxTimeOut, "0") + }); + + test(`@admin Modify defaultTimeOut via UI validation via API: Input value: 1`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.defaultTimeOut, "1") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.defaultTimeOut)).config[1]); + expect(value === "1").toBe(true); + await apiCall.modifySettingsRole(roles.defaultTimeOut, "0") + }); + + test(`@admin Modify resultSetSize via UI validation via API: Input value: 10001`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.resultSetSize, "10001") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.resultSetSize)).config[1]); + expect(value === "10001").toBe(true); + await apiCall.modifySettingsRole(roles.resultSetSize, "10000") + }); + + test(`@admin Modify queryMemCapacity via UI validation via API: Input value: 1`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.queryMemCapacity, "1") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.queryMemCapacity)).config[1]); + expect(value === "1").toBe(true); + await apiCall.modifySettingsRole(roles.queryMemCapacity, "0") + }); + + test(`@admin Modify vKeyMaxEntityCount via UI validation via API: Input value: 100001`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.vKeyMaxEntityCount, "100001") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.vKeyMaxEntityCount)).config[1]); + expect(value === "100001").toBe(true); + await apiCall.modifySettingsRole(roles.vKeyMaxEntityCount, "100000") + }); + + test(`@admin Modify cmdInfo via UI validation via API: Input value: no`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.cmdInfo, "no") + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.cmdInfo)).config[1]); + value = value === '1' ? 'yes' : value === '0' ? 'no' : value; + expect(value === "no").toBe(true); + await apiCall.modifySettingsRole(roles.cmdInfo, "yes") + }); + test(`@admin Modify maxInfoQueries via UI validation via API: Input value: 999`, async () => { + const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) + await settingsConfigPage.modifyRoleValue(roles.maxInfoQueries, "999") + await new Promise(resolve => { setTimeout(resolve, 1000) }); + const apiCall = new ApiCalls() + let value = String((await apiCall.getSettingsRoleValue(roles.maxInfoQueries)).config[1]); + expect(value === "999").toBe(true); + await apiCall.modifySettingsRole(roles.maxInfoQueries, "1000") + }); }) \ No newline at end of file From 47d76a58475711fc48e0477437d07a87610c254f Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 14:18:08 +0200 Subject: [PATCH 17/26] Update settingsConfig.spec.ts --- e2e/tests/settingsConfig.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 4fdc959..54226f8 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -138,9 +138,10 @@ test.describe('Settings Tests', () => { await apiCall.modifySettingsRole(roles.maxInfoQueries, input) await settingsConfigPage.refreshPage() const value = await settingsConfigPage.getRoleContentValue(roles.maxInfoQueries) + console.log(value); expect(value === input).toBe(expected); if (index === Data.inputDataAcceptsZero.length - 1) { - await apiCall.modifySettingsRole(roles.queryMemCapacity, "1000"); + await apiCall.modifySettingsRole(roles.maxInfoQueries, "1000"); } }); }) @@ -224,6 +225,8 @@ test.describe('Settings Tests', () => { await new Promise(resolve => { setTimeout(resolve, 1000) }); const apiCall = new ApiCalls() let value = String((await apiCall.getSettingsRoleValue(roles.maxInfoQueries)).config[1]); + console.log(value); + expect(value === "999").toBe(true); await apiCall.modifySettingsRole(roles.maxInfoQueries, "1000") }); From ad603534371a051864a379db241cee0b3bb2ed3e Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:07:41 +0200 Subject: [PATCH 18/26] update playwright config for artifacts --- .github/workflows/playwright.yml | 7 +++++++ playwright.config.ts | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index 83757c7..d90f998 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -40,3 +40,10 @@ jobs: name: playwright-report path: playwright-report/ retention-days: 30 + - name: Upload failed test screenshots + if: always() + uses: actions/upload-artifact@v4 + with: + name: failed-test-screenshots + path: playwright-report/screenshots/ + retention-days: 30 diff --git a/playwright.config.ts b/playwright.config.ts index b705a6f..4bc5ebd 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -21,7 +21,8 @@ export default defineConfig({ /* Opt out of parallel tests on CI. */ workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'html', + reporter: [['html', { outputFolder: 'playwright-report' }]], + outputDir: 'playwright-report/artifacts', /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ @@ -29,6 +30,7 @@ export default defineConfig({ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: 'on-first-retry', + screenshot: 'only-on-failure', }, /* Configure projects for major browsers */ From cd294475017a1d1ee8bf9086ebdc5bf4834ea013 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 18:58:04 +0200 Subject: [PATCH 19/26] Update playwright.yml --- .github/workflows/playwright.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index d90f998..e88f6b0 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -34,6 +34,10 @@ jobs: npm install npm run build NEXTAUTH_SECRET=SECRET npm start & npx playwright test --reporter=dot,list + - name: Ensure required directories exist + run: | + mkdir -p playwright-report + mkdir -p playwright-report/artifacts - uses: actions/upload-artifact@v4 if: always() with: @@ -45,5 +49,5 @@ jobs: uses: actions/upload-artifact@v4 with: name: failed-test-screenshots - path: playwright-report/screenshots/ + path: playwright-report/artifacts/ retention-days: 30 From a7e3b990601f0a388ae6607e75f8b22f94e4da90 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 19:27:00 +0200 Subject: [PATCH 20/26] updating tests --- e2e/logic/POM/settingsConfigPage.ts | 7 +++++++ e2e/tests/settingsConfig.spec.ts | 1 + 2 files changed, 8 insertions(+) diff --git a/e2e/logic/POM/settingsConfigPage.ts b/e2e/logic/POM/settingsConfigPage.ts index 3b6eea7..2403ca2 100644 --- a/e2e/logic/POM/settingsConfigPage.ts +++ b/e2e/logic/POM/settingsConfigPage.ts @@ -24,6 +24,10 @@ export default class SettingsConfigPage extends BasePage { return (role: string) => this.page.locator(`//tbody//tr[@data-id='${role}']/td[3]/div/div/button[1]`) } + private get toastCloseBtn(): Locator { + return this.page.locator("//li[@role='status']/button"); + } + async modifyRoleValue(role: string, input: string): Promise { await this.roleContentValue(role).hover(); await this.EditRoleButton(role).click(); @@ -33,4 +37,7 @@ export default class SettingsConfigPage extends BasePage { return value } + async clickOnToastCloseBtn(): Promise{ + await this.toastCloseBtn.click(); + } } \ No newline at end of file diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 54226f8..3197876 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -225,6 +225,7 @@ test.describe('Settings Tests', () => { await new Promise(resolve => { setTimeout(resolve, 1000) }); const apiCall = new ApiCalls() let value = String((await apiCall.getSettingsRoleValue(roles.maxInfoQueries)).config[1]); + await settingsConfigPage.clickOnToastCloseBtn(); console.log(value); expect(value === "999").toBe(true); From c719d037725f77802e43131e5ce9be5079d20643 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 19:45:07 +0200 Subject: [PATCH 21/26] increase timeout --- e2e/tests/settingsConfig.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 3197876..c9972b1 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -222,7 +222,7 @@ test.describe('Settings Tests', () => { test(`@admin Modify maxInfoQueries via UI validation via API: Input value: 999`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) await settingsConfigPage.modifyRoleValue(roles.maxInfoQueries, "999") - await new Promise(resolve => { setTimeout(resolve, 1000) }); + await new Promise(resolve => { setTimeout(resolve, 3000) }); const apiCall = new ApiCalls() let value = String((await apiCall.getSettingsRoleValue(roles.maxInfoQueries)).config[1]); await settingsConfigPage.clickOnToastCloseBtn(); From 91deab99578040d41dd1e4d63687dd32b70364d2 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Mon, 27 Jan 2025 20:00:50 +0200 Subject: [PATCH 22/26] Update settingsConfig.spec.ts --- e2e/tests/settingsConfig.spec.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index c9972b1..fc9efab 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -224,12 +224,16 @@ test.describe('Settings Tests', () => { await settingsConfigPage.modifyRoleValue(roles.maxInfoQueries, "999") await new Promise(resolve => { setTimeout(resolve, 3000) }); const apiCall = new ApiCalls() - let value = String((await apiCall.getSettingsRoleValue(roles.maxInfoQueries)).config[1]); - await settingsConfigPage.clickOnToastCloseBtn(); + let value; + for (let i = 0; i < 5; i++) { + value = String((await apiCall.getSettingsRoleValue(roles.maxInfoQueries)).config[1]); + if (value === "999") break; + await new Promise(resolve => setTimeout(resolve, 1500)); + } + console.log(value); - - expect(value === "999").toBe(true); - await apiCall.modifySettingsRole(roles.maxInfoQueries, "1000") + expect(value).toBe("999"); + await apiCall.modifySettingsRole(roles.maxInfoQueries, "1000"); }); }) \ No newline at end of file From eb0aad0a71e602c682ad7571eecf9f5097c5fd22 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Tue, 28 Jan 2025 10:51:45 +0200 Subject: [PATCH 23/26] refresh ui before api call --- e2e/tests/settingsConfig.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index fc9efab..48c51c8 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -222,6 +222,7 @@ test.describe('Settings Tests', () => { test(`@admin Modify maxInfoQueries via UI validation via API: Input value: 999`, async () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) await settingsConfigPage.modifyRoleValue(roles.maxInfoQueries, "999") + await settingsConfigPage.refreshPage(); await new Promise(resolve => { setTimeout(resolve, 3000) }); const apiCall = new ApiCalls() let value; From 0244c82f16cbe1a846c68ae638c6189084fd6c50 Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Tue, 28 Jan 2025 11:59:09 +0200 Subject: [PATCH 24/26] add scroll after reload --- components/ui/table.tsx | 2 +- e2e/logic/POM/settingsConfigPage.ts | 8 ++++++++ e2e/tests/settingsConfig.spec.ts | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/components/ui/table.tsx b/components/ui/table.tsx index dbe1675..6e98a5b 100644 --- a/components/ui/table.tsx +++ b/components/ui/table.tsx @@ -11,7 +11,7 @@ const Table = React.forwardRef< HTMLTableElement, TableProps >(({ className, parentClassName, ...props }, ref) => ( -
+
{ await this.roleContentValue(role).hover(); await this.EditRoleButton(role).click(); @@ -40,4 +44,8 @@ export default class SettingsConfigPage extends BasePage { async clickOnToastCloseBtn(): Promise{ await this.toastCloseBtn.click(); } + + async scrollToBottomInTable(): Promise { + await this.tableContent.evaluate((el) => el.scrollTo(0, el.scrollHeight)); + } } \ No newline at end of file diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 48c51c8..0378681 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -223,6 +223,7 @@ test.describe('Settings Tests', () => { const settingsConfigPage = await browser.createNewPage(SettingsConfigPage, urls.settingsUrl) await settingsConfigPage.modifyRoleValue(roles.maxInfoQueries, "999") await settingsConfigPage.refreshPage(); + await settingsConfigPage.scrollToBottomInTable(); await new Promise(resolve => { setTimeout(resolve, 3000) }); const apiCall = new ApiCalls() let value; From 338a4affbf67fcb0e4ffd91efd29b5b5ec6ddacb Mon Sep 17 00:00:00 2001 From: Naseem Ali <34807727+Naseem77@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:21:14 +0200 Subject: [PATCH 25/26] adding logging --- e2e/logic/api/apiCalls.ts | 1 + e2e/tests/settingsConfig.spec.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/e2e/logic/api/apiCalls.ts b/e2e/logic/api/apiCalls.ts index 2688106..1697766 100644 --- a/e2e/logic/api/apiCalls.ts +++ b/e2e/logic/api/apiCalls.ts @@ -35,6 +35,7 @@ export default class ApiCalls { async getSettingsRoleValue(roleName: string, data?: any): Promise { const result = await getRequest(urls.api.settingsConfig + roleName, data) const jsonData = await result.json(); + console.log("api calls res:", jsonData, " role: ", roleName); return jsonData } diff --git a/e2e/tests/settingsConfig.spec.ts b/e2e/tests/settingsConfig.spec.ts index 0378681..8f753fd 100644 --- a/e2e/tests/settingsConfig.spec.ts +++ b/e2e/tests/settingsConfig.spec.ts @@ -224,6 +224,9 @@ test.describe('Settings Tests', () => { await settingsConfigPage.modifyRoleValue(roles.maxInfoQueries, "999") await settingsConfigPage.refreshPage(); await settingsConfigPage.scrollToBottomInTable(); + const res = await settingsConfigPage.getRoleContentValue(roles.maxInfoQueries); + console.log("ui value: ", res); + await new Promise(resolve => { setTimeout(resolve, 3000) }); const apiCall = new ApiCalls() let value; @@ -233,7 +236,7 @@ test.describe('Settings Tests', () => { await new Promise(resolve => setTimeout(resolve, 1500)); } - console.log(value); + console.log("api value:", value); expect(value).toBe("999"); await apiCall.modifySettingsRole(roles.maxInfoQueries, "1000"); }); From d24a326ed09641d11fde945fa9a3b114f30eafff Mon Sep 17 00:00:00 2001 From: Guy Korland Date: Tue, 28 Jan 2025 21:06:26 +0200 Subject: [PATCH 26/26] Update playwright.yml --- .github/workflows/playwright.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index e88f6b0..adfffbb 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -16,7 +16,7 @@ jobs: services: falkordb: - image: falkordb/falkordb:latest + image: falkordb/falkordb:v4.4.1 ports: - 6379:6379