mirror of
https://github.com/koel/koel
synced 2024-11-24 13:13:05 +00:00
feat(test): add e2e test for queue
This commit is contained in:
parent
2b8d2b248f
commit
db9bb9ef5f
9 changed files with 258 additions and 3 deletions
3
cypress/fixtures/album-thumbnail.get.200.json
Normal file
3
cypress/fixtures/album-thumbnail.get.200.json
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"thumbnailUrl": "http://localhost:8080/test/images/sample.png"
|
||||||
|
}
|
|
@ -507,7 +507,7 @@
|
||||||
"useiTunes": true,
|
"useiTunes": true,
|
||||||
"allowDownload": true,
|
"allowDownload": true,
|
||||||
"supportsTranscoding": false,
|
"supportsTranscoding": false,
|
||||||
"cdnUrl": "http://localhost:8088",
|
"cdnUrl": "http://localhost:8088/",
|
||||||
"currentVersion": "v5.0.0",
|
"currentVersion": "v5.0.0",
|
||||||
"latestVersion": "v5.0.1"
|
"latestVersion": "v5.0.1"
|
||||||
}
|
}
|
||||||
|
|
|
@ -528,7 +528,7 @@
|
||||||
"useiTunes": true,
|
"useiTunes": true,
|
||||||
"allowDownload": true,
|
"allowDownload": true,
|
||||||
"supportsTranscoding": false,
|
"supportsTranscoding": false,
|
||||||
"cdnUrl": "http://localhost:8088",
|
"cdnUrl": "http://localhost:8088/",
|
||||||
"currentVersion": "v5.0.0",
|
"currentVersion": "v5.0.0",
|
||||||
"latestVersion": "v5.0.1"
|
"latestVersion": "v5.0.1"
|
||||||
}
|
}
|
||||||
|
|
117
cypress/fixtures/info.get.200.json
Normal file
117
cypress/fixtures/info.get.200.json
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
{
|
||||||
|
"lyrics": "Sample song lyrics",
|
||||||
|
"album_info": {
|
||||||
|
"url": "https://www.last.fm/music/Sample+Artist/Sample+Album",
|
||||||
|
"image": "http://localhost:8080/test/images/sample.png",
|
||||||
|
"wiki": {
|
||||||
|
"summary": "Album summary",
|
||||||
|
"full": "Album full wiki"
|
||||||
|
},
|
||||||
|
"tracks": [
|
||||||
|
{
|
||||||
|
"title": "Album track #1",
|
||||||
|
"length": 156,
|
||||||
|
"url": "https://www.last.fm/music/Sample-Artist/Album+track+1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Album track #2",
|
||||||
|
"length": 247,
|
||||||
|
"url": "https://www.last.fm/music/Sample+Artist/Album+track+2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Album track #3",
|
||||||
|
"length": 237,
|
||||||
|
"url": "https://www.last.fm/music/Sample+Artist/Album+track+3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"cover": "http://localhost:8080/test/images/sample.png"
|
||||||
|
},
|
||||||
|
"artist_info": {
|
||||||
|
"url": "https://www.last.fm/music/Sample+Artist",
|
||||||
|
"image": "http://localhost:8080/test/images/sample.png",
|
||||||
|
"bio": {
|
||||||
|
"summary": "Artist summary",
|
||||||
|
"full": "Artist full bio"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"youtube": {
|
||||||
|
"kind": "youtube#searchListResponse",
|
||||||
|
"etag": "xlATxAWpLP1mZdYFUuaCReqT_5E",
|
||||||
|
"nextPageToken": "CAoQAA",
|
||||||
|
"regionCode": "DE",
|
||||||
|
"pageInfo": {
|
||||||
|
"totalResults": 1000000,
|
||||||
|
"resultsPerPage": 10
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"kind": "youtube#searchResult",
|
||||||
|
"etag": "rlsZALtflq8Sdba4Nia7uPC-l5k",
|
||||||
|
"id": {
|
||||||
|
"kind": "youtube#video",
|
||||||
|
"videoId": "L397TWLwrUU"
|
||||||
|
},
|
||||||
|
"snippet": {
|
||||||
|
"publishedAt": "2009-11-24T13:38:04Z",
|
||||||
|
"channelId": "UCStHqF-8YWv8x6SJcTFkEXA",
|
||||||
|
"title": "YouTube Video #1",
|
||||||
|
"description": "Description for YouTube Video #1",
|
||||||
|
"thumbnails": {
|
||||||
|
"default": {
|
||||||
|
"url": "http://localhost:8080/test/images/youtube-thumbnail.png",
|
||||||
|
"width": 120,
|
||||||
|
"height": 90
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"url": "http://localhost:8080/test/images/youtube-thumbnail.png",
|
||||||
|
"width": 320,
|
||||||
|
"height": 180
|
||||||
|
},
|
||||||
|
"high": {
|
||||||
|
"url": "http://localhost:8080/test/images/youtube-thumbnail.png",
|
||||||
|
"width": 480,
|
||||||
|
"height": 360
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"channelTitle": "SampleArtistVEVO",
|
||||||
|
"liveBroadcastContent": "none",
|
||||||
|
"publishTime": "2009-11-24T13:38:04Z"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "youtube#searchResult",
|
||||||
|
"etag": "AwvO6Y5jkF0O-lDHehMYTy7Hims",
|
||||||
|
"id": {
|
||||||
|
"kind": "youtube#video",
|
||||||
|
"videoId": "AMfG3sMo34s"
|
||||||
|
},
|
||||||
|
"snippet": {
|
||||||
|
"publishedAt": "2017-01-26T03:19:52Z",
|
||||||
|
"channelId": "UCy6-RHgm74I8CCCvMu4NPJQ",
|
||||||
|
"title": "YouTube Video #2",
|
||||||
|
"description": "Description for YouTube Video #2",
|
||||||
|
"thumbnails": {
|
||||||
|
"default": {
|
||||||
|
"url": "http://localhost:8080/test/images/youtube-thumbnail.png",
|
||||||
|
"width": 120,
|
||||||
|
"height": 90
|
||||||
|
},
|
||||||
|
"medium": {
|
||||||
|
"url": "http://localhost:8080/test/images/youtube-thumbnail.png",
|
||||||
|
"width": 320,
|
||||||
|
"height": 180
|
||||||
|
},
|
||||||
|
"high": {
|
||||||
|
"url": "http://localhost:8080/test/images/youtube-thumbnail.png",
|
||||||
|
"width": 480,
|
||||||
|
"height": 360
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"channelTitle": "Sample Artist - Topic",
|
||||||
|
"liveBroadcastContent": "none",
|
||||||
|
"publishTime": "2017-01-26T03:19:52Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
BIN
cypress/fixtures/sample.mp3
Normal file
BIN
cypress/fixtures/sample.mp3
Normal file
Binary file not shown.
116
cypress/integration/queuing.spec.ts
Normal file
116
cypress/integration/queuing.spec.ts
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
// Setting scrollBehavior to false because we don't want Cypress to scroll the row into view,
|
||||||
|
// causing the first row lost due to virtual scrolling.
|
||||||
|
context('Queuing', { scrollBehavior: false }, () => {
|
||||||
|
const MIN_SONG_ITEMS_SHOWN = 15
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.$mockPlayback()
|
||||||
|
cy.$login()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('allows shuffling all songs', () => {
|
||||||
|
cy.$clickSidebarItem('Current Queue')
|
||||||
|
|
||||||
|
cy.get('#queueWrapper').within(() => {
|
||||||
|
cy.findByText('Current Queue').should('be.visible')
|
||||||
|
cy.findByText('shuffling all songs').click()
|
||||||
|
cy.get('tr.song-item').should('have.length.at.least', MIN_SONG_ITEMS_SHOWN)
|
||||||
|
cy.get('tr.song-item:first-child').should('have.class', 'playing')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('clears the queue', () => {
|
||||||
|
cy.$clickSidebarItem('Current Queue')
|
||||||
|
|
||||||
|
cy.get('#queueWrapper').within(() => {
|
||||||
|
cy.findByText('Current Queue').should('be.visible')
|
||||||
|
cy.findByText('shuffling all songs').click()
|
||||||
|
cy.get('tr.song-item').should('have.length.at.least', MIN_SONG_ITEMS_SHOWN)
|
||||||
|
cy.get('.screen-header [data-test=song-list-controls]')
|
||||||
|
.findByText('Clear')
|
||||||
|
.click()
|
||||||
|
cy.get('tr.song-item').should('have.length', 0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shuffles all from a song list screen', () => {
|
||||||
|
cy.$clickSidebarItem('All Songs')
|
||||||
|
|
||||||
|
cy.get('#songsWrapper').within(() => {
|
||||||
|
cy.get('.screen-header [data-test=btn-shuffle-all]').click()
|
||||||
|
cy.url().should('contains', '/#!/queue')
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.get('#queueWrapper').within(() => {
|
||||||
|
cy.get('tr.song-item').should('have.length.at.least', MIN_SONG_ITEMS_SHOWN)
|
||||||
|
cy.get('tr.song-item:first-child').should('have.class', 'playing')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
function queueSomeFromSongList (count = 3) {
|
||||||
|
cy.$clickSidebarItem('All Songs')
|
||||||
|
|
||||||
|
cy.get('#songsWrapper').within(() => {
|
||||||
|
cy.get('tr.song-item:nth-child(1)').click()
|
||||||
|
cy.get(`tr.song-item:nth-child(${count})`).click({
|
||||||
|
shiftKey: true
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.get('.screen-header [data-test=btn-shuffle-selected]').click()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
it('creates a queue from selected songs', () => {
|
||||||
|
queueSomeFromSongList()
|
||||||
|
|
||||||
|
cy.get('#queueWrapper').within(() => {
|
||||||
|
cy.get('tr.song-item').should('have.length', 3)
|
||||||
|
cy.get('tr.song-item:first-child').should('have.class', 'playing')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('deletes a song from queue', () => {
|
||||||
|
queueSomeFromSongList()
|
||||||
|
|
||||||
|
cy.get('#queueWrapper').within(() => {
|
||||||
|
cy.get('tr.song-item').should('have.length', 3)
|
||||||
|
cy.get('tr.song-item:first-child').type('{backspace}')
|
||||||
|
cy.get('tr.song-item').should('have.length', 2)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
;([
|
||||||
|
{ menuItem: 'After Current Song', queuedPosition: 2 },
|
||||||
|
{ menuItem: 'Bottom of Queue', queuedPosition: 4 },
|
||||||
|
{ menuItem: 'Top of Queue', queuedPosition: 1 },
|
||||||
|
]).forEach(config => {
|
||||||
|
it(`queues a song to ${config.menuItem}`, () => {
|
||||||
|
queueSomeFromSongList()
|
||||||
|
|
||||||
|
cy.$clickSidebarItem('All Songs')
|
||||||
|
|
||||||
|
let songTitle
|
||||||
|
cy.get('#songsWrapper').within(() => {
|
||||||
|
cy.get('tr.song-item:nth-child(4) .title')
|
||||||
|
.invoke('text')
|
||||||
|
.then(text => {
|
||||||
|
songTitle = text
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.get('tr.song-item:nth-child(4)').rightclick()
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.findByTestId('song-context-menu').should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.findByText('Add To').click()
|
||||||
|
cy.findByText(config.menuItem).click()
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.$clickSidebarItem('Current Queue')
|
||||||
|
cy.get('#queueWrapper').within(() => {
|
||||||
|
cy.get('tr.song-item').should('have.length', 4)
|
||||||
|
cy.get(`tr.song-item:nth-child(${config.queuedPosition}) .title`).should('have.text', songTitle)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -36,3 +36,17 @@ Cypress.Commands.add('$clickSidebarItem', (sidebarItemText: string): Chainable<J
|
||||||
.findByText(sidebarItemText)
|
.findByText(sidebarItemText)
|
||||||
.click()
|
.click()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Cypress.Commands.add('$mockPlayback', () => {
|
||||||
|
cy.intercept('GET', '/play/**?api_token=mock-token', {
|
||||||
|
fixture: 'sample.mp3'
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.intercept('GET', '/api/album/**/thumbnail', {
|
||||||
|
fixture: 'album-thumbnail.get.200.json'
|
||||||
|
})
|
||||||
|
|
||||||
|
cy.intercept('GET', '/api/**/info', {
|
||||||
|
fixture: 'info.get.200.json'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
5
cypress/types.d.ts
vendored
5
cypress/types.d.ts
vendored
|
@ -6,6 +6,11 @@ declare namespace Cypress {
|
||||||
$confirm(): void
|
$confirm(): void
|
||||||
$clickSidebarItem(sidebarItemText: string): Chainable<JQuery>
|
$clickSidebarItem(sidebarItemText: string): Chainable<JQuery>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock audio playback, including intercepting the media request, album thumbnail, media info etc.
|
||||||
|
*/
|
||||||
|
$mockPlayback(): void
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support finding an element within an element identified with a test ID.
|
* Support finding an element within an element identified with a test ID.
|
||||||
* For example, given a DOM like this:
|
* For example, given a DOM like this:
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 54589044115127e9fc17609db98f2773480aceb4
|
Subproject commit 2fd5be0f98e6b3edecdc847440eb81243625705b
|
Loading…
Reference in a new issue