From 484c66bad4689d797902429de03c8145ac1fd594 Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Fri, 18 Aug 2023 16:15:02 +0200 Subject: [PATCH 01/11] added vividus --- .../selectLocatorsByPageObject.mock.ts | 5 +- src/__tests__/pageObject/pageObject.test.js | 36 +++++++++---- .../pageObject/utils/editPomContent.test.ts | 22 ++++++-- src/app/App.tsx | 14 ++++- src/common/utils/localStorage.ts | 1 + .../selectors/locatorsByPO.selectors.ts | 3 +- .../components/PageObjGenerationBar.tsx | 51 +++++++++++++++++-- .../pageObjects/components/PageObjList.tsx | 16 +++--- .../components/PageObjListHeader.tsx | 7 ++- .../pageObjects/components/PageObjMenu.tsx | 33 ++++-------- src/features/pageObjects/pageObject.slice.ts | 7 ++- .../reducers/addPageObject.thunk.js | 24 +++++++-- .../selectors/pageObjects.selectors.ts | 2 + .../types/pageObjectSlice.types.ts | 3 +- src/features/pageObjects/utils/pageObject.ts | 20 ++++---- .../pageObjects/utils/pageObjectTemplate.ts | 38 ++++++++++---- .../utils/pageObjectTemplatePerfTest.ts | 11 ++-- .../pageObjects/utils/projectTemplate.ts | 45 +++++++++++----- src/services/backend.ts | 2 + 19 files changed, 243 insertions(+), 97 deletions(-) diff --git a/src/__tests__/pageObject/__mocks__/selectLocatorsByPageObject.mock.ts b/src/__tests__/pageObject/__mocks__/selectLocatorsByPageObject.mock.ts index efe16afb..c7ac0054 100644 --- a/src/__tests__/pageObject/__mocks__/selectLocatorsByPageObject.mock.ts +++ b/src/__tests__/pageObject/__mocks__/selectLocatorsByPageObject.mock.ts @@ -1,4 +1,4 @@ -import { LocatorType } from "../../../common/types/common"; +import { FrameworkType, LocatorType } from "../../../common/types/common"; import { ElementLibrary } from "../../../features/locators/types/generationClasses.types"; import { PageObject } from "../../../features/pageObjects/types/pageObjectSlice.types"; @@ -6,6 +6,7 @@ export const pageObject0: PageObject = { id: 0, name: "HomePage", url: "https://jdi-testing.github.io/jdi-light/index.html", + framework: FrameworkType.JdiLight, library: ElementLibrary.MUI, pathname: "/jdi-light/index.html", search: "", @@ -168,7 +169,7 @@ export const selectMockedLocators = (pageObject: PageObject) => [ elemId: "", elemText: "Home", elemAriaLabel: null, - ...(pageObject.locatorType === LocatorType.cssSelector ? { locatorType: LocatorType.cssSelector } : null), + locatorType: pageObject.locatorType || LocatorType.xPath, locator: { taskStatus: "PENDING", xPathStatus: "SUCCESS", diff --git a/src/__tests__/pageObject/pageObject.test.js b/src/__tests__/pageObject/pageObject.test.js index b6672e51..c692765f 100644 --- a/src/__tests__/pageObject/pageObject.test.js +++ b/src/__tests__/pageObject/pageObject.test.js @@ -1,4 +1,5 @@ import { + locators, pageObjectMUI, pageObjectHTML, pageObjectVuetify, @@ -16,29 +17,44 @@ import { AnnotationType } from "../../common/types/common"; const templateTestData = [ { - input: "HTML", + pageObject: { + framework: "JDI Light", + library: "HTML", + name: "HomePage", + }, output: pageObjectHTML, }, { - input: "MUI", + pageObject: { + framework: "JDI Light", + library: "MUI", + name: "HomePage", + }, output: pageObjectMUI, }, { - input: "Vuetify", + pageObject: { + framework: "JDI Light", + library: "Vuetify", + name: "HomePage", + }, output: pageObjectVuetify, }, ]; const templateTestDataWithFindBy = { - input: "HTML", + pageObject: { + framework: "JDI Light", + library: "HTML", + name: "HomePage", + }, output: pageObjectHTMLWithFindBy, }; describe("page object code generation", () => { - const locators = getLocatorsByAnnotationType(AnnotationType.UI); - templateTestData.forEach(({ input, output }) => { - test(`page object generated with ${input}`, () => { - const page = pageObjectTemplate(locators, "HomePage", input); + templateTestData.forEach(({ pageObject, output }) => { + test(`page object generated with ${pageObject.library}`, () => { + const page = pageObjectTemplate(locators, pageObject); expect(page.pageCode).toBe(output); expect(page.title).toBe("HomePage"); }); @@ -52,8 +68,8 @@ describe("page object code generation", () => { describe("pageObjectTemplate should return pageObjectHTML with FindBy import", () => { const locators = getLocatorsByAnnotationType(AnnotationType.FindBy); - test(`when page object generated with ${templateTestDataWithFindBy.input} and locators has Annotation Type === 'FindBy'`, () => { - const page = pageObjectTemplate(locators, "HomePage", templateTestDataWithFindBy.input); + test(`when page object generated with ${templateTestDataWithFindBy.pageObject.library} and locators has Annotation Type === 'FindBy'`, () => { + const page = pageObjectTemplate(locators, templateTestDataWithFindBy.pageObject); expect(page.pageCode).toBe(templateTestDataWithFindBy.output); expect(page.title).toBe("HomePage"); }); diff --git a/src/__tests__/pageObject/utils/editPomContent.test.ts b/src/__tests__/pageObject/utils/editPomContent.test.ts index 31ed3d6e..15df7db2 100644 --- a/src/__tests__/pageObject/utils/editPomContent.test.ts +++ b/src/__tests__/pageObject/utils/editPomContent.test.ts @@ -1,3 +1,4 @@ +import { FrameworkType, LocatorType } from "../../../common/types/common"; import { ElementLibrary } from "../../../features/locators/types/generationClasses.types"; import { editPomContent } from "../../../features/pageObjects/utils/templateFileContent"; import { html5Result, muiResult, vuetifyResult } from "../__mocks__/pomTemplates.mock"; @@ -23,15 +24,30 @@ describe("editPomContent function", () => { const testData = [ { output: html5Result, - po: { ...pageObject0, library: ElementLibrary.HTML5 }, + po: { + ...pageObject0, + framework: FrameworkType.JdiLight, + locator: LocatorType.xPath, + library: ElementLibrary.HTML5, + }, }, { output: muiResult, - po: { ...pageObject0, library: ElementLibrary.MUI }, + po: { + ...pageObject0, + framework: FrameworkType.JdiLight, + locator: LocatorType.xPath, + library: ElementLibrary.MUI, + }, }, { output: vuetifyResult, - po: { ...pageObject0, library: ElementLibrary.Vuetify }, + po: { + ...pageObject0, + framework: FrameworkType.JdiLight, + locator: LocatorType.xPath, + library: ElementLibrary.Vuetify, + }, }, ]; diff --git a/src/app/App.tsx b/src/app/App.tsx index 62294c74..3598be52 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -23,12 +23,16 @@ import { LocatorsPage } from "../features/locators/LocatorsPage"; import { PageObjectPage } from "../features/pageObjects/PageObjectPage"; import { OnboardingProvider } from "../features/onboarding/OnboardingProvider"; import { isPageObjectPage } from "./utils/heplers"; +import { selectCurrentPageObject, selectLastFrameworkType } from "../features/pageObjects/selectors/pageObjects.selectors"; +import { getLocalStorage, LocalStorageKey } from "../common/utils/localStorage"; +import { FrameworkType } from "../common/types/common"; const App = () => { const [template, setTemplate] = useState(undefined); const backendAvailable = useSelector((state: RootState) => state.main.backendAvailable); const xpathConfig = useSelector((state: RootState) => state.main.xpathConfig); const currentPage = useSelector(selectCurrentPage); + const currentPageObject = useSelector(selectCurrentPageObject); const dispatch = useDispatch(); const isSessionUnique = useSelector((state: RootState) => state.main.isSessionUnique); @@ -45,9 +49,15 @@ const App = () => { useEffect(() => { const fetchTemplate = async () => { setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); + // setTemplate( + // await request.getBlob( + // framework === FrameworkType.Vividus ? HttpEndpoint.DOWNLOAD_TEMPLATE_VIVIDUS : HttpEndpoint.DOWNLOAD_TEMPLATE + // ) + // ); }; if (backendAvailable === BackendStatus.Accessed) { + // fetchTemplate(getLocalStorage(LocalStorageKey.Framework)); fetchTemplate(); initLocatorSocketController(xpathConfig); } @@ -55,7 +65,9 @@ const App = () => { const renderPage = () => { const { page } = currentPage; - return isPageObjectPage(page) ? : ; + console.log("🥵"); + console.log(currentPageObject); + return isPageObjectPage(page) ? : ; }; return ( diff --git a/src/common/utils/localStorage.ts b/src/common/utils/localStorage.ts index 44ab3d8d..e35dcd90 100644 --- a/src/common/utils/localStorage.ts +++ b/src/common/utils/localStorage.ts @@ -4,6 +4,7 @@ export enum LocalStorageKey { AnnotationType = "JDN_ANNOTATION_TYPE", LocatorType = "JDN_LOCATOR_TYPE", Library = "JDN_LIBRARY", + Framework = "JDN_FRAMEWORK", Filter = "JDN_FILTER", } diff --git a/src/features/locators/selectors/locatorsByPO.selectors.ts b/src/features/locators/selectors/locatorsByPO.selectors.ts index b9c40d19..17279cad 100644 --- a/src/features/locators/selectors/locatorsByPO.selectors.ts +++ b/src/features/locators/selectors/locatorsByPO.selectors.ts @@ -36,12 +36,13 @@ export const selectPresentLocatorsByPO = createSelector( .filter((loc) => locByPageObj.includes(loc.element_id)) .map((loc) => { const annotationType = loc.annotationType || pageObject?.annotationType; + const locatorType = loc.locatorType || pageObject?.locatorType || LocatorType.xPath; const isDefaultLocatorType = () => !loc.locatorType && pageObject?.locatorType === LocatorType.cssSelector; return { ...loc, ...(annotationType && { annotationType }), - ...(isDefaultLocatorType() && { locatorType: pageObject?.locatorType }), + ...(locatorType && { locatorType }), ...(isDefaultLocatorType() && { locator: { ...loc.locator, output: getLocator(loc.locator, pageObject?.locatorType) }, }), diff --git a/src/features/pageObjects/components/PageObjGenerationBar.tsx b/src/features/pageObjects/components/PageObjGenerationBar.tsx index 2645c7d9..7eced10d 100644 --- a/src/features/pageObjects/components/PageObjGenerationBar.tsx +++ b/src/features/pageObjects/components/PageObjGenerationBar.tsx @@ -1,5 +1,5 @@ import { Col, Row, Select, Space, Typography } from "antd"; -import React, { useContext, useRef } from "react"; +import React, { useContext, useEffect, useRef, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { RootState } from "../../../app/store/store"; import { selectCurrentPageObject } from "../selectors/pageObjects.selectors"; @@ -9,6 +9,7 @@ import { setHideUnadded, setLocatorType, setAnnotationType, + changeFrameworkType, } from "../pageObject.slice"; import { PageObjectId } from "../types/pageObjectSlice.types"; import { ElementLibrary, libraryNames } from "../../locators/types/generationClasses.types"; @@ -22,6 +23,9 @@ import { isIdentificationLoading } from "../../locators/utils/helpers"; import { PageObjGenerationButton } from "./PageObjGenerationButton"; import { OnboardingContext } from "../../onboarding/OnboardingProvider"; import { IN_DEVELOPMENT_TITLE } from "../../../common/constants/constants"; +import { BackendStatus } from "../../../app/types/mainSlice.types"; +import { initLocatorSocketController } from "../../../app/utils/appUtils"; +import { request, HttpEndpoint } from "../../../services/backend"; interface Props { pageObj: PageObjectId; @@ -65,8 +69,7 @@ const frameworkTypeOptions = [ { value: FrameworkType.Vividus, label: FrameworkType.Vividus, - title: IN_DEVELOPMENT_TITLE, - disabled: true, + disabled: false, }, ]; @@ -97,7 +100,27 @@ export const PageObjGenerationBar: React.FC = ({ pageObj, library, url }) const currentPageObject = useSelector(selectCurrentPageObject); const { isOpen: isOnboardingOpen } = useContext(OnboardingContext); - const handleGenerate = () => { + const [template, setTemplate] = useState(undefined); + const backendAvailable = useSelector((state: RootState) => state.main.backendAvailable); + const xpathConfig = useSelector((state: RootState) => state.main.xpathConfig); + + // useEffect(() => { + // const fetchTemplate = async () => { + // setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); + // console.log("🤭"); + // console.log(template); + // }; + + // if (backendAvailable === BackendStatus.Accessed) { + // fetchTemplate(); + // initLocatorSocketController(xpathConfig); + // } + // }, [backendAvailable]); + + const handleGenerate = async () => { + setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); + console.log("👻"); + console.log(template); dispatch(setHideUnadded({ id: pageObj, hideUnadded: false })); dispatch(identifyElements({ library, pageObj })); }; @@ -106,11 +129,26 @@ export const PageObjGenerationBar: React.FC = ({ pageObj, library, url }) const dispatch = useDispatch(); + const currentLibrary = currentPageObject?.library; + const isCurrentFrameworkVividus = currentPageObject?.framework === FrameworkType.Vividus; + const onLibraryChange = (library: ElementLibrary) => { dispatch(changeElementLibrary({ id: pageObj, library })); setLocalStorage(LocalStorageKey.Library, library); }; + const onFrameworkChange = async (framework: FrameworkType) => { + dispatch(changeFrameworkType({ id: pageObj, framework })); + setLocalStorage(LocalStorageKey.Framework, framework); + + if (framework === FrameworkType.Vividus) { + // setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE_VIVIDUS)); + onLibraryChange(ElementLibrary.HTML5); + } else { + // setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); + } + }; + const onAnnotationTypeChange = (annotationType: AnnotationType) => { dispatch(setAnnotationType({ id: pageObj, annotationType })); setLocalStorage(LocalStorageKey.AnnotationType, annotationType); @@ -143,9 +181,10 @@ export const PageObjGenerationBar: React.FC = ({ pageObj, library, url }) = (props) => { {...(!isNil(activePanel) ? { activeKey: activePanel } : {})} onChange={(key) => setActivePanel([...key])} > - {pageObjects.map(({ id, name, url, locators, library }) => { - const elements = selectConfirmedLocators(state as RootState, id); - const isPageObjectNotEmpty = !!size(locators); + {pageObjects.map((pageObject) => { + const elements = selectConfirmedLocators(state as RootState, pageObject.id); + const isPageObjectNotEmpty = !!size(pageObject.locators); return ( triggerNode} align={{ offset: [-28, 0] }} > - {name} + {pageObject.name} } extra={ <> {isPageObjectNotEmpty && } - + } > - {renderContent(id, url, elements, library, isPageObjectNotEmpty)} + {renderContent(pageObject.id, pageObject.url, elements, pageObject.library, isPageObjectNotEmpty)} ); })} diff --git a/src/features/pageObjects/components/PageObjListHeader.tsx b/src/features/pageObjects/components/PageObjListHeader.tsx index e1aaf229..102d2821 100644 --- a/src/features/pageObjects/components/PageObjListHeader.tsx +++ b/src/features/pageObjects/components/PageObjListHeader.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from "react"; +import React, { useMemo, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { Button, Modal, Row, Space, Tooltip } from "antd"; import { CaretDown, Plus, Trash } from "phosphor-react"; @@ -27,7 +27,8 @@ interface Props { isExpanded: boolean; } -export const PageObjListHeader: React.FC = ({ template, toggleExpand, isExpanded, setActivePanel }) => { +export const PageObjListHeader: React.FC = ({ toggleExpand, isExpanded, setActivePanel }) => { + const [template, setTemplate] = useState(undefined); const state = useSelector((state) => state) as RootState; const pageObjects = useSelector(selectPageObjects); const locatorsToGenerate = useSelector(selectLocatorsToGenerate); @@ -39,6 +40,8 @@ export const PageObjListHeader: React.FC = ({ template, toggleExpand, isE const handleDownload = () => { dispatch(pushNotification({ action: { type: "downloadTemplate" } })); + console.log("🤯"); + console.log(template); if (template) generateAndDownloadZip(state, template); }; diff --git a/src/features/pageObjects/components/PageObjMenu.tsx b/src/features/pageObjects/components/PageObjMenu.tsx index c763d82d..94a81452 100644 --- a/src/features/pageObjects/components/PageObjMenu.tsx +++ b/src/features/pageObjects/components/PageObjMenu.tsx @@ -16,8 +16,7 @@ import { import { ElementId, Locator } from "../../locators/types/locator.types"; import { removeLocators } from "../../locators/locators.slice"; import { removePageObject, setCurrentPageObj } from "../pageObject.slice"; -import { PageObjectId } from "../types/pageObjectSlice.types"; -import { ElementLibrary } from "../../locators/types/generationClasses.types"; +import { PageObject } from "../types/pageObjectSlice.types"; import { generatePageObject, generatePageObjectPerfTest } from "../../pageObjects/utils/pageObject"; import { RenamePageObjectDialog } from "./RenamePageObjDialog"; import { checkLocatorsValidity } from "../../locators/reducers/checkLocatorValidity.thunk"; @@ -27,49 +26,39 @@ import { OnbrdTooltip } from "../../onboarding/components/OnbrdTooltip"; import { OnboardingContext } from "../../onboarding/OnboardingProvider"; interface Props { - id: PageObjectId; - name: string; - url: string; - locators?: ElementId[]; + pageObject: PageObject; elements: Locator[]; - library: ElementLibrary; } -export const PageObjMenu: React.FC = ({ id, name, url, locators, elements, library }) => { +export const PageObjMenu: React.FC = ({ pageObject, elements }) => { const dispatch = useDispatch(); const [isRenameModalOpen, setIsRenameModalOpen] = useState(false); const { isOpen: isOnboardingOpen } = useContext(OnboardingContext); - const getMenuItems = ( - id: PageObjectId, - locatorIds: ElementId[] | undefined, - locatorObjects: Locator[], - name: string, - url: string - ) => { + const getMenuItems = (pageObject: PageObject, locatorIds: ElementId[] | undefined, locatorObjects: Locator[]) => { const handleRename = () => setIsRenameModalOpen(true); const handleRemove = () => { - dispatch(removePageObject(id)); + dispatch(removePageObject(pageObject.id)); dispatch(removeLocators(locatorIds)); }; const handleDownload = () => { - generatePageObject(locatorObjects, name, library).then(() => + generatePageObject(locatorObjects, pageObject).then(() => dispatch(pushNotification({ action: { type: "downloadFile" } })) ); }; const handleDownloadPerfTest = () => { - generatePageObjectPerfTest(locatorObjects, name, url).then(() => + generatePageObjectPerfTest(locatorObjects, pageObject).then(() => dispatch(pushNotification({ action: { type: "downloadJSFile" } })) ); }; const handleEdit = () => { - dispatch(setCurrentPageObj(id)); + dispatch(setCurrentPageObj(pageObject.id)); dispatch(checkLocatorsValidity()); // create thunk }; @@ -94,7 +83,7 @@ export const PageObjMenu: React.FC = ({ id, name, url, locators, elements disabled={isOnboardingOpen} align={{ offset: [15, 0] }} trigger={["click"]} - menu={getMenuItems(id, locators, elements, name, url)} + menu={getMenuItems(pageObject, pageObject.locators, elements)} getPopupContainer={(triggerNode) => triggerNode} destroyPopupOnHide > @@ -110,8 +99,8 @@ export const PageObjMenu: React.FC = ({ id, name, url, locators, elements ); diff --git a/src/features/pageObjects/pageObject.slice.ts b/src/features/pageObjects/pageObject.slice.ts index ab5ad689..14d5b834 100644 --- a/src/features/pageObjects/pageObject.slice.ts +++ b/src/features/pageObjects/pageObject.slice.ts @@ -5,7 +5,7 @@ import { PageObjectState, PageObject, PageObjectId } from "./types/pageObjectSli import { ElementId } from "../locators/types/locator.types"; import { addPageObjReducer } from "./reducers/addPageObject.thunk"; import { ElementLibrary } from "../locators/types/generationClasses.types"; -import { LocatorType, AnnotationType } from "../../common/types/common"; +import { LocatorType, AnnotationType, FrameworkType } from "../../common/types/common"; const initialState: PageObjectState = {}; @@ -35,6 +35,10 @@ const pageObjSlice = createSlice({ const { id, library } = payload; pageObjAdapter.upsertOne(state, { id, library } as PageObject); }, + changeFrameworkType(state, { payload }: PayloadAction<{ id: PageObjectId; framework: FrameworkType }>) { + const { id, framework } = payload; + pageObjAdapter.upsertOne(state, { id, framework } as PageObject); + }, clearLocators(state, { payload }) { const id = payload || state.currentPageObject; pageObjAdapter.upsertOne(state, { id, locators: undefined } as PageObject); @@ -75,6 +79,7 @@ export const { addLocatorToPageObj, addLocatorsToPageObj, changeElementLibrary, + changeFrameworkType, changeName, clearLocators, removeAll, diff --git a/src/features/pageObjects/reducers/addPageObject.thunk.js b/src/features/pageObjects/reducers/addPageObject.thunk.js index 8241706a..6bab9746 100644 --- a/src/features/pageObjects/reducers/addPageObject.thunk.js +++ b/src/features/pageObjects/reducers/addPageObject.thunk.js @@ -7,12 +7,13 @@ import { selectLastAnnotationType, selectMaxId, simpleSelectPageObjects, + selectLastFrameworkType, } from "../selectors/pageObjects.selectors"; import { defaultLibrary } from "../../locators/types/generationClasses.types"; import { getPageAttributes, isPONameUnique } from "../utils/pageObject"; import { getClassName } from "../utils/pageObjectTemplate"; import { LocalStorageKey, getLocalStorage } from "../../../common/utils/localStorage"; -import { AnnotationType, LocatorType } from "../../../common/types/common"; +import { AnnotationType, LocatorType, FrameworkType } from "../../../common/types/common"; export const addPageObj = createAsyncThunk("pageObject/addPageObj", async (payload, { getState }) => { const res = await getPageAttributes(); @@ -21,19 +22,35 @@ export const addPageObj = createAsyncThunk("pageObject/addPageObj", async (paylo const state = getState(); + const lastSelectedFrameworkType = + getLocalStorage(LocalStorageKey.Framework) || selectLastFrameworkType(state) || FrameworkType.JdiLight; const lastSelectedLibrary = getLocalStorage(LocalStorageKey.Library) || selectLastElementLibrary(state) || defaultLibrary; const lastSelectedLocatorType = getLocalStorage(LocalStorageKey.LocatorType) || selectLastLocatorType(state); const lastSelectedAnnotationType = getLocalStorage(LocalStorageKey.AnnotationType) || selectLastAnnotationType(state) || AnnotationType.UI; - return { className, url, lastSelectedLibrary, lastSelectedLocatorType, lastSelectedAnnotationType }; + return { + className, + url, + lastSelectedFrameworkType, + lastSelectedLibrary, + lastSelectedLocatorType, + lastSelectedAnnotationType, + }; }); export const addPageObjReducer = (builder) => { return builder .addCase(addPageObj.fulfilled, (state, { payload }) => { - const { className, url, lastSelectedLibrary, lastSelectedLocatorType, lastSelectedAnnotationType } = payload; + const { + className, + url, + lastSelectedFrameworkType, + lastSelectedLibrary, + lastSelectedLocatorType, + lastSelectedAnnotationType, + } = payload; // create unique PO name let maxExistingId = selectMaxId(state); @@ -58,6 +75,7 @@ export const addPageObjReducer = (builder) => { id, name, url, + framework: lastSelectedFrameworkType, library: lastSelectedLibrary, annotationType: lastSelectedAnnotationType, pathname, diff --git a/src/features/pageObjects/selectors/pageObjects.selectors.ts b/src/features/pageObjects/selectors/pageObjects.selectors.ts index d79e35ea..ea60296b 100644 --- a/src/features/pageObjects/selectors/pageObjects.selectors.ts +++ b/src/features/pageObjects/selectors/pageObjects.selectors.ts @@ -33,6 +33,8 @@ export const selectMaxId = createSelector(simpleSelectPageObjects, (items) => { return res !== -Infinity ? res : null; }); +export const selectLastFrameworkType = createSelector(selectPageObjects, (pageObjects) => last(pageObjects)?.framework); + export const selectLastElementLibrary = createSelector(selectPageObjects, (pageObjects) => last(pageObjects)?.library); export const selectLastLocatorType = createSelector(selectPageObjects, (pageObjects) => last(pageObjects)?.locatorType); diff --git a/src/features/pageObjects/types/pageObjectSlice.types.ts b/src/features/pageObjects/types/pageObjectSlice.types.ts index 1f88466e..3b537306 100644 --- a/src/features/pageObjects/types/pageObjectSlice.types.ts +++ b/src/features/pageObjects/types/pageObjectSlice.types.ts @@ -1,6 +1,6 @@ import { ElementId } from "../../locators/types/locator.types"; import { ElementLibrary } from "../../locators/types/generationClasses.types"; -import { LocatorType, AnnotationType } from "../../../common/types/common"; +import { FrameworkType, LocatorType, AnnotationType } from "../../../common/types/common"; export type PageObjectId = number; @@ -11,6 +11,7 @@ export interface PageObjectState { export interface PageObject { hideUnadded?: boolean; // whether to show in list Locators with "generate" set to false id: PageObjectId; + framework: FrameworkType; library: ElementLibrary; locators?: ElementId[]; annotationType?: AnnotationType; diff --git a/src/features/pageObjects/utils/pageObject.ts b/src/features/pageObjects/utils/pageObject.ts index 6fc1f72f..077cfbb4 100644 --- a/src/features/pageObjects/utils/pageObject.ts +++ b/src/features/pageObjects/utils/pageObject.ts @@ -125,28 +125,26 @@ export const getPageAttributes = async () => { }); }; -export const getPage = async (locators: Array, title: string, library: ElementLibrary) => { - const pageObject = pageObjectTemplate(locators, title, library); - return pageObject; +export const getPage = async (locators: Array, pageObject: PageObject) => { + return pageObjectTemplate(locators, pageObject); }; -export const getPagePerfTest = async (locators: Array, title: string, url: string) => { - const pageObject = pageObjectTemplatePerfTest(locators, title, url); - return pageObject; +export const getPagePerfTest = async (locators: Array, pageObject: PageObject) => { + return pageObjectTemplatePerfTest(locators, pageObject); }; -export const generatePageObject = async (elements: Array, title: string, library: ElementLibrary) => { - const page = await getPage(elements, title, library); +export const generatePageObject = async (elements: Array, pageObject: PageObject) => { + const page = await getPage(elements, pageObject); const blob = new Blob([page.pageCode], { type: "text/plain;charset=utf-8", }); saveAs(blob, `${page.title}.java`); }; -export const generatePageObjectPerfTest = async (elements: Array, title: string, url: string) => { - const page = await getPagePerfTest(elements, title, url); +export const generatePageObjectPerfTest = async (elements: Array, pageObject: PageObject) => { + const page = await getPagePerfTest(elements, pageObject); const blob = new Blob([page.pageCode], { type: "text/plain;charset=utf-8", }); - saveAs(blob, `${page.title}.js`); + saveAs(blob, `${page.name}.js`); }; diff --git a/src/features/pageObjects/utils/pageObjectTemplate.ts b/src/features/pageObjects/utils/pageObjectTemplate.ts index f81c7113..f325fdf0 100644 --- a/src/features/pageObjects/utils/pageObjectTemplate.ts +++ b/src/features/pageObjects/utils/pageObjectTemplate.ts @@ -3,8 +3,10 @@ import { camelCase, upperFirst } from "lodash"; import transliterate from "@sindresorhus/transliterate"; import { Locator } from "../../locators/types/locator.types"; import { getLocatorPrefix } from "../../locators/utils/locatorOutput"; -import { AnnotationType } from "../../../common/types/common"; +import { AnnotationType, LocatorType, FrameworkType } from "../../../common/types/common"; import { hasAnnotationType } from "./hasAnnotationType"; +import { PageObject } from "../types/pageObjectSlice.types"; +import _ from "lodash"; export const getClassName = (title: string) => { let className = transliterate(title); @@ -18,14 +20,32 @@ export const getClassName = (title: string) => { return className; }; -export const pageObjectTemplate = (locators: Locator[], title: string, library: ElementLibrary) => { - const className = title; +export const vividusTemplate = (locators: Locator[], pageObject: PageObject) => { + let pageCode = `variables.${pageObject.name}.url=(${pageObject.pathname})\n`; + + locators.forEach((it) => { + const currentLocatorType = _.camelCase(it.locatorType || pageObject.locatorType || LocatorType.xPath); + // @ts-ignore + pageCode += `variables.${pageObject.name}.${it.type}.${it.name}=By.${currentLocatorType}(${it.locator[currentLocatorType]})\n`; + }); + + return { pageCode, title: pageObject.name }; +}; + +export const pageObjectTemplate = (locators: Locator[], pageObject: PageObject) => { + if (pageObject.framework === FrameworkType.Vividus) { + return vividusTemplate(locators, pageObject); + } + + const className = pageObject.name; const locatorsCode = locators.map((loc) => { const locatorEscaped = loc.locator.output?.replace(/\\/g, "\\\\").replace(/"/g, '\\"'); - return ` ${loc.annotationType}(${getLocatorPrefix( - loc.annotationType, - loc.locatorType - )}"${locatorEscaped}")\n public ${loc.type} ${loc.name};`; + return pageObject.framework === FrameworkType.Vividus + ? `variables.${className}.url=(${pageObject.pathname})` + : ` ${loc.annotationType}(${getLocatorPrefix( + loc.annotationType, + loc.locatorType + )}"${locatorEscaped}")\n public ${loc.type} ${loc.name};`; }); const hasFindByAnnotationType: boolean = hasAnnotationType(locators, AnnotationType.FindBy); @@ -41,7 +61,7 @@ import com.epam.jdi.light.elements.complex.dropdown.*; import com.epam.jdi.light.elements.complex.table.*; import com.epam.jdi.light.ui.html.elements.complex.*; ${ - library === ElementLibrary.MUI + pageObject.library === ElementLibrary.MUI ? ` import com.epam.jdi.light.material.elements.displaydata.*; import com.epam.jdi.light.material.elements.displaydata.table.*; @@ -57,7 +77,7 @@ import com.epam.jdi.light.material.elements.utils.*; ` : "" }${ - library === ElementLibrary.Vuetify + pageObject.library === ElementLibrary.Vuetify ? ` import com.epam.jdi.light.vuetify.elements.common.*; import com.epam.jdi.light.vuetify.elements.complex.*; diff --git a/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts b/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts index 6370f72d..377fe5de 100644 --- a/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts +++ b/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts @@ -1,6 +1,7 @@ import { Locator } from "../../locators/types/locator.types"; +import { PageObject } from "../types/pageObjectSlice.types"; -export const pageObjectTemplatePerfTest = (locators: Locator[], title: string, url: string) => { +export const pageObjectTemplatePerfTest = (locators: Locator[], pageObject: PageObject) => { const locatorsCode = locators.map((loc) => ` this.${loc.name} = new ${loc.type}("${loc.locator.output}", page)`); const pageCode = `const Page = require("../../core/page"); @@ -8,18 +9,18 @@ export const pageObjectTemplatePerfTest = (locators: Locator[], title: string, u const Button = require("../../core/elements/button"); const UploadField = require("../../core/elements/uploadField"); const UIElement = require("../../core/elements/element");\n -class ${title} extends Page {\n +class ${pageObject.name} extends Page {\n constructor(page) { super(page) - this.url = "${url}" + this.url = "${pageObject.url}" }\n init(page){ super.init(page) ${locatorsCode.join("\n")} }\n }\n -module.exports = ${title}; +module.exports = ${pageObject.name}; `; - return { pageCode, title }; + return { pageCode, name: pageObject.name }; }; diff --git a/src/features/pageObjects/utils/projectTemplate.ts b/src/features/pageObjects/utils/projectTemplate.ts index df082eb4..a84b8158 100644 --- a/src/features/pageObjects/utils/projectTemplate.ts +++ b/src/features/pageObjects/utils/projectTemplate.ts @@ -9,9 +9,20 @@ import { PageObject } from "../types/pageObjectSlice.types"; import { ElementLibrary } from "../../locators/types/generationClasses.types"; import { editPomContent } from "./templateFileContent"; import { selectConfirmedLocators } from "../../locators/selectors/locatorsFiltered.selectors"; +import { FrameworkType } from "../../../common/types/common"; -const generatePoFile = (newZip: JSZip, page: { pageCode: string; title: string }) => - newZip.file(`src/main/java/site/pages/${page.title}.java`, page.pageCode, { binary: false }); +const PAGES_PROPERTIES_PATH = "src/main/resources/properties/suite/web_app/pages.properties"; +const SITE_PROPERTIES_PATH = "src/main/resources/properties/suite/web_app/site.properties"; +const MY_SITE_PATH = "src/main/java/site/MySite.java"; +const EXAMPLE_STRING = "// ADD SITE PAGES WITH URLS"; + +const isVividusFramework = (framework: FrameworkType) => framework === FrameworkType.Vividus; + +const generatePoFile = (newZip: JSZip, framework: FrameworkType, page: { pageCode: string; title: string }) => { + const path = isVividusFramework(framework) ? PAGES_PROPERTIES_PATH : `src/main/java/site/pages/${page.title}.java`; + + newZip.file(path, page.pageCode, { binary: false }); +}; const editTestPropertiesFile = (newZip: JSZip, po: PageObject) => newZip @@ -23,21 +34,24 @@ const editTestPropertiesFile = (newZip: JSZip, po: PageObject) => return newZip.file(`src/test/resources/test.properties`, newContent, { binary: true }); }); -const editMySiteFile = (newZip: JSZip, po: PageObject, instanceName: string) => +const editMySiteFile = (newZip: JSZip, po: PageObject, instanceName: string) => { + if (isVividusFramework(po.framework)) return; + // const path = isVividusFramework(po.framework) ? PAGES_PROPERTIES_PATH : MY_SITE_PATH; newZip - .file("src/main/java/site/MySite.java")! + .file(MY_SITE_PATH)! .async("string") .then((content) => { if (content.includes(instanceName)) instanceName = `${instanceName}1`; const urlSearchParams = po.search; const testUrl = urlSearchParams.length ? po.pathname + urlSearchParams : po.pathname; const newContent = content.replace( - "// ADD SITE PAGES WITH URLS", - `// ADD SITE PAGES WITH URLS\n @Url("${testUrl}")\n public static ${po.name} ${instanceName}; + EXAMPLE_STRING, + `${EXAMPLE_STRING}\n @Url("${testUrl}")\n public static ${po.name} ${instanceName}; ` ); - return newZip.file(`src/main/java/site/MySite.java`, newContent, { binary: true }); + return newZip.file(MY_SITE_PATH, newContent, { binary: true }); }); +}; const editTestsFile = (newZip: JSZip, po: PageObject, instanceName: string) => newZip.file(`src/test/java/tests/${po.name}Tests.java`, testFileTemplate(instanceName, po.name)); @@ -81,15 +95,20 @@ export const generateAndDownloadZip = async (state: RootState, template: Blob) = // create page object files const locators = selectConfirmedLocators(state, po.id); if (!size(locators)) continue; - const page = await getPage(locators, po.name, po.library); + const page = await getPage(locators, po); const instanceName = lowerFirst(po.name); - await generatePoFile(newZip, page); - await editTestPropertiesFile(newZip, po); - await editMySiteFile(newZip, po, instanceName); - await editTestsFile(newZip, po, instanceName); - await editPomFile(newZip, po); + await generatePoFile(newZip, po.framework, page); + + if (!isVividusFramework(po.framework)) { + await editTestPropertiesFile(newZip, po); + await editMySiteFile(newZip, po, instanceName); + await editTestsFile(newZip, po, instanceName); + await editPomFile(newZip, po); + } else { + newZip.file(SITE_PROPERTIES_PATH, `variables.siteURL=${po.url}`, { binary: true }); + } } saveZip(); diff --git a/src/services/backend.ts b/src/services/backend.ts index 38172285..81d161fd 100644 --- a/src/services/backend.ts +++ b/src/services/backend.ts @@ -8,6 +8,8 @@ export enum HttpEndpoint { NGMAT_PREDICT = "angular-predict", // TODO: check when implemented at BE REPORT_PROBLEM = "report_problem", DOWNLOAD_TEMPLATE = "download_template", + DOWNLOAD_TEMPLATE_VIVIDUS = "download_template?repo_zip_url=https://github.com/vividus-framework/vividus-sample-tests/archive/refs/heads/main.zip", + SESSION_ID = "get_session_id", PING_SMTP = "ping_smtp", } From 710d70aaa8c326fb59eea7692572599fd4a5e22b Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Fri, 18 Aug 2023 19:38:34 +0200 Subject: [PATCH 02/11] getting template dynamically --- src/app/App.tsx | 21 +------------- src/features/pageObjects/PageObjectPage.tsx | 8 ++---- .../components/PageObjGenerationBar.tsx | 28 +------------------ .../pageObjects/components/PageObjList.tsx | 27 +++++++++++++----- .../components/PageObjListHeader.tsx | 3 +- 5 files changed, 25 insertions(+), 62 deletions(-) diff --git a/src/app/App.tsx b/src/app/App.tsx index 3598be52..d0ff7146 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect } from "react"; import { Provider as ReduxProvider, useDispatch, useSelector } from "react-redux"; import "antd/dist/antd.less"; @@ -8,7 +8,6 @@ import Layout, { Content, Header } from "antd/lib/layout/layout"; import { Backdrop } from "./components/Backdrop"; import { StatusBar } from "./components/StatusBar"; import { SeveralTabsWarning } from "./components/SeveralTabsWarning"; -import { HttpEndpoint, request } from "../services/backend"; import { checkSession, initLocatorSocketController } from "./utils/appUtils"; import { selectCurrentPage } from "./main.selectors"; import { RootState, store } from "./store/store"; @@ -23,16 +22,11 @@ import { LocatorsPage } from "../features/locators/LocatorsPage"; import { PageObjectPage } from "../features/pageObjects/PageObjectPage"; import { OnboardingProvider } from "../features/onboarding/OnboardingProvider"; import { isPageObjectPage } from "./utils/heplers"; -import { selectCurrentPageObject, selectLastFrameworkType } from "../features/pageObjects/selectors/pageObjects.selectors"; -import { getLocalStorage, LocalStorageKey } from "../common/utils/localStorage"; -import { FrameworkType } from "../common/types/common"; const App = () => { - const [template, setTemplate] = useState(undefined); const backendAvailable = useSelector((state: RootState) => state.main.backendAvailable); const xpathConfig = useSelector((state: RootState) => state.main.xpathConfig); const currentPage = useSelector(selectCurrentPage); - const currentPageObject = useSelector(selectCurrentPageObject); const dispatch = useDispatch(); const isSessionUnique = useSelector((state: RootState) => state.main.isSessionUnique); @@ -47,26 +41,13 @@ const App = () => { }, []); useEffect(() => { - const fetchTemplate = async () => { - setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); - // setTemplate( - // await request.getBlob( - // framework === FrameworkType.Vividus ? HttpEndpoint.DOWNLOAD_TEMPLATE_VIVIDUS : HttpEndpoint.DOWNLOAD_TEMPLATE - // ) - // ); - }; - if (backendAvailable === BackendStatus.Accessed) { - // fetchTemplate(getLocalStorage(LocalStorageKey.Framework)); - fetchTemplate(); initLocatorSocketController(xpathConfig); } }, [backendAvailable]); const renderPage = () => { const { page } = currentPage; - console.log("🥵"); - console.log(currentPageObject); return isPageObjectPage(page) ? : ; }; diff --git a/src/features/pageObjects/PageObjectPage.tsx b/src/features/pageObjects/PageObjectPage.tsx index 15c6bc48..d95e10f3 100644 --- a/src/features/pageObjects/PageObjectPage.tsx +++ b/src/features/pageObjects/PageObjectPage.tsx @@ -1,14 +1,10 @@ import React from "react"; import { PageObjList } from "./components/PageObjList"; -interface Props { - template?: Blob; -} - -export const PageObjectPage: React.FC = (props) => { +export const PageObjectPage: React.FC = () => { return (
- +
); }; diff --git a/src/features/pageObjects/components/PageObjGenerationBar.tsx b/src/features/pageObjects/components/PageObjGenerationBar.tsx index 7eced10d..05141ad4 100644 --- a/src/features/pageObjects/components/PageObjGenerationBar.tsx +++ b/src/features/pageObjects/components/PageObjGenerationBar.tsx @@ -1,5 +1,5 @@ import { Col, Row, Select, Space, Typography } from "antd"; -import React, { useContext, useEffect, useRef, useState } from "react"; +import React, { useContext, useRef } from "react"; import { useDispatch, useSelector } from "react-redux"; import { RootState } from "../../../app/store/store"; import { selectCurrentPageObject } from "../selectors/pageObjects.selectors"; @@ -23,9 +23,6 @@ import { isIdentificationLoading } from "../../locators/utils/helpers"; import { PageObjGenerationButton } from "./PageObjGenerationButton"; import { OnboardingContext } from "../../onboarding/OnboardingProvider"; import { IN_DEVELOPMENT_TITLE } from "../../../common/constants/constants"; -import { BackendStatus } from "../../../app/types/mainSlice.types"; -import { initLocatorSocketController } from "../../../app/utils/appUtils"; -import { request, HttpEndpoint } from "../../../services/backend"; interface Props { pageObj: PageObjectId; @@ -100,27 +97,7 @@ export const PageObjGenerationBar: React.FC = ({ pageObj, library, url }) const currentPageObject = useSelector(selectCurrentPageObject); const { isOpen: isOnboardingOpen } = useContext(OnboardingContext); - const [template, setTemplate] = useState(undefined); - const backendAvailable = useSelector((state: RootState) => state.main.backendAvailable); - const xpathConfig = useSelector((state: RootState) => state.main.xpathConfig); - - // useEffect(() => { - // const fetchTemplate = async () => { - // setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); - // console.log("🤭"); - // console.log(template); - // }; - - // if (backendAvailable === BackendStatus.Accessed) { - // fetchTemplate(); - // initLocatorSocketController(xpathConfig); - // } - // }, [backendAvailable]); - const handleGenerate = async () => { - setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); - console.log("👻"); - console.log(template); dispatch(setHideUnadded({ id: pageObj, hideUnadded: false })); dispatch(identifyElements({ library, pageObj })); }; @@ -142,10 +119,7 @@ export const PageObjGenerationBar: React.FC = ({ pageObj, library, url }) setLocalStorage(LocalStorageKey.Framework, framework); if (framework === FrameworkType.Vividus) { - // setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE_VIVIDUS)); onLibraryChange(ElementLibrary.HTML5); - } else { - // setTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); } }; diff --git a/src/features/pageObjects/components/PageObjList.tsx b/src/features/pageObjects/components/PageObjList.tsx index bd64e37d..a11dac03 100644 --- a/src/features/pageObjects/components/PageObjList.tsx +++ b/src/features/pageObjects/components/PageObjList.tsx @@ -6,7 +6,7 @@ import { useSelector } from "react-redux"; import { CaretDown } from "phosphor-react"; import PageSvg from "../assets/page.svg"; -import { selectPageObjects } from "../selectors/pageObjects.selectors"; +import { selectCurrentPageObject, selectPageObjects } from "../selectors/pageObjects.selectors"; import { PageObjGenerationBar } from "./PageObjGenerationBar"; import { PageObjectPlaceholder } from "./PageObjectPlaceholder"; import { PageObjCopyButton } from "./PageObjCopyButton"; @@ -20,26 +20,39 @@ import { PageObjectId } from "../types/pageObjectSlice.types"; import { ElementLibrary } from "../../locators/types/generationClasses.types"; import { PageType } from "../../../app/types/mainSlice.types"; import { selectConfirmedLocators } from "../../locators/selectors/locatorsFiltered.selectors"; +import { request, HttpEndpoint } from "../../../services/backend"; +import { FrameworkType } from "../../../common/types/common"; -interface Props { - template?: Blob; -} - -export const PageObjList: React.FC = (props) => { +export const PageObjList: React.FC = () => { const DEFAULT_ACTIVE_KEY = "0"; const state = useSelector((state) => state); // due to antd types: onChange?: (key: string | string[]) => void; const currentPageObject = useSelector((state: RootState): string | undefined => state.pageObject.present.currentPageObject?.toString() ); + const currentPageObject2 = useSelector(selectCurrentPageObject); const pageObjects = useSelector(selectPageObjects); const [activePanel, setActivePanel] = useState([DEFAULT_ACTIVE_KEY]); + const [template, setTemplate] = useState(undefined); const contentRef = useRef(null); useNotifications(contentRef?.current); const isExpanded = !!size(activePanel); + const fetchTemplate = async (framework: FrameworkType) => { + const targetTemplate = + framework === FrameworkType.Vividus ? HttpEndpoint.DOWNLOAD_TEMPLATE_VIVIDUS : HttpEndpoint.DOWNLOAD_TEMPLATE; + setTemplate(await request.getBlob(targetTemplate)); + }; + + useEffect(() => { + currentPageObject2 && fetchTemplate(currentPageObject2.framework); + }, [currentPageObject2?.framework]); + + console.log("👽"); + console.log(template); + useEffect(() => { if (currentPageObject) { setActivePanel([currentPageObject]); @@ -85,7 +98,7 @@ export const PageObjList: React.FC = (props) => { return (
- +
{size(pageObjects) ? ( diff --git a/src/features/pageObjects/components/PageObjListHeader.tsx b/src/features/pageObjects/components/PageObjListHeader.tsx index 102d2821..db3a4ee2 100644 --- a/src/features/pageObjects/components/PageObjListHeader.tsx +++ b/src/features/pageObjects/components/PageObjListHeader.tsx @@ -27,8 +27,7 @@ interface Props { isExpanded: boolean; } -export const PageObjListHeader: React.FC = ({ toggleExpand, isExpanded, setActivePanel }) => { - const [template, setTemplate] = useState(undefined); +export const PageObjListHeader: React.FC = ({ template, toggleExpand, isExpanded, setActivePanel }) => { const state = useSelector((state) => state) as RootState; const pageObjects = useSelector(selectPageObjects); const locatorsToGenerate = useSelector(selectLocatorsToGenerate); From 82bbbc89494fd43056db4608e17751b8b91f6e22 Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Fri, 18 Aug 2023 20:04:59 +0200 Subject: [PATCH 03/11] final working version --- src/app/App.tsx | 13 ++++++-- src/features/pageObjects/PageObjectPage.tsx | 9 ++++-- .../pageObjects/components/PageObjList.tsx | 31 +++++++++---------- .../components/PageObjListHeader.tsx | 2 +- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/app/App.tsx b/src/app/App.tsx index d0ff7146..41d73743 100644 --- a/src/app/App.tsx +++ b/src/app/App.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { Provider as ReduxProvider, useDispatch, useSelector } from "react-redux"; import "antd/dist/antd.less"; @@ -8,6 +8,7 @@ import Layout, { Content, Header } from "antd/lib/layout/layout"; import { Backdrop } from "./components/Backdrop"; import { StatusBar } from "./components/StatusBar"; import { SeveralTabsWarning } from "./components/SeveralTabsWarning"; +import { HttpEndpoint, request } from "../services/backend"; import { checkSession, initLocatorSocketController } from "./utils/appUtils"; import { selectCurrentPage } from "./main.selectors"; import { RootState, store } from "./store/store"; @@ -24,6 +25,8 @@ import { OnboardingProvider } from "../features/onboarding/OnboardingProvider"; import { isPageObjectPage } from "./utils/heplers"; const App = () => { + const [jdiTemplate, setJdiTemplate] = useState(undefined); + const [vividusTemplate, setVividusTemplate] = useState(undefined); const backendAvailable = useSelector((state: RootState) => state.main.backendAvailable); const xpathConfig = useSelector((state: RootState) => state.main.xpathConfig); const currentPage = useSelector(selectCurrentPage); @@ -41,14 +44,20 @@ const App = () => { }, []); useEffect(() => { + const fetchTemplates = async () => { + setJdiTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE)); + setVividusTemplate(await request.getBlob(HttpEndpoint.DOWNLOAD_TEMPLATE_VIVIDUS)); + }; + if (backendAvailable === BackendStatus.Accessed) { + fetchTemplates(); initLocatorSocketController(xpathConfig); } }, [backendAvailable]); const renderPage = () => { const { page } = currentPage; - return isPageObjectPage(page) ? : ; + return isPageObjectPage(page) ? : ; }; return ( diff --git a/src/features/pageObjects/PageObjectPage.tsx b/src/features/pageObjects/PageObjectPage.tsx index d95e10f3..264cfe81 100644 --- a/src/features/pageObjects/PageObjectPage.tsx +++ b/src/features/pageObjects/PageObjectPage.tsx @@ -1,10 +1,15 @@ import React from "react"; import { PageObjList } from "./components/PageObjList"; -export const PageObjectPage: React.FC = () => { +interface Props { + jdiTemplate?: Blob; + vividusTemplate?: Blob; +} + +export const PageObjectPage: React.FC = (props) => { return (
- +
); }; diff --git a/src/features/pageObjects/components/PageObjList.tsx b/src/features/pageObjects/components/PageObjList.tsx index a11dac03..f5c46ed7 100644 --- a/src/features/pageObjects/components/PageObjList.tsx +++ b/src/features/pageObjects/components/PageObjList.tsx @@ -20,10 +20,14 @@ import { PageObjectId } from "../types/pageObjectSlice.types"; import { ElementLibrary } from "../../locators/types/generationClasses.types"; import { PageType } from "../../../app/types/mainSlice.types"; import { selectConfirmedLocators } from "../../locators/selectors/locatorsFiltered.selectors"; -import { request, HttpEndpoint } from "../../../services/backend"; import { FrameworkType } from "../../../common/types/common"; -export const PageObjList: React.FC = () => { +interface Props { + jdiTemplate?: Blob; + vividusTemplate?: Blob; +} + +export const PageObjList: React.FC = ({ jdiTemplate, vividusTemplate }) => { const DEFAULT_ACTIVE_KEY = "0"; const state = useSelector((state) => state); // due to antd types: onChange?: (key: string | string[]) => void; @@ -33,26 +37,12 @@ export const PageObjList: React.FC = () => { const currentPageObject2 = useSelector(selectCurrentPageObject); const pageObjects = useSelector(selectPageObjects); const [activePanel, setActivePanel] = useState([DEFAULT_ACTIVE_KEY]); - const [template, setTemplate] = useState(undefined); const contentRef = useRef(null); useNotifications(contentRef?.current); const isExpanded = !!size(activePanel); - const fetchTemplate = async (framework: FrameworkType) => { - const targetTemplate = - framework === FrameworkType.Vividus ? HttpEndpoint.DOWNLOAD_TEMPLATE_VIVIDUS : HttpEndpoint.DOWNLOAD_TEMPLATE; - setTemplate(await request.getBlob(targetTemplate)); - }; - - useEffect(() => { - currentPageObject2 && fetchTemplate(currentPageObject2.framework); - }, [currentPageObject2?.framework]); - - console.log("👽"); - console.log(template); - useEffect(() => { if (currentPageObject) { setActivePanel([currentPageObject]); @@ -98,7 +88,14 @@ export const PageObjList: React.FC = () => { return (
- +
{size(pageObjects) ? ( diff --git a/src/features/pageObjects/components/PageObjListHeader.tsx b/src/features/pageObjects/components/PageObjListHeader.tsx index db3a4ee2..b2fb19eb 100644 --- a/src/features/pageObjects/components/PageObjListHeader.tsx +++ b/src/features/pageObjects/components/PageObjListHeader.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from "react"; +import React, { useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { Button, Modal, Row, Space, Tooltip } from "antd"; import { CaretDown, Plus, Trash } from "phosphor-react"; From 40404cbe2fe6c71b27e05e24e4a6e32ab1171024 Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Fri, 18 Aug 2023 20:14:34 +0200 Subject: [PATCH 04/11] cleanup --- src/features/pageObjects/components/PageObjGenerationBar.tsx | 2 +- src/features/pageObjects/components/PageObjListHeader.tsx | 2 -- src/features/pageObjects/utils/projectTemplate.ts | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/features/pageObjects/components/PageObjGenerationBar.tsx b/src/features/pageObjects/components/PageObjGenerationBar.tsx index 05141ad4..4f7b8899 100644 --- a/src/features/pageObjects/components/PageObjGenerationBar.tsx +++ b/src/features/pageObjects/components/PageObjGenerationBar.tsx @@ -97,7 +97,7 @@ export const PageObjGenerationBar: React.FC = ({ pageObj, library, url }) const currentPageObject = useSelector(selectCurrentPageObject); const { isOpen: isOnboardingOpen } = useContext(OnboardingContext); - const handleGenerate = async () => { + const handleGenerate = () => { dispatch(setHideUnadded({ id: pageObj, hideUnadded: false })); dispatch(identifyElements({ library, pageObj })); }; diff --git a/src/features/pageObjects/components/PageObjListHeader.tsx b/src/features/pageObjects/components/PageObjListHeader.tsx index b2fb19eb..e1aaf229 100644 --- a/src/features/pageObjects/components/PageObjListHeader.tsx +++ b/src/features/pageObjects/components/PageObjListHeader.tsx @@ -39,8 +39,6 @@ export const PageObjListHeader: React.FC = ({ template, toggleExpand, isE const handleDownload = () => { dispatch(pushNotification({ action: { type: "downloadTemplate" } })); - console.log("🤯"); - console.log(template); if (template) generateAndDownloadZip(state, template); }; diff --git a/src/features/pageObjects/utils/projectTemplate.ts b/src/features/pageObjects/utils/projectTemplate.ts index a84b8158..8ff8c436 100644 --- a/src/features/pageObjects/utils/projectTemplate.ts +++ b/src/features/pageObjects/utils/projectTemplate.ts @@ -36,7 +36,6 @@ const editTestPropertiesFile = (newZip: JSZip, po: PageObject) => const editMySiteFile = (newZip: JSZip, po: PageObject, instanceName: string) => { if (isVividusFramework(po.framework)) return; - // const path = isVividusFramework(po.framework) ? PAGES_PROPERTIES_PATH : MY_SITE_PATH; newZip .file(MY_SITE_PATH)! .async("string") From c6220823aa58e45a0ac64a96cc139b02d031161e Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Fri, 18 Aug 2023 20:19:13 +0200 Subject: [PATCH 05/11] better naming --- src/features/pageObjects/components/PageObjList.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/features/pageObjects/components/PageObjList.tsx b/src/features/pageObjects/components/PageObjList.tsx index 587ef6a6..53244fa0 100644 --- a/src/features/pageObjects/components/PageObjList.tsx +++ b/src/features/pageObjects/components/PageObjList.tsx @@ -32,10 +32,10 @@ const DEFAULT_ACTIVE_KEY = "0"; export const PageObjList: React.FC = ({ jdiTemplate, vividusTemplate }) => { const state = useSelector((state) => state); // due to antd types: onChange?: (key: string | string[]) => void; - const currentPageObject = useSelector((state: RootState): string | undefined => + const currentPageObjectIndex = useSelector((state: RootState): string | undefined => state.pageObject.present.currentPageObject?.toString() ); - const currentPageObject2 = useSelector(selectCurrentPageObject); + const currentPageObject = useSelector(selectCurrentPageObject); const pageObjects = useSelector(selectPageObjects); const [activePanel, setActivePanel] = useState([DEFAULT_ACTIVE_KEY]); @@ -45,12 +45,12 @@ export const PageObjList: React.FC = ({ jdiTemplate, vividusTemplate }) = const isExpanded = !!size(activePanel); useEffect(() => { - if (currentPageObject) { - setActivePanel([currentPageObject]); + if (currentPageObjectIndex) { + setActivePanel([currentPageObjectIndex]); } else { setActivePanel([DEFAULT_ACTIVE_KEY]); } - }, [currentPageObject]); + }, [currentPageObjectIndex]); const renderLocators = (elements: LocatorType[], library: ElementLibrary) => { if (size(elements)) { @@ -91,7 +91,7 @@ export const PageObjList: React.FC = ({ jdiTemplate, vividusTemplate }) =
Date: Fri, 18 Aug 2023 20:25:01 +0200 Subject: [PATCH 06/11] better constatnts naming --- .../pageObjects/utils/projectTemplate.ts | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/features/pageObjects/utils/projectTemplate.ts b/src/features/pageObjects/utils/projectTemplate.ts index 8ff8c436..e5ecf222 100644 --- a/src/features/pageObjects/utils/projectTemplate.ts +++ b/src/features/pageObjects/utils/projectTemplate.ts @@ -11,15 +11,22 @@ import { editPomContent } from "./templateFileContent"; import { selectConfirmedLocators } from "../../locators/selectors/locatorsFiltered.selectors"; import { FrameworkType } from "../../../common/types/common"; -const PAGES_PROPERTIES_PATH = "src/main/resources/properties/suite/web_app/pages.properties"; -const SITE_PROPERTIES_PATH = "src/main/resources/properties/suite/web_app/site.properties"; -const MY_SITE_PATH = "src/main/java/site/MySite.java"; -const EXAMPLE_STRING = "// ADD SITE PAGES WITH URLS"; +const VIVIDUS = { + PAGES_PROPERTIES_PATH: "src/main/resources/properties/suite/web_app/pages.properties", + SITE_PROPERTIES_PATH: "src/main/resources/properties/suite/web_app/site.properties", +}; + +const JDI = { + MY_SITE_PATH: "src/main/java/site/MySite.java", + EXAMPLE_STRING: "// ADD SITE PAGES WITH URLS", +}; const isVividusFramework = (framework: FrameworkType) => framework === FrameworkType.Vividus; const generatePoFile = (newZip: JSZip, framework: FrameworkType, page: { pageCode: string; title: string }) => { - const path = isVividusFramework(framework) ? PAGES_PROPERTIES_PATH : `src/main/java/site/pages/${page.title}.java`; + const path = isVividusFramework(framework) + ? VIVIDUS.PAGES_PROPERTIES_PATH + : `src/main/java/site/pages/${page.title}.java`; newZip.file(path, page.pageCode, { binary: false }); }; @@ -37,18 +44,18 @@ const editTestPropertiesFile = (newZip: JSZip, po: PageObject) => const editMySiteFile = (newZip: JSZip, po: PageObject, instanceName: string) => { if (isVividusFramework(po.framework)) return; newZip - .file(MY_SITE_PATH)! + .file(JDI.MY_SITE_PATH)! .async("string") .then((content) => { if (content.includes(instanceName)) instanceName = `${instanceName}1`; const urlSearchParams = po.search; const testUrl = urlSearchParams.length ? po.pathname + urlSearchParams : po.pathname; const newContent = content.replace( - EXAMPLE_STRING, - `${EXAMPLE_STRING}\n @Url("${testUrl}")\n public static ${po.name} ${instanceName}; + JDI.EXAMPLE_STRING, + `${JDI.EXAMPLE_STRING}\n @Url("${testUrl}")\n public static ${po.name} ${instanceName}; ` ); - return newZip.file(MY_SITE_PATH, newContent, { binary: true }); + return newZip.file(JDI.MY_SITE_PATH, newContent, { binary: true }); }); }; @@ -106,7 +113,7 @@ export const generateAndDownloadZip = async (state: RootState, template: Blob) = await editTestsFile(newZip, po, instanceName); await editPomFile(newZip, po); } else { - newZip.file(SITE_PROPERTIES_PATH, `variables.siteURL=${po.url}`, { binary: true }); + newZip.file(VIVIDUS.SITE_PROPERTIES_PATH, `variables.siteURL=${po.url}`, { binary: true }); } } From 360fe9a74d76ef2b92d93826b8da37462494c366 Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Mon, 21 Aug 2023 12:51:15 +0200 Subject: [PATCH 07/11] codacy issues --- src/features/pageObjects/utils/pageObject.ts | 14 ++++++++++---- .../pageObjects/utils/pageObjectTemplate.ts | 7 +++++-- .../utils/pageObjectTemplatePerfTest.ts | 5 ++++- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/features/pageObjects/utils/pageObject.ts b/src/features/pageObjects/utils/pageObject.ts index 077cfbb4..84860fb6 100644 --- a/src/features/pageObjects/utils/pageObject.ts +++ b/src/features/pageObjects/utils/pageObject.ts @@ -125,15 +125,21 @@ export const getPageAttributes = async () => { }); }; -export const getPage = async (locators: Array, pageObject: PageObject) => { +export const getPage = async ( + locators: Array, + pageObject: PageObject +): Promise<{ pageCode: string; title: string }> => { return pageObjectTemplate(locators, pageObject); }; -export const getPagePerfTest = async (locators: Array, pageObject: PageObject) => { +export const getPagePerfTest = async ( + locators: Array, + pageObject: PageObject +): Promise<{ pageCode: string; name: string }> => { return pageObjectTemplatePerfTest(locators, pageObject); }; -export const generatePageObject = async (elements: Array, pageObject: PageObject) => { +export const generatePageObject = async (elements: Array, pageObject: PageObject): Promise => { const page = await getPage(elements, pageObject); const blob = new Blob([page.pageCode], { type: "text/plain;charset=utf-8", @@ -141,7 +147,7 @@ export const generatePageObject = async (elements: Array, pageObject: P saveAs(blob, `${page.title}.java`); }; -export const generatePageObjectPerfTest = async (elements: Array, pageObject: PageObject) => { +export const generatePageObjectPerfTest = async (elements: Array, pageObject: PageObject): Promise => { const page = await getPagePerfTest(elements, pageObject); const blob = new Blob([page.pageCode], { type: "text/plain;charset=utf-8", diff --git a/src/features/pageObjects/utils/pageObjectTemplate.ts b/src/features/pageObjects/utils/pageObjectTemplate.ts index f325fdf0..fad55b90 100644 --- a/src/features/pageObjects/utils/pageObjectTemplate.ts +++ b/src/features/pageObjects/utils/pageObjectTemplate.ts @@ -20,7 +20,7 @@ export const getClassName = (title: string) => { return className; }; -export const vividusTemplate = (locators: Locator[], pageObject: PageObject) => { +export const vividusTemplate = (locators: Locator[], pageObject: PageObject): { pageCode: string; title: string } => { let pageCode = `variables.${pageObject.name}.url=(${pageObject.pathname})\n`; locators.forEach((it) => { @@ -32,7 +32,10 @@ export const vividusTemplate = (locators: Locator[], pageObject: PageObject) => return { pageCode, title: pageObject.name }; }; -export const pageObjectTemplate = (locators: Locator[], pageObject: PageObject) => { +export const pageObjectTemplate = ( + locators: Locator[], + pageObject: PageObject +): { pageCode: string; title: string } => { if (pageObject.framework === FrameworkType.Vividus) { return vividusTemplate(locators, pageObject); } diff --git a/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts b/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts index 377fe5de..2d6cc214 100644 --- a/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts +++ b/src/features/pageObjects/utils/pageObjectTemplatePerfTest.ts @@ -1,7 +1,10 @@ import { Locator } from "../../locators/types/locator.types"; import { PageObject } from "../types/pageObjectSlice.types"; -export const pageObjectTemplatePerfTest = (locators: Locator[], pageObject: PageObject) => { +export const pageObjectTemplatePerfTest = ( + locators: Locator[], + pageObject: PageObject +): { pageCode: string; name: string } => { const locatorsCode = locators.map((loc) => ` this.${loc.name} = new ${loc.type}("${loc.locator.output}", page)`); const pageCode = `const Page = require("../../core/page"); From d1dcaf7625e775a5540c29c092beedf62ef9b7d2 Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Mon, 21 Aug 2023 18:33:10 +0200 Subject: [PATCH 08/11] review fixes --- .../pageObjects/components/PageObjList.tsx | 17 ++++++----- .../pageObjects/components/PageObjMenu.tsx | 11 ++++---- .../pageObjects/utils/pageObjectTemplate.ts | 28 +++++++++---------- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/features/pageObjects/components/PageObjList.tsx b/src/features/pageObjects/components/PageObjList.tsx index 53244fa0..1e4e17de 100644 --- a/src/features/pageObjects/components/PageObjList.tsx +++ b/src/features/pageObjects/components/PageObjList.tsx @@ -87,11 +87,13 @@ export const PageObjList: React.FC = ({ jdiTemplate, vividusTemplate }) = } }; + const template = currentPageObject?.framework === FrameworkType.Vividus ? vividusTemplate : jdiTemplate; + return (
= ({ jdiTemplate, vividusTemplate }) = onChange={(key) => setActivePanel([...key])} > {pageObjects.map((pageObject) => { - const elements = selectConfirmedLocators(state as RootState, pageObject.id); - const isPageObjectNotEmpty = !!size(pageObject.locators); + const { id, locators, url, name, library } = pageObject; + const elements = selectConfirmedLocators(state as RootState, id); + const isPageObjectNotEmpty = !!size(locators); return ( triggerNode} align={{ offset: [-28, 0] }} > - {pageObject.name} + {name} } extra={ @@ -139,7 +142,7 @@ export const PageObjList: React.FC = ({ jdiTemplate, vividusTemplate }) = } > - {renderContent(pageObject.id, pageObject.url, elements, pageObject.library, isPageObjectNotEmpty)} + {renderContent(id, url, elements, library, isPageObjectNotEmpty)} ); })} diff --git a/src/features/pageObjects/components/PageObjMenu.tsx b/src/features/pageObjects/components/PageObjMenu.tsx index 94a81452..2a6f9d57 100644 --- a/src/features/pageObjects/components/PageObjMenu.tsx +++ b/src/features/pageObjects/components/PageObjMenu.tsx @@ -32,6 +32,7 @@ interface Props { export const PageObjMenu: React.FC = ({ pageObject, elements }) => { const dispatch = useDispatch(); + const { id, locators, name } = pageObject; const [isRenameModalOpen, setIsRenameModalOpen] = useState(false); @@ -41,7 +42,7 @@ export const PageObjMenu: React.FC = ({ pageObject, elements }) => { const handleRename = () => setIsRenameModalOpen(true); const handleRemove = () => { - dispatch(removePageObject(pageObject.id)); + dispatch(removePageObject(id)); dispatch(removeLocators(locatorIds)); }; @@ -58,7 +59,7 @@ export const PageObjMenu: React.FC = ({ pageObject, elements }) => { }; const handleEdit = () => { - dispatch(setCurrentPageObj(pageObject.id)); + dispatch(setCurrentPageObj(id)); dispatch(checkLocatorsValidity()); // create thunk }; @@ -83,7 +84,7 @@ export const PageObjMenu: React.FC = ({ pageObject, elements }) => { disabled={isOnboardingOpen} align={{ offset: [15, 0] }} trigger={["click"]} - menu={getMenuItems(pageObject, pageObject.locators, elements)} + menu={getMenuItems(pageObject, locators, elements)} getPopupContainer={(triggerNode) => triggerNode} destroyPopupOnHide > @@ -99,8 +100,8 @@ export const PageObjMenu: React.FC = ({ pageObject, elements }) => {
); diff --git a/src/features/pageObjects/utils/pageObjectTemplate.ts b/src/features/pageObjects/utils/pageObjectTemplate.ts index fad55b90..a1bf8d42 100644 --- a/src/features/pageObjects/utils/pageObjectTemplate.ts +++ b/src/features/pageObjects/utils/pageObjectTemplate.ts @@ -21,34 +21,34 @@ export const getClassName = (title: string) => { }; export const vividusTemplate = (locators: Locator[], pageObject: PageObject): { pageCode: string; title: string } => { - let pageCode = `variables.${pageObject.name}.url=(${pageObject.pathname})\n`; + const { name, pathname, locatorType } = pageObject; + let pageCode = `variables.${name}.url=(${pathname})\n`; locators.forEach((it) => { - const currentLocatorType = _.camelCase(it.locatorType || pageObject.locatorType || LocatorType.xPath); + const currentLocatorType = _.camelCase(it.locatorType || locatorType || LocatorType.xPath); // @ts-ignore - pageCode += `variables.${pageObject.name}.${it.type}.${it.name}=By.${currentLocatorType}(${it.locator[currentLocatorType]})\n`; + pageCode += `variables.${name}.${it.type}.${it.name}=By.${currentLocatorType}(${it.locator[currentLocatorType]})\n`; }); - return { pageCode, title: pageObject.name }; + return { pageCode, title: name }; }; export const pageObjectTemplate = ( locators: Locator[], pageObject: PageObject ): { pageCode: string; title: string } => { - if (pageObject.framework === FrameworkType.Vividus) { + const { framework, name: className, library } = pageObject; + + if (framework === FrameworkType.Vividus) { return vividusTemplate(locators, pageObject); } - const className = pageObject.name; const locatorsCode = locators.map((loc) => { const locatorEscaped = loc.locator.output?.replace(/\\/g, "\\\\").replace(/"/g, '\\"'); - return pageObject.framework === FrameworkType.Vividus - ? `variables.${className}.url=(${pageObject.pathname})` - : ` ${loc.annotationType}(${getLocatorPrefix( - loc.annotationType, - loc.locatorType - )}"${locatorEscaped}")\n public ${loc.type} ${loc.name};`; + return ` ${loc.annotationType}(${getLocatorPrefix( + loc.annotationType, + loc.locatorType + )}"${locatorEscaped}")\n public ${loc.type} ${loc.name};`; }); const hasFindByAnnotationType: boolean = hasAnnotationType(locators, AnnotationType.FindBy); @@ -64,7 +64,7 @@ import com.epam.jdi.light.elements.complex.dropdown.*; import com.epam.jdi.light.elements.complex.table.*; import com.epam.jdi.light.ui.html.elements.complex.*; ${ - pageObject.library === ElementLibrary.MUI + library === ElementLibrary.MUI ? ` import com.epam.jdi.light.material.elements.displaydata.*; import com.epam.jdi.light.material.elements.displaydata.table.*; @@ -80,7 +80,7 @@ import com.epam.jdi.light.material.elements.utils.*; ` : "" }${ - pageObject.library === ElementLibrary.Vuetify + library === ElementLibrary.Vuetify ? ` import com.epam.jdi.light.vuetify.elements.common.*; import com.epam.jdi.light.vuetify.elements.complex.*; From 28dc9f1b7049312017dd15999f3826a71f12618a Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Tue, 22 Aug 2023 13:35:40 +0200 Subject: [PATCH 09/11] added annotation type to vividus template --- src/features/pageObjects/utils/pageObjectTemplate.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/features/pageObjects/utils/pageObjectTemplate.ts b/src/features/pageObjects/utils/pageObjectTemplate.ts index a1bf8d42..a70b454f 100644 --- a/src/features/pageObjects/utils/pageObjectTemplate.ts +++ b/src/features/pageObjects/utils/pageObjectTemplate.ts @@ -21,13 +21,17 @@ export const getClassName = (title: string) => { }; export const vividusTemplate = (locators: Locator[], pageObject: PageObject): { pageCode: string; title: string } => { - const { name, pathname, locatorType } = pageObject; + const { name, pathname, annotationType, locatorType } = pageObject; let pageCode = `variables.${name}.url=(${pathname})\n`; locators.forEach((it) => { + const currentAnnotationType = it.annotationType || annotationType || AnnotationType.UI; const currentLocatorType = _.camelCase(it.locatorType || locatorType || LocatorType.xPath); - // @ts-ignore - pageCode += `variables.${name}.${it.type}.${it.name}=By.${currentLocatorType}(${it.locator[currentLocatorType]})\n`; + pageCode += `variables.${name}.${it.type}.${it.name}=By.${currentLocatorType}(${getLocatorPrefix( + currentAnnotationType, + currentLocatorType as LocatorType + // @ts-ignore + )}${it.locator[currentLocatorType]})\n`; }); return { pageCode, title: name }; From 267f7be49facb1c7880c2c2d9fc8edade292659e Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Tue, 22 Aug 2023 15:59:57 +0200 Subject: [PATCH 10/11] test for vividus template --- .../pageObjectMocks/pageObject.mock.js | 138 ++++++++++++++++++ src/__tests__/pageObject/pageObject.test.js | 21 ++- 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/src/__tests__/__mocks__/pageObjectMocks/pageObject.mock.js b/src/__tests__/__mocks__/pageObjectMocks/pageObject.mock.js index 4ea39e96..c4c3ed9f 100644 --- a/src/__tests__/__mocks__/pageObjectMocks/pageObject.mock.js +++ b/src/__tests__/__mocks__/pageObjectMocks/pageObject.mock.js @@ -206,6 +206,137 @@ export const locatorsWithFindBy = [ }, ]; +export const locatorsVividus = [ + { + element_id: "0057770603115098154872149076_0", + predicted_label: "label", + childs: ["1052464727115098158766915230"], + displayed: false, + jdnHash: "0057770603115098154872149076", + pageObj: 0, + elemName: "", + elemId: "", + elemText: "Simple Table", + elemAriaLabel: null, + locator: { + xPath: "//*[@index='3']//*[@index='4']/a", + fullXpath: "/html/body/div/div[1]/div/div[1]/div/div[1]/ul/li[3]/ul/li[4]/a", + cssSelector: '[index="\\33 "] [index="\\34 "] > a', + cssSelectorStatus: "SUCCESS", + xPathStatus: "SUCCESS", + output: '[index="\\33 "] [index="\\34 "] > a', + taskStatus: "SUCCESS", + }, + name: "simpleTable", + type: "Label", + parent_id: "", + children: [], + active: false, + generate: true, + annotationType: "@FindBy", + locatorType: "CSS selector", + }, + { + element_id: "0735357117115098156691382591_0", + predicted_label: "label", + childs: null, + displayed: false, + jdnHash: "0735357117115098156691382591", + pageObj: 0, + elemName: "", + elemId: "", + elemText: "User Table ", + elemAriaLabel: null, + locator: { + xPath: "//*[contains(text(), 'User Table ')]", + fullXpath: "/html/body/header/div/nav/ul[1]/li[3]/ul/li[6]/a", + cssSelector: '[role="menu"] > li:nth-child(6) > a', + cssSelectorStatus: "SUCCESS", + xPathStatus: "SUCCESS", + output: "//*[contains(text(), 'User Table ')]", + taskStatus: "SUCCESS", + }, + name: "userTable", + type: "Label", + parent_id: "", + children: [], + active: false, + locatorType: "xPath", + annotationType: "@FindBy", + library: "HTML5", + message: "", + isCustomName: true, + isCustomLocator: true, + generate: true, + }, + { + element_id: "0790139442115098150038335533_0", + predicted_label: "textarea", + childs: null, + displayed: false, + jdnHash: "0790139442115098150038335533", + pageObj: 0, + elemName: "", + elemId: "password", + elemText: "", + elemAriaLabel: null, + locator: { + xPath: "//*[@id='password']", + fullXpath: "/html/body/header/div/nav/ul[2]/li/div/form/div/div[2]/div/input", + cssSelector: "#password", + cssSelectorStatus: "SUCCESS", + xPathStatus: "SUCCESS", + output: "#password", + taskStatus: "SUCCESS", + }, + name: "password", + type: "TextArea", + parent_id: "", + children: [], + active: false, + locatorType: "CSS selector", + annotationType: "@UI", + library: "HTML5", + message: "", + isCustomName: true, + isCustomLocator: true, + generate: true, + }, + { + element_id: "0928942213115098152027249027_0", + predicted_label: "label", + childs: null, + displayed: false, + jdnHash: "0928942213115098152027249027", + pageObj: 0, + elemName: "", + elemId: "", + elemText: "Dates", + elemAriaLabel: null, + locator: { + xPath: "//a[contains(text(), 'Dates')]", + fullXpath: "/html/body/header/div/nav/ul[1]/li[3]/ul/li[2]/a", + cssSelector: '[role="menu"] > li:nth-child(2) > a', + cssSelectorStatus: "SUCCESS", + xPathStatus: "SUCCESS", + output: "//a[contains(text(), 'Dates')]", + taskStatus: "SUCCESS", + }, + name: "dates", + type: "Label", + parent_id: "", + children: [], + active: true, + locatorType: "xPath", + annotationType: "@UI", + library: "HTML5", + message: "", + isCustomName: true, + isCustomLocator: true, + generate: true, + }, +]; + export const pageObjectHTML = `package site.pages; import com.epam.jdi.light.elements.pageobjects.annotations.locators.*; @@ -321,3 +452,10 @@ public class HomePage extends WebPage { public badge badge; } `; + +export const pageObjectVividus = `variables.HomePage.url=(/jdi-light/index.html) +variables.HomePage.Label.simpleTable=By.cssSelector(xpath = [index="\\33 "] [index="\\34 "] > a) +variables.HomePage.Label.userTable=By.xPath(xpath = //*[contains(text(), 'User Table ')]) +variables.HomePage.TextArea.password=By.cssSelector(#password) +variables.HomePage.Label.dates=By.xPath(//a[contains(text(), 'Dates')]) +`; diff --git a/src/__tests__/pageObject/pageObject.test.js b/src/__tests__/pageObject/pageObject.test.js index c692765f..128e746c 100644 --- a/src/__tests__/pageObject/pageObject.test.js +++ b/src/__tests__/pageObject/pageObject.test.js @@ -5,6 +5,8 @@ import { pageObjectVuetify, pageObjectHTMLWithFindBy, getLocatorsByAnnotationType, + locatorsVividus, + pageObjectVividus, } from "../__mocks__/pageObjectMocks/pageObject.mock"; import { elementsWithoutNames } from "../__mocks__/pageObjectMocks/elementsWithoutNames"; import { elementsWithNames } from "../__mocks__/pageObjectMocks/elementsWithNames"; @@ -13,7 +15,7 @@ import { ElementLibrary } from "../../features/locators/types/generationClasses. import { pageObjectTemplate } from "../../features/pageObjects/utils/pageObjectTemplate"; import { createLocatorNames } from "../../features/pageObjects/utils/pageObject"; import { getClassName } from "../../features/pageObjects/utils/pageObjectTemplate"; -import { AnnotationType } from "../../common/types/common"; +import { AnnotationType, LocatorType } from "../../common/types/common"; const templateTestData = [ { @@ -51,6 +53,17 @@ const templateTestDataWithFindBy = { output: pageObjectHTMLWithFindBy, }; +const templateTestDataVividus = { + pageObject: { + framework: "Vividus", + library: "HTML", + name: "HomePage", + pathname: "/jdi-light/index.html", + locatorType: LocatorType.cssSelector, + }, + output: pageObjectVividus, +}; + describe("page object code generation", () => { templateTestData.forEach(({ pageObject, output }) => { test(`page object generated with ${pageObject.library}`, () => { @@ -66,6 +79,12 @@ describe("page object code generation", () => { }); }); + test("generate page object template for Vividus", () => { + const { pageObject, output } = templateTestDataVividus; + const page = pageObjectTemplate(locatorsVividus, pageObject); + expect(page.pageCode).toBe(output); + }); + describe("pageObjectTemplate should return pageObjectHTML with FindBy import", () => { const locators = getLocatorsByAnnotationType(AnnotationType.FindBy); test(`when page object generated with ${templateTestDataWithFindBy.pageObject.library} and locators has Annotation Type === 'FindBy'`, () => { From ce075800fecdf141da3027cdd100b3a449d2e48c Mon Sep 17 00:00:00 2001 From: Igor Kostrubin Date: Tue, 22 Aug 2023 16:01:35 +0200 Subject: [PATCH 11/11] version updated --- manifest.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manifest.json b/manifest.json index 3914342b..021f3911 100644 --- a/manifest.json +++ b/manifest.json @@ -3,7 +3,7 @@ "name": "JDN", "description": "JDN – helps Test Automation Engineer to create Page Objects in the test automation framework and speed up test development", "devtools_page": "index.html", - "version": "3.13.561", + "version": "3.13.562", "icons": { "128": "icon128.png" }, diff --git a/package.json b/package.json index c6e745af..3ed9ed42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jdn-ai-chrome-extension", - "version": "3.13.561", + "version": "3.13.562", "description": "jdn-ai chrome extension", "scripts": { "start": "webpack --watch --env devenv",