feat(test): add e2e test for queue

This commit is contained in:
Phan An 2021-01-01 20:53:58 +01:00
parent 2b8d2b248f
commit db9bb9ef5f
9 changed files with 258 additions and 3 deletions

View file

@ -0,0 +1,3 @@
{
"thumbnailUrl": "http://localhost:8080/test/images/sample.png"
}

View file

@ -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"
}

View file

@ -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"
}

View 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

Binary file not shown.

View 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)
})
})
})
})

View file

@ -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
View file

@ -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