mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
test: migrate LoginForm component test to vitest
Cypress has some limitations: - its vue 2 supported was removed - it fails with our vue 3 migration due to 2 different vue versions being present - its slow compared to vitest Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
678a8a75ad
commit
ba01412389
6 changed files with 109 additions and 82 deletions
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
import LoginForm from './LoginForm.vue'
|
||||
|
||||
describe('core: LoginForm', { testIsolation: true }, () => {
|
||||
beforeEach(() => {
|
||||
// Mock the required global state
|
||||
cy.window().then(($window) => {
|
||||
$window.OC = {
|
||||
theme: {
|
||||
name: 'J\'s cloud',
|
||||
},
|
||||
requestToken: 'request-token',
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Ensure that characters like ' are not double HTML escaped.
|
||||
* This was a bug in https://github.com/nextcloud/server/issues/34990
|
||||
*/
|
||||
it('does not double escape special characters in product name', () => {
|
||||
cy.mount(LoginForm, {
|
||||
propsData: {
|
||||
username: 'test-user',
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('h2').contains('J\'s cloud')
|
||||
})
|
||||
|
||||
it('fills username from props into form', () => {
|
||||
cy.mount(LoginForm, {
|
||||
propsData: {
|
||||
username: 'test-user',
|
||||
},
|
||||
})
|
||||
|
||||
cy.get('input[name="user"]')
|
||||
.should('exist')
|
||||
.and('have.attr', 'id', 'user')
|
||||
|
||||
cy.get('input[name="user"]')
|
||||
.should('have.value', 'test-user')
|
||||
})
|
||||
|
||||
it('clears password after timeout', () => {
|
||||
// mock timeout of 5 seconds
|
||||
cy.window().then(($window) => {
|
||||
const state = $window.document.createElement('input')
|
||||
state.type = 'hidden'
|
||||
state.id = 'initial-state-core-loginTimeout'
|
||||
state.value = btoa(JSON.stringify(5))
|
||||
$window.document.body.appendChild(state)
|
||||
})
|
||||
|
||||
// mount forms
|
||||
cy.mount(LoginForm)
|
||||
|
||||
cy.get('input[name="password"]')
|
||||
.should('exist')
|
||||
.type('MyPassword')
|
||||
|
||||
cy.get('input[name="password"]')
|
||||
.should('have.value', 'MyPassword')
|
||||
|
||||
// Wait for timeout
|
||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||
cy.wait(5100)
|
||||
|
||||
cy.get('input[name="password"]')
|
||||
.should('have.value', '')
|
||||
})
|
||||
})
|
||||
|
|
@ -194,10 +194,10 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
data(props) {
|
||||
return {
|
||||
loading: false,
|
||||
user: '',
|
||||
user: props.username,
|
||||
password: '',
|
||||
}
|
||||
},
|
||||
|
|
@ -262,7 +262,7 @@ export default {
|
|||
},
|
||||
|
||||
emailEnabled() {
|
||||
return this.emailStates ? this.emailStates.every((state) => state === '1') : 1
|
||||
return this.emailStates.every((state) => state === '1')
|
||||
},
|
||||
|
||||
loginText() {
|
||||
|
|
@ -286,7 +286,6 @@ export default {
|
|||
if (this.username === '') {
|
||||
this.$refs.user.$refs.inputField.$refs.input.focus()
|
||||
} else {
|
||||
this.user = this.username
|
||||
this.$refs.password.$refs.inputField.$refs.input.focus()
|
||||
}
|
||||
},
|
||||
|
|
|
|||
102
core/src/tests/components/Login/LoginForm.spec.ts
Normal file
102
core/src/tests/components/Login/LoginForm.spec.ts
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*!
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { cleanup, render } from '@testing-library/vue'
|
||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import LoginForm from '../../../components/login/LoginForm.vue'
|
||||
|
||||
describe('core: LoginForm', () => {
|
||||
afterEach(cleanup)
|
||||
|
||||
beforeEach(() => {
|
||||
// Mock the required global state
|
||||
window.OC = {
|
||||
theme: {
|
||||
name: 'J\'s cloud',
|
||||
},
|
||||
requestToken: 'request-token',
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Ensure that characters like ' are not double HTML escaped.
|
||||
* This was a bug in https://github.com/nextcloud/server/issues/34990
|
||||
*/
|
||||
it('does not double escape special characters in product name', () => {
|
||||
const page = render(LoginForm, {
|
||||
props: {
|
||||
username: 'test-user',
|
||||
},
|
||||
})
|
||||
|
||||
const heading = page.getByRole('heading', { level: 2 })
|
||||
expect(heading.textContent).toContain('J\'s cloud')
|
||||
})
|
||||
|
||||
it('offers email as login name by default', async () => {
|
||||
const page = render(LoginForm)
|
||||
|
||||
const input = await page.findByRole('textbox', { name: /Account name or email/ })
|
||||
expect(input).toBeInstanceOf(HTMLInputElement)
|
||||
})
|
||||
|
||||
it('offers only account name if email is not enabled', async () => {
|
||||
const page = render(LoginForm, {
|
||||
propsData: {
|
||||
emailStates: ['0', '1'],
|
||||
},
|
||||
})
|
||||
|
||||
await expect(async () => page.findByRole('textbox', { name: /Account name or email/ })).rejects.toThrow()
|
||||
await expect(page.findByRole('textbox', { name: /Account name/ })).resolves.not.toThrow()
|
||||
})
|
||||
|
||||
it('fills username from props into form', () => {
|
||||
const page = render(LoginForm, {
|
||||
props: {
|
||||
username: 'test-user',
|
||||
},
|
||||
})
|
||||
|
||||
page.debug()
|
||||
|
||||
const input: HTMLInputElement = page.getByRole('textbox', { name: /Account name or email/ })
|
||||
expect(input.id).toBe('user')
|
||||
expect(input.name).toBe('user')
|
||||
expect(input.value).toBe('test-user')
|
||||
})
|
||||
|
||||
describe('', () => {
|
||||
beforeAll(() => {
|
||||
vi.useFakeTimers()
|
||||
// mock timeout of 5 seconds
|
||||
const state = document.createElement('input')
|
||||
state.type = 'hidden'
|
||||
state.id = 'initial-state-core-loginTimeout'
|
||||
state.value = btoa(JSON.stringify(5))
|
||||
document.body.appendChild(state)
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
vi.useRealTimers()
|
||||
document.querySelector('#initial-state-core-loginTimeout')?.remove()
|
||||
})
|
||||
|
||||
it('clears password after timeout', () => {
|
||||
// mount forms
|
||||
const page = render(LoginForm)
|
||||
const input: HTMLInputElement = page.getByLabelText('Password', { selector: 'input' })
|
||||
input.dispatchEvent(new InputEvent('input', { data: 'MyPassword' }))
|
||||
|
||||
vi.advanceTimersByTime(2500)
|
||||
// see its still the value
|
||||
expect(input.value).toBe('')
|
||||
|
||||
// Wait for timeout
|
||||
vi.advanceTimersByTime(2600)
|
||||
expect(input.value).toBe('')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -63,6 +63,8 @@ export default defineConfig([
|
|||
rules: {
|
||||
'no-console': 'off',
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
'jsdoc/require-param-type': 'off',
|
||||
'jsdoc/require-param-description': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-unused-expressions': 'off',
|
||||
},
|
||||
|
|
|
|||
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -104,7 +104,7 @@
|
|||
"@testing-library/cypress": "^10.1.0",
|
||||
"@testing-library/jest-dom": "^6.6.4",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@testing-library/vue": "^5.8.3",
|
||||
"@testing-library/vue": "^5.9.0",
|
||||
"@types/dockerode": "^3.3.44",
|
||||
"@types/wait-on": "^5.3.4",
|
||||
"@vitejs/plugin-vue2": "^2.3.3",
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@
|
|||
"@testing-library/cypress": "^10.1.0",
|
||||
"@testing-library/jest-dom": "^6.6.4",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@testing-library/vue": "^5.8.3",
|
||||
"@testing-library/vue": "^5.9.0",
|
||||
"@types/dockerode": "^3.3.44",
|
||||
"@types/wait-on": "^5.3.4",
|
||||
"@vitejs/plugin-vue2": "^2.3.3",
|
||||
|
|
|
|||
Loading…
Reference in a new issue