-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Krzysztof Gruszczynski
committed
Sep 27, 2024
1 parent
83fc2de
commit 4e41c25
Showing
22 changed files
with
1,603 additions
and
2 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
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,2 @@ | ||
test-results/ | ||
playwright-report/ |
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,2 @@ | ||
cd playwright | ||
npm run lint && npm run prettier |
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,4 @@ | ||
# Playwright Specific | ||
node_modules/ | ||
test-results/ | ||
playwright-report |
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,6 @@ | ||
{ | ||
"trailingComma": "es5", | ||
"singleQuote": true, | ||
"printWidth": 100, | ||
"experimentalTernaries": true | ||
} |
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,13 @@ | ||
# Overview | ||
|
||
This service helps in E2E testing of the web application. | ||
|
||
## Before you start | ||
|
||
- Run the app locally from the root directory. | ||
- To run all tests in headless mode use `yarn test`. | ||
- To debug tests use `yarn test:debug` UI mode. | ||
|
||
## Coding practices | ||
|
||
We use a mix of [Husky](https://github.com/typicode/husky), [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/) within our project to help enforce consistent coding practices. |
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,33 @@ | ||
import { Locator, expect } from '@playwright/test'; | ||
import playwrightObject from '../engine/playwright_object'; | ||
|
||
export interface Selector { | ||
cssSelector?: string; | ||
label?: string; | ||
testId?: string; | ||
} | ||
|
||
export abstract class BaseElement { | ||
constructor(public selector: Selector) {} | ||
|
||
element(): Locator { | ||
switch (true) { | ||
case !!this.selector.cssSelector: | ||
return playwrightObject.page().locator(this.selector.cssSelector); | ||
case !!this.selector.label: | ||
return playwrightObject.page().getByLabel(this.selector.label); | ||
case !!this.selector.testId: | ||
return playwrightObject.page().getByTestId(this.selector.testId); | ||
default: | ||
throw new Error('You need to specify some selector'); | ||
} | ||
} | ||
|
||
public async toBeVisible() { | ||
await this.element().waitFor({ state: 'visible' }); | ||
} | ||
|
||
public async toHaveText(text: string) { | ||
await expect(this.element()).toHaveText(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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { BaseElement } from './base_element'; | ||
|
||
export class ButtonElement extends BaseElement { | ||
constructor(testId: string) { | ||
super({ testId }); | ||
} | ||
|
||
async click(options?: { force?: boolean; noWaitAfter?: boolean; timeout?: number }) { | ||
await this.element().click(options); | ||
} | ||
} | ||
|
||
export function getButtonElement(testId: string): ButtonElement { | ||
return new ButtonElement(testId); | ||
} |
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,27 @@ | ||
import { expect } from '@playwright/test'; | ||
import { BaseElement } from './base_element'; | ||
|
||
export class InputElement extends BaseElement { | ||
constructor(label: string) { | ||
super({ label }); | ||
} | ||
|
||
async fill( | ||
value: string, | ||
options?: { force?: boolean; noWaitAfter?: boolean; timeout?: number } | ||
) { | ||
await this.element().fill(value, options); | ||
} | ||
|
||
async checkValue(value: string) { | ||
await expect(this.element()).toHaveValue(value); | ||
} | ||
|
||
async shouldBeValid() { | ||
await expect(this.element()).toHaveJSProperty('validationMessage', ''); | ||
} | ||
} | ||
|
||
export function getInputElement(label: string): InputElement { | ||
return new InputElement(label); | ||
} |
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,11 @@ | ||
import { BaseElement } from './base_element'; | ||
|
||
export class TextElement extends BaseElement { | ||
constructor(testId: string, public text: string) { | ||
super({ testId }); | ||
} | ||
|
||
async validateText() { | ||
await this.toHaveText(this.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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { Browser, BrowserContext, Page } from 'playwright-core'; | ||
|
||
export interface Initialization { | ||
playwrightBrowser?: Browser; | ||
browserContext?: BrowserContext; | ||
page?: Page; | ||
browserName?: string; | ||
} | ||
|
||
export class PlaywrightObject { | ||
browser?: Browser; | ||
context?: BrowserContext; | ||
browserName?: string; | ||
private playwrightPage?: Page; | ||
|
||
async init(init: Initialization) { | ||
if (this.browser) return; | ||
this.browser = init.playwrightBrowser; | ||
this.context = init.browserContext; | ||
this.playwrightPage = init.page; | ||
} | ||
|
||
async initNew(init: Initialization) { | ||
if (!init.playwrightBrowser) { | ||
throw new Error('Cannot start without browser'); | ||
} | ||
this.browser = init.playwrightBrowser; | ||
this.browserName = init.browserName; | ||
this.context = await this.browser.newContext(); | ||
this.playwrightPage = await this.browser.newPage(); | ||
} | ||
|
||
async close() { | ||
await this.browser?.close(); | ||
this.browser = undefined; | ||
} | ||
|
||
async initAll(init: Initialization) { | ||
if (!init.playwrightBrowser) { | ||
throw new Error('Cannot start without browser'); | ||
} | ||
if (this.browser) return; | ||
this.browser = init.playwrightBrowser; | ||
this.browserName = init.browserName; | ||
this.context = await this.browser.newContext(); | ||
this.playwrightPage = await this.browser.newPage(); | ||
} | ||
|
||
async open(url: string) { | ||
if (!this.page) { | ||
throw new Error('Cannot open page without context'); | ||
} | ||
await this.page().goto(url); | ||
} | ||
|
||
page() { | ||
if (!this.playwrightPage) { | ||
throw new Error('Please initialize page first using init() method in Playwright'); | ||
} | ||
return this.playwrightPage; | ||
} | ||
} | ||
|
||
export default new PlaywrightObject(); |
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,12 @@ | ||
import { test as base } from '@playwright/test'; | ||
import playwrightObject from '@engine/playwright_object'; | ||
|
||
export const test = base.extend<{ initNew: void }>({ | ||
initNew: async ({ browser, browserName }, testFunction) => { | ||
await playwrightObject.initNew({ | ||
playwrightBrowser: browser, | ||
browserName: browserName, | ||
}); | ||
await testFunction(); | ||
}, | ||
}); |
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,4 @@ | ||
export interface ToDoEntity { | ||
taskName: string; | ||
isCompleted: boolean; | ||
} |
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,44 @@ | ||
import typescriptEslint from '@typescript-eslint/eslint-plugin'; | ||
import tsParser from '@typescript-eslint/parser'; | ||
import path from 'node:path'; | ||
import { fileURLToPath } from 'node:url'; | ||
import js from '@eslint/js'; | ||
import { FlatCompat } from '@eslint/eslintrc'; | ||
|
||
const __filename = fileURLToPath(import.meta.url); | ||
const __dirname = path.dirname(__filename); | ||
const compat = new FlatCompat({ | ||
baseDirectory: __dirname, | ||
recommendedConfig: js.configs.recommended, | ||
allConfig: js.configs.all, | ||
}); | ||
|
||
export default [ | ||
js.configs.recommended, | ||
|
||
...compat.extends( | ||
'plugin:@typescript-eslint/recommended', | ||
'plugin:@typescript-eslint/stylistic', | ||
'plugin:eslint-plugin-playwright/recommended', | ||
'prettier' | ||
), | ||
{ | ||
plugins: { | ||
'@typescript-eslint': typescriptEslint, | ||
}, | ||
|
||
languageOptions: { | ||
parser: tsParser, | ||
}, | ||
}, | ||
{ | ||
files: ['**/*.spec.ts'], | ||
rules: { | ||
'@typescript-eslint/no-unused-vars': 'off', | ||
'playwright/expect-expect': 'off', | ||
}, | ||
}, | ||
{ | ||
ignores: ['node_modules/', 'playwright-report/', 'test-results/'], | ||
}, | ||
]; |
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,38 @@ | ||
{ | ||
"name": "playwright", | ||
"version": "1.0.0", | ||
"main": "index.js", | ||
"license": "MIT", | ||
"type": "module", | ||
"scripts": { | ||
"check-types": "tsc --noemit", | ||
"eslint": "eslint '**/*.{ts, json}' --max-warnings=0", | ||
"lint": "yarn eslint && yarn check-types", | ||
"prepare": "cd .. && husky playwright/.husky", | ||
"prettier": "prettier --check \"**/*.{js,cjs,ts,json,md,yml}\"", | ||
"prettify": "prettier --write \"**/*.{js,cjs,ts,json,md,yml}\"", | ||
"test": "playwright test", | ||
"test:debug": "playwright test --ui" | ||
}, | ||
"dependencies": { | ||
"@playwright/test": "^1.47.1", | ||
"lodash": "^4.17.21", | ||
"playwright": "^1.47.1", | ||
"typescript": "^5.6.2" | ||
}, | ||
"devDependencies": { | ||
"@types/lodash": "^4.17.9", | ||
"@types/node": "^22.5.5", | ||
"@typescript-eslint/eslint-plugin": "^8.7.0", | ||
"@typescript-eslint/parser": "^8.7.0", | ||
"eslint": "^9.11.1", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-playwright": "^1.6.2", | ||
"husky": "^9.1.6", | ||
"lint-staged": "^15.2.10", | ||
"prettier": "^3.3.3" | ||
}, | ||
"lint-staged": { | ||
"**/*": "prettier --write --ignore-unknown" | ||
} | ||
} |
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,60 @@ | ||
import { expect } from '@playwright/test'; | ||
import playwrightObject from '../engine/playwright_object'; | ||
|
||
export abstract class BasePage { | ||
protected constructor( | ||
protected partialUrl?: string, | ||
protected tabName?: string, | ||
public pageSelector?: string | ||
) {} | ||
|
||
async open() { | ||
await playwrightObject.open(this.partialUrl as string); | ||
} | ||
|
||
async shouldBeOpened() { | ||
await this.waitForLoadState('domcontentloaded'); | ||
if (this.pageSelector) { | ||
await this.waitForPageSelector(); | ||
} | ||
if (this.partialUrl) { | ||
await this.validateUrl(); | ||
} | ||
if (this.tabName) { | ||
await this.validatePageTitle(); | ||
} | ||
} | ||
|
||
async waitForUrl(url: string) { | ||
await playwrightObject.page().waitForURL(url); | ||
} | ||
|
||
async waitForLoadState( | ||
state?: 'load' | 'domcontentloaded' | 'networkidle', | ||
options?: { timeout: number } | ||
) { | ||
await playwrightObject.page().waitForLoadState(state, options); | ||
} | ||
|
||
async waitForPageSelector() { | ||
if (!this.pageSelector) { | ||
throw new Error('You need to specify page selector to be a'); | ||
} | ||
await playwrightObject.page().locator(this.pageSelector).waitFor(); | ||
} | ||
|
||
async validateUrl() { | ||
if (!this.partialUrl) { | ||
throw new Error("Can't checkUrl because uri is not specified"); | ||
} | ||
await playwrightObject.page().waitForURL(this.partialUrl); | ||
} | ||
|
||
async validatePageTitle() { | ||
if (!this.tabName) { | ||
throw new Error("Can't checkTitle because title is not specified"); | ||
} | ||
const actualTitle = await playwrightObject.page().title(); | ||
expect(actualTitle).toEqual(this.tabName); | ||
} | ||
} |
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,7 @@ | ||
import { BasePage } from './base_page'; | ||
|
||
export class DashboardPage extends BasePage { | ||
constructor(private url = '/cpf/my-space') { | ||
super(url); | ||
} | ||
} |
Oops, something went wrong.