diff --git a/pages/SearchResultsPage.ts b/pages/SearchResultsPage.ts index e9ab311..5765b6f 100644 --- a/pages/SearchResultsPage.ts +++ b/pages/SearchResultsPage.ts @@ -3,11 +3,21 @@ import { expect, Locator, Page } from '@playwright/test'; export class SearchResultsPage { readonly page: Page; readonly mainContent: Locator; + readonly resultLinks: Locator; + readonly noResultsMessage: Locator; constructor(page: Page) { - this.page = page; - this.mainContent = page.locator('main, [role="main"], body').first(); - } + this.page = page; + this.mainContent = page.locator('main, [role="main"], body').first(); + + this.resultLinks = page.locator( + 'a[href*="/release/"], a[href*="/master/"], a[href*="/artist/"], a[href*="/label/"]' + ); + + this.noResultsMessage = page.getByText( + /no results|nothing found|did not match|try a different search/i + ); +} async expectSearchResultsPageLoaded(query: string): Promise { await expect(this.page).toHaveURL(/\/search(\?|\/|$)/); @@ -35,4 +45,21 @@ export class SearchResultsPage { releaseOrMasterResult.click(), ]); } + +async expectGracefulNoResultState(query: string): Promise { + await expect(this.page).toHaveURL(/\/search(?:\?|\/|$)/); + await expect(this.mainContent).toContainText(query, { timeout: 10000 }); + + await expect(this.mainContent).not.toContainText( + /server error|something went wrong|application error|internal error/i + ); + + const resultCount = await this.resultLinks.count(); + const noResultsMessageCount = await this.noResultsMessage.count(); + + expect( + resultCount === 0 || noResultsMessageCount > 0, + `Expected no result links or a no-results message for query: ${query}` + ).toBeTruthy(); +} } \ No newline at end of file diff --git a/test-data/negative-search-cases.json b/test-data/negative-search-cases.json new file mode 100644 index 0000000..dda1254 --- /dev/null +++ b/test-data/negative-search-cases.json @@ -0,0 +1,6 @@ +[ + { + "description": "unlikely search query", + "query": "zzzxxy-discogs-ui-no-results-qa-portfolio-2026" + } +] \ No newline at end of file diff --git a/tests/search/negative-search.spec.ts b/tests/search/negative-search.spec.ts new file mode 100644 index 0000000..4d60b26 --- /dev/null +++ b/tests/search/negative-search.spec.ts @@ -0,0 +1,33 @@ +import { test } from '@playwright/test'; +import { HomePage } from '../../pages/HomePage'; +import { SearchResultsPage } from '../../pages/SearchResultsPage'; +import negativeSearchCases from '../../test-data/negative-search-cases.json'; + +type NegativeSearchCase = { + description: string; + query: string; +}; + +test.describe('Discogs negative search', () => { + for (const searchCase of negativeSearchCases as NegativeSearchCase[]) { + test(`@negative search handles ${searchCase.description} gracefully`, async ({ + page, + }) => { + const homePage = new HomePage(page); + const searchResultsPage = new SearchResultsPage(page); + + await test.step('Navigate to Discogs homepage', async () => { + await homePage.goto(); + await homePage.expectPageLoaded(); + }); + + await test.step(`Search for unlikely query: ${searchCase.query}`, async () => { + await homePage.searchFor(searchCase.query); + }); + + await test.step('Validate graceful no-result behavior', async () => { + await searchResultsPage.expectGracefulNoResultState(searchCase.query); + }); + }); + } +}); \ No newline at end of file