mirror of
https://github.com/koel/koel
synced 2024-11-10 06:34:14 +00:00
feat(test): add e2e tests for song context menu
This commit is contained in:
parent
1c39a59449
commit
67703be7ca
11 changed files with 208 additions and 96 deletions
|
@ -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": [
|
||||
|
|
|
@ -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": [
|
||||
|
|
|
@ -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', {})
|
||||
|
|
|
@ -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', () => {
|
||||
|
|
|
@ -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
|
||||
|
|
153
cypress/integration/song-context-menu.spec.ts
Normal file
153
cypress/integration/song-context-menu.spec.ts
Normal 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')
|
||||
})
|
||||
})
|
3
cypress/integration/song-editing.spec.ts
Normal file
3
cypress/integration/song-editing.spec.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
context.skip('Song Editing', () => {
|
||||
// @todo Write tests for song editing
|
||||
})
|
|
@ -1,3 +0,0 @@
|
|||
context('Queuing', { scrollBehavior: false }, () => {
|
||||
|
||||
})
|
|
@ -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
9
cypress/types.d.ts
vendored
|
@ -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
|
Loading…
Reference in a new issue