Skip to content

Commit 2105397

Browse files
test(ranking): add e2e coverage for restore, clear form and required behavior
Signed-off-by: paul bochtler <65470117+datapumpernickel@users.noreply.github.com>
1 parent 1cba4a2 commit 2105397

3 files changed

Lines changed: 121 additions & 0 deletions

File tree

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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 formTest } from '../support/fixtures/form.ts'
8+
import { test as appNavigationTest } from '../support/fixtures/navigation.ts'
9+
import { test as randomUserTest } from '../support/fixtures/random-user.ts'
10+
import { test as submitTest } from '../support/fixtures/submit.ts'
11+
import { test as topBarTest } from '../support/fixtures/topBar.ts'
12+
import { QuestionType } from '../support/sections/QuestionType.ts'
13+
import { FormsView } from '../support/sections/TopBarSection.ts'
14+
15+
const test = mergeTests(
16+
randomUserTest,
17+
appNavigationTest,
18+
formTest,
19+
topBarTest,
20+
submitTest,
21+
)
22+
23+
test.describe('Ranking question', () => {
24+
test.beforeEach(async ({ page, appNavigation, form }) => {
25+
await page.goto('apps/forms')
26+
await page.waitForURL(/apps\/forms\/?$/)
27+
await appNavigation.clickNewForm()
28+
await form.fillTitle('Ranking test form')
29+
30+
await form.addQuestion(QuestionType.Ranking)
31+
const questions = await form.getQuestions()
32+
await questions[0].fillTitle('Rank snacks')
33+
await questions[0].addAnswer('Pretzels')
34+
await questions[0].addAnswer('Popcorn')
35+
await questions[0].addAnswer('Nuts')
36+
})
37+
38+
test('Restores unsubmitted ranking from local storage on reload', async ({
39+
topBar,
40+
submitView,
41+
page,
42+
}) => {
43+
await topBar.toggleView(FormsView.View)
44+
45+
await submitView.rankOption('Rank snacks', 'Pretzels')
46+
await submitView.rankOption('Rank snacks', 'Popcorn')
47+
48+
await page.reload()
49+
50+
const question = submitView.getQuestion('Rank snacks')
51+
await expect(
52+
question.getByRole('button', { name: 'Remove from ranking' }),
53+
).toHaveCount(2)
54+
})
55+
56+
test('Clear form resets ranked options', async ({ topBar, submitView }) => {
57+
await topBar.toggleView(FormsView.View)
58+
59+
await submitView.rankOption('Rank snacks', 'Pretzels')
60+
await submitView.rankOption('Rank snacks', 'Popcorn')
61+
await submitView.clearForm()
62+
63+
const question = submitView.getQuestion('Rank snacks')
64+
await expect(
65+
question.getByRole('button', { name: 'Remove from ranking' }),
66+
).toHaveCount(0)
67+
await expect(
68+
question.getByRole('button', { name: 'Pretzels' }),
69+
).toBeVisible()
70+
await expect(question.getByRole('button', { name: 'Popcorn' })).toBeVisible()
71+
})
72+
73+
test('Required ranking blocks submit until all options are ranked', async ({
74+
topBar,
75+
submitView,
76+
form,
77+
}) => {
78+
const questions = await form.getQuestions()
79+
await questions[0].toggleRequired()
80+
81+
await topBar.toggleView(FormsView.View)
82+
83+
await submitView.submitButton.click()
84+
await expect(submitView.successMessage).not.toBeVisible()
85+
86+
await submitView.rankOption('Rank snacks', 'Pretzels')
87+
await submitView.submitButton.click()
88+
await expect(submitView.successMessage).not.toBeVisible()
89+
90+
await submitView.rankOption('Rank snacks', 'Popcorn')
91+
await submitView.rankOption('Rank snacks', 'Nuts')
92+
await submitView.submit()
93+
await expect(submitView.successMessage).toBeVisible()
94+
})
95+
})

playwright/support/sections/QuestionType.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export enum QuestionType {
1111
File = 'File',
1212
LinearScale = 'Linear scale',
1313
LongAnswer = 'Long text',
14+
Ranking = 'Ranking',
1415
RadioButtons = 'Radio buttons',
1516
ShortAnswer = 'Short answer',
1617
}

playwright/support/sections/SubmitSection.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
import type { Locator, Page, Response } from '@playwright/test'
77

88
export class SubmitSection {
9+
public readonly clearFormButton: Locator
910
public readonly submitButton: Locator
1011
public readonly successMessage: Locator
1112

1213
constructor(public readonly page: Page) {
14+
this.clearFormButton = this.page.getByRole('button', { name: 'Clear form' })
1315
this.submitButton = this.page.getByRole('button', { name: 'Submit' })
1416
this.successMessage = this.page.getByText(
1517
'Thank you for completing the form!',
@@ -99,6 +101,29 @@ export class SubmitSection {
99101
await this.page.getByRole('option', { name: optionName }).click()
100102
}
101103

104+
/**
105+
* Rank an option by clicking it in the unranked pool.
106+
*
107+
* @param questionName the title of the question
108+
* @param optionName the option text to move into ranked list
109+
*/
110+
public async rankOption(
111+
questionName: string | RegExp,
112+
optionName: string | RegExp,
113+
): Promise<void> {
114+
const question = this.getQuestion(questionName)
115+
await question.getByRole('button', { name: optionName }).click()
116+
}
117+
118+
/**
119+
* Click clear form and confirm the dialog.
120+
*/
121+
public async clearForm(): Promise<void> {
122+
await this.clearFormButton.click()
123+
const dialog = this.page.getByRole('dialog', { name: 'Clear form' })
124+
await dialog.getByRole('button', { name: 'Clear' }).click()
125+
}
126+
102127
/** Click submit and wait for the API response. */
103128
public async submit(): Promise<Response> {
104129
const response = this.page.waitForResponse(

0 commit comments

Comments
 (0)