Skip to content

Commit

Permalink
test: Add e2e tests for the form description
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Aug 14, 2024
1 parent 5fa4682 commit c3d5082
Show file tree
Hide file tree
Showing 4 changed files with 180 additions and 1 deletion.
100 changes: 100 additions & 0 deletions playwright/e2e/form-description.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <[email protected]>
* 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')
},
)
})
18 changes: 18 additions & 0 deletions playwright/support/fixtures/topBar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <[email protected]>
* 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)
},
})
25 changes: 24 additions & 1 deletion playwright/support/sections/FormSection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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> {
Expand All @@ -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'),
)
}
}
38 changes: 38 additions & 0 deletions playwright/support/sections/TopBarSection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <[email protected]>
* 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$/)
}
}

0 comments on commit c3d5082

Please sign in to comment.