diff --git a/test/e2e/fixtures/vpTest.ts b/test/e2e/fixtures/vpTest.ts index 7eb5c2d4..011e114c 100644 --- a/test/e2e/fixtures/vpTest.ts +++ b/test/e2e/fixtures/vpTest.ts @@ -1,5 +1,6 @@ import { ConsoleMessage, test } from '@playwright/test'; import { MainPage } from '../src/pom/mainPage'; +import PageManager from '../src/pom/PageManager'; /** * Fixture parameters. @@ -7,12 +8,23 @@ import { MainPage } from '../src/pom/mainPage'; type FixtureParams = { consoleErrors: ConsoleMessage[]; vpExamples: MainPage; + pomPages: PageManager; }; /** * Extend Playwright test with custom fixtures. */ export const vpTest = test.extend({ + /** + * Page Manager + */ + pomPages: [ + async ({ page }, use) => { + const pomPages = new PageManager(page); + await use(pomPages); + }, + { scope: 'test' }, + ], /** * Fixture for the video player examples page object. */ diff --git a/test/e2e/specs/highlightsGraphPageVideoIsPlaying.spec.ts b/test/e2e/specs/highlightsGraphPageVideoIsPlaying.spec.ts new file mode 100644 index 00000000..04cd2e91 --- /dev/null +++ b/test/e2e/specs/highlightsGraphPageVideoIsPlaying.spec.ts @@ -0,0 +1,19 @@ +import { vpTest } from '../fixtures/vpTest'; +import { expect, test } from '@playwright/test'; +import { waitForPageToLoadWithTimeout } from '../src/helpers/waitForPageToLoadWithTimeout'; +import { ExampleLinkName, getLinkByName } from '../testData/pageLinksData'; + +// Link to AI Highlights Graph page +const link = getLinkByName(ExampleLinkName.AIHighlightsGraph); +/** + * Testing if video on highlights graph page is playing by checking that is pause return false. + */ +vpTest(`Test if video on highlights graph page is playing as expected`, async ({ page, vpExamples, pomPages }) => { + await test.step('Navigate to highlights graph page by clicking on link', async () => { + await vpExamples.clickLinkByName(link.name); + await waitForPageToLoadWithTimeout(page, 5000); + }); + await test.step('Validating that the video is playing (in case isPause is false)', async () => { + expect(await pomPages.highlightGraphPage.videoHighlightsGraphPage.isPaused()).toEqual(false); + }); +}); diff --git a/test/e2e/src/pom/BasePage.ts b/test/e2e/src/pom/BasePage.ts new file mode 100644 index 00000000..5902ef93 --- /dev/null +++ b/test/e2e/src/pom/BasePage.ts @@ -0,0 +1,13 @@ +import { Page } from '@playwright/test'; + +/** + * Base Page represent an example page + * Such as main page, highlight graph page etc. + */ +export class BasePage { + protected page: Page; + + constructor(page: Page) { + this.page = page; + } +} diff --git a/test/e2e/src/pom/PageManager.ts b/test/e2e/src/pom/PageManager.ts new file mode 100644 index 00000000..aeada9ca --- /dev/null +++ b/test/e2e/src/pom/PageManager.ts @@ -0,0 +1,36 @@ +import { Page } from '@playwright/test'; +import { HighlightsGraphPage } from './highlightsGraphPage'; +import { BasePage } from './BasePage'; + +/** + * Page manager, + * Contains and initialize pages that uses in the tests + */ +export class PageManager { + private readonly page: Page; + private readonly pageMap = new Map(); + + constructor(page: Page) { + this.page = page; + } + + /** + * Helper: + * Returns and initialize relevant page + */ + private getPage(page: new (page: Page) => T): T { + const pageName = page.name; + if (!this.pageMap.has(pageName)) { + this.pageMap.set(pageName, new page(this.page)); + } + return this.pageMap.get(pageName) as T; + } + + /** + * Returns highlightGraphPage page object + */ + public get highlightGraphPage(): HighlightsGraphPage { + return this.getPage(HighlightsGraphPage); + } +} +export default PageManager; diff --git a/test/e2e/src/pom/highlightsGraphPage.ts b/test/e2e/src/pom/highlightsGraphPage.ts new file mode 100644 index 00000000..fbe4e5bd --- /dev/null +++ b/test/e2e/src/pom/highlightsGraphPage.ts @@ -0,0 +1,16 @@ +import { Page } from '@playwright/test'; +import { VideoComponent } from '../../components/videoComponent'; +import { BasePage } from './BasePage'; +const HIGHLIGHTS_GRAPH_PAGE_VIDEO_SELECTOR = '//*[@id="player_html5_api"]'; + +/** + * Video player examples highlight graph page object + */ +export class HighlightsGraphPage extends BasePage { + public videoHighlightsGraphPage: VideoComponent; + + constructor(page: Page) { + super(page); + this.videoHighlightsGraphPage = new VideoComponent(page, HIGHLIGHTS_GRAPH_PAGE_VIDEO_SELECTOR); + } +} diff --git a/test/e2e/src/pom/mainPage.ts b/test/e2e/src/pom/mainPage.ts index dbcd7c58..147fe3a9 100644 --- a/test/e2e/src/pom/mainPage.ts +++ b/test/e2e/src/pom/mainPage.ts @@ -1,16 +1,16 @@ import { Page } from '@playwright/test'; import { VideoComponent } from '../../components/videoComponent'; +import { BasePage } from './BasePage'; const MAIN_PAGE_VIDEO_SELECTOR = '//*[@id="player_html5_api"]'; /** * Video player examples main page object */ -export class MainPage { - private page: Page; +export class MainPage extends BasePage { public videoMainPage: VideoComponent; constructor(page: Page) { - this.page = page; + super(page); this.videoMainPage = new VideoComponent(page, MAIN_PAGE_VIDEO_SELECTOR); } diff --git a/test/e2e/testData/pageLinksData.ts b/test/e2e/testData/pageLinksData.ts index 82cf6265..fa0b3d39 100644 --- a/test/e2e/testData/pageLinksData.ts +++ b/test/e2e/testData/pageLinksData.ts @@ -1,43 +1,92 @@ import { ExampleLinkType } from '../types/exampleLinkType'; +/** + * Enum representing the names of example pages. + */ +export enum ExampleLinkName { + AdaptiveStreaming = 'Adaptive Streaming', + AIHighlightsGraph = 'AI Highlights Graph', + Analytics = 'Analytics', + APIAndEvents = 'API and Events', + AudioPlayer = 'Audio Player', + AutoplayOnScroll = 'Autoplay on Scroll', + Chapters = 'Chapters', + CloudinaryAnalytics = 'Cloudinary Analytics', + CodecsAndFormats = 'Codecs and formats', + ColorsAPI = 'Colors API', + Components = 'Components', + CustomErrors = 'Custom Errors', + DisplayConfigurations = 'Display Configurations', + DebugMode = 'Debug mode', + ESModuleImports = 'ES Module Imports', + FloatingPlayer = 'Floating Player', + FluidLayouts = 'Fluid Layouts', + ForceHLSSubtitles = 'Force HLS Subtitles', + HighlightsGraph = 'Highlights Graph', + InteractionArea = 'Interaction Area', + MultiplePlayers = 'Multiple Players', + Playlist = 'Playlist', + PlaylistByTag = 'Playlist by Tag', + PosterOptions = 'Poster Options', + Profiles = 'Profiles', + RawURL = 'Raw URL', + Recommendations = 'Recommendations', + SeekThumbnails = 'Seek Thumbnails', + ShoppableVideos = 'Shoppable Videos', + SubtitlesAndCaptions = 'Subtitles & Captions', + VideoTransformations = 'Video Transformations', + UIConfig = 'UI Config', + VASTAndVPAIDSupport = 'VAST & VPAID Support', + VR360Videos = 'VR/360 Videos', + EmbeddedIframePlayer = 'Embedded (iframe) player', + ESMImports = 'ESM Imports', +} + /** * Array of all the examples pages names and links. */ export const LINKS: ExampleLinkType[] = [ - { name: 'Adaptive Streaming', endpoint: 'adaptive-streaming.html' }, - { name: 'AI Highlights Graph', endpoint: 'highlights-graph.html' }, - { name: 'Analytics', endpoint: 'analytics.html' }, - { name: 'API and Events', endpoint: 'api.html' }, - { name: 'Audio Player', endpoint: 'audio.html' }, - { name: 'Autoplay on Scroll', endpoint: 'autoplay-on-scroll.html' }, - { name: 'Chapters', endpoint: 'chapters.html' }, - { name: 'Cloudinary Analytics', endpoint: 'cloudinary-analytics.html' }, - { name: 'Codecs and formats', endpoint: 'codec-formats.html' }, - { name: 'Colors API', endpoint: 'colors.html' }, - { name: 'Components', endpoint: 'components.html' }, - { name: 'Custom Errors', endpoint: 'custom-cld-errors.html' }, - { name: 'Display Configurations', endpoint: 'ui-config.html' }, - { name: 'Debug mode', endpoint: 'debug.html' }, - { name: 'ES Module Imports', endpoint: 'es-imports.html' }, - { name: 'Floating Player', endpoint: 'floating-player.html' }, - { name: 'Fluid Layouts', endpoint: 'fluid.html' }, - { name: 'Force HLS Subtitles', endpoint: 'force-hls-subtitles-ios.html' }, - { name: 'Highlights Graph', endpoint: 'highlights-graph.html' }, - { name: 'Interaction Area', endpoint: 'interaction-area.html' }, - { name: 'Multiple Players', endpoint: 'multiple-players.html' }, - { name: 'Playlist', endpoint: 'playlist.html' }, - { name: 'Playlist by Tag', endpoint: 'playlist-by-tag-captions.html' }, - { name: 'Poster Options', endpoint: 'poster.html' }, - { name: 'Profiles', endpoint: 'profiles.html' }, - { name: 'Raw URL', endpoint: 'raw-url.html' }, - { name: 'Recommendations', endpoint: 'recommendations.html' }, - { name: 'Seek Thumbnails', endpoint: 'seek-thumbs.html' }, - { name: 'Shoppable Videos', endpoint: 'shoppable.html' }, - { name: 'Subtitles & Captions', endpoint: 'subtitles-and-captions.html' }, - { name: 'Video Transformations', endpoint: 'transformations.html' }, - { name: 'UI Config', endpoint: 'ui-config.html' }, - { name: 'VAST & VPAID Support', endpoint: 'vast-vpaid.html' }, - { name: 'VR/360 Videos', endpoint: '360.html' }, - { name: 'Embedded (iframe) player', endpoint: 'embedded-iframe.html' }, - { name: 'ESM Imports', endpoint: 'cld-vp-esm-pages.netlify.app' }, + { name: ExampleLinkName.AdaptiveStreaming, endpoint: 'adaptive-streaming.html' }, + { name: ExampleLinkName.AIHighlightsGraph, endpoint: 'highlights-graph.html' }, + { name: ExampleLinkName.Analytics, endpoint: 'analytics.html' }, + { name: ExampleLinkName.APIAndEvents, endpoint: 'api.html' }, + { name: ExampleLinkName.AudioPlayer, endpoint: 'audio.html' }, + { name: ExampleLinkName.AutoplayOnScroll, endpoint: 'autoplay-on-scroll.html' }, + { name: ExampleLinkName.Chapters, endpoint: 'chapters.html' }, + { name: ExampleLinkName.CloudinaryAnalytics, endpoint: 'cloudinary-analytics.html' }, + { name: ExampleLinkName.CodecsAndFormats, endpoint: 'codec-formats.html' }, + { name: ExampleLinkName.ColorsAPI, endpoint: 'colors.html' }, + { name: ExampleLinkName.Components, endpoint: 'components.html' }, + { name: ExampleLinkName.CustomErrors, endpoint: 'custom-cld-errors.html' }, + { name: ExampleLinkName.DisplayConfigurations, endpoint: 'ui-config.html' }, + { name: ExampleLinkName.DebugMode, endpoint: 'debug.html' }, + { name: ExampleLinkName.ESModuleImports, endpoint: 'es-imports.html' }, + { name: ExampleLinkName.FloatingPlayer, endpoint: 'floating-player.html' }, + { name: ExampleLinkName.FluidLayouts, endpoint: 'fluid.html' }, + { name: ExampleLinkName.ForceHLSSubtitles, endpoint: 'force-hls-subtitles-ios.html' }, + { name: ExampleLinkName.HighlightsGraph, endpoint: 'highlights-graph.html' }, + { name: ExampleLinkName.InteractionArea, endpoint: 'interaction-area.html' }, + { name: ExampleLinkName.MultiplePlayers, endpoint: 'multiple-players.html' }, + { name: ExampleLinkName.Playlist, endpoint: 'playlist.html' }, + { name: ExampleLinkName.PlaylistByTag, endpoint: 'playlist-by-tag-captions.html' }, + { name: ExampleLinkName.PosterOptions, endpoint: 'poster.html' }, + { name: ExampleLinkName.Profiles, endpoint: 'profiles.html' }, + { name: ExampleLinkName.RawURL, endpoint: 'raw-url.html' }, + { name: ExampleLinkName.Recommendations, endpoint: 'recommendations.html' }, + { name: ExampleLinkName.SeekThumbnails, endpoint: 'seek-thumbs.html' }, + { name: ExampleLinkName.ShoppableVideos, endpoint: 'shoppable.html' }, + { name: ExampleLinkName.SubtitlesAndCaptions, endpoint: 'subtitles-and-captions.html' }, + { name: ExampleLinkName.VideoTransformations, endpoint: 'transformations.html' }, + { name: ExampleLinkName.UIConfig, endpoint: 'ui-config.html' }, + { name: ExampleLinkName.VASTAndVPAIDSupport, endpoint: 'vast-vpaid.html' }, + { name: ExampleLinkName.VR360Videos, endpoint: '360.html' }, + { name: ExampleLinkName.EmbeddedIframePlayer, endpoint: 'embedded-iframe.html' }, + { name: ExampleLinkName.ESMImports, endpoint: 'cld-vp-esm-pages.netlify.app' }, ]; + +/** + * Retrieves an example link object from the `LINKS` array based on a given name. + */ +export function getLinkByName(name: ExampleLinkName): ExampleLinkType { + return LINKS.find((link) => link.name === name); +} diff --git a/test/e2e/types/exampleLinkType.ts b/test/e2e/types/exampleLinkType.ts index 0b649bbc..4d536de7 100644 --- a/test/e2e/types/exampleLinkType.ts +++ b/test/e2e/types/exampleLinkType.ts @@ -1,4 +1,6 @@ +import { ExampleLinkName } from '../testData/pageLinksData'; + /** * Example links type */ -export type ExampleLinkType = { name: string; endpoint: string }; +export type ExampleLinkType = { name: ExampleLinkName; endpoint: string };