diff --git a/tests/page-objects/infinite-scroller.ts b/tests/page-objects/infinite-scroller.ts index b21bc5e0..fc263df2 100644 --- a/tests/page-objects/infinite-scroller.ts +++ b/tests/page-objects/infinite-scroller.ts @@ -12,6 +12,7 @@ import { } from '../models'; import { datesSorted, viewsSorted } from '../utils'; +import { CollectionSearchInput } from './collection-search-input'; export class InfiniteScroller { readonly page: Page; @@ -22,6 +23,7 @@ export class InfiniteScroller { readonly firstItemTile: Locator; readonly sortBar: SortBar; + readonly collectionSearchInput: CollectionSearchInput; public constructor(page: Page) { this.page = page; @@ -30,6 +32,7 @@ export class InfiniteScroller { this.infiniteScrollerSectionContainer = this.infiniteScroller.locator('#container'); + this.collectionSearchInput = new CollectionSearchInput(page); this.sortBar = new SortBar(page); const sortBarSection = this.sortBar.sortFilterBar; this.displayStyleSelector = sortBarSection.locator( @@ -42,10 +45,6 @@ export class InfiniteScroller { .first(); } - async awaitLoadingState() { - await this.page.waitForLoadState('networkidle', { timeout: 60000 }); - } - async clickViewMode(viewModeLocator: LayoutViewModeLocator) { await this.displayStyleSelectorOptions.locator(viewModeLocator).click(); } @@ -54,19 +53,19 @@ export class InfiniteScroller { switch (viewMode) { case 'tile': await expect( - this.displayStyleSelector.locator('#grid-button'), + this.displayStyleSelector.getByTestId('grid-button'), ).toHaveClass('active'); expect(await expect(this.infiniteScroller).toHaveClass(/grid/)); return; case 'list': await expect( - this.displayStyleSelector.locator('#list-detail-button'), + this.displayStyleSelector.getByTestId('list-detail-button'), ).toHaveClass('active'); expect(await expect(this.infiniteScroller).toHaveClass(/list-detail/)); return; case 'compact': await expect( - this.displayStyleSelector.locator('#list-compact-button'), + this.displayStyleSelector.getByTestId('list-compact-button'), ).toHaveClass('active'); expect(await expect(this.infiniteScroller).toHaveClass(/list-compact/)); return; @@ -76,7 +75,6 @@ export class InfiniteScroller { } async hoverToFirstItem() { - await this.awaitLoadingState(); expect(await this.firstItemTile.count()).toBe(1); await this.firstItemTile.hover(); @@ -97,7 +95,9 @@ export class InfiniteScroller { } async clickFirstResultAndCheckRedirectToDetailsPage() { - await this.page.waitForLoadState('networkidle', { timeout: 60000 }); + await this.firstItemTile.waitFor({ state: 'attached' }); + await this.firstItemTile.waitFor({ state: 'visible' }); + expect(await this.firstItemTile.count()).toBe(1); // Get item tile link to compare with the redirect URL @@ -120,7 +120,6 @@ export class InfiniteScroller { ) { // This test is only applicable in tile view mode for "views" filters if (filter === 'Weekly views' || filter === 'All-time views') { - await this.awaitLoadingState(); const tileStatsViews = await this.getTileStatsViewCountTitles( displayItemCount, ); @@ -144,7 +143,6 @@ export class InfiniteScroller { filter === 'Date added' || filter === 'Date reviewed' ) { - await this.awaitLoadingState(); const dateMetadataLabels = await this.getDateMetadataLabels( displayItemCount, ); @@ -169,7 +167,6 @@ export class InfiniteScroller { toInclude: boolean, displayItemCount: Number, ) { - await this.awaitLoadingState(); const facetedResults = await this.getFacetedResultsByViewFacetGroup( viewFacetMetadata, displayItemCount, @@ -193,12 +190,12 @@ export class InfiniteScroller { displayItemCount: Number, ): Promise { const arrTileStatsTitle: string[] = []; - const allItems = await this.infiniteScrollerSectionContainer - .locator('article') - .all(); + const allItems = await this.getAllInfiniteScrollerArticleItems(); let index = 0; while (index !== displayItemCount) { + await this.checkIfPageStillLoading(); + const itemTileCount = await allItems[index] .locator('a > item-tile') .count(); @@ -221,9 +218,7 @@ export class InfiniteScroller { displayItemCount: Number, ): Promise { const arrDateLine: DateMetadataLabel[] = []; - const allItems = await this.infiniteScrollerSectionContainer - .locator('article') - .all(); + const allItems = await this.getAllInfiniteScrollerArticleItems(); let index = 0; while (index !== displayItemCount) { @@ -231,7 +226,6 @@ export class InfiniteScroller { // There can be 2 date metadata in a row if filter is either Date archived, Date reviewed, or Date added // eg. Published: Nov 15, 2023 - Archived: Jan 19, 2024 // We always want the last one since it will correspond to the current "sort by" field - const dateSpanLabel = await allItems[index] .locator('#dates-line > div.metadata') .last() @@ -250,88 +244,105 @@ export class InfiniteScroller { index++; } - return arrDateLine; } - async getTileIconTitle(displayItemCount: Number): Promise { - const arrTileIconTitle: string[] = []; - const allItems = await this.infiniteScrollerSectionContainer - .locator('article') - .all(); + async getItemTileIconTitle(item: Locator, arrItem: string[]) { + const tileIconTitle = await this.getTileIconTitleAttr(item); + if (tileIconTitle) arrItem.push(tileIconTitle); + } - let index = 0; - while (index !== displayItemCount) { - // Load items based on displayItemCount - // Get mediatype-icon title from tile-stats row - const tileIcon = allItems[index].locator( - '#stats-row > li:nth-child(1) > mediatype-icon > #icon', - ); + async getCollectionItemTileTitle(item: Locator, arrItem: string[]) { + await item.locator('#container').waitFor({ state: 'visible' }); + const collectionTileCount = await item.locator('a > collection-tile').count(); + const itemTileCount = await item.locator('a > item-tile').count(); + if (collectionTileCount === 1 && itemTileCount === 0) { + arrItem.push('collection'); + } else if (collectionTileCount === 0 && itemTileCount === 1) { + const tileIconTitle = await this.getTileIconTitleAttr(item); + if (tileIconTitle) arrItem.push(tileIconTitle); + } + } - const tileIconTitle = await tileIcon.getAttribute('title'); - if (tileIconTitle) arrTileIconTitle.push(tileIconTitle); + async getDateMetadataText(item: Locator, arrItem: DateMetadataLabel[]) { + await item.locator('#container').waitFor({ state: 'visible' }); + const dateSpanLabel = await item + .locator('#dates-line > div.metadata') + .last() + .innerText(); - index++; + if (dateSpanLabel) { + // Need to split date filter and date format value: Published: 2150 or Published: Nov 15, 2023 + // Ideal format: { filter: 'Published', date: '2150' } + const strSplitColonSpace = dateSpanLabel.split(': '); + const objDateLine = { + filter: strSplitColonSpace[0], + date: strSplitColonSpace[1], + }; + arrItem.push(objDateLine); } + } + + async getTileIconTitleAttr(item: Locator) { + await item.locator('#container').waitFor({ state: 'visible' }); + // Get mediatype-icon title attr from tile-stats row element + return await item.locator('#stats-row > li:nth-child(1) > mediatype-icon > #icon').getAttribute('title'); + } - return arrTileIconTitle; + async getAllInfiniteScrollerArticleItems() { + const container = this.infiniteScroller.locator('section#container'); + await container.waitFor({ state: 'visible' }); + return await container.locator('article').all(); } - async getTileCollectionIconTitle( + async getFacetedResultsByViewFacetGroup( + viewFacetMetadata: ViewFacetMetadata, displayItemCount: Number, - ): Promise { - const arrTileIconTitle: string[] = []; - const allItems = await this.infiniteScrollerSectionContainer - .locator('article') - .all(); + ): Promise { + let arrIdentifiers: string[]; + const arrTitles: string[] = []; + const arrDates: DateMetadataLabel[] = []; + const allItems = await this.getAllInfiniteScrollerArticleItems(); let index = 0; while (index !== displayItemCount) { - const collectionTileCount = await allItems[index] - .locator('a > collection-tile') - .count(); - const itemTileCount = await allItems[index] - .locator('a > item-tile') - .count(); + await this.checkIfPageStillLoading(); - if (collectionTileCount === 1 && itemTileCount === 0) { - arrTileIconTitle.push('collection'); - } else if (collectionTileCount === 0 && itemTileCount === 1) { - // Load items based on displayItemCount - // Get mediatype-icon title from tile-stats row - const tileIcon = allItems[index].locator( - '#stats-row > li:nth-child(1) > mediatype-icon > #icon', - ); - - const tileIconTitle = await tileIcon.getAttribute('title'); - if (tileIconTitle) arrTileIconTitle.push(tileIconTitle); - } + switch(viewFacetMetadata) { + case 'tile-collection-icon-title': + await this.getCollectionItemTileTitle(allItems[index], arrTitles); + break; - index++; - } + case 'tile-icon-title': + await this.getItemTileIconTitle(allItems[index], arrTitles); + break; - return arrTileIconTitle; - } + case 'list-date': + await this.getDateMetadataText(allItems[index], arrDates); + break; - async getFacetedResultsByViewFacetGroup( - viewFacetMetadata: ViewFacetMetadata, - displayItemCount: Number, - ): Promise { - switch (viewFacetMetadata) { - case 'tile-collection-icontitle': - return await this.getTileCollectionIconTitle(displayItemCount); + default: // something else ---- test is broken + break; + } - case 'tile-icontitle': - return await this.getTileIconTitle(displayItemCount); + index++; + } - case 'list-date': - const dateLabels = await this.getDateMetadataLabels(displayItemCount); - if (dateLabels) return dateLabels.map(label => label.date); + arrIdentifiers = arrDates.length !== 0 + ? arrDates.map(label => label.date) + : arrTitles; - return null; + return arrIdentifiers; + } - default: - return null; + async checkIfPageStillLoading() { + const resultsText = await (this.page.getByTestId('results-total').locator('#big-results-count').innerText()); + const btnIndicatorText = await this.page.locator('#go-button').getAttribute('class'); + if (resultsText.includes('Searching') && btnIndicatorText === 'loading') { + await this.checkIfPageStillLoading(); // Recursive call + } else { + return; } } -} \ No newline at end of file + +} diff --git a/tests/page-objects/profile-page.ts b/tests/page-objects/profile-page.ts index aad900b1..adc817db 100644 --- a/tests/page-objects/profile-page.ts +++ b/tests/page-objects/profile-page.ts @@ -5,7 +5,7 @@ import { CollectionFacets } from './collection-facets'; import { InfiniteScroller } from './infinite-scroller'; import { SortBar } from './sort-bar'; -import { FacetGroupLocatorLabel } from '../models'; +import { FacetGroup, FacetGroupLocatorLabel } from '../models'; export class ProfilePage { readonly page: Page; @@ -33,7 +33,7 @@ export class ProfilePage { } async visit(userid: string) { - await this.page.goto(`/details/@${userid}`); + await this.page.goto(`/details/@${userid}?ab_config=EagerFacets:On`); await this.page.waitForLoadState('load', { timeout: 60000 }); } @@ -77,13 +77,13 @@ export class ProfilePage { } async validateDatePickerIsVisible() { - const facetContainer = await this.collectionFacets.getFacetGroupContainer( - FacetGroupLocatorLabel.DATE, - ); + const facetContainer = await this.collectionFacets.getFacetGroupContent(FacetGroup.DATE); - await facetContainer - .locator('histogram-date-range #container') - .waitFor({ state: 'visible', timeout: 60000 }); + if(facetContainer) { + await facetContainer + .locator('histogram-date-range #container') + .waitFor({ state: 'visible', timeout: 60000 }); + } } async validateClickedTabAppeared(tabName: string) { diff --git a/tests/profile/profile-page-uploads-facets.spec.ts b/tests/profile/profile-page-uploads-facets.spec.ts index fd132be9..78db69c6 100644 --- a/tests/profile/profile-page-uploads-facets.spec.ts +++ b/tests/profile/profile-page-uploads-facets.spec.ts @@ -1,4 +1,5 @@ import { test } from '../fixtures'; +import { SearchFacetGroupHeaderNames } from '../models'; test(`Profile Page - Uploads: facets appear`, async ({ profilePageUploads, @@ -8,6 +9,6 @@ test(`Profile Page - Uploads: facets appear`, async ({ }); await test.step(`Check if facet groups appear`, async () => { - await profilePageUploads.collectionFacets.assertCollectionFacetGroupCount(); + await profilePageUploads.collectionFacets.assertFacetGroupCount('search', SearchFacetGroupHeaderNames); }); }); diff --git a/tests/profile/profile-page.spec.ts b/tests/profile/profile-page.spec.ts index 35b168f2..d8df9509 100644 --- a/tests/profile/profile-page.spec.ts +++ b/tests/profile/profile-page.spec.ts @@ -1,6 +1,7 @@ import { test } from '@playwright/test'; import { ProfilePage } from '../page-objects/profile-page'; +import { SearchFacetGroupHeaderNames } from '../models'; let profilePage: ProfilePage; @@ -81,7 +82,7 @@ test.describe('Profile Page - Lists', () => { }); await test.step(`7 facet groups appear`, async () => { - await profilePage.collectionFacets.assertListFacetGroupCount(); + await profilePage.collectionFacets.assertFacetGroupCount('search', SearchFacetGroupHeaderNames); }); await test.step(`Date picker appears`, async () => {