зеркало из https://github.com/nextcloud/forms.git
test: Add e2e test for IME input (#2267)
* test: Add e2e test for IME input Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de> * fix: Unify translation for label and placeholder Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de> --------- Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
Родитель
f18c6f3f7e
Коммит
b7d9f79015
|
@ -0,0 +1,77 @@
|
|||
import { expect, mergeTests } from '@playwright/test'
|
||||
import { test as randomUserTest } from '../support/fixtures/random-user'
|
||||
import { test as appNavigationTest } from '../support/fixtures/navigation'
|
||||
import { test as formTest } from '../support/fixtures/form'
|
||||
import { QuestionType } from '../support/sections/QuestionType'
|
||||
|
||||
const test = mergeTests(randomUserTest, appNavigationTest, formTest)
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('apps/forms')
|
||||
await page.waitForURL(/apps\/forms$/)
|
||||
})
|
||||
|
||||
test(
|
||||
'IME input does not trigger new option',
|
||||
{
|
||||
annotation: {
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nextcloud/forms/issues/2220',
|
||||
},
|
||||
},
|
||||
async ({ browserName, appNavigation, page, form }) => {
|
||||
test.skip(
|
||||
browserName !== 'chromium',
|
||||
'IME testing is currently only implemented in Chromium API',
|
||||
)
|
||||
|
||||
// Now get the developer tools API
|
||||
const client = await page.context().newCDPSession(page)
|
||||
// Create a new form
|
||||
await appNavigation.clickNewForm()
|
||||
await form.fillTitle('Example')
|
||||
// Create a new Drop down question
|
||||
await form.addQuestion(QuestionType.Dropdown)
|
||||
const question = (await form.getQuestions()).at(-1)!
|
||||
// expect there is question
|
||||
expect(question).not.toBe(undefined)
|
||||
// Add the title
|
||||
await question.fillTitle('IME input')
|
||||
|
||||
// no answers yet
|
||||
await expect(question.answerInputs).toHaveCount(0)
|
||||
|
||||
// Start composing a new name by focussing the input and composing
|
||||
await question.newAnswerInput.focus()
|
||||
await client.send('Input.imeSetComposition', {
|
||||
selectionStart: -1,
|
||||
selectionEnd: -1,
|
||||
text: '',
|
||||
})
|
||||
await expect(question.newAnswerInput).toHaveValue('')
|
||||
await expect(question.answerInputs).toHaveCount(0) // not committed yet
|
||||
|
||||
await client.send('Input.imeSetComposition', {
|
||||
selectionStart: 0,
|
||||
selectionEnd: 1,
|
||||
text: 's',
|
||||
})
|
||||
await expect(question.newAnswerInput).toHaveValue('s')
|
||||
await expect(question.answerInputs).toHaveCount(0) // not committed yet
|
||||
|
||||
await client.send('Input.imeSetComposition', {
|
||||
selectionStart: 0,
|
||||
selectionEnd: 2,
|
||||
text: 'sa',
|
||||
})
|
||||
await expect(question.newAnswerInput).toHaveValue('sa')
|
||||
await expect(question.answerInputs).toHaveCount(0) // not committed yet
|
||||
|
||||
await client.send('Input.insertText', {
|
||||
text: 'さ',
|
||||
})
|
||||
// so there were 4 inputs but those should only result in one new option
|
||||
await expect(question.answerInputs).toHaveCount(1)
|
||||
await expect(question.answerInputs).toHaveValue('さ')
|
||||
},
|
||||
)
|
|
@ -29,6 +29,7 @@ export class AppNavigationSection {
|
|||
|
||||
public async clickNewForm(): Promise<void> {
|
||||
await this.newFormLocator.click()
|
||||
await this.page.waitForURL(/apps\/forms\/.+/)
|
||||
}
|
||||
|
||||
public async openArchivedForms(): Promise<void> {
|
||||
|
|
|
@ -4,14 +4,20 @@
|
|||
*/
|
||||
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import type { QuestionType } from './QuestionType'
|
||||
import { QuestionSection } from './QuestionSection'
|
||||
|
||||
export class FormSection {
|
||||
public readonly mainContent: Locator
|
||||
public readonly titleField: Locator
|
||||
public readonly newQuestionButton: Locator
|
||||
|
||||
// eslint-disable-next-line no-useless-constructor
|
||||
constructor(public readonly page: Page) {
|
||||
this.mainContent = this.page.getByRole('main')
|
||||
this.newQuestionButton = this.page.getByRole('button', {
|
||||
name: 'Add a question',
|
||||
})
|
||||
this.titleField = this.mainContent.getByRole('textbox', {
|
||||
name: 'Form title',
|
||||
})
|
||||
|
@ -20,4 +26,18 @@ export class FormSection {
|
|||
public async fillTitle(text: string): Promise<void> {
|
||||
await this.titleField.fill(text)
|
||||
}
|
||||
|
||||
public async addQuestion(type: QuestionType): Promise<void> {
|
||||
await this.newQuestionButton.click()
|
||||
await this.page.getByRole('menuitem', { name: type }).click()
|
||||
}
|
||||
|
||||
public async getQuestions(): Promise<QuestionSection[]> {
|
||||
return this.page
|
||||
.locator('main section')
|
||||
.all()
|
||||
.then((sections) =>
|
||||
sections.map((section) => new QuestionSection(this.page, section)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <opensource@fthiessen.de>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
|
||||
export class QuestionSection {
|
||||
public readonly titleInput: Locator
|
||||
public readonly newAnswerInput: Locator
|
||||
public readonly answerInputs: Locator
|
||||
|
||||
// eslint-disable-next-line no-useless-constructor
|
||||
constructor(
|
||||
public readonly page: Page,
|
||||
public readonly section: Locator,
|
||||
) {
|
||||
this.titleInput = this.section.getByRole('textbox', { name: /title of/i })
|
||||
this.newAnswerInput = this.section.getByRole('textbox', {
|
||||
name: 'Add a new answer',
|
||||
})
|
||||
this.answerInputs = this.section.getByRole('textbox', {
|
||||
name: /Answer number \d+/i,
|
||||
})
|
||||
}
|
||||
|
||||
async fillTitle(title: string): Promise<void> {
|
||||
await this.titleInput.fill(title)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export enum QuestionType {
|
||||
Checkboxes = 'Checkboxes',
|
||||
Dropdown = 'Dropdown',
|
||||
}
|
|
@ -6,9 +6,7 @@
|
|||
class="question__item__pseudoInput" />
|
||||
<input
|
||||
ref="input"
|
||||
:aria-label="
|
||||
t('forms', 'An answer for the {index} option', { index: index + 1 })
|
||||
"
|
||||
:aria-label="t('forms', 'Answer number {index}', { index: index + 1 })"
|
||||
:placeholder="t('forms', 'Answer number {index}', { index: index + 1 })"
|
||||
:value="answer.text"
|
||||
class="question__input"
|
||||
|
|
Загрузка…
Ссылка в новой задаче