diff --git a/apps/docs-e2e/src/docs.spec.ts b/apps/docs-e2e/src/docs.spec.ts index 5ae5a96d..29bcc9ad 100644 --- a/apps/docs-e2e/src/docs.spec.ts +++ b/apps/docs-e2e/src/docs.spec.ts @@ -25,39 +25,115 @@ const CUHACKING_2025_DOCS_URL = `${DOCS_BASE_URL}/docs` const CUHACKING_2025_LANDING_PAGE_URL = 'https://www.cuhacking.ca/' -const MOBILE_WIDTH = 320 -const MOBILE_HEIGHT = 480 - -const TABLET_WIDTH = 768 -const TABLET_HEIGHT = 1024 - -/* ---------------- DESKTOP TITLE ---------------- */ -test('should contain desktop title page', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.page).toHaveTitle(/Welcome to the Docs/) -}) - -/* ---------------- DESKTOP HEADER ---------------- */ -test.describe('should contain desktop header elements', { +const DEVICES: { DEVICE: string, VIEWPORT: { width: number, height: number } }[] = [ + { DEVICE: 'desktop', VIEWPORT: { width: 1024, height: 1440 } }, + { DEVICE: 'tablet', VIEWPORT: { width: 768, height: 1024 } }, + { DEVICE: 'mobile', VIEWPORT: { width: 320, height: 480 } }, +] + +const NARROW_DEVICES = DEVICES.filter(device => device.DEVICE !== 'desktop') +const WIDE_DEVICES = DEVICES.filter(device => device.DEVICE !== 'mobile') + +const MOBILE_DEVICE = DEVICES.find(device => device.DEVICE === 'mobile')! +const TABLET_DEVICE = DEVICES.find(device => device.DEVICE === 'tablet')! + +/* ---------------- MOBILE + DESKTOP + TABLET ---------------- */ +for (const { DEVICE, VIEWPORT } of DEVICES) { + test.describe(`[${DEVICE.toUpperCase()}] - Common Layout Elements`, { + tag: '@smoke', + }, () => { + test.beforeEach(async ({ docsLayoutPage }) => { + await docsLayoutPage.page.setViewportSize(VIEWPORT) + await docsLayoutPage.goto() + }) + + test(`should contain ${DEVICE} title page`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.page).toHaveTitle(/Welcome to the Docs/) + }) + + test(`should contain cuHacking logo icon in ${DEVICE} header`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.cuHackingLogoIcon).toBeVisible() + }) + + test(`should take user to docs home page when cuHacking logo icon is clicked in ${DEVICE} header`, async ({ docsLayoutPage }) => { + await docsLayoutPage.cuHackingLogoIcon.click() + await expect(docsLayoutPage.page).toHaveURL(CUHACKING_2025_DOCS_URL) + }) + + test(`should contain cuHacking logo Text in ${DEVICE} header`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.cuHackingLogoText).toBeVisible() + }) + + test(`should take user to docs home page when cuHacking logo text is clicked in ${DEVICE} header`, async ({ docsLayoutPage }) => { + await docsLayoutPage.cuHackingLogoText.click() + await expect(docsLayoutPage.page).toHaveURL(CUHACKING_2025_DOCS_URL) + }) + + test(`should contain last updated text in docs page footer for ${DEVICE}`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.lastUpdatedText).toBeVisible() + }) + }) +} + +/* ---------------- MOBILE + DESKTOP ---------------- */ +for (const { DEVICE, VIEWPORT } of NARROW_DEVICES) { + test.describe(`[${DEVICE.toUpperCase()}] - Mobile and Desktop Layout Elements`, { + tag: '@smoke', + }, () => { + test.beforeEach(async ({ docsLayoutPage }) => { + await docsLayoutPage.page.setViewportSize(VIEWPORT) + await docsLayoutPage.goto() + }) + + test(`should have quick links section visible in ${DEVICE} header`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.quickLinks).toBeVisible() + }) + + test(`should have "Edit on Github" button visible in ${DEVICE} quick links`, async ({ docsLayoutPage }) => { + await docsLayoutPage.quickLinks.click() + await expect(docsLayoutPage.editOnGitHubButton).toBeVisible() + }) + + test(`should take user to github index page when "Edit on Github" button is clicked from ${DEVICE}`, async ({ docsLayoutPage }) => { + await docsLayoutPage.quickLinks.click() + await clickAndGoToPage(docsLayoutPage, docsLayoutPage.editOnGitHubButton, CUHACKING_2025_PLATFORM_GITHUB_INDEX_PAGE_URL) + }) + }) +} + +/* ---------------- TABLET + DESKTOP ---------------- */ +for (const { DEVICE, VIEWPORT } of WIDE_DEVICES) { + test.describe(`[${DEVICE.toUpperCase()}] - Tablet and Desktop Layout Elements`, { + tag: '@smoke', + }, () => { + test.beforeEach(async ({ docsLayoutPage }) => { + await docsLayoutPage.page.setViewportSize(VIEWPORT) + await docsLayoutPage.goto() + }) + + test(`should contain search bar in ${DEVICE} header`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.searchBar).toBeVisible() + }) + + test(`should show search modal when search bar clicked in ${DEVICE} header`, async ({ docsLayoutPage }) => { + await docsLayoutPage.searchBar.click() + await expect(docsLayoutPage.searchDialog).toBeVisible() + }) + + test(`should have docs pages section dropdown menu visible in ${DEVICE} sidebar`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.sectionsDropdownButton).toBeVisible() + }) + + test(`should contain sidebar toggle in ${DEVICE} sidebar`, async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.sideBarToggle).toBeVisible() + }) + }) +} + +/* ---------------- UNIQUE DESKTOP HEADER ---------------- */ +test.describe('[DESKTOP] - Header elements', { tag: '@smoke', }, () => { - test('should contain cuHacking logo icon in desktop header', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.cuHackingLogoIcon).toBeVisible() - }) - - test('should take user to docs home page when cuHacking logo icon is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.cuHackingLogoIcon.click() - await expect(docsLayoutPage.page).toHaveURL(CUHACKING_2025_DOCS_URL) - }) - - test('should contain cuHacking logo Text in desktop header', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.cuHackingLogoText).toBeVisible() - }) - - test('should take user to docs home page when cuHacking logo text is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.cuHackingLogoText.click() - await expect(docsLayoutPage.page).toHaveURL(CUHACKING_2025_DOCS_URL) - }) - test('should contain Website dropdown button in desktop header', async ({ docsLayoutPage }) => { await expect(docsLayoutPage.websiteDropdownButton).toBeVisible() }) @@ -107,15 +183,6 @@ test.describe('should contain desktop header elements', { await clickAndGoToPage(docsLayoutPage, docsLayoutPage.hackerPortalProjectBoardLink, CUHACKING_2025_PLATFORM_GITHUB_PROJECT_BOARD_URL) }) - test('should contain search bar in desktop header', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.searchBar).toBeVisible() - }) - - test('should show search modal when search bar in desktop header is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.searchBar.click() - await expect(docsLayoutPage.searchDialog).toBeVisible() - }) - test('should contain theme toggle in desktop header', async ({ docsLayoutPage }) => { await expect(docsLayoutPage.themeToggle).toBeVisible() }) @@ -129,17 +196,8 @@ test.describe('should contain desktop header elements', { }) }) -/* ---------------- DESKTOP SIDEBAR ---------------- */ -test.describe('should contain desktop sidebar elements', { - tag: '@smoke', -}, () => { - test('should contain sidebar toggle in desktop sidebar', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.sideBarToggle).toBeVisible() - }) -}) - -/* ---------------- DESKTOP FLOATING TABLE ---------------- */ -test.describe('should contain floating table of contents elements', { +/* ---------------- UNIQUE DESKTOP FLOATING TABLE ---------------- */ +test.describe('[DESKTOP]- Floating table of contents elements', { tag: '@smoke', }, () => { test('should contain \'Edit on GitHub\' button in floating table of contents', async ({ docsLayoutPage }) => { @@ -151,48 +209,19 @@ test.describe('should contain floating table of contents elements', { }) }) -/* ---------------- DESKTOP DOCS ELEMENTS ---------------- */ -test.describe('should contain docs page elements', { - tag: '@smoke', -}, () => { - test('should contain last updated text in docs page footer', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.lastUpdatedText).toBeVisible() - }) -}) - -/* ---------------- MOBILE TITLE ---------------- */ -test('should contain the title page on mobile layout', async ({ docsLayoutPage }) => { - await docsLayoutPage.page.setViewportSize({ width: MOBILE_WIDTH, height: MOBILE_HEIGHT }) - await docsLayoutPage.goto() - await expect(docsLayoutPage.page).toHaveTitle(/Welcome to the Docs/) -}) - -/* ---------------- MOBILE HEADER ---------------- */ -test.describe('should contain mobile header elements', { +/* ---------------- UNIQUE MOBILE HEADER ---------------- */ +test.describe('[MOBILE] - Header elements', { tag: '@smoke', }, () => { test.beforeEach(async ({ docsLayoutPage }) => { await docsLayoutPage.goto() - await docsLayoutPage.page.setViewportSize({ width: MOBILE_WIDTH, height: MOBILE_HEIGHT }) - }) - - test('should contain cuHacking Logo Icon', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.cuHackingLogoIcon).toBeVisible() + await docsLayoutPage.page.setViewportSize(MOBILE_DEVICE.VIEWPORT) }) test('should contain hamburger icon', async ({ docsLayoutPage }) => { await expect(docsLayoutPage.hamburgerIcon).toBeVisible() }) - test('should take user to docs home page when cuHacking logo icon is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.cuHackingLogoIcon.click() - await expect(docsLayoutPage.page).toHaveURL(CUHACKING_2025_DOCS_URL) - }) - - test('should contain cuHacking logo Text', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.cuHackingLogoText).toBeVisible() - }) - test('should contain search icon', async ({ docsLayoutPage }) => { await expect(docsLayoutPage.searchIcon).toBeVisible() }) @@ -201,29 +230,30 @@ test.describe('should contain mobile header elements', { await docsLayoutPage.searchIcon.click() await expect(docsLayoutPage.searchModal).toBeVisible() }) +}) - test('should have quick links section visible', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.quickLinks).toBeVisible() - }) - - test('should have `Edit on Github` button visible', async ({ docsLayoutPage }) => { - await docsLayoutPage.quickLinks.click() - await expect(docsLayoutPage.editOnGitHubButton).toBeVisible() +/* ---------------- UNIQUE TABLET HEADER ---------------- */ +test.describe('[TABLET] - Header elements', { + tag: '@smoke', +}, () => { + test.beforeEach(async ({ docsLayoutPage }) => { + await docsLayoutPage.goto() + await docsLayoutPage.page.setViewportSize(TABLET_DEVICE.VIEWPORT) }) - test('should take user to github index page when `Edit on Github` button is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.quickLinks.click() - await clickAndGoToPage(docsLayoutPage, docsLayoutPage.editOnGitHubButton, CUHACKING_2025_PLATFORM_GITHUB_INDEX_PAGE_URL) + test('should have kebab icon visible', async ({ docsLayoutPage }) => { + await expect(docsLayoutPage.kebabIcon).toBeVisible() }) }) +// TODO: create helper function to help test both tablet and mobile elements /* ---------------- MOBILE HAMBURGER ELEMENTS ---------------- */ -test.describe('should contain hamburger menu elements', { +test.describe('[MOBILE] - Hamburger menu elements', { tag: '@smoke', }, () => { test.beforeEach(async ({ docsLayoutPage }) => { await docsLayoutPage.goto() - await docsLayoutPage.page.setViewportSize({ width: MOBILE_WIDTH, height: MOBILE_HEIGHT }) + await docsLayoutPage.page.setViewportSize(MOBILE_DEVICE.VIEWPORT) await docsLayoutPage.hamburgerIcon.click() }) @@ -295,89 +325,13 @@ test.describe('should contain hamburger menu elements', { }) }) -/* ---------------- MOBILE DOCS ELEMENTS ---------------- */ -test.describe('should contain mobile docs page elements', { - tag: '@smoke', -}, () => { - test.beforeEach(async ({ docsLayoutPage }) => { - await docsLayoutPage.goto() - await docsLayoutPage.page.setViewportSize({ width: MOBILE_WIDTH, height: MOBILE_HEIGHT }) - }) - - test('should contain last updated text in mobile docs page footer', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.lastUpdatedText).toBeVisible() - }) -}) - -/* ---------------- TABLET TITLE ---------------- */ -test('should contain the title page on tablet', async ({ docsLayoutPage }) => { - await docsLayoutPage.page.setViewportSize({ width: TABLET_WIDTH, height: TABLET_HEIGHT }) - await docsLayoutPage.goto() - await expect(docsLayoutPage.page).toHaveTitle(/Welcome to the Docs/) -}) - -/* ---------------- TABLET HEADER ---------------- */ -test.describe('should contain tablet header elements', { - tag: '@smoke', -}, () => { - test.beforeEach(async ({ docsLayoutPage }) => { - await docsLayoutPage.goto() - await docsLayoutPage.page.setViewportSize({ width: TABLET_WIDTH, height: TABLET_HEIGHT }) - }) - - test('should contain cuHacking logo icon', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.cuHackingLogoIcon).toBeVisible() - }) - - test('should take user to docs home page when cuHacking logo icon is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.cuHackingLogoIcon.click() - await expect(docsLayoutPage.page).toHaveURL(CUHACKING_2025_DOCS_URL) - }) - - test('should contain cuHacking logo Text', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.cuHackingLogoText).toBeVisible() - }) - - test('should take user to docs home page when cuHacking logo text is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.cuHackingLogoText.click() - await expect(docsLayoutPage.page).toHaveURL(CUHACKING_2025_DOCS_URL) - }) - - test('should contain search bar', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.searchBar).toBeVisible() - }) - - test('should show search modal when search bar is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.searchBar.click() - await expect(docsLayoutPage.searchDialog).toBeVisible() - }) - - test('should have kebab icon visible', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.kebabIcon).toBeVisible() - }) - - test('should have quick links section visible', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.tabletQuickLinks).toBeVisible() - }) - - test('should have `Edit on Github` button visible', async ({ docsLayoutPage }) => { - await docsLayoutPage.tabletQuickLinks.click() - await expect(docsLayoutPage.editOnGitHubButton).toBeVisible() - }) - - test('should take user to index page when `Edit on Github` button is clicked', async ({ docsLayoutPage }) => { - await docsLayoutPage.tabletQuickLinks.click() - await clickAndGoToPage(docsLayoutPage, docsLayoutPage.editOnGitHubButton, CUHACKING_2025_PLATFORM_GITHUB_INDEX_PAGE_URL) - }) -}) - /* ---------------- TABLET KEBAB ELEMENTS ---------------- */ -test.describe('should contain tablet kebab menu items', { +test.describe('[TABLET] - Kebab menu items', { tag: '@smoke', }, () => { test.beforeEach(async ({ docsLayoutPage }) => { await docsLayoutPage.goto() - await docsLayoutPage.page.setViewportSize({ width: TABLET_WIDTH, height: TABLET_HEIGHT }) + await docsLayoutPage.page.setViewportSize(TABLET_DEVICE.VIEWPORT) await docsLayoutPage.kebabIcon.click() }) @@ -444,35 +398,3 @@ test.describe('should contain tablet kebab menu items', { await expect(docsLayoutPage.themeToggle).toBeVisible() }) }) - -/* ---------------- TABLET SIDEBAR ---------------- */ -test.describe('should contain tablet sidebar elements', { - tag: '@smoke', -}, () => { - test.beforeEach(async ({ docsLayoutPage }) => { - await docsLayoutPage.goto() - await docsLayoutPage.page.setViewportSize({ width: TABLET_WIDTH, height: TABLET_HEIGHT }) - }) - - test('should have docs pages section dropdown menu visible', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.sectionsDropdownButton).toBeVisible() - }) - - test('should contain sidebar toggle in tablet sidebar', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.sideBarToggle).toBeVisible() - }) -}) - -/* ---------------- TABLET DOCS ELEMENTS ---------------- */ -test.describe('should contain tablet docs page elements', { - tag: '@smoke', -}, () => { - test.beforeEach(async ({ docsLayoutPage }) => { - await docsLayoutPage.goto() - await docsLayoutPage.page.setViewportSize({ width: TABLET_WIDTH, height: TABLET_HEIGHT }) - }) - - test('should contain last updated text in tablet docs page footer', async ({ docsLayoutPage }) => { - await expect(docsLayoutPage.lastUpdatedText).toBeVisible() - }) -}) diff --git a/apps/docs-e2e/src/pom.ts b/apps/docs-e2e/src/pom.ts index bf39f3bf..b31a091b 100644 --- a/apps/docs-e2e/src/pom.ts +++ b/apps/docs-e2e/src/pom.ts @@ -26,7 +26,7 @@ export class DocsLayout { readonly searchModal: Locator readonly quickLinks: Locator - // Mobile Hamburger Elements + // Mobile + Tablet Elements readonly sectionsDropdownButton: Locator readonly mobileWebsiteLink: Locator readonly mobileHackerPortalSourceLink: Locator @@ -49,7 +49,6 @@ export class DocsLayout { // Tablet Header readonly kebabIcon: Locator - readonly tabletQuickLinks: Locator constructor(page: Page) { this.page = page @@ -77,7 +76,7 @@ export class DocsLayout { this.searchModal = page.getByPlaceholder('Search') this.quickLinks = page.getByRole('button', { name: 'On this page Quick Links' }) - // Mobile Hamburger Elements + // Mobile + Tablet Elements this.sectionsDropdownButton = page.getByRole('button', { name: 'Home Leave none behind' }) this.mobileWebsiteLink = page.getByRole('link', { name: 'Website' }) this.mobileHackerPortalSourceLink = page.getByRole('link', { name: 'Source', exact: true }) @@ -100,7 +99,6 @@ export class DocsLayout { // Tablet Header this.kebabIcon = page.locator('#nd-nav').getByRole('button').nth(1) - this.tabletQuickLinks = page.getByRole('button', { name: 'On this page Quick Links' }) } async goto() {