mirror of
https://github.com/nextcloud/server.git
synced 2026-10-10 22:51:08 +02:00
The dialog only appears once a session's confirmation window has expired, so the old helper probed for it for 500 ms and silently skipped it on a slow shard, leaving the guarded request unsent; its wait for the dialog to close was unbounded. Install a locator handler per logged-in page instead, and use awaitPasswordGuardedRequest() where a response promise is awaited, since handlers never run during a bare waitForResponse. Assisted-by: ClaudeCode:claude-opus-5 Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
156 lines
5.5 KiB
TypeScript
156 lines
5.5 KiB
TypeScript
/*
|
|
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
import { runOcc } from '@nextcloud/e2e-test-server/docker'
|
|
import { login } from '@nextcloud/e2e-test-server/playwright'
|
|
import { expect } from '@playwright/test'
|
|
import { test } from '../../support/fixtures/admin-with-user.ts'
|
|
import { SettingsUsersPage } from '../../support/sections/SettingsUsersPage.ts'
|
|
import { getToast } from '../../support/utils/toast.ts'
|
|
|
|
test.describe('Settings: Change user properties', () => {
|
|
test('can change the display name', async ({ page, user }) => {
|
|
const settingsPage = new SettingsUsersPage(page)
|
|
await settingsPage.open()
|
|
|
|
await settingsPage.openEditDialog(user.userId)
|
|
const dialog = settingsPage.editUserDialog()
|
|
const displayNameInput = dialog.getByLabel('Display name')
|
|
await expect(displayNameInput).toHaveValue(user.userId)
|
|
await displayNameInput.fill('John Doe')
|
|
|
|
await settingsPage.saveEditDialog()
|
|
|
|
await expect(getToast(page, /Account updated/i)).toBeVisible()
|
|
|
|
// Verify backend
|
|
const { stdout: jsonList } = await runOcc(['user:info', '--output=json', user.userId])
|
|
const info = JSON.parse(jsonList)
|
|
expect(info?.display_name).toBe('John Doe')
|
|
})
|
|
|
|
test('can change the password', async ({ page, user, context }) => {
|
|
const settingsPage = new SettingsUsersPage(page)
|
|
await settingsPage.open()
|
|
|
|
await settingsPage.openEditDialog(user.userId)
|
|
const dialog = settingsPage.editUserDialog()
|
|
const passwordInput = dialog.getByLabel(/New password/i).and(page.locator('input')) // hack because there is no accessible role for input fields with type=password
|
|
await expect(passwordInput).toHaveValue('')
|
|
await passwordInput.fill('newpassword123')
|
|
|
|
await settingsPage.saveEditDialog()
|
|
|
|
await expect(getToast(page, /Account updated/i)).toBeVisible()
|
|
|
|
// Verify by logging in with the new password
|
|
await login(context.request, { ...user, password: 'newpassword123' })
|
|
await page.goto('/apps/dashboard')
|
|
await expect(page).toHaveURL(/\/apps\/dashboard/)
|
|
})
|
|
|
|
test('can change the email address', async ({ page, user }) => {
|
|
const settingsPage = new SettingsUsersPage(page)
|
|
await settingsPage.open()
|
|
|
|
await settingsPage.openEditDialog(user.userId)
|
|
const dialog = settingsPage.editUserDialog()
|
|
const emailInput = dialog.getByLabel(/Email/)
|
|
await expect(emailInput).toHaveValue('')
|
|
await emailInput.fill('mymail@example.com')
|
|
|
|
await settingsPage.saveEditDialog()
|
|
|
|
await expect(getToast(page, /Account updated/i)).toBeVisible()
|
|
|
|
// Verify backend
|
|
const { stdout: jsonList } = await runOcc(['user:info', '--output=json', user.userId])
|
|
const info = JSON.parse(jsonList)
|
|
expect(info?.email).toBe('mymail@example.com')
|
|
})
|
|
|
|
test('can change the user quota to a predefined value', async ({ page, user }) => {
|
|
const settingsPage = new SettingsUsersPage(page)
|
|
await settingsPage.open()
|
|
|
|
await settingsPage.openEditDialog(user.userId)
|
|
const dialog = settingsPage.editUserDialog()
|
|
|
|
// Open the Quota NcSelect and choose 5 GB
|
|
const quotaCombobox = dialog.getByRole('combobox', { name: /Quota/i })
|
|
await quotaCombobox.click()
|
|
await page.getByRole('option', { name: '5 GB' }).click()
|
|
|
|
await settingsPage.saveEditDialog()
|
|
|
|
await expect(getToast(page, /Account updated/i)).toBeVisible()
|
|
|
|
// Verify backend
|
|
const { stdout: jsonList } = await runOcc(['user:info', '--output=json', user.userId])
|
|
const info = JSON.parse(jsonList)
|
|
expect(info?.quota).toBe('5 GB')
|
|
})
|
|
|
|
test('can change the user quota to a custom value', async ({ page, user }) => {
|
|
const settingsPage = new SettingsUsersPage(page)
|
|
await settingsPage.open()
|
|
|
|
await settingsPage.openEditDialog(user.userId)
|
|
const dialog = settingsPage.editUserDialog()
|
|
|
|
// Type a custom value directly into the combobox
|
|
const quotaCombobox = dialog.getByRole('combobox', { name: /Quota/i })
|
|
await quotaCombobox.fill('4 MB')
|
|
await quotaCombobox.press('Enter')
|
|
|
|
await settingsPage.saveEditDialog()
|
|
|
|
await expect(getToast(page, /Account updated/i)).toBeVisible()
|
|
|
|
// Verify backend (stored as bytes)
|
|
const { stdout: jsonList } = await runOcc(['user:info', '--output=json', user.userId])
|
|
const info = JSON.parse(jsonList)
|
|
expect(info?.quota).not.toBe('none')
|
|
})
|
|
|
|
test('can make user a subadmin of a group', async ({ page, user }) => {
|
|
const groupName = crypto.randomUUID().slice(0, 6)
|
|
const shortName = groupName.slice(0, 4)
|
|
await runOcc(['group:add', groupName])
|
|
|
|
try {
|
|
const settingsPage = new SettingsUsersPage(page)
|
|
await settingsPage.open()
|
|
|
|
await settingsPage.openEditDialog(user.userId)
|
|
const dialog = settingsPage.editUserDialog()
|
|
|
|
// Open the subadmin NcSelect and pick the group
|
|
const subadminCombobox = dialog.getByRole('combobox', { name: /Admin of the following groups/i })
|
|
await subadminCombobox.click()
|
|
|
|
const waitForSearch = page
|
|
.waitForResponse((r) => r.request().url().includes(`ocs/v2.php/cloud/groups/details?search=${shortName}`))
|
|
await subadminCombobox.fill(shortName)
|
|
await waitForSearch
|
|
await page.getByRole('option', { name: new RegExp(groupName) }).click()
|
|
|
|
await settingsPage.saveEditDialog()
|
|
|
|
await expect(getToast(page, /Account updated/i)).toBeVisible()
|
|
|
|
// Verify backend via OCS API (page shares admin auth state)
|
|
const response = await page.request.get(
|
|
`/ocs/v2.php/cloud/users/${user.userId}/subadmins`,
|
|
{ headers: { 'OCS-APIRequest': 'true', Accept: 'application/json' } },
|
|
)
|
|
const data = await response.json()
|
|
expect(data?.ocs?.data).toContain(groupName)
|
|
} finally {
|
|
await runOcc(['group:delete', groupName])
|
|
}
|
|
})
|
|
})
|