mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +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,
|
||||
"allowDownload": true,
|
||||
"supportsTranscoding": false,
|
||||
"cdnUrl": "http://localhost:8088",
|
||||
"cdnUrl": "http://localhost:8088/",
|
||||
"currentVersion": "v5.0.0",
|
||||
"latestVersion": "v5.0.1"
|
||||
}
|
||||
|
|
|
@ -528,7 +528,7 @@
|
|||
"useiTunes": true,
|
||||
"allowDownload": true,
|
||||
"supportsTranscoding": false,
|
||||
"cdnUrl": "http://localhost:8088",
|
||||
"cdnUrl": "http://localhost:8088/",
|
||||
"currentVersion": "v5.0.0",
|
||||
"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)
|
||||
.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
|
||||
$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.
|
||||
* For example, given a DOM like this:
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 54589044115127e9fc17609db98f2773480aceb4
|
||||
Subproject commit 2fd5be0f98e6b3edecdc847440eb81243625705b
|
Loading…
Reference in a new issue