Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions css/CollectionCover-B5FNrHoX.chunk.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion css/CollectionCover-CmbAS5BV.chunk.css

This file was deleted.

18 changes: 14 additions & 4 deletions cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,24 @@ export default defineConfig({
trashAssetsBeforeRuns: true,

e2e: {
// Disable session isolation
testIsolation: false,

// We've imported your old cypress plugins here.
// You may want to clean this up later by importing these.
async setupNodeEvents(on, config) {
configureVisualRegression(on)

// This allows to store global data (e.g. the name of a snapshot)
// because Cypress.env() and other options are local to the current spec file.
const data = {}
on('task', {
setVariable({ key, value }) {
data[key] = value
return null
},
getVariable({ key }) {
return data[key] ?? null
},
})

// Disable spell checking to prevent rendering differences
on('before:browser:launch', (browser, launchOptions) => {
if (browser.family === 'chromium' && browser.name !== 'electron') {
Expand Down Expand Up @@ -71,7 +81,7 @@ export default defineConfig({

// Before the browser launches
// starting Nextcloud testing container
const ip = await startNextcloud(process.env.BRANCH || 'master')
const ip = await startNextcloud(process.env.BRANCH || 'master', undefined, { exposePort: 8080 })
// Setting container's IP as base Url
config.baseUrl = `http://${ip}/index.php`
await waitOnNextcloud(ip)
Expand Down
71 changes: 36 additions & 35 deletions cypress/e2e/albums.cy.js → cypress/e2e/albums.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import {
addFilesToAlbumFromAlbum,
addFilesToAlbumFromAlbumFromHeader,
createAnAlbumFromAlbums,
goToAlbum,
removeSelectionFromAlbum,
} from './albumsUtils'
removeSelectionFromCollection,
} from './albumsUtils.ts'
import {
deleteSelection,
favoriteSelection,
mkdir,
navigateToCollection,
navigateToCollections,
selectMedia,
setupPhotosTests,
unfavoriteSelection,
unselectMedia,
uploadTestMedia,
} from './photosUtils'
} from './photosUtils.ts'

const resizeObserverLoopErrRe = /^[^(ResizeObserver loop limit exceeded)]/
Cypress.on('uncaught:exception', (err) => {
Expand All @@ -28,36 +28,34 @@ Cypress.on('uncaught:exception', (err) => {
})

describe('Manage albums', () => {
let user = null
const albumName = 'albums_test'

beforeEach(function () {
cy.createRandomUser()
.then(_user => {
user = _user
mkdir(user, '/Photos')
uploadTestMedia(user)
cy.login(user)
})
cy.visit(`${Cypress.env('baseUrl')}/index.php/apps/photos/albums`)
createAnAlbumFromAlbums('albums_test')
addFilesToAlbumFromAlbum('albums_test', [0, 1, 2])
setupPhotosTests()

navigateToCollections('albums')
createAnAlbumFromAlbums(albumName)
addFilesToAlbumFromAlbum(albumName, [0, 1, 2])
})

it('Create an album, populate it and delete it', () => {
cy.get('[data-test="media"]').should('have.length', 3)
})

it('Remove a file to an album from an album content view', () => {
navigateToCollection('albums', albumName)
selectMedia([0])
removeSelectionFromAlbum()
removeSelectionFromCollection('albums', albumName)
})

it('Remove multiple files to an album from an album content view', () => {
navigateToCollection('albums', albumName)
selectMedia([0, 1])
removeSelectionFromAlbum()
removeSelectionFromCollection('albums', albumName)
})

it('Favorite a file from an album content view', () => {
navigateToCollection('albums', albumName)
selectMedia([0])
favoriteSelection()
cy.get('[data-test="media"]').eq(0).find('[aria-label="Favorite"]')
Expand All @@ -67,6 +65,7 @@ describe('Manage albums', () => {
})

it('Favorite multiple files from an album content view', () => {
navigateToCollection('albums', albumName)
selectMedia([1, 2])
favoriteSelection()
cy.get('[data-test="media"]').eq(1).find('[aria-label="Favorite"]')
Expand All @@ -76,25 +75,26 @@ describe('Manage albums', () => {
cy.get('[aria-label="Favorite"]').should('not.exist')
})

// it('Download a file from an album content view', () => {
// selectMedia([0])
// downloadSelection()
// unselectMedia([0])
// })
xit('Download a file from an album content view', () => {
selectMedia([0])
// downloadSelection()
unselectMedia([0])
})

// it('Download multiple files from an album content view', () => {
// selectMedia([1, 2])
// downloadSelection()
// unselectMedia([1, 2])
// })
xit('Download multiple files from an album content view', () => {
selectMedia([1, 2])
// downloadSelection()
unselectMedia([1, 2])
})

// it('Download all files from an album content view', () => {
// selectMedia([1, 2])
// downloadSelection()
// unselectMedia([1, 2])
// })
xit('Download all files from an album content view', () => {
selectMedia([1, 2])
// downloadSelection()
unselectMedia([1, 2])
})

it('Edit an album\'s name', () => {
navigateToCollection('albums', albumName)
cy.get('[aria-label="Open actions menu"]').click()
cy.contains('Edit album details').click()
cy.get('form [name="name"]').clear()
Expand All @@ -115,6 +115,7 @@ describe('Manage albums', () => {
})

it('Edit an album\'s location', () => {
navigateToCollection('albums', albumName)
cy.get('[aria-label="Open actions menu"]').click()
cy.contains('Edit album details').click()
cy.get('form [name="location"]').clear()
Expand All @@ -141,7 +142,7 @@ describe('Manage albums', () => {
cy.visit('/apps/photos')
selectMedia([3])
deleteSelection()
goToAlbum('albums_test')
navigateToCollection('albums', 'albums_test')
cy.get('[data-test="media"]').should('have.length', 3)
})
})
46 changes: 22 additions & 24 deletions cypress/e2e/albumsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,36 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { selectMedia } from './photosUtils'
import { navigateToCollection, navigateToCollections, selectMedia } from './photosUtils'
import { navigateToTimeline } from './timelines'

export function createAnAlbumFromTimeline(albumName: string) {
navigateToTimeline('all-media')
cy.contains('Create new album').click()
cy.get('form [name="name"]').type(albumName)
cy.contains('Create album').click()
}

export function createAnAlbumFromAlbums(albumName: string) {
cy.intercept({ times: 1, method: 'PROPFIND', url: `**/dav/photos/**/albums/${albumName}` }).as('propFind')
navigateToCollections('albums')
cy.contains('New album').click()
cy.get('form [name="name"]').type(albumName)
cy.intercept({ times: 1, method: 'PROPFIND', url: `/remote.php/dav/photos/*/albums/${albumName}` }).as('propFind')
cy.contains('Create album').click()
cy.wait('@propFind')
}

export function deleteAnAlbumFromAlbumContent() {
export function deleteAnAlbumFromAlbumContent(albumName: string) {
navigateToCollection('albums', albumName)
cy.get('[aria-label="Open actions menu"]').click()
cy.contains('Delete album').click()
}

export function addFilesToAlbumFromTimeline(albumName: string) {
cy.intercept({ times: 1, method: 'COPY', url: '**/dav/files/**' }).as('copy')
cy.intercept({ times: 1, method: 'PROPFIND', url: '**/dav/photos/**/albums/' }).as('propFindAlbums')
cy.intercept({ times: 1, method: 'PROPFIND', url: '**/dav/photos/**/sharedalbums/' }).as('propFindSharedAlbums')
navigateToTimeline('all-media')
cy.intercept({ times: 1, method: 'COPY', url: '/remote.php/dav/files/**' }).as('copy')
cy.intercept({ times: 1, method: 'PROPFIND', url: '/remote.php/dav/photos/*/albums/' }).as('propFindAlbums')
cy.intercept({ times: 1, method: 'PROPFIND', url: '/remote.php/dav/photos/*/sharedalbums/' }).as('propFindSharedAlbums')
cy.contains('Add to album').click()
cy.wait('@propFindAlbums')
cy.wait('@propFindSharedAlbums')
Expand All @@ -36,44 +41,37 @@ export function addFilesToAlbumFromTimeline(albumName: string) {
}

export function addFilesToAlbumFromAlbum(albumName: string, itemsIndex: number[]) {
cy.intercept({ times: 1, method: 'SEARCH', url: '**/dav/' }).as('search')
navigateToCollection('albums', albumName)
cy.intercept({ times: 1, method: 'SEARCH', url: '/remote.php/dav/' }).as('search')
cy.get('[aria-label="Add photos to this album"]').click()
cy.wait('@search')
cy.get('.photos-picker__file-list').within(() => {
selectMedia(itemsIndex)
})
cy.intercept({ times: itemsIndex.length, method: 'COPY', url: '**/dav/files/**' }).as('copy')
cy.intercept({ times: 1, method: 'PROPFIND', url: `**/dav/photos/**/albums/${albumName}` }).as('propFind')
cy.intercept({ times: itemsIndex.length, method: 'COPY', url: '/remote.php/dav/files/**' }).as('copy')
cy.intercept({ times: 1, method: 'PROPFIND', url: `/remote.php/dav/photos/*/albums/${albumName}` }).as('propFind')
cy.contains(`Add to ${albumName}`).click()
cy.wait('@copy')
cy.wait('@propFind')
}

export function addFilesToAlbumFromAlbumFromHeader(albumName: string, itemsIndex: number[]) {
navigateToCollection('albums', albumName)
cy.contains('Add photos to this album').click()
cy.get('.photos-picker__file-list').within(() => {
selectMedia(itemsIndex)
})

cy.intercept({ times: 1, method: 'PROPFIND', url: `**/dav/photos/**/albums/${albumName}` }).as('propFind')
cy.intercept({ times: 1, method: 'PROPFIND', url: `/remote.php/dav/photos/*/albums/${albumName}` }).as('propFind')
cy.contains(`Add to ${albumName}`).click()
cy.wait('@propFind')
}

export function removeSelectionFromAlbum() {
cy.intercept({ times: 1, method: 'DELETE', url: '**/dav/photos/**' }).as('delete')
export function removeSelectionFromCollection(collectionId: string, albumName: string) {
cy.get('[aria-label="Open actions menu"]').click()
cy.intercept({ times: 1, method: 'DELETE', url: `/remote.php/dav/photos/*/${collectionId}/${encodeURIComponent(albumName)}/*` }).as('deleteFromAlbum')
cy.contains('Remove selection from album').click()
cy.wait('@delete')
}

export function goToAlbum(albumName: string) {
cy.intercept({ times: 1, method: 'PROPFIND', url: '**/dav/photos/**/albums' }).as('propFindAlbums')
cy.intercept({ times: 1, method: 'PROPFIND', url: `**/dav/photos/**/albums/${albumName}` }).as('propFindAlbumContent')
cy.get('.app-navigation__list').contains('Albums').click()
cy.wait('@propFindAlbums')
cy.get('ul.collections__list').contains(albumName).click()
cy.wait('@propFindAlbumContent')
cy.wait('@deleteFromAlbum')
}

export function addCollaborators(collaborators: string[]) {
Expand Down Expand Up @@ -101,8 +99,8 @@ export function removeCollaborators(collaborators: string[]) {

export function createPublicShare() {
cy.get('[aria-label="Manage collaborators for this album"]').click()
cy.intercept({ times: 1, method: 'PROPPATCH', url: '**/dav/photos/*/albums/*' }).as('patchCall')
cy.intercept({ times: 1, method: 'PROPFIND', url: '**/dav/photos/*/albums/*' }).as('propFind')
cy.intercept({ times: 1, method: 'PROPPATCH', url: '/remote.php/dav/photos/*/albums/*' }).as('patchCall')
cy.intercept({ times: 1, method: 'PROPFIND', url: '/remote.php/dav/photos/*/albums/*' }).as('propFind')
cy.get('[aria-label="Create public link share"]').click()
cy.wait('@patchCall')
cy.wait('@propFind')
Expand Down
72 changes: 71 additions & 1 deletion cypress/e2e/photosUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function mkdir(user: User, target: string) {
cy.clearCookies()
.then({ timeout: 8000 }, async () => {
try {
const rootPath = `${Cypress.env('baseUrl')}/remote.php/dav/files/${encodeURIComponent(user.userId)}`
const rootPath = `${Cypress.env('baseUrl')}//remote.php/dav/files/${encodeURIComponent(user.userId)}`
const filePath = target.split('/').map(encodeURIComponent).join('/')
const response = await axios({
url: `${rootPath}${filePath}`,
Expand All @@ -81,3 +81,73 @@ export function mkdir(user: User, target: string) {
}
})
}

type SetupInfo = {
snapshot: string
alice: User
bob: User
charlie: User
}

export function setupPhotosTests(): Cypress.Chainable<SetupInfo> {
return cy.task('getVariable', { key: 'timeline-data' })
.then((_setupInfo) => {
const setupInfo = _setupInfo as SetupInfo || {}
if (setupInfo.snapshot) {
cy.restoreState(setupInfo.snapshot)
} else {
cy.createRandomUser().then(user => { setupInfo.alice = user })
cy.createRandomUser().then(user => { setupInfo.bob = user })
cy.createRandomUser().then(user => { setupInfo.charlie = user })

cy.then(() => {
mkdir(setupInfo.alice, '/Photos')
mkdir(setupInfo.bob, '/Photos')
mkdir(setupInfo.charlie, '/Photos')
uploadTestMedia(setupInfo.alice)
uploadTestMedia(setupInfo.bob)
uploadTestMedia(setupInfo.charlie)
})

cy.runOccCommand('files:scan --all --generate-metadata')

cy.then(() => {
cy.saveState().then((value) => { setupInfo.snapshot = value })
cy.task('setVariable', { key: 'timeline-data', value: setupInfo })
})
}

return cy.then(() => {
Cypress.session.clearAllSavedSessions()
cy.login(setupInfo.alice)
cy.visit('/apps/photos')
return cy.wrap(setupInfo)
})
})
}

export function navigateToCollections(collectionId: 'places'|'albums'|'sharedalbums') {
cy.url()
.then((url) => {
if (!url.endsWith(`/apps/photos/${collectionId}/`) && !url.endsWith(`/apps/photos/${collectionId}`)) {
cy.intercept({ times: 1, method: 'PROPFIND', url: `/remote.php/dav/photos/*/${collectionId}/` }).as('propFindCollections')
cy.get(`[data-id-app-nav-item="${collectionId}"]`).click()
cy.wait('@propFindCollections')
}
})
}

export function navigateToCollection(collectionId: 'places'|'albums'|'sharedalbums', collectionName: string) {
cy.url()
.then((url) => {
if (!url.endsWith(`/apps/photos/${collectionId}/${encodeURIComponent(collectionName)}`)) {
navigateToCollections(collectionId)

cy.intercept({ times: 1, method: 'PROPFIND', url: `/remote.php/dav/photos/*/${collectionId}/${encodeURIComponent(collectionName)}` }).as('propFindCollection')
cy.intercept({ times: 1, method: 'PROPFIND', url: `/remote.php/dav/photos/*/${collectionId}/${encodeURIComponent(collectionName)}/` }).as('propFindCollectionContent')
cy.get('[data-cy-collections-list-collection="' + collectionName + '"]').click()
cy.wait('@propFindCollection')
cy.wait('@propFindCollectionContent')
}
})
}
Loading
Loading