feat(test): add e2e tests for song context menu

This commit is contained in:
Phan An 2021-01-02 12:58:46 +01:00
parent 1c39a59449
commit 67703be7ca
11 changed files with 208 additions and 96 deletions

View file

@ -69,17 +69,17 @@
{
"id": 3,
"name": "The Band",
"image": null
"image": "http://localhost:8088/test/images/sample.png"
},
{
"id": 1,
"name": "Unknown Artist",
"image": null
"image": "http://localhost:8088/test/images/sample.png"
},
{
"id": 2,
"name": "Various Artists",
"image": null
"image": "http://localhost:8088/test/images/sample.png"
}
],
"songs": [

View file

@ -69,17 +69,17 @@
{
"id": 3,
"name": "The Band",
"image": null
"image": "http://localhost:8088/test/images/sample.png"
},
{
"id": 1,
"name": "Unknown Artist",
"image": null
"image": "http://localhost:8088/test/images/sample.png"
},
{
"id": 2,
"name": "Various Artists",
"image": null
"image": "http://localhost:8088/test/images/sample.png"
}
],
"songs": [

View file

@ -1,11 +1,6 @@
context('Favorites', { scrollBehavior: false }, () => {
beforeEach(() => cy.$login())
function assertFavoriteCount (count: number) {
cy.$clickSidebarItem('Favorites')
cy.get('#favoritesWrapper').within(() => cy.get('tr.song-item').should('have.length', count))
}
it('loads the list of favorites', () => {
cy.$clickSidebarItem('Favorites')
@ -37,7 +32,7 @@ context('Favorites', { scrollBehavior: false }, () => {
.within(() => cy.get('[data-test=btn-like-liked]').should('be.visible'))
})
assertFavoriteCount(4)
cy.$assertFavoriteSongCount(4)
})
it('adds a favorite song from Add To dropdown', () => {
@ -57,24 +52,9 @@ context('Favorites', { scrollBehavior: false }, () => {
.should('not.be.visible')
})
assertFavoriteCount(4)
cy.$assertFavoriteSongCount(4)
})
it('adds a favorite song from context menu', () => {
cy.intercept('POST', '/api/interaction/like', {
fixture: 'like.post.200.json'
})
cy.$clickSidebarItem('All Songs')
cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick())
cy.findByTestId('song-context-menu').within(() => {
cy.findByText('Add To').click()
cy.findByText('Favorites').click()
})
assertFavoriteCount(4)
})
it('deletes a favorite with Unlike button', () => {
cy.intercept('POST', '/api/interaction/like', {})

View file

@ -1,11 +1,6 @@
context('Playlists', () => {
beforeEach(() => cy.$login())
const assertPlaylistSongCount = (name: string, count: number) => {
cy.$clickSidebarItem(name)
cy.get('#playlistWrapper tr.song-item').should('have.length', count)
}
it('displays a playlist when sidebar menu item is clicked', () => {
cy.intercept('GET', '/api/playlist/1/songs', {
fixture: 'playlist-songs.get.200.json'
@ -102,11 +97,9 @@ context('Playlists', () => {
fixture: 'playlist-songs.get.200.json'
})
cy.intercept('PUT', '/api/playlist/1/sync', {
fixture: 'playlist.post.200.json'
})
cy.intercept('PUT', '/api/playlist/1/sync', {})
assertPlaylistSongCount('Simple Playlist', 3)
cy.$assertPlaylistSongCount('Simple Playlist', 3)
cy.$clickSidebarItem('All Songs')
@ -121,7 +114,7 @@ context('Playlists', () => {
})
cy.findByText('Added 2 songs into "Simple Playlist".').should('be.visible')
assertPlaylistSongCount('Simple Playlist', 5)
cy.$assertPlaylistSongCount('Simple Playlist', 5)
})
it('creates a playlist directly from songs', () => {
@ -148,7 +141,7 @@ context('Playlists', () => {
.and('have.class', 'active')
cy.findByText('Created playlist "A New Playlist".').should('be.visible')
assertPlaylistSongCount('A New Playlist', 3)
cy.$assertPlaylistSongCount('A New Playlist', 3)
})
it('updates a simple playlist from the sidebar', () => {
@ -245,7 +238,7 @@ context('Playlists', () => {
.findByText('My Smart Playlist')
.should('have.class', 'active')
assertPlaylistSongCount('My Smart Playlist', 3)
cy.$assertPlaylistSongCount('My Smart Playlist', 3)
})
it('updates a smart playlist', () => {

View file

@ -47,21 +47,8 @@ context('Queuing', { scrollBehavior: false }, () => {
})
})
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.$queueSeveralSongs()
cy.get('#queueWrapper').within(() => {
cy.get('tr.song-item').should('have.length', 3)
@ -70,7 +57,7 @@ context('Queuing', { scrollBehavior: false }, () => {
})
it('deletes a song from queue', () => {
queueSomeFromSongList()
cy.$queueSeveralSongs()
cy.get('#queueWrapper').within(() => {
cy.get('tr.song-item').should('have.length', 3)
@ -79,44 +66,8 @@ context('Queuing', { scrollBehavior: false }, () => {
})
})
;([
{ 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)
})
})
})
it('queues a song when plays it', () => {
queueSomeFromSongList()
cy.$queueSeveralSongs()
cy.$clickSidebarItem('All Songs')
let songTitle

View file

@ -0,0 +1,153 @@
context('Song Context Menu', { scrollBehavior: false }, () => {
beforeEach(() => {
cy.$login()
cy.$clickSidebarItem('All Songs')
})
it('plays a song via double-clicking', () => {
cy.$mockPlayback()
cy.get('#songsWrapper').within(() => {
cy.get('tr.song-item:first-child').dblclick()
cy.get('tr.song-item:first-child').should('have.class', 'playing')
})
})
it('plays a song via context menu', () => {
cy.$mockPlayback()
cy.get('#songsWrapper').within(() => {
cy.get('tr.song-item:first-child')
.as('item')
.rightclick()
})
cy.findByTestId('song-context-menu').within(() => cy.findByText('Play').click())
cy.get('@item').should('have.class', 'playing')
})
it('goes to album', () => {
cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick())
cy.findByTestId('song-context-menu').within(() => cy.findByText('Go to Album').click())
cy.get('#albumWrapper')
.should('be.visible')
.within(() => {
cy.get('.screen-header').should('be.visible')
cy.get('tr.song-item').should('have.length.at.least', 1)
})
})
it('goes to artist', () => {
cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick())
cy.findByTestId('song-context-menu').within(() => cy.findByText('Go to Artist').click())
cy.get('#artistWrapper')
.should('be.visible')
.within(() => {
cy.get('.screen-header').should('be.visible')
cy.get('tr.song-item').should('have.length.at.least', 1)
})
})
;([
{ 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}`, () => {
cy.$queueSeveralSongs()
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').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)
})
})
})
;[
{ name: 'one song', songCount: 1 },
{ name: 'several songs', songCount: 2 }
].forEach((config) => {
it(`add ${config.name} into a simple playlist`, () => {
cy.intercept('GET', '/api/playlist/1/songs', {
fixture: 'playlist-songs.get.200.json'
})
cy.intercept('PUT', '/api/playlist/1/sync', {})
cy.$assertPlaylistSongCount('Simple Playlist', 3)
cy.get('#songsWrapper').within(() => {
cy.get('tr.song-item:first-child').click()
if (config.songCount > 1) {
cy.get(`tr.song-item:nth-child(${config.songCount})`).click({ shiftKey: true })
}
cy.get('tr.song-item:first-child').rightclick()
})
cy.findByTestId('song-context-menu')
.within(() => {
cy.findByText('Add To').click()
cy.findByText('Simple Playlist').click()
})
cy.$assertPlaylistSongCount('Simple Playlist', 3 + config.songCount)
})
})
it('does not have smart playlists as target for adding songs', () => {
cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick())
cy.findByTestId('song-context-menu')
.within(() => {
cy.findByText('Add To').click()
cy.findByText('Smart Playlist').should('not.exist')
})
})
it('adds a favorite song from context menu', () => {
cy.intercept('POST', '/api/interaction/like', {
fixture: 'like.post.200.json'
})
cy.$assertFavoriteSongCount(3)
cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick())
cy.findByTestId('song-context-menu').within(() => {
cy.findByText('Add To').click()
cy.findByText('Favorites').click()
})
cy.$assertFavoriteSongCount(4)
})
it.only('initiates editing a song', () => {
cy.intercept('GET', '/api/**/info', {
fixture: 'info.get.200.json'
})
cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick())
cy.findByTestId('song-context-menu').within(() => cy.findByText('Edit').click())
cy.findByTestId('edit-song-form').should('be.visible')
})
})

View file

@ -0,0 +1,3 @@
context.skip('Song Editing', () => {
// @todo Write tests for song editing
})

View file

@ -1,3 +0,0 @@
context('Queuing', { scrollBehavior: false }, () => {
})

View file

@ -50,3 +50,29 @@ Cypress.Commands.add('$mockPlayback', () => {
fixture: 'info.get.200.json'
})
})
Cypress.Commands.add('$queueSeveralSongs', (count = 3) => {
cy.$mockPlayback()
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()
})
})
Cypress.Commands.add('$assertPlaylistSongCount', (name: string, count: number) => {
cy.$clickSidebarItem(name)
cy.get('#playlistWrapper tr.song-item').should('have.length', count)
cy.go('back')
})
Cypress.Commands.add('$assertFavoriteSongCount', (count: number) => {
cy.$clickSidebarItem('Favorites')
cy.get('#favoritesWrapper').within(() => cy.get('tr.song-item').should('have.length', count))
cy.go('back')
})

9
cypress/types.d.ts vendored
View file

@ -11,6 +11,15 @@ declare namespace Cypress {
*/
$mockPlayback(): void
/**
* Queue several songs from the All Song screen.
* @param count
*/
$queueSeveralSongs(count?: number): void
$assertPlaylistSongCount(name: string, count: number): void
$assertFavoriteSongCount(count: number): void
/**
* Support finding an element within an element identified with a test ID.
* For example, given a DOM like this:

@ -1 +1 @@
Subproject commit 9e72452c39d09a275ebbcb5aa25531e7f66525a1
Subproject commit 925ebc48432a3fa401ea21a35508a8d48e42079c