diff --git a/pages/HomePage.ts b/pages/HomePage.ts index 776abf1..763e62c 100644 --- a/pages/HomePage.ts +++ b/pages/HomePage.ts @@ -23,12 +23,14 @@ export class HomePage { await expect(this.searchInput).toBeVisible(); } - async searchFor(query: string): Promise { - await this.searchInput.fill(query); +async searchFor(query: string): Promise { + await this.searchInput.fill(query); - await Promise.all([ - this.page.waitForURL(/\/search(\?|\/|$)/), - this.searchInput.press('Enter'), - ]); - } + await Promise.all([ + this.page.waitForURL(/\/search(?:\?|\/|$)/, { + waitUntil: 'domcontentloaded', + }), + this.searchInput.press('Enter'), + ]); +} } \ No newline at end of file diff --git a/pages/ReleasePage.ts b/pages/ReleasePage.ts new file mode 100644 index 0000000..6c4fd1c --- /dev/null +++ b/pages/ReleasePage.ts @@ -0,0 +1,38 @@ +import { expect, Locator, Page } from '@playwright/test'; + +export class ReleasePage { + readonly page: Page; + readonly mainContent: Locator; + readonly pageHeading: Locator; + + constructor(page: Page) { + this.page = page; + this.mainContent = page.locator('main, [role="main"], body').first(); + this.pageHeading = page.locator('h1').first(); + } + + async expectReleasePageLoaded(): Promise { + await expect(this.page).toHaveURL(/\/(release|master)\//); + await expect(this.mainContent).toBeVisible(); + } + + async expectReleaseContent( + expectedReleaseText: string, + expectedArtistText: string + ): Promise { + await expect(this.mainContent).toContainText(expectedReleaseText, { + timeout: 10000, + }); + + await expect(this.mainContent).toContainText(expectedArtistText, { + timeout: 10000, + }); + } + + async expectPageHasReleaseLikeContent(): Promise { + await expect(this.mainContent).toContainText( + /tracklist|versions|marketplace|statistics|recommendations/i, + { timeout: 10000 } + ); + } +} \ No newline at end of file diff --git a/pages/SearchResultsPage.ts b/pages/SearchResultsPage.ts index 83f4947..e9ab311 100644 --- a/pages/SearchResultsPage.ts +++ b/pages/SearchResultsPage.ts @@ -19,4 +19,20 @@ export class SearchResultsPage { this.page.getByText(expectedText, { exact: false }).first() ).toBeVisible({ timeout: 10000 }); } + + async openReleaseOrMasterResult(expectedText: string): Promise { + const releaseOrMasterResult = this.page + .locator('a[href*="/release/"], a[href*="/master/"]') + .filter({ hasText: expectedText }) + .first(); + + await expect(releaseOrMasterResult).toBeVisible({ timeout: 10000 }); + + await Promise.all([ + this.page.waitForURL(/\/(release|master)\//, { + waitUntil: 'domcontentloaded', + }), + releaseOrMasterResult.click(), + ]); +} } \ No newline at end of file diff --git a/test-data/release-cases.json b/test-data/release-cases.json new file mode 100644 index 0000000..2321ebd --- /dev/null +++ b/test-data/release-cases.json @@ -0,0 +1,7 @@ +[ + { + "query": "Kind Of Blue", + "expectedReleaseText": "Kind Of Blue", + "expectedArtistText": "Miles Davis" + } +] \ No newline at end of file diff --git a/tests/integration/search-to-release.spec.ts b/tests/integration/search-to-release.spec.ts new file mode 100644 index 0000000..cdffe5d --- /dev/null +++ b/tests/integration/search-to-release.spec.ts @@ -0,0 +1,52 @@ +import { test } from '@playwright/test'; +import { HomePage } from '../../pages/HomePage'; +import { SearchResultsPage } from '../../pages/SearchResultsPage'; +import { ReleasePage } from '../../pages/ReleasePage'; +import releaseCases from '../../test-data/release-cases.json'; + +type ReleaseCase = { + query: string; + expectedReleaseText: string; + expectedArtistText: string; +}; + +test.describe('Discogs search to release flow', () => { + for (const releaseCase of releaseCases as ReleaseCase[]) { + test(`@integration selected search result opens matching release page: ${releaseCase.query}`, async ({ + page, + }) => { + const homePage = new HomePage(page); + const searchResultsPage = new SearchResultsPage(page); + const releasePage = new ReleasePage(page); + + await test.step('Navigate to Discogs homepage', async () => { + await homePage.goto(); + await homePage.expectPageLoaded(); + }); + + await test.step(`Search for release: ${releaseCase.query}`, async () => { + await homePage.searchFor(releaseCase.query); + await searchResultsPage.expectSearchResultsPageLoaded( + releaseCase.query + ); + }); + + await test.step('Open matching release or master result', async () => { + await searchResultsPage.openReleaseOrMasterResult( + releaseCase.expectedReleaseText + ); + }); + + await test.step('Validate destination page contains expected release content', async () => { + await releasePage.expectReleasePageLoaded(); + + await releasePage.expectReleaseContent( + releaseCase.expectedReleaseText, + releaseCase.expectedArtistText + ); + + await releasePage.expectPageHasReleaseLikeContent(); + }); + }); + } +}); \ No newline at end of file