From e5d96f087031d3abd4634c47c66968ef7705fced Mon Sep 17 00:00:00 2001 From: Vishal Date: Mon, 30 Oct 2023 18:09:23 +0530 Subject: [PATCH 1/3] Fix ListView improper data, case not displayed as a link, and add playwright tests --- src/components/templates/ListPage/index.tsx | 11 +- src/components/templates/ListView/index.tsx | 158 +++++++++--------- .../Digv2/LandingPages/LandingPages.spec.js | 100 +++++++++++ 3 files changed, 188 insertions(+), 81 deletions(-) create mode 100644 tests/e2e/Digv2/LandingPages/LandingPages.spec.js diff --git a/src/components/templates/ListPage/index.tsx b/src/components/templates/ListPage/index.tsx index 890988c28..5bfdfcdc8 100644 --- a/src/components/templates/ListPage/index.tsx +++ b/src/components/templates/ListPage/index.tsx @@ -1,13 +1,12 @@ -import React from "react"; -import PropTypes from "prop-types"; +import React from 'react'; +import PropTypes from 'prop-types'; import ListView from '../ListView'; export default function ListPage(props) { - - return ( - - ) + // special case for ListView - add in a prop + const listViewProps = { ...props, bInForm: false }; + return ; } ListPage.defaultProps = { diff --git a/src/components/templates/ListView/index.tsx b/src/components/templates/ListView/index.tsx index b8aef20f7..fb5307ae4 100644 --- a/src/components/templates/ListView/index.tsx +++ b/src/components/templates/ListView/index.tsx @@ -38,12 +38,11 @@ import { Radio } from '@material-ui/core'; import Checkbox from '@material-ui/core/Checkbox'; import { filterData } from '../../templates/SimpleTable/helpers'; import './ListView.css'; -import useInit from './hooks' +import useInit from './hooks'; import { getDateFormatInfo } from '../../../helpers/date-format-utils'; import { getCurrencyOptions } from '../../forms/Currency/currency-utils'; import { format } from '../../../helpers/formatters/'; - const SELECTION_MODE = { SINGLE: 'single', MULTI: 'multi' }; declare const PCore: any; @@ -59,8 +58,19 @@ let sortColumnId: any; const filterByColumns: Array = []; export default function ListView(props) { - const { getPConnect, bInForm } = props; - const { globalSearch, referenceList, rowClickAction, selectionMode, referenceType, payload, parameters, compositeKeys, showDynamicFields, presets } = props; + const { getPConnect, bInForm = true } = props; + const { + globalSearch, + referenceList, + /* rowClickAction, */ + selectionMode, + referenceType, + payload, + parameters, + compositeKeys, + showDynamicFields, + presets + } = props; const ref = useRef({}).current; const cosmosTableRef = useRef(); // List component context @@ -101,7 +111,7 @@ export default function ListView(props) { // Will contain the list of columns specific for an instance let columnList: any = useRef([]); - let dashboardFilterPayload: any ; + let dashboardFilterPayload: any; // Will be sent in the dashboardFilterPayload let selectParam: Array = []; @@ -235,7 +245,7 @@ export default function ListView(props) { field.type === 'Currency' || false; headerRow.disablePadding = false; - headerRow.label = presetFields[index].config.label; + headerRow.label = presetFields[index].config.label; if (colIndex > -1) { headerRow.classID = fields[colIndex].classID; } @@ -264,11 +274,12 @@ export default function ListView(props) { const record = arTableData?.length > 0 ? arTableData[0] : ''; if (typeof record === 'object' && !('pyGUID' in record) && !('pyID' in record)) { // eslint-disable-next-line no-console - console.error('pyGUID or pyID values are mandatory to select the required row from the list'); + console.error( + 'pyGUID or pyID values are mandatory to select the required row from the list' + ); } } const arReturn = arTableData?.map((data: any) => { - const row = data; return row; @@ -353,7 +364,7 @@ export default function ListView(props) { validFilter = true; /** Below are the 2 cases for- Text & Date-Range filter types where we'll construct filter data which will be sent in the dashboardFilterPayload * In Constellation DX Components, through Repeating Structures they might be using several APIs to do it. We're doing it here - */ + */ if (isDateRange) { const dateRelationalOp = filter?.AND ? 'AND' : 'OR'; dashboardFilterPayload.query.filter.filterConditions = { @@ -362,11 +373,13 @@ export default function ListView(props) { [`T${index++}`]: { ...filter[relationalOp][1].condition } }; if (dashboardFilterPayload.query.filter.logic) { - dashboardFilterPayload.query.filter.logic = `${dashboardFilterPayload.query.filter.logic} ${relationalOp} (T${ - index - 2 - } ${dateRelationalOp} T${index - 1})`; + dashboardFilterPayload.query.filter.logic = `${ + dashboardFilterPayload.query.filter.logic + } ${relationalOp} (T${index - 2} ${dateRelationalOp} T${index - 1})`; } else { - dashboardFilterPayload.query.filter.logic = `(T${index - 2} ${relationalOp} T${index - 1})`; + dashboardFilterPayload.query.filter.logic = `(T${index - 2} ${relationalOp} T${ + index - 1 + })`; } dashboardFilterPayload.query.select = selectParam; @@ -377,9 +390,9 @@ export default function ListView(props) { }; if (dashboardFilterPayload.query.filter.logic) { - dashboardFilterPayload.query.filter.logic = `${dashboardFilterPayload.query.filter.logic} ${relationalOp} T${ - index - 1 - }`; + dashboardFilterPayload.query.filter.logic = `${ + dashboardFilterPayload.query.filter.logic + } ${relationalOp} T${index - 1}`; } else { dashboardFilterPayload.query.filter.logic = `T${index - 1}`; } @@ -431,18 +444,20 @@ export default function ListView(props) { if (payload) { query = payload.query; } else if (fields?.length && meta.isQueryable) { - query = {select: fields}; + query = { select: fields }; } else if (dashboardFilterPayload) { query = dashboardFilterPayload.query; } const context = getPConnect().getContextName(); - return PCore.getDataPageUtils().getDataAsync( - referenceList, - context, - payload ? payload.dataViewParameters : dataViewParameters, - null, - query - ); + return !bInForm + ? PCore.getDataApiUtils().getData(referenceList, payload) + : PCore.getDataPageUtils().getDataAsync( + referenceList, + context, + payload ? payload.dataViewParameters : dataViewParameters, + null, + query + ); } const buildSelect = (fieldDefs, colId, patchQueryFields = [], compositeKeys = []) => { @@ -481,18 +496,22 @@ export default function ListView(props) { return listFields; }; - const addItemKeyInSelect = ( - fieldDefs, - itemKey, - select, - compositeKeys - ) => { + const addItemKeyInSelect = (fieldDefs, itemKey, select, compositeKeys) => { const elementFound = getField(fieldDefs, itemKey); - if (itemKey && !elementFound && Array.isArray(select) && !(compositeKeys !== null && compositeKeys?.length) && !select.find(sel => sel.field === itemKey)) { - return [...select, { - field: itemKey - }]; + if ( + itemKey && + !elementFound && + Array.isArray(select) && + !(compositeKeys !== null && compositeKeys?.length) && + !select.find(sel => sel.field === itemKey) + ) { + return [ + ...select, + { + field: itemKey + } + ]; } return select; @@ -514,7 +533,9 @@ export default function ListView(props) { async function fetchDataFromServer() { let bCallSetRowsColumns = true; const { fieldDefs, itemKey, patchQueryFields } = meta; - let listFields = fieldDefs ? buildSelect(fieldDefs, undefined, patchQueryFields, compositeKeys) : []; + let listFields = fieldDefs + ? buildSelect(fieldDefs, undefined, patchQueryFields, compositeKeys) + : []; listFields = addItemKeyInSelect(fieldDefs, itemKey, listFields, compositeKeys); const workListJSON = await fetchAllData(listFields); @@ -524,7 +545,7 @@ export default function ListView(props) { // this is an unresovled version of this.fields$, need unresolved, so can get the property reference const columnFields = componentConfig.presets[0].children[0].children; - const tableDataResults = workListJSON['data']; + const tableDataResults = !bInForm ? workListJSON['data'].data : workListJSON['data']; const myColumns = getHeaderCells(columnFields, fieldDefs, fields); @@ -637,17 +658,17 @@ export default function ListView(props) { }); } - function _rowClick(row: any) { - // eslint-disable-next-line sonarjs/no-small-switch - switch (rowClickAction) { - case 'openAssignment': - openAssignment(row); - break; + // function _rowClick(row: any) { + // // eslint-disable-next-line sonarjs/no-small-switch + // switch (rowClickAction) { + // case 'openAssignment': + // openAssignment(row); + // break; - default: - break; - } - } + // default: + // break; + // } + // } function openWork(row) { const { pxRefObjectKey } = row; @@ -855,7 +876,7 @@ export default function ListView(props) { } function _listViewClick(row, column) { - const name = column.id + const name = column.id; if (column.displayAsLink) { const { pxObjClass } = row; let { pzInsKey } = row; @@ -884,7 +905,6 @@ export default function ListView(props) { break; } } - } function _listTitle() { @@ -913,14 +933,12 @@ export default function ListView(props) { const index = response.findIndex(element => element[rowID] === value); const selectedRow = response[index]; compositeKeys.forEach(element => { - reqObj[element] = selectedRow[element] + reqObj[element] = selectedRow[element]; }); } else { reqObj[rowID] = value; } - getPConnect() - ?.getListActions?.() - ?.setSelectedRows([reqObj]); + getPConnect()?.getListActions?.()?.setSelectedRows([reqObj]); setSelectedValue(value); }; @@ -932,16 +950,14 @@ export default function ListView(props) { const index = response.findIndex(element => element[rowID] === value); const selectedRow = response[index]; compositeKeys.forEach(element => { - reqObj[element] = selectedRow[element] + reqObj[element] = selectedRow[element]; }); reqObj['$selected'] = checked; } else { reqObj[rowID] = value; reqObj['$selected'] = checked; } - getPConnect() - ?.getListActions() - ?.setSelectedRows([reqObj]); + getPConnect()?.getListActions()?.setSelectedRows([reqObj]); }; const processColumnValue = (column, value) => { @@ -954,14 +970,17 @@ export default function ListView(props) { case 'Date': case 'DateTime': theDateFormatInfo = getDateFormatInfo(); - theFormat = (type === 'DateTime') ? `${theDateFormatInfo.dateFormatStringLong} hh:mm a` : theDateFormatInfo.dateFormatStringLong; + theFormat = + type === 'DateTime' + ? `${theDateFormatInfo.dateFormatStringLong} hh:mm a` + : theDateFormatInfo.dateFormatStringLong; val = format(value, column.type, { format: theFormat }); - break; + break; case 'Currency': theCurrencyOptions = getCurrencyOptions(PCore?.getEnvironmentInfo()?.getLocale()); val = format(value, column.type, theCurrencyOptions); - break; + break; default: val = column.format && typeof value === 'number' ? column.format(value) : value; @@ -983,12 +1002,12 @@ export default function ListView(props) { @@ -1038,12 +1057,7 @@ export default function ListView(props) { .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map(row => { return ( - { - _rowClick(row); - }} - > + {arColumns.map(column => { const value = row[column.id]; return ( @@ -1117,12 +1131,7 @@ export default function ListView(props) { .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map(row => { return ( - { - _rowClick(row); - }} - > + {selectionMode === SELECTION_MODE.SINGLE && ( { + await page.setViewportSize({ width: 1720, height: 1080 }); + await page.goto('http://localhost:3502/portal', { waitUntil: 'networkidle' }); +}); + +test.describe('E2E test', () => { + test('should login, create case and run different test cases for My Work landing page', async ({ + page + }) => { + await common.Login( + config.config.apps.digv2.user.username, + config.config.apps.digv2.user.password, + page + ); + + /** Testing announcement banner presence */ + const announcementBanner = page.locator('h6:has-text("Announcements")'); + await expect(announcementBanner).toBeVisible(); + + /** Testing worklist presence */ + const worklist = page.locator('h6:has-text("My Worklist")'); + await expect(worklist).toBeVisible(); + + /** Creating a View Templates case-type */ + const viewTemplatesCase = page.locator('div[role="button"]:has-text("View Templates")'); + await viewTemplatesCase.click(); + + /** Extract caseID from CaseView */ + const caseID = await page.locator('#caseId').textContent(); + + /** Click on the `MyWork` landing page */ + const myWorkLandingPage = page.locator('div[role="button"]:has-text("My Work")'); + await myWorkLandingPage.click(); + + await page.locator('input[id="search"]').type(caseID); + + await page.locator(`button:has-text("${caseID}")`).click(); + + /** Testing that the Case View has rendered */ + expect(await page.locator('div[id="current-caseID"]').textContent()).toBe( + `DXIL-DIGV2-WORK ${caseID}` + ); + + /** Testing that the Assignment has opened */ + expect(page.locator('div[id="APP/PRIMARY_1/WORKAREA"]')).toBeVisible(); + }, 10000), + test('should login, create case and come back to Home landing page and run tests', async ({ + page + }) => { + await common.Login( + config.config.apps.digv2.user.username, + config.config.apps.digv2.user.password, + page + ); + + /** Testing announcement banner presence */ + const announcementBanner = page.locator('h6:has-text("Announcements")'); + await expect(announcementBanner).toBeVisible(); + + /** Testing worklist presence */ + const worklist = page.locator('h6:has-text("My Worklist")'); + await expect(worklist).toBeVisible(); + + /** Creating a View Templates case-type */ + const viewTemplatesCase = page.locator('div[role="button"]:has-text("View Templates")'); + await viewTemplatesCase.click(); + + /** Click on the `Home` landing page */ + const homeLandingPage = page.locator('div[role="button"]:has-text("Home")'); + await homeLandingPage.click(); + + /** Test whether Home has loaded as expected */ + await expect(announcementBanner).toBeVisible(); + + await expect(worklist).toBeVisible(); + }, 10000); +}); + +test.afterEach(async ({ page }) => { + const coverageData = await page.evaluate(() => window.__coverage__); + expect(coverageData, 'expect found Istanbul data: __coverage__').toBeTruthy(); + // coverage report + const report = await attachCoverageReport(coverageData, test.info(), { + outputDir: './test-reports/e2e/DigV2/LandingPages/LandingPages' + }); + // eslint-disable-next-line no-console + console.log(report.summary); + await page.close(); +}); From 6b9b972caf16724271f48c98fe8ed7bb25bf9b3e Mon Sep 17 00:00:00 2001 From: Vishal Date: Mon, 30 Oct 2023 18:47:43 +0530 Subject: [PATCH 2/3] Fix a condition --- src/components/templates/ListView/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/templates/ListView/index.tsx b/src/components/templates/ListView/index.tsx index fb5307ae4..d5f50caec 100644 --- a/src/components/templates/ListView/index.tsx +++ b/src/components/templates/ListView/index.tsx @@ -1014,7 +1014,7 @@ export default function ListView(props) { )} <> - {bInForm ? ( + {!bInForm ? ( From fee9e3e77a49fc22198697047ea7b49390afbd4e Mon Sep 17 00:00:00 2001 From: Vishal Date: Tue, 31 Oct 2023 00:14:32 +0530 Subject: [PATCH 3/3] Remove LandingPage tests as we aren't supposed to have all the tests in this repo --- .../Digv2/LandingPages/LandingPages.spec.js | 100 ------------------ 1 file changed, 100 deletions(-) delete mode 100644 tests/e2e/Digv2/LandingPages/LandingPages.spec.js diff --git a/tests/e2e/Digv2/LandingPages/LandingPages.spec.js b/tests/e2e/Digv2/LandingPages/LandingPages.spec.js deleted file mode 100644 index e3b6f12fd..000000000 --- a/tests/e2e/Digv2/LandingPages/LandingPages.spec.js +++ /dev/null @@ -1,100 +0,0 @@ -/* eslint-disable no-unused-expressions */ -/* eslint-disable no-template-curly-in-string */ -/* eslint-disable no-undef */ - -import { attachCoverageReport } from 'monocart-reporter'; - -const { test, expect } = require('@playwright/test'); - -const config = require('../../../config'); -const common = require('../../../common'); - -test.beforeEach(async ({ page }) => { - await page.setViewportSize({ width: 1720, height: 1080 }); - await page.goto('http://localhost:3502/portal', { waitUntil: 'networkidle' }); -}); - -test.describe('E2E test', () => { - test('should login, create case and run different test cases for My Work landing page', async ({ - page - }) => { - await common.Login( - config.config.apps.digv2.user.username, - config.config.apps.digv2.user.password, - page - ); - - /** Testing announcement banner presence */ - const announcementBanner = page.locator('h6:has-text("Announcements")'); - await expect(announcementBanner).toBeVisible(); - - /** Testing worklist presence */ - const worklist = page.locator('h6:has-text("My Worklist")'); - await expect(worklist).toBeVisible(); - - /** Creating a View Templates case-type */ - const viewTemplatesCase = page.locator('div[role="button"]:has-text("View Templates")'); - await viewTemplatesCase.click(); - - /** Extract caseID from CaseView */ - const caseID = await page.locator('#caseId').textContent(); - - /** Click on the `MyWork` landing page */ - const myWorkLandingPage = page.locator('div[role="button"]:has-text("My Work")'); - await myWorkLandingPage.click(); - - await page.locator('input[id="search"]').type(caseID); - - await page.locator(`button:has-text("${caseID}")`).click(); - - /** Testing that the Case View has rendered */ - expect(await page.locator('div[id="current-caseID"]').textContent()).toBe( - `DXIL-DIGV2-WORK ${caseID}` - ); - - /** Testing that the Assignment has opened */ - expect(page.locator('div[id="APP/PRIMARY_1/WORKAREA"]')).toBeVisible(); - }, 10000), - test('should login, create case and come back to Home landing page and run tests', async ({ - page - }) => { - await common.Login( - config.config.apps.digv2.user.username, - config.config.apps.digv2.user.password, - page - ); - - /** Testing announcement banner presence */ - const announcementBanner = page.locator('h6:has-text("Announcements")'); - await expect(announcementBanner).toBeVisible(); - - /** Testing worklist presence */ - const worklist = page.locator('h6:has-text("My Worklist")'); - await expect(worklist).toBeVisible(); - - /** Creating a View Templates case-type */ - const viewTemplatesCase = page.locator('div[role="button"]:has-text("View Templates")'); - await viewTemplatesCase.click(); - - /** Click on the `Home` landing page */ - const homeLandingPage = page.locator('div[role="button"]:has-text("Home")'); - await homeLandingPage.click(); - - /** Test whether Home has loaded as expected */ - await expect(announcementBanner).toBeVisible(); - - await expect(worklist).toBeVisible(); - }, 10000); -}); - -test.afterEach(async ({ page }) => { - const coverageData = await page.evaluate(() => window.__coverage__); - expect(coverageData, 'expect found Istanbul data: __coverage__').toBeTruthy(); - // coverage report - const report = await attachCoverageReport(coverageData, test.info(), { - outputDir: './test-reports/e2e/DigV2/LandingPages/LandingPages' - }); - // eslint-disable-next-line no-console - console.log(report.summary); - await page.close(); -});