Skip to content

Commit

Permalink
test: Add proper styles for Cypress component tests
Browse files Browse the repository at this point in the history
This also fixes Typescript issue but requires to slightly
adjust the Navigation test as the progress bar is not visible (because it is overlayed by another element).

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Oct 15, 2024
1 parent 28dd417 commit 465404b
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 99 deletions.
4 changes: 2 additions & 2 deletions apps/files/src/views/Navigation.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ describe('Quota rendering', () => {

cy.get('[data-cy-files-navigation-settings-quota]').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota]').should('contain.text', '1 GB of 5 GB used')
cy.get('[data-cy-files-navigation-settings-quota] progress').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota] progress').should('exist')
cy.get('[data-cy-files-navigation-settings-quota] progress').should('have.attr', 'value', '20')
})

Expand All @@ -237,7 +237,7 @@ describe('Quota rendering', () => {

cy.get('[data-cy-files-navigation-settings-quota]').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota]').should('contain.text', '5 GB of 1 GB used')
cy.get('[data-cy-files-navigation-settings-quota] progress').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota] progress').should('exist')
cy.get('[data-cy-files-navigation-settings-quota] progress').should('have.attr', 'value', '100') // progress max is 100
})
})
75 changes: 1 addition & 74 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
// eslint-disable-next-line n/no-extraneous-import
import axios, { type AxiosResponse } from 'axios'
import axios from 'axios'
import { addCommands, User } from '@nextcloud/cypress'
import { basename } from 'path'

Expand All @@ -13,79 +13,6 @@ import 'cypress-if'
import 'cypress-wait-until'
addCommands()

// Register this file's custom commands types
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
interface Chainable<Subject = any> {
/**
* Enable or disable a given user
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
enableUser(user: User, enable?: boolean): Cypress.Chainable<Cypress.Response<any>>,

/**
* Upload a file from the fixtures folder to a given user storage.
* **Warning**: Using this function will reset the previous session
*/
uploadFile(user: User, fixture?: string, mimeType?: string, target?: string): Cypress.Chainable<void>,

/**
* Upload a raw content to a given user storage.
* **Warning**: Using this function will reset the previous session
*/
uploadContent(user: User, content: Blob, mimeType: string, target: string, mtime?: number): Cypress.Chainable<AxiosResponse>,

/**
* Create a new directory
* **Warning**: Using this function will reset the previous session
*/
mkdir(user: User, target: string): Cypress.Chainable<void>,

/**
* Set a file as favorite (or remove from favorite)
*/
setFileAsFavorite(user: User, target: string, favorite?: boolean): Cypress.Chainable<void>,

/**
* Reset the admin theming entirely.
* **Warning**: Using this function will reset the previous session
*/
resetAdminTheming(): Cypress.Chainable<void>,

/**
* Reset the user theming settings.
* If provided, will clear session and login as the given user.
* **Warning**: Providing a user will reset the previous session.
*/
resetUserTheming(user?: User): Cypress.Chainable<void>,

/**
* Run an occ command in the docker container.
*/
runOccCommand(command: string, options?: Partial<Cypress.ExecOptions>): Cypress.Chainable<Cypress.Exec>,

userFileExists(user: string, path: string): Cypress.Chainable<number>

/**
* Create a snapshot of the current database
*/
backupDB(): Cypress.Chainable<string>,

/**
* Restore a snapshot of the database
* Default is the post-setup state
*/
restoreDB(snapshot?: string): Cypress.Chainable

backupData(users?: string[]): Cypress.Chainable<string>

restoreData(snapshot?: string): Cypress.Chainable
}
}
}

const url = (Cypress.config('baseUrl') || '').replace(/\/index.php\/?$/g, '')
Cypress.env('baseUrl', url)

Expand Down
35 changes: 13 additions & 22 deletions cypress/support/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,25 @@
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import '../../apps/theming/css/default.css'
import '../../core/css/server.css'

import '@testing-library/cypress/add-commands'
import 'cypress-axe'

/* eslint-disable */
import { mount } from '@cypress/vue2'

// Example use:
// cy.mount(MyComponent)
Cypress.Commands.add('mount', (component, optionsOrProps) => {
let instance = null
const oldMounted = component?.mounted || false

// Override the mounted method to expose
// the component instance to cypress
component.mounted = function() {
// eslint-disable-next-line
instance = this
if (oldMounted) {
oldMounted.call(instance)
}
}
Cypress.Commands.add('mount', (component, options = {}) => {
// Setup options object
options.extensions = options.extensions || {}
options.extensions.plugins = options.extensions.plugins || []
options.extensions.components = options.extensions.components || {}

// Expose the component with cy.get('@component')
return mount(component, optionsOrProps).then(() => {
return cy.wrap(instance).as('component')
})
return mount(component, options)
})

Cypress.Commands.add('mockInitialState', (app: string, key: string, value: any) => {
Cypress.Commands.add('mockInitialState', (app: string, key: string, value: unknown) => {
cy.document().then(($document) => {
const input = $document.createElement('input')
input.setAttribute('type', 'hidden')
Expand All @@ -44,4 +35,4 @@ Cypress.Commands.add('unmockInitialState', (app?: string, key?: string) => {
$document.querySelectorAll('body > input[type="hidden"]' + (app ? `[id="initial-state-${app}-${key}"]` : ''))
.forEach((node) => $document.body.removeChild(node))
})
})
})
17 changes: 17 additions & 0 deletions cypress/support/cypress-component.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*!
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import type { mount } from '@cypress/vue2'

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
interface Chainable {
mount: typeof mount
mockInitialState: (app: string, key: string, value: unknown) => Cypress.Chainable<void>
unmockInitialState: (app?: string, key?: string) => Cypress.Chainable<void>
}
}
}
79 changes: 79 additions & 0 deletions cypress/support/cypress-e2e.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*!
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

// eslint-disable-next-line n/no-extraneous-import
import type { AxiosResponse } from 'axios'

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace Cypress {
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
interface Chainable<Subject = any> {
/**
* Enable or disable a given user
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
enableUser(user: User, enable?: boolean): Cypress.Chainable<Cypress.Response<any>>,

/**
* Upload a file from the fixtures folder to a given user storage.
* **Warning**: Using this function will reset the previous session
*/
uploadFile(user: User, fixture?: string, mimeType?: string, target?: string): Cypress.Chainable<void>,

/**
* Upload a raw content to a given user storage.
* **Warning**: Using this function will reset the previous session
*/
uploadContent(user: User, content: Blob, mimeType: string, target: string, mtime?: number): Cypress.Chainable<AxiosResponse>,

/**
* Create a new directory
* **Warning**: Using this function will reset the previous session
*/
mkdir(user: User, target: string): Cypress.Chainable<void>,

/**
* Set a file as favorite (or remove from favorite)
*/
setFileAsFavorite(user: User, target: string, favorite?: boolean): Cypress.Chainable<void>,

/**
* Reset the admin theming entirely.
* **Warning**: Using this function will reset the previous session
*/
resetAdminTheming(): Cypress.Chainable<void>,

/**
* Reset the user theming settings.
* If provided, will clear session and login as the given user.
* **Warning**: Providing a user will reset the previous session.
*/
resetUserTheming(user?: User): Cypress.Chainable<void>,

/**
* Run an occ command in the docker container.
*/
runOccCommand(command: string, options?: Partial<Cypress.ExecOptions>): Cypress.Chainable<Cypress.Exec>,

userFileExists(user: string, path: string): Cypress.Chainable<number>

/**
* Create a snapshot of the current database
*/
backupDB(): Cypress.Chainable<string>,

/**
* Restore a snapshot of the database
* Default is the post-setup state
*/
restoreDB(snapshot?: string): Cypress.Chainable

backupData(users?: string[]): Cypress.Chainable<string>

restoreData(snapshot?: string): Cypress.Chainable
}
}
}
3 changes: 2 additions & 1 deletion cypress/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "../tsconfig.json",
"include": ["./**/*.ts"],
"include": ["./**/*.ts", "../**/*.cy.ts", "./cypress-e2e.d.ts", "./cypress-component.d.ts"],
"exclude": [],
"compilerOptions": {
"types": [
"@testing-library/cypress",
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "@vue/tsconfig/tsconfig.json",
"include": ["./apps/**/*.ts", "./apps/**/*.vue", "./core/**/*.ts", "./core/**/*.vue", "./*.d.ts"],
"exclude": ["./**/*.cy.ts"],
"compilerOptions": {
"types": ["node", "vue", "vue-router"],
"outDir": "./dist/",
Expand Down

0 comments on commit 465404b

Please sign in to comment.