diff --git a/e2e/content-services/document-list/document-list-component.e2e.ts b/e2e/content-services/document-list/document-list-component.e2e.ts index b51c9779455..d4ec363ebfb 100644 --- a/e2e/content-services/document-list/document-list-component.e2e.ts +++ b/e2e/content-services/document-list/document-list-component.e2e.ts @@ -17,11 +17,11 @@ import { ContentServicesPage } from '../../core/pages/content-services.page'; import { browser } from 'protractor'; -import { createApiService, LoginPage, StringUtil, UploadActions, UsersActions, ViewerPage } from '@alfresco/adf-testing'; +import { createApiService, LoginPage, StringUtil, UploadActions, UserModel, UsersActions, ViewerPage } from '@alfresco/adf-testing'; import { FileModel } from '../../models/ACS/file.model'; -import * as moment from 'moment'; import { NavigationBarPage } from '../../core/pages/navigation-bar.page'; import { NodeEntry } from '@alfresco/js-api'; +import { DateFnsUtils } from '../../../lib/core/src/lib/common/utils/date-fns-utils'; describe('Document List Component', () => { let uploadedFolder: NodeEntry; @@ -35,9 +35,9 @@ describe('Document List Component', () => { const usersActions = new UsersActions(apiService); const uploadActions = new UploadActions(apiService); - let acsUser = null; - let testFileNode: any; - let pdfBFileNode: any; + let acsUser: UserModel = null; + let testFileNode: NodeEntry; + let pdfBFileNode: NodeEntry; afterEach(async () => { await apiService.loginWithProfile('admin'); @@ -78,7 +78,10 @@ describe('Document List Component', () => { location: browser.params.resources.Files.ADF_DOCUMENTS.PDF_B.file_path }); - let pdfUploadedNode; let docxUploadedNode; let timeAgoUploadedNode; let mediumDateUploadedNode; + let pdfUploadedNode: NodeEntry; + let docxUploadedNode: NodeEntry; + let timeAgoUploadedNode: NodeEntry; + let mediumDateUploadedNode: NodeEntry; beforeAll(async () => { /* cspell:disable-next-line */ @@ -146,7 +149,7 @@ describe('Document List Component', () => { it('[C279929] Should be able to display the date with date type', async () => { await apiService.login(acsUser.username, acsUser.password); mediumDateUploadedNode = await uploadActions.uploadFile(mediumFileModel.location, mediumFileModel.name, '-my-'); - const createdDate = moment(mediumDateUploadedNode.createdAt).format('ll'); + const createdDate = DateFnsUtils.formatDate(mediumDateUploadedNode.entry.createdAt, 'll'); await contentServicesPage.goToDocumentList(); await contentServicesPage.enableMediumTimeFormat(); const dateValue = await contentServicesPage.getColumnValueForRow(mediumFileModel.name, 'Created'); diff --git a/e2e/process-services-cloud/process/process-header-cloud.e2e.ts b/e2e/process-services-cloud/process/process-header-cloud.e2e.ts index 3e1924d883e..cd96cb44717 100644 --- a/e2e/process-services-cloud/process/process-header-cloud.e2e.ts +++ b/e2e/process-services-cloud/process/process-header-cloud.e2e.ts @@ -21,8 +21,8 @@ import { ProcessCloudDemoPage } from './../pages/process-cloud-demo.page'; import { TasksCloudDemoPage } from './../pages/tasks-cloud-demo.page'; import { NavigationBarPage } from '../../core/pages/navigation-bar.page'; import CONSTANTS = require('../../util/constants'); -import * as moment from 'moment'; import { EditProcessFilterConfiguration } from './../config/edit-process-filter.config'; +import { DateFnsUtils } from '../../../lib/core/src/lib/common/utils/date-fns-utils'; describe('Process Header cloud component', () => { @@ -76,7 +76,7 @@ describe('Process Header cloud component', () => { runningProcess = await processInstancesService.createProcessInstance(simpleProcess.entry.key, simpleApp, { name: StringUtil.generateRandomString(), businessKey: 'test' }); - runningCreatedDate = moment(runningProcess.entry.startDate).format(formatDate); + runningCreatedDate = DateFnsUtils.formatDate(new Date(runningProcess.entry.startDate), formatDate); parentCompleteProcess = await processInstancesService.createProcessInstance(processparent.entry.key, subProcessApp); @@ -86,7 +86,7 @@ describe('Process Header cloud component', () => { childCompleteProcess = parentProcessInstance.list.entries[0]; - completedCreatedDate = moment(childCompleteProcess.entry.startDate).format(formatDate); + completedCreatedDate = DateFnsUtils.formatDate(new Date(childCompleteProcess.entry.startDate), formatDate); await loginSSOPage.login(testUser.username, testUser.password); await LocalStorageUtil.setConfigField('adf-edit-process-filter', JSON.stringify(editProcessFilterConfigFile)); diff --git a/e2e/process-services-cloud/task-list/task-header-cloud.e2e.ts b/e2e/process-services-cloud/task-list/task-header-cloud.e2e.ts index 547aeecc1b4..6856529b2cd 100644 --- a/e2e/process-services-cloud/task-list/task-header-cloud.e2e.ts +++ b/e2e/process-services-cloud/task-list/task-header-cloud.e2e.ts @@ -29,7 +29,7 @@ import { createApiService, import { browser } from 'protractor'; import { TasksCloudDemoPage } from './../pages/tasks-cloud-demo.page'; import { NavigationBarPage } from '../../core/pages/navigation-bar.page'; -import * as moment from 'moment'; +import { DateFnsUtils } from '../../../lib/core/src/lib/common/utils/date-fns-utils'; const isValueInvalid = (value: any): boolean => value === null || value === undefined; @@ -91,7 +91,7 @@ describe('Task Header cloud component', () => { const createdTaskId = await tasksService.createStandaloneTask(basicCreatedTaskName, simpleApp); await tasksService.claimTask(createdTaskId.entry.id, simpleApp); basicCreatedTask = await tasksService.getTask(createdTaskId.entry.id, simpleApp); - basicCreatedDate = moment(basicCreatedTask.entry.createdDate).format(formatDate); + basicCreatedDate = DateFnsUtils.formatDate(new Date(basicCreatedTask.entry.createdDate), formatDate); return createdTaskId; }; @@ -109,12 +109,12 @@ describe('Task Header cloud component', () => { completedTask = await createCompletedTask(); - completedCreatedDate = moment(completedTask.entry.createdDate).format(formatDate); - dueDate = moment(completedTask.entry.dueDate).format(dateTimeFormat); - completedEndDate = moment(completedTask.entry.endDate).format(formatDate); + completedCreatedDate = DateFnsUtils.formatDate(new Date(completedTask.entry.createdDate), formatDate); + dueDate = DateFnsUtils.formatDate(new Date(completedTask.entry.dueDate), dateTimeFormat); + completedEndDate = DateFnsUtils.formatDate(new Date(completedTask.entry.completedDate), formatDate); subTask = await createSubTask(createdTaskId); - subTaskCreatedDate = moment(subTask.entry.createdDate).format(formatDate); + subTaskCreatedDate = DateFnsUtils.formatDate(new Date(subTask.entry.createdDate), formatDate); await browser.sleep(3000); await loginSSOPage.login(testUser.username, testUser.password); diff --git a/e2e/process-services/process/process-instance-details.e2e.ts b/e2e/process-services/process/process-instance-details.e2e.ts index 51d15253850..85642fa4b94 100644 --- a/e2e/process-services/process/process-instance-details.e2e.ts +++ b/e2e/process-services/process/process-instance-details.e2e.ts @@ -22,8 +22,8 @@ import { NavigationBarPage } from '../../core/pages/navigation-bar.page'; import { ProcessServiceTabBarPage } from '../pages/process-service-tab-bar.page'; import { ProcessListPage } from '../pages/process-list.page'; import { ProcessDetailsPage } from '../pages/process-details.page'; -import * as moment from 'moment'; import { AppDefinitionRepresentation, ProcessInstanceRepresentation, ProcessInstancesApi } from '@alfresco/js-api'; +import { DateFnsUtils } from '../../../lib/core/src/lib/common/utils/date-fns-utils'; describe('Process Instance Details', () => { const app = browser.params.resources.Files.SIMPLE_APP_WITH_USER_FORM; @@ -76,6 +76,6 @@ describe('Process Instance Details', () => { it('[C307031] Should display the created date in the default format', async () => { await processDetailsPage.checkProcessHeaderDetailsAreVisible(); - await expect(await processDetailsPage.getCreated()).toEqual(moment(process.started).format(PROCESS_DATE_FORMAT)); + await expect(await processDetailsPage.getCreated()).toEqual(DateFnsUtils.formatDate(process.started, PROCESS_DATE_FORMAT)); }); }); diff --git a/e2e/process-services/tasks/info-drawer.e2e.ts b/e2e/process-services/tasks/info-drawer.e2e.ts index 79f8cefa4bd..5199f9654c2 100644 --- a/e2e/process-services/tasks/info-drawer.e2e.ts +++ b/e2e/process-services/tasks/info-drawer.e2e.ts @@ -33,7 +33,7 @@ import { ProcessServiceTabBarPage } from './../pages/process-service-tab-bar.pag import { ProcessFiltersPage } from './../pages/process-filters.page'; import { infoDrawerConfiguration } from './../config/task.config'; import CONSTANTS = require('../../util/constants'); -import * as moment from 'moment'; +import { DateFnsUtils } from '../../../lib/core/src/lib/common/utils/date-fns-utils'; describe('Info Drawer', () => { @@ -161,7 +161,7 @@ describe('Info Drawer', () => { }); await taskPage.taskDetails().updateDueDate(); - await expect(await taskPage.taskDetails().getDueDate()).toEqual(moment('Aug 1, 2017').format(taskDetails.dateFormat)); + await expect(await taskPage.taskDetails().getDueDate()).toEqual(DateFnsUtils.formatDate(new Date('Aug 1, 2017'), taskDetails.dateFormat)); await taskPage.taskDetails().clickCompleteFormTask(); @@ -187,7 +187,7 @@ describe('Info Drawer', () => { it('[C260329] Task with no form', async () => { const name = StringUtil.generateRandomString(5); - await taskPage.createTask( { ...taskDetails, formName: '', name }); + await taskPage.createTask({ ...taskDetails, formName: '', name }); await taskPage.tasksListPage().getDataTable().waitTillContentLoaded(); await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.INV_TASKS); await taskPage.tasksListPage().checkContentIsDisplayed(name); @@ -204,7 +204,7 @@ describe('Info Drawer', () => { it('[C260320] Assign user to the task', async () => { const name = StringUtil.generateRandomString(5); - await taskPage.createTask( { ...taskDetails, formName: app.formName, name }); + await taskPage.createTask({ ...taskDetails, formName: app.formName, name }); await taskPage.tasksListPage().getDataTable().waitTillContentLoaded(); await taskPage.filtersPage().goToFilter(CONSTANTS.TASK_FILTERS.MY_TASKS); await taskPage.tasksListPage().checkContentIsDisplayed(name); @@ -337,15 +337,32 @@ describe('Info Drawer', () => { await taskPage.taskDetails().clickCompleteFormTask(); }); - async function shouldHaveInfoDrawerDetails({ description, status, priority, category, parentName, dateFormat, formName, fullName, dueDate }) { - await expect(await taskPage.taskDetails().getAssignee()).toEqual(fullName); - await expect(await taskPage.taskDetails().getDescription()).toEqual(description); - await expect(await taskPage.taskDetails().getStatus()).toEqual(status); - await expect(await taskPage.taskDetails().getPriority()).toEqual(priority); - await expect(await taskPage.taskDetails().getDueDate()).toEqual(dueDate !== 'No date' ? moment(dueDate).format(dateFormat) : 'No date'); - await expect(await taskPage.taskDetails().getCategory()).toEqual(category); - await expect(await taskPage.taskDetails().getParentName()).toEqual(parentName); - await expect(await taskPage.taskDetails().getCreated()).toEqual(moment(Date.now()).format(dateFormat)); - await taskPage.taskDetails().waitFormNameEqual(formName); + interface TaskDetailsProps { + description: string; + status: string; + priority: string; + category: string; + parentName: string; + dateFormat: string; + formName: string; + fullName: string; + dueDate: string; + } + + /** + * Validate the info drawer has expected values for the task details + * + * @param props task details properties to validate + */ + async function shouldHaveInfoDrawerDetails(props: TaskDetailsProps) { + await expect(await taskPage.taskDetails().getAssignee()).toEqual(props.fullName); + await expect(await taskPage.taskDetails().getDescription()).toEqual(props.description); + await expect(await taskPage.taskDetails().getStatus()).toEqual(props.status); + await expect(await taskPage.taskDetails().getPriority()).toEqual(props.priority); + await expect(await taskPage.taskDetails().getDueDate()).toEqual(props.dueDate !== 'No date' ? DateFnsUtils.formatDate(new Date(props.dueDate), props.dateFormat) : 'No date'); + await expect(await taskPage.taskDetails().getCategory()).toEqual(props.category); + await expect(await taskPage.taskDetails().getParentName()).toEqual(props.parentName); + await expect(await taskPage.taskDetails().getCreated()).toEqual(DateFnsUtils.formatDate(new Date().getTime(), props.dateFormat)); + await taskPage.taskDetails().waitFormNameEqual(props.formName); } }); diff --git a/lib/core/src/lib/common/utils/date-fns-utils.ts b/lib/core/src/lib/common/utils/date-fns-utils.ts index 33332246241..15937cdae62 100644 --- a/lib/core/src/lib/common/utils/date-fns-utils.ts +++ b/lib/core/src/lib/common/utils/date-fns-utils.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { format, parse } from 'date-fns'; +import { format, parse, parseISO } from 'date-fns'; import { ar, cs, da, de, enUS, es, fi, fr, it, ja, nb, nl, pl, ptBR, ru, sv, zhCN } from 'date-fns/locale'; export class DateFnsUtils { @@ -86,7 +86,8 @@ export class DateFnsUtils { static momentToDateFnsMap = { D: 'd', Y: 'y', - A: 'a' + A: 'a', + ll: 'PP' }; /** @@ -95,7 +96,8 @@ export class DateFnsUtils { static dateFnsToMomentMap = { d: 'D', y: 'Y', - a: 'A' + a: 'A', + PP: 'll' }; /** @@ -137,7 +139,10 @@ export class DateFnsUtils { * @param dateFormat - The date format string to use for formatting. * @returns The formatted date as a string. */ - static formatDate(date: number | Date, dateFormat: string): string { + static formatDate(date: number | Date | string, dateFormat: string): string { + if (typeof date === 'string') { + date = parseISO(date); + } return format(date, this.convertMomentToDateFnsFormat(dateFormat)); } diff --git a/lib/testing/src/lib/protractor/content-services/actions/upload.actions.ts b/lib/testing/src/lib/protractor/content-services/actions/upload.actions.ts index 3bc90f3aa81..719cdac032d 100644 --- a/lib/testing/src/lib/protractor/content-services/actions/upload.actions.ts +++ b/lib/testing/src/lib/protractor/content-services/actions/upload.actions.ts @@ -34,7 +34,7 @@ export class UploadActions { this.nodesApi = new NodesApi(apiService.getInstance()); } - async uploadFile(fileLocation, fileName, parentFolderId): Promise { + async uploadFile(fileLocation: fs.PathLike, fileName: string, parentFolderId: string): Promise { const file = fs.createReadStream(fileLocation); return this.uploadApi.uploadFile( @@ -50,7 +50,7 @@ export class UploadActions { ); } - async createEmptyFiles(emptyFileNames: string[], parentFolderId): Promise { + async createEmptyFiles(emptyFileNames: string[], parentFolderId: string): Promise { const filesRequest = []; // eslint-disable-next-line @typescript-eslint/prefer-for-of @@ -64,7 +64,7 @@ export class UploadActions { return this.nodesApi.createNode(parentFolderId, filesRequest as any, {}); } - async createFolder(folderName, parentFolderId): Promise { + async createFolder(folderName: string, parentFolderId: string): Promise { return this.nodesApi.createNode(parentFolderId, { name: folderName, nodeType: 'cm:folder'