diff --git a/e2e/pages/base.page.ts b/e2e/pages/base.page.ts index 12f5cb6..209fc20 100644 --- a/e2e/pages/base.page.ts +++ b/e2e/pages/base.page.ts @@ -18,4 +18,36 @@ export class BasePage { async isVisible(selector: string) { return this.page.isVisible(selector); } + + async selectOptionByValue(selector: string, value: string) { + await this.page.selectOption(selector, { value }); + } + + async getSelectedOption(selector: string): Promise { + return this.page.$eval(selector, (dropdown) => { + const selectElement = dropdown as HTMLSelectElement; + return selectElement.options[selectElement.selectedIndex].text; + }); + } + + async dragAndDrop(source: string, target: string) { + await this.page.dragAndDrop(source, target); + } + + async getTextOfElement(selector: string): Promise { + return this.page.textContent(selector); + } + + async clickAndWaitForNewWindow(selector: string): Promise { + const [newPage] = await Promise.all([ + this.page.context().waitForEvent('page'), + this.page.click(selector), + ]); + await newPage.waitForLoadState(); + return newPage; + } + + async switchToWindow(page: Page) { + await page.bringToFront(); + } } diff --git a/e2e/pages/drag_and_drop.page.ts b/e2e/pages/drag_and_drop.page.ts new file mode 100644 index 0000000..6df543b --- /dev/null +++ b/e2e/pages/drag_and_drop.page.ts @@ -0,0 +1,20 @@ +import { BasePage } from './base.page'; + +export class DragAndDropPage extends BasePage { + private url = '/drag_and_drop'; + public columnA = '#column-a'; + public columnB = '#column-b'; + + async open() { + await this.page.goto(this.url); + } + + async dragColumnAToColumnB() { + await super.dragAndDrop(this.columnA, this.columnB); + } + + async getColumnText(selector: string): Promise { + return super.getTextOfElement(selector); + } +} + diff --git a/e2e/pages/dropdown.page.ts b/e2e/pages/dropdown.page.ts new file mode 100644 index 0000000..db30260 --- /dev/null +++ b/e2e/pages/dropdown.page.ts @@ -0,0 +1,18 @@ +import { BasePage } from './base.page'; + +export class DropdownPage extends BasePage { + private url = '/dropdown'; + private dropdownSelector = '#dropdown'; + + async open() { + await this.page.goto(this.url); + } + + async selectOptionByValue(value: string) { + await super.selectOptionByValue(this.dropdownSelector, value); + } + + async getSelectedOption() { + return super.getSelectedOption(this.dropdownSelector); + } +} \ No newline at end of file diff --git a/e2e/pages/login.page.ts b/e2e/pages/login.page.ts index 35dbeb3..b5f14d3 100644 --- a/e2e/pages/login.page.ts +++ b/e2e/pages/login.page.ts @@ -1,11 +1,16 @@ import { BasePage } from './base.page'; export class LoginPage extends BasePage { + private url = '/login'; private usernameInput = '#username'; private passwordInput = '#password'; private loginButton = 'button[type="submit"]'; private errorMessage = '.flash.error' + async open() { + await this.page.goto(this.url); + } + async enterUsername(username: string) { await this.type(this.usernameInput, username); } diff --git a/e2e/pages/multiple_windows.page.ts b/e2e/pages/multiple_windows.page.ts new file mode 100644 index 0000000..0454dc3 --- /dev/null +++ b/e2e/pages/multiple_windows.page.ts @@ -0,0 +1,15 @@ +import { BasePage } from './base.page'; +import { Page } from '@playwright/test'; + +export class MultipleWindowsPage extends BasePage { + private url = '/windows'; + private clickHereLink = 'a[href="/windows/new"]'; + + async open() { + await this.page.goto(this.url); + } + + async clickHereAndOpenNewWindow(): Promise { + return this.clickAndWaitForNewWindow(this.clickHereLink); + } +} diff --git a/e2e/tests/drag_and_drop.spec.ts b/e2e/tests/drag_and_drop.spec.ts new file mode 100644 index 0000000..1aaef05 --- /dev/null +++ b/e2e/tests/drag_and_drop.spec.ts @@ -0,0 +1,19 @@ +import { test, expect } from '@playwright/test'; +import { DragAndDropPage } from '../pages/drag_and_drop.page'; + +test.describe('Drag and Drop functionality', () => { + let dragAndDropPage: DragAndDropPage; + + test.beforeEach(async ({ page }) => { + dragAndDropPage = new DragAndDropPage(page); + await dragAndDropPage.open(); // Navigate to the Drag and Drop page + }); + + test('Drag column A to column B', async ({ page }) => { + await dragAndDropPage.dragColumnAToColumnB(); + const columnAText = await dragAndDropPage.getColumnText(dragAndDropPage.columnA); + const columnBText = await dragAndDropPage.getColumnText(dragAndDropPage.columnB); + expect(columnAText).toBe('B'); + expect(columnBText).toBe('A'); + }); +}); diff --git a/e2e/tests/dropdown.spec.ts b/e2e/tests/dropdown.spec.ts new file mode 100644 index 0000000..ded5968 --- /dev/null +++ b/e2e/tests/dropdown.spec.ts @@ -0,0 +1,24 @@ +import { test, expect } from '@playwright/test'; +import { DropdownPage } from '../pages/dropdown.page'; + + +test.describe('Dropdown functionality', () => { + let dropdownPage: DropdownPage; + + test.beforeEach(async ({ page }) => { + dropdownPage = new DropdownPage(page); + await dropdownPage.open(); // Navigate to the Dropdown page + }); + + test('Select option 1 from the dropdown', async ({ page }) => { + await dropdownPage.selectOptionByValue('1'); + const selectedOption = await dropdownPage.getSelectedOption(); + expect(selectedOption).toBe('Option 1'); + }); + + test('Select option 2 from the dropdown', async ({ page }) => { + await dropdownPage.selectOptionByValue('2'); + const selectedOption = await dropdownPage.getSelectedOption(); + expect(selectedOption).toBe('Option 2'); + }); +}); diff --git a/e2e/tests/example.spec.ts b/e2e/tests/login.spec.ts similarity index 92% rename from e2e/tests/example.spec.ts rename to e2e/tests/login.spec.ts index 559e21e..6449894 100644 --- a/e2e/tests/example.spec.ts +++ b/e2e/tests/login.spec.ts @@ -7,7 +7,7 @@ test.describe('Login functionality', () => { test.beforeEach(async ({ page }) => { loginPage = new LoginPage(page); - await loginPage.open('http://the-internet.herokuapp.com/login'); + await loginPage.open(); }); test('Login with valid credentials', async ({ page }) => { diff --git a/e2e/tests/multiple_windows.spec.ts b/e2e/tests/multiple_windows.spec.ts new file mode 100644 index 0000000..e62f037 --- /dev/null +++ b/e2e/tests/multiple_windows.spec.ts @@ -0,0 +1,18 @@ +import { test, expect, Page } from '@playwright/test'; +import { MultipleWindowsPage } from '../pages/multiple_windows.page'; + +test.describe('Multiple Windows functionality', () => { + let multipleWindowsPage: MultipleWindowsPage; + let newPage: Page; + + test.beforeEach(async ({ page }) => { + multipleWindowsPage = new MultipleWindowsPage(page); + await multipleWindowsPage.open(); // Navigate to the Multiple Windows page + }); + + test('Open new window and verify content', async ({ page }) => { + newPage = await multipleWindowsPage.clickHereAndOpenNewWindow(); + await multipleWindowsPage.switchToWindow(newPage); + expect(await newPage.textContent('h3')).toBe('New Window'); + }); +}); diff --git a/playwright.config.ts b/playwright.config.ts index f890d09..b8827e5 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from '@playwright/test'; export default defineConfig({ use: { + baseURL: 'http://the-internet.herokuapp.com', browserName: 'chromium', headless: false, viewport: { width: 1280, height: 720 },