test: Add e2e tests for the form description

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
Ferdinand Thiessen 2024-08-14 14:11:24 +02:00
Родитель 5fa4682fa9
Коммит c3d50824a1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 45FAE7268762B400
4 изменённых файлов: 180 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,100 @@
/**
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <opensource@fthiessen.de>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
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 topBarTest } from '../support/fixtures/topBar'
import { test as formTest } from '../support/fixtures/form'
import { FormsView } from '../support/sections/TopBarSection'
const test = mergeTests(randomUserTest, appNavigationTest, formTest, topBarTest)
test.beforeEach(async ({ page }) => {
await page.goto('apps/forms')
await page.waitForURL(/apps\/forms$/)
})
test.describe('Form description', () => {
test('Can edit the description', async ({
appNavigation,
form,
topBar,
page,
}) => {
await appNavigation.clickNewForm()
await form.fillTitle('Test form')
await form.fillDescription('Hello this is an example')
await topBar.toggleView(FormsView.View)
await expect(page.locator('.form-desc')).toContainText(
'Hello this is an example',
)
})
test('Can use Markdown in the description', async ({
appNavigation,
form,
topBar,
page,
}) => {
await appNavigation.clickNewForm()
await form.fillTitle('Test form')
await form.fillDescription('Hello **this** is an example')
await topBar.toggleView(FormsView.View)
await expect(page.locator('.form-desc')).toContainText(
'Hello this is an example',
)
await expect(page.locator('.form-desc').locator('strong')).toContainText(
'this',
)
})
test(
'Markdown links are opened in a new tab',
{
annotation: {
type: 'issue',
description: 'https://github.com/nextcloud/forms/issues/1680',
},
},
async ({ appNavigation, form, topBar, page }) => {
await appNavigation.clickNewForm()
await form.fillTitle('Test form')
await form.fillDescription('The link: [link-name](http://example.com)')
await topBar.toggleView(FormsView.View)
await expect(page.locator('.form-desc')).toContainText(
'The link: link-name',
)
const link = page.locator('.form-desc').getByRole('link')
await expect(link).toContainText('link-name')
await expect(link).toHaveAttribute('href', 'http://example.com')
await expect(link).toHaveAttribute('target', '_blank')
// check opening works
// lets mock the response to not need to query that server for real
page.context().route(/example\.com/, (route) =>
route.fulfill({
body: '<!doctype html><meta charset=utf-8><title>success</title>',
status: 200,
contentType: 'text/html; charset=utf-8',
}),
)
const pagePromise = page.context().waitForEvent('page', {})
await link.click()
const newPage = await pagePromise
await expect(newPage).toHaveTitle('success')
},
)
})

Просмотреть файл

@ -0,0 +1,18 @@
/**
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <opensource@fthiessen.de>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { test as baseTest } from '@playwright/test'
import { TopBarSection } from '../sections/TopBarSection'
interface TopBarFixture {
topBar: TopBarSection
}
export const test = baseTest.extend<TopBarFixture>({
topBar: async ({ page }, use) => {
const form = new TopBarSection(page)
await use(form)
},
})

Просмотреть файл

@ -3,13 +3,14 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Locator, Page } from '@playwright/test'
import type { Locator, Page, Response } 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 descriptionField: Locator
public readonly newQuestionButton: Locator
// eslint-disable-next-line no-useless-constructor
@ -21,10 +22,21 @@ export class FormSection {
this.titleField = this.mainContent.getByRole('textbox', {
name: 'Form title',
})
this.descriptionField = this.mainContent.getByRole('textbox', {
name: 'Description',
})
}
public async fillTitle(text: string): Promise<void> {
const update = this.getFormUpdatedPromise()
await this.titleField.fill(text)
await update
}
public async fillDescription(text: string): Promise<void> {
const update = this.getFormUpdatedPromise()
await this.descriptionField.fill(text)
await update
}
public async addQuestion(type: QuestionType): Promise<void> {
@ -40,4 +52,15 @@ export class FormSection {
sections.map((section) => new QuestionSection(this.page, section)),
)
}
private getFormUpdatedPromise(): Promise<Response> {
return this.page.waitForResponse(
(response) =>
response.request().method() === 'PATCH' &&
response
.request()
.url()
.endsWith('/ocs/v2.php/apps/forms/api/v2.4/form/update'),
)
}
}

Просмотреть файл

@ -0,0 +1,38 @@
/**
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <opensource@fthiessen.de>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Locator, Page } from '@playwright/test'
export enum FormsView {
View = 'View',
Edit = 'Edit',
Results = 'Results',
}
export class TopBarSection {
public readonly toolbar: Locator
// eslint-disable-next-line no-useless-constructor
constructor(public readonly page: Page) {
this.toolbar = this.page.getByRole('toolbar', { name: 'View mode' })
}
public async getActiveView(): Promise<Locator> {
return this.toolbar.getByRole('radio', { checked: true })
}
public async getAllViews(): Promise<Locator> {
return this.toolbar.getByRole('radio')
}
public async toggleView(view: FormsView): Promise<void> {
const radio = this.toolbar.getByRole('radio', { name: view })
if (await radio.isChecked()) {
return
}
await radio.check({ force: true }) // force is needed as the input element is hidden behind the icon
await this.page.waitForURL(/\/submit$/)
}
}