diff --git a/cypress/fixtures/songs-multiple.put.200.json b/cypress/fixtures/songs-multiple.put.200.json new file mode 100644 index 00000000..088ba936 --- /dev/null +++ b/cypress/fixtures/songs-multiple.put.200.json @@ -0,0 +1,51 @@ +{ + "artists": [ + { + "id": 3, + "name": "The Band", + "image": "http://localhost:8088/test/images/sample.png" + } + ], + "albums": [ + { + "id": 5, + "artist_id": 3, + "name": "The Wall", + "cover": "http://localhost:8088/test/images/sample.png", + "created_at": "2016-02-01 06:48:45", + "is_compilation": false + } + ], + "songs": [ + { + "id": "03bebf17f54e2afc7c0513fb1d931009", + "album_id": 5, + "artist_id": 3, + "title": "Instinct", + "length": 204.11, + "track": null, + "disc": 1, + "created_at": "2019-08-24 18:03:35" + }, + { + "id": "1326f8a4fc90843f07ef550c54cd88f9", + "album_id": 5, + "artist_id": 3, + "title": "Better Days", + "length": 153.84, + "track": null, + "disc": 1, + "created_at": "2019-08-24 18:03:35" + }, + { + "id": "14680f3ffef690f8521200e82f9ebb30", + "album_id": 5, + "artist_id": 3, + "title": "Acoustic Breeze", + "length": 157.2, + "track": null, + "disc": 1, + "created_at": "2019-08-24 18:03:35" + } + ] +} diff --git a/cypress/integration/playlists.spec.ts b/cypress/integration/playlists.spec.ts index 9d433ec7..b8822dad 100644 --- a/cypress/integration/playlists.spec.ts +++ b/cypress/integration/playlists.spec.ts @@ -104,8 +104,7 @@ context('Playlists', () => { cy.$clickSidebarItem('All Songs') cy.get('#songsWrapper').within(() => { - cy.get('tr.song-item:first-child').click() - cy.get('tr.song-item:nth-child(2)').click({ shiftKey: true }) + cy.$selectSongRange(1, 2) cy.get('[data-test=add-to-btn]').click() cy.get('[data-test=add-to-menu]') .should('be.visible') @@ -129,8 +128,7 @@ context('Playlists', () => { cy.$clickSidebarItem('All Songs') cy.get('#songsWrapper').within(() => { - cy.get('tr.song-item:first-child').click() - cy.get('tr.song-item:nth-child(3)').click({ shiftKey: true }) + cy.$selectSongRange(1, 3) cy.get('[data-test=add-to-btn]').click() cy.get('[data-test=new-playlist-name]').type('A New Playlist{enter}') }) diff --git a/cypress/integration/song-context-menu.spec.ts b/cypress/integration/song-context-menu.spec.ts index 6f2ecd92..afcba179 100644 --- a/cypress/integration/song-context-menu.spec.ts +++ b/cypress/integration/song-context-menu.spec.ts @@ -96,13 +96,11 @@ context('Song Context Menu', { scrollBehavior: false }, () => { 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.$selectSongRange(1, config.songCount).rightclick() + } else { + cy.get('tr.song-item:first-child').rightclick() } - - cy.get('tr.song-item:first-child').rightclick() }) cy.findByTestId('song-context-menu') diff --git a/cypress/integration/song-editing.spec.ts b/cypress/integration/song-editing.spec.ts index f47564e7..cd9b5725 100644 --- a/cypress/integration/song-editing.spec.ts +++ b/cypress/integration/song-editing.spec.ts @@ -1,4 +1,4 @@ -context('Song Editing', () => { +context('Song Editing', { scrollBehavior: false }, () => { beforeEach(() => { cy.intercept('GET', '/api/**/info', { fixture: 'info.get.200.json' @@ -6,9 +6,6 @@ context('Song Editing', () => { cy.$login() cy.$clickSidebarItem('All Songs') - - cy.get('#songsWrapper').within(() => cy.get('tr.song-item:first-child').rightclick()) - cy.findByTestId('song-context-menu').within(() => cy.findByText('Edit').click()) }) it('edits a song', () => { @@ -16,7 +13,14 @@ context('Song Editing', () => { fixture: 'songs.put.200.json' }) + cy.get('#songsWrapper tr.song-item:first-child').rightclick() + cy.findByTestId('song-context-menu').within(() => cy.findByText('Edit').click()) + cy.findByTestId('edit-song-form').within(() => { + ['artist', 'album', 'is_compilation', 'track'].forEach(selector => { + cy.get(`[name=${selector}]`).should('be.visible') + }) + cy.get('[name=title]').clear().type('New Title') cy.findByTestId('edit-song-lyrics-tab').click() cy.get('textarea[name=lyrics]') @@ -33,8 +37,50 @@ context('Song Editing', () => { cy.get('#songsWrapper tr.song-item:first-child .title').should('have.text', 'New Title') }) - it('edits a song', () => { + it('cancels editing', () => { + cy.get('#songsWrapper tr.song-item:first-child').rightclick() + cy.findByTestId('song-context-menu').within(() => cy.findByText('Edit').click()) + cy.$findInTestId('edit-song-form .btn-cancel').click() cy.findByTestId('edit-song-form').should('not.exist') }) + + it('edits multiple songs', () => { + cy.intercept('PUT', '/api/songs', { + fixture: 'songs-multiple.put.200.json' + }) + + cy.get('#songsWrapper').within(() => { + cy.$selectSongRange(1, 3).rightclick() + }) + + cy.findByTestId('song-context-menu').within(() => cy.findByText('Edit').click()) + + cy.findByTestId('edit-song-form').within(() => { + ;['title', 'track'].forEach(selector => { + cy.get(`[name=${selector}]`).should('not.exist') + }) + + cy.get('textarea[name=lyrics]').should('not.exist') + ;['3 songs selected', 'Mixed Albums'].forEach(text => cy.findByText(text).should('be.visible')) + + cy.get('[name=album]').invoke('attr', 'placeholder').should('contain', 'No change') + + // Test the typeahead/auto-complete feature + cy.get('[name=album]').type('A') + cy.findByText('Abstract').click() + cy.get('[name=album]').should('contain.value', 'Abstract') + cy.get('[name=album]').type('{downArrow}{downArrow}{downArrow}{downArrow}{enter}') + cy.get('[name=album]').should('contain.value', 'The Wall') + + cy.get('button[type=submit]').click() + }) + + cy.findByText('Updated 3 songs.').should('be.visible') + cy.findByTestId('edit-song-form').should('not.exist') + + cy.get('#songsWrapper tr.song-item:nth-child(1) .album').should('have.text', 'The Wall') + cy.get('#songsWrapper tr.song-item:nth-child(2) .album').should('have.text', 'The Wall') + cy.get('#songsWrapper tr.song-item:nth-child(3) .album').should('have.text', 'The Wall') + }) }) diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 88b380d9..ac868d04 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -1,8 +1,9 @@ import '@testing-library/cypress/add-commands' import AUTWindow = Cypress.AUTWindow import Chainable = Cypress.Chainable +import scrollBehaviorOptions = Cypress.scrollBehaviorOptions -function _login(dataFixture, redirectTo = '/'): Chainable { +function _login (dataFixture, redirectTo = '/'): Chainable { window.localStorage.setItem('api-token', 'mock-token') cy.intercept('api/data', { @@ -76,3 +77,13 @@ Cypress.Commands.add('$assertFavoriteSongCount', (count: number) => { cy.get('#favoritesWrapper').within(() => cy.get('tr.song-item').should('have.length', count)) cy.go('back') }) + +Cypress.Commands.add( + '$selectSongRange', + (start: number, end: number, scrollBehavior: scrollBehaviorOptions = false): Chainable => { + cy.get(`tr.song-item:nth-child(${start})`).click() + return cy.get(`tr.song-item:nth-child(${end})`).click({ + scrollBehavior, + shiftKey: true + }) + }) diff --git a/cypress/types.d.ts b/cypress/types.d.ts index b8d34631..4cc7af0a 100644 --- a/cypress/types.d.ts +++ b/cypress/types.d.ts @@ -19,6 +19,7 @@ declare namespace Cypress { $assertPlaylistSongCount(name: string, count: number): void $assertFavoriteSongCount(count: number): void + $selectSongRange(start: number, end: number, scrollBehavior?: scrollBehaviorOptions): Chainable /** * Support finding an element within an element identified with a test ID. diff --git a/resources/assets b/resources/assets index 925ebc48..68d2c8ae 160000 --- a/resources/assets +++ b/resources/assets @@ -1 +1 @@ -Subproject commit 925ebc48432a3fa401ea21a35508a8d48e42079c +Subproject commit 68d2c8aeb5d1b0f69447181d69ba4effe5c2e576