-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Roee Dean
authored and
Roee Dean
committed
Dec 24, 2024
1 parent
9580b11
commit 0352a0b
Showing
16 changed files
with
1,450 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import {defineConfig} from 'cypress'; | ||
|
||
export default defineConfig({ | ||
experimentalWebKitSupport: true, | ||
chromeWebSecurity: false, | ||
defaultCommandTimeout: 30000, | ||
fileServerFolder: 'cypress/public', | ||
e2e: { | ||
supportFile: false, | ||
watchForFileChanges: false | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
public/playkit-related.js | ||
public/playkit-related.js.map |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,284 @@ | ||
declare global { | ||
interface Window { | ||
KalturaPlayer: { | ||
setup: (config: any) => any; | ||
getPlayer: () => any; | ||
}; | ||
} | ||
} | ||
|
||
import { | ||
clickOnNextButton, | ||
clickOnListToggle, | ||
clickOnCloseButton, | ||
clickOnRelatedEntry | ||
} from './utils/actions'; | ||
import { | ||
expectElementContains, | ||
expectElementDoesntExist, | ||
expectElementExists, | ||
expectRelatedGridVisible, | ||
expectRelatedListVisible, | ||
setupAndExpect | ||
} from './utils/expects'; | ||
import { | ||
getRelatedGridElement, | ||
getRelatedListElement, | ||
getNextButtonElement, | ||
getListToggleButtonElement, | ||
getCountdownElement, | ||
getCloseButtonElement | ||
} from './utils/getters'; | ||
import {loadPlayerAndSetMedia, mockRelatedEntries, getPlayer} from './utils/setup'; | ||
import {DEFAULT_COUNTDOWN_TIME, DEFAULT_ENTRIES_LIMIT} from './utils/values'; | ||
|
||
describe('Related plugin', () => { | ||
describe('entry relation methods', () => { | ||
beforeEach(() => { | ||
// Mock playlist API response | ||
cy.intercept('GET', '**/service/playlist/execute*', { | ||
body: { | ||
data: mockRelatedEntries | ||
} | ||
}); | ||
|
||
// Mock context API response | ||
cy.intercept('GET', '**/service/playlist*', req => { | ||
if (req.body?.filter?.objectType === 'KalturaMediaEntryFilterForPlaylist') { | ||
req.reply({ | ||
data: mockRelatedEntries | ||
}); | ||
} | ||
}); | ||
}); | ||
|
||
it('should load related entries from playlistId', () => { | ||
const playlistId = 'test_playlist_123'; | ||
setupAndExpect({playlistId}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
expectElementContains(getRelatedListElement, [mockRelatedEntries[0].name, mockRelatedEntries[1].name]); | ||
}); | ||
}); | ||
|
||
it('should load related entries from entryList', () => { | ||
const entryList = mockRelatedEntries.map(entry => ({ | ||
entryId: entry.id, | ||
...entry | ||
})); | ||
setupAndExpect({entryList}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
expectElementContains(getRelatedListElement, [mockRelatedEntries[0].name, mockRelatedEntries[1].name]); | ||
}); | ||
}); | ||
|
||
it('should load related entries from sourcesList', () => { | ||
const sourcesList = mockRelatedEntries.map(entry => ({ | ||
id: entry.id, | ||
duration: entry.duration, | ||
metadata: { | ||
name: entry.name, | ||
description: entry.description | ||
}, | ||
poster: entry.thumbnailUrl, | ||
progressive: [ | ||
{ | ||
mimetype: 'video/mp4', | ||
url: 'test-video.mp4' | ||
} | ||
] | ||
})); | ||
setupAndExpect({sourcesList}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
expectElementContains(getRelatedListElement, [mockRelatedEntries[0].name, mockRelatedEntries[1].name]); | ||
}); | ||
}); | ||
|
||
it('should load related entries using context when useContext is true', () => { | ||
setupAndExpect({useContext: true, entriesByContextLimit: 2}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
expectElementContains(getRelatedListElement, [mockRelatedEntries[0].name, mockRelatedEntries[1].name]); | ||
}); | ||
}); | ||
|
||
it('should prioritize playlistId over other methods', () => { | ||
const playlistEntries = [ | ||
{ | ||
id: 'playlist_1', | ||
name: 'Playlist Video 1', | ||
description: 'From Playlist', | ||
thumbnailUrl: 'thumb1.jpg', | ||
duration: 120 | ||
} | ||
]; | ||
|
||
// Mock playlist response with different entries | ||
cy.intercept('GET', '**/service/playlist/execute*', { | ||
body: { | ||
data: playlistEntries | ||
} | ||
}); | ||
|
||
setupAndExpect({ | ||
playlistId: 'test_playlist', | ||
entryList: mockRelatedEntries, | ||
sourcesList: mockRelatedEntries, | ||
useContext: true | ||
}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
expectElementContains(getRelatedListElement, [playlistEntries[0].name]); | ||
expectElementDoesntExist(() => cy.contains(mockRelatedEntries[0].name)); | ||
}); | ||
}); | ||
|
||
it('should prioritize entryList over sourcesList and context', () => { | ||
const sourcesList = [{ | ||
id: 'source_1', | ||
metadata: { name: 'Source Video' }, | ||
progressive: [{ mimetype: 'video/mp4', url: 'test.mp4' }] | ||
}]; | ||
|
||
setupAndExpect({ | ||
entryList: mockRelatedEntries, | ||
sourcesList, | ||
useContext: true | ||
}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
expectElementContains(getRelatedListElement, [mockRelatedEntries[0].name]); | ||
expectElementDoesntExist(() => cy.contains('Source Video')); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('initialization', () => { | ||
it('should not show related content by default when video starts', () => { | ||
setupAndExpect({}, loadPlayerAndSetMedia, () => { | ||
expectElementDoesntExist(getRelatedGridElement); | ||
expectElementDoesntExist(getRelatedListElement); | ||
}); | ||
}); | ||
|
||
it('should load with provided related entries', () => { | ||
setupAndExpect({entryList: mockRelatedEntries}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
expectElementContains(getRelatedListElement, [mockRelatedEntries[0].name, mockRelatedEntries[1].name]); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('list view', () => { | ||
beforeEach(() => { | ||
cy.intercept('GET', '**/service/playlist*', { | ||
body: { | ||
data: mockRelatedEntries | ||
} | ||
}); | ||
}); | ||
|
||
it('should show list view when toggle button is clicked', () => { | ||
setupAndExpect({entryList: mockRelatedEntries}, loadPlayerAndSetMedia, () => { | ||
expectElementDoesntExist(getRelatedListElement); | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
}); | ||
}); | ||
|
||
it('should hide list view when close button is clicked', () => { | ||
setupAndExpect({entryList: mockRelatedEntries}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
expectElementExists(getRelatedListElement); | ||
clickOnCloseButton(); | ||
expectElementDoesntExist(getRelatedListElement); | ||
}); | ||
}); | ||
|
||
it('should play selected entry when clicked', () => { | ||
setupAndExpect({entryList: mockRelatedEntries}, loadPlayerAndSetMedia, () => { | ||
clickOnListToggle(); | ||
clickOnRelatedEntry(0); | ||
// Verify the video source has changed to the selected entry | ||
cy.window().then(win => { | ||
expect((win as any).KalturaPlayer.getPlayer().sources.id).to.equal(mockRelatedEntries[0].id); | ||
}); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('auto continue', () => { | ||
it('should show countdown when video ends with autoContinue enabled', () => { | ||
setupAndExpect({entryList: mockRelatedEntries, autoContinue: true}, loadPlayerAndSetMedia, player => { | ||
player.currentTime = player.duration; | ||
expectElementExists(getCountdownElement); | ||
}); | ||
}); | ||
|
||
it('should not show countdown when autoContinue is disabled', () => { | ||
setupAndExpect({entryList: mockRelatedEntries, autoContinue: false}, loadPlayerAndSetMedia, player => { | ||
player.currentTime = player.duration; | ||
expectElementDoesntExist(getCountdownElement); | ||
}); | ||
}); | ||
|
||
it('should auto continue to next video after countdown', () => { | ||
setupAndExpect( | ||
{entryList: mockRelatedEntries, autoContinue: true, autoContinueTime: 1}, | ||
loadPlayerAndSetMedia, | ||
player => { | ||
player.currentTime = player.duration; | ||
cy.wait(1500).then(() => { | ||
cy.window().then(win => { | ||
expect((win as any).KalturaPlayer.getPlayer().sources.id).to.equal(mockRelatedEntries[0].id); | ||
}); | ||
}); | ||
} | ||
); | ||
}); | ||
}); | ||
|
||
describe('grid view', () => { | ||
it('should show grid view on pause when showOnPlaybackPaused is true', () => { | ||
setupAndExpect({entryList: mockRelatedEntries, showOnPlaybackPaused: true}, loadPlayerAndSetMedia, player => { | ||
player.pause(); | ||
expectElementExists(getRelatedGridElement); | ||
}); | ||
}); | ||
|
||
it('should not show grid view on pause when showOnPlaybackPaused is false', () => { | ||
setupAndExpect({entryList: mockRelatedEntries, showOnPlaybackPaused: false}, loadPlayerAndSetMedia, player => { | ||
player.pause(); | ||
expectElementDoesntExist(getRelatedGridElement); | ||
}); | ||
}); | ||
|
||
it('should play selected entry from grid when clicked', () => { | ||
setupAndExpect({entryList: mockRelatedEntries, showOnPlaybackPaused: true}, loadPlayerAndSetMedia, player => { | ||
player.pause(); | ||
clickOnRelatedEntry(0); | ||
expect(getPlayer().sources.id).to.equal(mockRelatedEntries[0].id); | ||
}); | ||
}); | ||
}); | ||
|
||
describe('next button', () => { | ||
it('should show next button when there are related entries', () => { | ||
setupAndExpect({entryList: mockRelatedEntries}, loadPlayerAndSetMedia, () => { | ||
expectElementExists(getNextButtonElement); | ||
}); | ||
}); | ||
|
||
it('should play next entry when next button is clicked', () => { | ||
setupAndExpect({entryList: mockRelatedEntries}, loadPlayerAndSetMedia, () => { | ||
clickOnNextButton(); | ||
cy.window().then(win => { | ||
expect((win as any).KalturaPlayer.getPlayer().sources.id).to.equal(mockRelatedEntries[0].id); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import {getNextButtonElement, getListToggleButtonElement, getCloseButtonElement, getRelatedEntryElement} from './getters'; | ||
|
||
export const clickOnNextButton = () => { | ||
getNextButtonElement().click({force: true}); | ||
}; | ||
|
||
export const clickOnListToggle = () => { | ||
getListToggleButtonElement().click({force: true}); | ||
}; | ||
|
||
export const clickOnCloseButton = () => { | ||
getCloseButtonElement().click({force: true}); | ||
}; | ||
|
||
export const clickOnRelatedEntry = (index: number) => { | ||
getRelatedEntryElement(index).click({force: true}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import {getRelatedGridElement, getRelatedListElement, getNextButtonElement} from './getters'; | ||
import {loadPlayerAndSetMedia} from './setup'; | ||
|
||
export const setupAndExpect = (pluginConfig: any, setupFunc: (pluginConfig: any) => Promise<any>, expectFunc: (setupResult: any) => void) => { | ||
setupFunc(pluginConfig).then(result => { | ||
expectFunc(result); | ||
}); | ||
}; | ||
|
||
export const expectElementExists = (getElement: () => any) => { | ||
getElement().should('exist'); | ||
}; | ||
|
||
export const expectElementDoesntExist = (getElement: () => any) => { | ||
getElement().should('not.exist'); | ||
}; | ||
|
||
export const expectElementContains = (getElement: () => any, texts: string[]) => { | ||
for (const text of texts) { | ||
getElement().contains(text).should('exist'); | ||
} | ||
}; | ||
|
||
export const expectRelatedGridVisible = (pluginConfig: any) => { | ||
setupAndExpect(pluginConfig, loadPlayerAndSetMedia, () => { | ||
expectElementExists(getRelatedGridElement); | ||
}); | ||
}; | ||
|
||
export const expectRelatedListVisible = (pluginConfig: any) => { | ||
setupAndExpect(pluginConfig, loadPlayerAndSetMedia, () => { | ||
expectElementExists(getRelatedListElement); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export const getRelatedGridElement = () => cy.get('[data-testid="related-grid"]'); | ||
export const getRelatedListElement = () => cy.get('[data-testid="related-list"]'); | ||
export const getRelatedEntryElement = (index: number) => cy.get(`[data-testid="related-entry-${index}"]`); | ||
export const getNextButtonElement = () => cy.get('[data-testid="related-next-button"]'); | ||
export const getListToggleButtonElement = () => cy.get('.listToggleButton'); | ||
export const getCountdownElement = () => cy.get('[data-testid="related-countdown"]'); | ||
export const getCloseButtonElement = () => cy.get('[data-testid="related-close-button"]'); |
Oops, something went wrong.