Skip to content

Commit ab027f5

Browse files
committed
feat(e2e): add required field validation tests
Signed-off-by: Peter Ringelmann <peter.ringelmann@nextcloud.com>
1 parent 91c26bf commit ab027f5

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { expect, mergeTests } from '@playwright/test'
7+
import { test as randomUserTest } from '../support/fixtures/random-user'
8+
import { test as appNavigationTest } from '../support/fixtures/navigation'
9+
import { test as formTest } from '../support/fixtures/form'
10+
import { test as topBarTest } from '../support/fixtures/topBar'
11+
import { test as submitTest } from '../support/fixtures/submit'
12+
import { QuestionType } from '../support/sections/QuestionType'
13+
import { FormsView } from '../support/sections/TopBarSection'
14+
15+
const test = mergeTests(
16+
randomUserTest,
17+
appNavigationTest,
18+
formTest,
19+
topBarTest,
20+
submitTest,
21+
)
22+
23+
test.describe('Required field validation', () => {
24+
// Setup: create form with 2 questions, mark the first as required
25+
test.beforeEach(async ({ page, appNavigation, form }) => {
26+
await page.goto('apps/forms')
27+
await page.waitForURL(/apps\/forms$/)
28+
await appNavigation.clickNewForm()
29+
await form.fillTitle('Required fields test')
30+
31+
// Add a required short answer
32+
await form.addQuestion(QuestionType.ShortAnswer)
33+
const questions = await form.getQuestions()
34+
await questions[0].fillTitle('Required field')
35+
36+
// Toggle required via the actions menu.
37+
// Question.vue has an NcActionCheckbox with label "Required"
38+
// inside the NcActions menu.
39+
await questions[0].section
40+
.getByRole('button', { name: 'Actions' })
41+
.click()
42+
await page.getByRole('menuitemcheckbox', { name: 'Required' }).click()
43+
// Close the menu by pressing Escape
44+
await page.keyboard.press('Escape')
45+
46+
// Add a non-required question
47+
await form.addQuestion(QuestionType.ShortAnswer)
48+
const questions2 = await form.getQuestions()
49+
await questions2[1].fillTitle('Optional field')
50+
})
51+
52+
test('Submit with empty required field shows validation error', async ({
53+
topBar,
54+
submitView,
55+
}) => {
56+
await topBar.toggleView(FormsView.View)
57+
58+
// Fill only the optional field
59+
await submitView.fillText('Optional field', 'some text')
60+
61+
// Try to submit — should fail due to required field
62+
await submitView.submitButton.click()
63+
64+
// The form should NOT show success message (submission blocked by HTML5 validation)
65+
await expect(submitView.successMessage).not.toBeVisible()
66+
})
67+
68+
test('Submit succeeds after filling required field', async ({
69+
topBar,
70+
submitView,
71+
}) => {
72+
await topBar.toggleView(FormsView.View)
73+
74+
await submitView.fillText('Required field', 'my answer')
75+
await submitView.submit()
76+
await expect(submitView.successMessage).toBeVisible()
77+
})
78+
})

0 commit comments

Comments
 (0)