From 1b98bed18f68817d9a54022f41ffe684cff96065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=9Awiderski?= Date: Mon, 15 Apr 2024 13:44:11 +0200 Subject: [PATCH] [ACS-7334] [E2E] Search filters - date - tests migrated to Playwright (#3770) * [ACS-7334] [E2E] Search filters - date - tests migrated to Playwright * [ACS-7334] sonar cloud fix 1 * [ACS-7334] review fix 1 * [ACS-7334] review fix 2 --- .../src/tests/search-filters-date.e2e.ts | 150 ++++++++++++++++++ .../search-filters-date.component.ts | 100 +++++++++++- .../src/page-objects/pages/search.page.ts | 19 ++- .../aca-playwright-shared/src/utils/utils.ts | 27 +++- 4 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 e2e/playwright/search/src/tests/search-filters-date.e2e.ts diff --git a/e2e/playwright/search/src/tests/search-filters-date.e2e.ts b/e2e/playwright/search/src/tests/search-filters-date.e2e.ts new file mode 100644 index 000000000..28edf8e48 --- /dev/null +++ b/e2e/playwright/search/src/tests/search-filters-date.e2e.ts @@ -0,0 +1,150 @@ +/*! + * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Alfresco Example Content Application + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * from Hyland Software. If not, see . + */ + +import { expect } from '@playwright/test'; +import { ApiClientFactory, Utils, test, NodesApi, TrashcanApi, FileActionsApi, TEST_FILES } from '@alfresco/playwright-shared'; + +test.describe('Search - Filters - Date', () => { + let nodesApi: NodesApi; + let trashcanApi: TrashcanApi; + + const randomId = Utils.random(); + const username = `user-${randomId}`; + const fileNamePdfKb = `${randomId}-fileNamePdf.pdf`; + const fileNameJpgMb = `${randomId}-fileNameJpg.jpg`; + const currentAndPreviousDay = Utils.getCurrentAndPreviousDay(); + + test.beforeEach(async ({ loginPage }) => { + await Utils.tryLoginUser(loginPage, username, username, 'beforeEach failed'); + }); + + test.beforeAll(async () => { + try { + const apiClientFactory = new ApiClientFactory(); + await apiClientFactory.setUpAcaBackend('admin'); + await apiClientFactory.createUser({ username }); + trashcanApi = await TrashcanApi.initialize(username, username); + nodesApi = await NodesApi.initialize(username, username); + const fileActionsApi = await FileActionsApi.initialize(username, username); + await fileActionsApi.uploadFileWithRename(TEST_FILES.PDF.path, fileNamePdfKb, '-my-'); + await fileActionsApi.uploadFileWithRename(TEST_FILES.JPG_FILE.path, fileNameJpgMb, '-my-'); + } catch (error) { + console.error(`beforeAll failed: ${error}`); + } + }); + + test.afterAll(async () => { + await Utils.deleteNodesSitesEmptyTrashcan(nodesApi, trashcanApi, 'afterAll failed'); + }); + + test('[C699048-1] [C699049-1] Filter by date - Changing tabs', async ({ searchPage }) => { + await searchPage.acaHeader.searchButton.click(); + await searchPage.searchFilters.dateFilter.click(); + await searchPage.searchFiltersDate.betweenButton.click(); + await expect(searchPage.searchFiltersDate.betweenRadioButton).toBeChecked(); + await expect(searchPage.searchFiltersDate.modifiedTabTitle).toHaveCSS('color', 'rgba(0, 0, 0, 0.54)'); + await searchPage.searchFiltersDate.openCreatedModifiedTab(searchPage, 'Modified'); + + await expect(searchPage.searchFiltersDate.anytimeRadioButton).toBeChecked(); + await expect(searchPage.searchFiltersDate.modifiedTabTitle).toHaveCSS('color', 'rgb(33, 33, 33)'); + await searchPage.searchFiltersDate.openCreatedModifiedTab(searchPage, 'Created'); + + await expect(searchPage.searchFiltersDate.betweenRadioButton).toBeChecked(); + await expect(searchPage.searchFiltersDate.createdTabTitle).toHaveCSS('color', 'rgb(33, 33, 33)'); + }); + + test('[C699048-2] Filter by date - Created anytime', async ({ searchPage }) => { + await searchPage.searchFiltersDate.filterFilesByDate({ + searchPage, + filterType: 'anytime', + dateFilterTab: 'Created', + searchPhrase: randomId, + searchType: 'files', + expectSearchResults: 2 + }); + }); + + test('[C699049-2] Filter by date - Modified anytime', async ({ searchPage }) => { + await searchPage.searchFiltersDate.filterFilesByDate({ + searchPage, + filterType: 'anytime', + dateFilterTab: 'Modified', + searchPhrase: randomId, + searchType: 'files', + expectSearchResults: 2 + }); + }); + + test('[C699048-3] Filter by date - Created in the last', async ({ searchPage }) => { + await searchPage.searchFiltersDate.filterFilesByDate({ + searchPage, + filterType: 'inTheLast', + dateFilterTab: 'Created', + searchPhrase: randomId, + searchType: 'files', + expectSearchResults: 2, + inTheLastInputValue: '1' + }); + }); + + test('[C699049-3] Filter by date - Modified in the last', async ({ searchPage }) => { + await searchPage.searchFiltersDate.filterFilesByDate({ + searchPage, + filterType: 'inTheLast', + dateFilterTab: 'Modified', + searchPhrase: randomId, + searchType: 'files', + expectSearchResults: 2, + inTheLastInputValue: '1' + }); + }); + + test('[C699048-4] Filter by date - Created between', async ({ searchPage }) => { + await searchPage.searchFiltersDate.filterFilesByDate({ + searchPage, + filterType: 'between', + dateFilterTab: 'Created', + searchPhrase: randomId, + searchType: 'files', + expectSearchResults: 2, + inTheLastInputValue: '1', + startDay: currentAndPreviousDay.previousDate, + endDay: currentAndPreviousDay.currentDate + }); + }); + + test('[C699049-4] Filter by date - Modified between', async ({ searchPage }) => { + await searchPage.searchFiltersDate.filterFilesByDate({ + searchPage, + filterType: 'between', + dateFilterTab: 'Modified', + searchPhrase: randomId, + searchType: 'files', + expectSearchResults: 2, + inTheLastInputValue: '1', + startDay: currentAndPreviousDay.previousDate, + endDay: currentAndPreviousDay.currentDate + }); + }); +}); diff --git a/projects/aca-playwright-shared/src/page-objects/components/search/search-filters/search-filters-date.component.ts b/projects/aca-playwright-shared/src/page-objects/components/search/search-filters/search-filters-date.component.ts index e44a0411d..a570b48dc 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/search/search-filters/search-filters-date.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/search/search-filters/search-filters-date.component.ts @@ -23,7 +23,22 @@ */ import { BaseComponent } from '../../base.component'; -import { Page } from '@playwright/test'; +import { Page, expect } from '@playwright/test'; +import { SearchPage, SearchType } from '@alfresco/playwright-shared'; + +type FilterTab = 'Created' | 'Modified'; + +interface FilterFilesByDateParams { + searchPage: SearchPage; + filterType: 'anytime' | 'inTheLast' | 'between'; + dateFilterTab: FilterTab; + searchPhrase: string; + searchType: SearchType; + expectSearchResults: number; + inTheLastInputValue?: string; + startDay?: string; + endDay?: string; +} export class SearchFiltersDate extends BaseComponent { private static rootElement = '.adf-search-filter-menu-card'; @@ -34,11 +49,94 @@ export class SearchFiltersDate extends BaseComponent { public createdTab = this.getChild(`[role='tab']`, { hasText: 'Created' }); public modifiedTab = this.getChild(`[role='tab']`, { hasText: 'Modified' }); + public createdTabTitle = this.createdTab.locator(`div`); + public modifiedTabTitle = this.modifiedTab.locator(`div`); public anytimeButton = this.getChild(`[data-automation-id$='date-range-anytime']`); + public anytimeRadioButton = this.anytimeButton.locator(`input`); public inTheLastButton = this.getChild(`[data-automation-id$='date-range-in-last']`); public inTheLastInput = this.getChild(`[data-automation-id$='date-range-in-last-input']`); public inTheLastDropdown = this.getChild(`[data-automation-id$='date-range-in-last-dropdown']`); public betweenButton = this.getChild(`[data-automation-id$='date-range-between']`); + public betweenRadioButton = this.betweenButton.locator(`input`); public betweenStartDate = this.getChild(`[data-automation-id$='date-range-between-start-input']`); public betweenEndDate = this.getChild(`[data-automation-id$='date-range-between-end-input']`); + + async openCreatedModifiedTab(page: SearchPage, tab: FilterTab): Promise { + switch (tab) { + case 'Created': + await page.searchFiltersDate.createdTab.click(); + break; + case 'Modified': + await page.searchFiltersDate.modifiedTab.click(); + break; + default: + break; + } + await page.page.waitForTimeout(2000); + } + + /** + * Method used in cases where we want to filter search results by Date + * + * @param searchPage page context for the test + * @param filterType filter type for the Date filter + * @param dateFilterTab tab in Date filter. Either Created or Modified + * @param searchPhrase search phrase for the search + * @param searchType type of items we want in search results e.g. files or folders + * @param expectSearchResults expect a number of search results + * @param inTheLastInputValue a value for 'in the last' input. e.g. in the last X days + * @param startDay start day for time-frame search. DD-MMMM-YY + * @param endDay end day for time-frame search. DD-MMMM-YY + */ + async filterFilesByDate(params: FilterFilesByDateParams) { + const { + searchPage, + filterType, + dateFilterTab, + searchPhrase, + searchType, + expectSearchResults, + inTheLastInputValue, + startDay, + endDay + } = params; + + await searchPage.searchWithin(searchPhrase, searchType); + await searchPage.searchFilters.dateFilter.click(); + + if (dateFilterTab === 'Modified') { + await searchPage.searchFiltersDate.openCreatedModifiedTab(searchPage, 'Modified'); + } + + switch (filterType) { + case 'anytime': + await searchPage.searchFiltersDate.anytimeButton.click(); + break; + case 'inTheLast': + await searchPage.searchFiltersDate.inTheLastButton.click(); + await searchPage.searchFiltersDate.inTheLastInput.fill(inTheLastInputValue); + break; + case 'between': + await searchPage.searchFiltersDate.betweenButton.click(); + await searchPage.searchFiltersDate.betweenStartDate.fill(startDay); + await searchPage.searchFiltersDate.betweenEndDate.fill(endDay); + break; + default: + throw new Error('Invalid filter type'); + } + + await searchPage.searchFilters.menuCardApply.click(); + await searchPage.dataTable.spinnerWaitForReload(); + expect(await searchPage.dataTable.getRowsCount()).toEqual(expectSearchResults); + + let dateText: string; + if (filterType === 'between') { + if (dateFilterTab === 'Modified') { + dateText = `Modified: ${startDay} - ${endDay}`; + } else { + dateText = `Created: ${startDay} - ${endDay}`; + } + await expect(searchPage.searchFilters.dateFilter).toContainText(dateText, { ignoreCase: true }); + } + } } diff --git a/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts index 4963c9a37..30febe904 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/search.page.ts @@ -24,11 +24,26 @@ import { Page } from '@playwright/test'; import { BasePage } from './base.page'; -import { DataTableComponent, MatMenuComponent, ViewerComponent, SearchInputComponent, SearchOverlayComponent, SidenavComponent, SearchSortingPicker, SearchFilters, SearchFiltersTags, SearchFiltersCategories, SearchFiltersDate, SearchFiltersLocation, SearchFiltersLogic, SearchFiltersProperties } from '../components'; +import { + DataTableComponent, + MatMenuComponent, + ViewerComponent, + SearchInputComponent, + SearchOverlayComponent, + SidenavComponent, + SearchSortingPicker, + SearchFilters, + SearchFiltersTags, + SearchFiltersCategories, + SearchFiltersDate, + SearchFiltersLocation, + SearchFiltersLogic, + SearchFiltersProperties +} from '../components'; import { AcaHeader } from '../components/aca-header.component'; import { AdfConfirmDialogComponent, AdfFolderDialogComponent } from '../components/dialogs'; -type SearchType = 'files' | 'folders' | 'filesAndFolders' | 'libraries'; +export type SearchType = 'files' | 'folders' | 'filesAndFolders' | 'libraries'; export class SearchPage extends BasePage { private static pageUrl = 'search'; diff --git a/projects/aca-playwright-shared/src/utils/utils.ts b/projects/aca-playwright-shared/src/utils/utils.ts index 52cb998d4..8050f144d 100644 --- a/projects/aca-playwright-shared/src/utils/utils.ts +++ b/projects/aca-playwright-shared/src/utils/utils.ts @@ -26,6 +26,7 @@ const crypto = require('crypto'); import * as path from 'path'; import { LoginPage, MyLibrariesPage, PersonalFilesPage, FavoritesLibrariesPage, SearchPage, SharedPage, TrashPage } from '../'; import { NodesApi, TrashcanApi, SitesApi } from '@alfresco/playwright-shared'; +import { format, subDays, subMonths, endOfMonth } from 'date-fns'; export class Utils { static string257Long = 'x'.repeat(257); @@ -105,9 +106,9 @@ export class Utils { errorMessage = 'reloadPageIfRowNotVisible Error ' ): Promise { try { - if (!await pageContext.dataTable.getRowByName(nodeName).isVisible()) { + if (!(await pageContext.dataTable.getRowByName(nodeName).isVisible())) { await pageContext.page.reload({ waitUntil: 'load' }); - }; + } } catch (error) { console.error(`${errorMessage}: ${error}`); } @@ -118,11 +119,31 @@ export class Utils { errorMessage = 'reloadPageIfDatatableEmpty Error ' ): Promise { try { - if (await pageContext.dataTable.getEmptyFolderLocator.isVisible() || await pageContext.dataTable.emptyListTitle.isVisible()) { + if ((await pageContext.dataTable.getEmptyFolderLocator.isVisible()) || (await pageContext.dataTable.emptyListTitle.isVisible())) { await pageContext.page.reload({ waitUntil: 'load' }); } } catch (error) { console.error(`${errorMessage}: ${error}`); } } + + static getCurrentAndPreviousDay(currentDate = new Date()): { currentDate: string; previousDate: string } { + let formattedDate: string; + let formattedDate2: string; + + const formatDate = (date: Date): string => { + return format(date, 'dd-MMM-yy').toUpperCase(); + }; + + if (currentDate.getDate() === 1) { + const lastDayOfPreviousMonth: Date = endOfMonth(subMonths(currentDate, 1)); + formattedDate = formatDate(lastDayOfPreviousMonth); + formattedDate2 = formatDate(subDays(lastDayOfPreviousMonth, 1)); + } else { + formattedDate = formatDate(currentDate); + formattedDate2 = formatDate(subDays(currentDate, 1)); + } + + return { currentDate: formattedDate, previousDate: formattedDate2 }; + } }