-
Notifications
You must be signed in to change notification settings - Fork 100
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Page object models allow to write tests independent of locators, this allows for easier maintenance in case locators change. Signed-off-by: Ferdinand Thiessen <[email protected]>
- Loading branch information
Showing
6 changed files
with
163 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,58 @@ | ||
/** | ||
* @copyright Copyright (c) 2024 Ferdinand Thiessen <[email protected]> | ||
* | ||
* @author Ferdinand Thiessen <[email protected]> | ||
* | ||
* @license AGPL-3.0-or-later | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Affero General Public License as | ||
* published by the Free Software Foundation, either version 3 of the | ||
* License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU Affero General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Affero General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <[email protected]> | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
import { expect } from '@playwright/test' | ||
import { test } from '../fixtures/random-user' | ||
|
||
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' | ||
|
||
const test = mergeTests(randomUserTest, appNavigationTest, formTest) | ||
|
||
test.beforeEach(async ({ page }) => { | ||
await page.goto('apps/forms') | ||
await page.waitForURL(/apps\/forms$/) | ||
}) | ||
|
||
test('It shows the empty content', async ({ page }) => { | ||
await expect(page.getByText('No forms created yet')).toBeVisible() | ||
await expect(page.getByRole('button', { name: 'Create a form' })).toBeVisible() | ||
}) | ||
test.describe('No forms created - empty content', () => { | ||
test('It shows the empty content', async ({ page }) => { | ||
await expect(page.getByText('No forms created yet')).toBeVisible() | ||
await expect( | ||
page.getByRole('button', { name: 'Create a form' }), | ||
).toBeVisible() | ||
}) | ||
|
||
test('Use button to create new form', async ({ page }) => { | ||
await page.getByRole('button', { name: 'Create a form' }).click() | ||
test('Use button to create new form', async ({ page, appNavigation }) => { | ||
const oldNumber = (await appNavigation.ownFormsLocator.all()).length | ||
|
||
await page.waitForURL(/apps\/forms\/.+/) | ||
await page.getByRole('button', { name: 'Create a form' }).click() | ||
await page.waitForURL(/apps\/forms\/.+/) | ||
|
||
// check we are in edit mode by default and the heading is focussed | ||
await expect(page.locator('h2 textarea')).toBeVisible() | ||
await expect(page.locator('h2 textarea')).toBeFocused() | ||
const newNumber = (await appNavigation.ownFormsLocator.all()).length | ||
expect(newNumber - oldNumber).toBe(1) | ||
}) | ||
}) | ||
|
||
test('Use app navigation to create new form', async ({ page }) => { | ||
await page.getByRole('navigation') | ||
.getByRole('button', { name: 'New form' }) | ||
.click() | ||
|
||
await page.waitForURL(/apps\/forms\/.+/) | ||
test('Use app navigation to create new form', async ({ appNavigation, form }) => { | ||
await appNavigation.clickNewForm() | ||
|
||
// check we are in edit mode by default and the heading is focussed | ||
await expect(page.locator('h2 textarea')).toBeVisible() | ||
await expect(page.locator('h2 textarea')).toBeFocused() | ||
await expect(form.titleField).toBeFocused() | ||
}) | ||
|
||
test('Form name updated in navigation', async ({ page }) => { | ||
// Create a form | ||
await page | ||
.getByRole('navigation') | ||
.getByRole('button', { name: 'New form' }) | ||
.click() | ||
|
||
await page.waitForURL(/apps\/forms\/.+/) | ||
test('Form name updated in navigation', async ({ appNavigation, form }) => { | ||
await appNavigation.clickNewForm() | ||
|
||
// check we are in edit mode by default and the heading is focussed | ||
await expect(page.locator('h2 textarea')).toBeVisible() | ||
await expect(page.locator('h2 textarea')).toBeFocused() | ||
await expect(form.titleField).toBeFocused() | ||
|
||
// check the form exists in the navigation | ||
await page | ||
.getByRole('list', { name: 'Your forms' }) | ||
.getByRole('link', { name: 'New form' }) | ||
.isVisible() | ||
await expect(appNavigation.getOwnForm('New form')).toBeVisible() | ||
|
||
// Update the title | ||
await page.locator('h2 textarea').fill('My example form') | ||
await form.fillTitle('My example form') | ||
|
||
// See the title is updated | ||
await page | ||
.getByRole('list', { name: 'Your forms' }) | ||
.getByRole('link', { name: 'My example form' }) | ||
.isVisible() | ||
await expect(appNavigation.getOwnForm('My example form')).toBeVisible() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { FormSection } from '../sections/FormSection' | ||
|
||
interface FormFixture { | ||
form: FormSection | ||
} | ||
|
||
export const test = baseTest.extend<FormFixture>({ | ||
form: async ({ page }, use) => { | ||
const form = new FormSection(page) | ||
await use(form) | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { AppNavigationSection } from '../sections/AppNavigationSection' | ||
|
||
interface AppNavigationFixture { | ||
appNavigation: AppNavigationSection | ||
} | ||
|
||
export const test = baseTest.extend<AppNavigationFixture>({ | ||
appNavigation: async ({ page }, use) => { | ||
const appNavigation = new AppNavigationSection(page) | ||
await use(appNavigation) | ||
}, | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <[email protected]> | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
import type { Locator, Page } from '@playwright/test' | ||
|
||
export class AppNavigationSection { | ||
public readonly navigationLocator: Locator | ||
public readonly newFormLocator: Locator | ||
public readonly ownFormsLocator: Locator | ||
public readonly sharedFormsLocator: Locator | ||
|
||
// eslint-disable-next-line no-useless-constructor | ||
constructor(public readonly page: Page) { | ||
this.navigationLocator = this.page.getByRole('navigation', { | ||
name: 'Forms navigation', | ||
}) | ||
this.newFormLocator = this.navigationLocator.getByRole('button', { | ||
name: 'New form', | ||
}) | ||
this.ownFormsLocator = this.navigationLocator | ||
.getByRole('list', { name: 'Your forms' }) | ||
.getByRole('listitem') | ||
this.sharedFormsLocator = this.navigationLocator | ||
.getByRole('button', { name: 'Shared forms' }) | ||
.getByRole('listitem') | ||
} | ||
|
||
public async clickNewForm(): Promise<void> { | ||
await this.newFormLocator.click() | ||
} | ||
|
||
public async openArchivedForms(): Promise<void> { | ||
await this.navigationLocator | ||
.getByRole('button', { name: 'Archived forms' }) | ||
.click() | ||
} | ||
|
||
public getOwnForm(name: string | RegExp): Locator { | ||
return this.ownFormsLocator.getByRole('link', { name }) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* SPDX-FileCopyrightText: 2024 Ferdinand Thiessen <[email protected]> | ||
* SPDX-License-Identifier: AGPL-3.0-or-later | ||
*/ | ||
|
||
import type { Locator, Page } from '@playwright/test' | ||
|
||
export class FormSection { | ||
public readonly mainContent: Locator | ||
public readonly titleField: Locator | ||
|
||
// eslint-disable-next-line no-useless-constructor | ||
constructor(public readonly page: Page) { | ||
this.mainContent = this.page.getByRole('main') | ||
this.titleField = this.mainContent.getByRole('textbox', { | ||
name: 'Form title', | ||
}) | ||
} | ||
|
||
public async fillTitle(text: string): Promise<void> { | ||
await this.titleField.fill(text) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters