зеркало из https://github.com/nextcloud/forms.git
test: Add e2e tests for the form description
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
Родитель
5fa4682fa9
Коммит
c3d50824a1
|
@ -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$/)
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче