diff --git a/src/pages/portfolio/positions/position.ts b/src/pages/portfolio/positions/position.ts index a446344e..27bdc9c9 100644 --- a/src/pages/portfolio/positions/position.ts +++ b/src/pages/portfolio/positions/position.ts @@ -102,7 +102,7 @@ export class Position { @step async shouldHaveAutomations(automations: AutomationStatus) { for (let i = 0; i < automations.length; i++) { - const automationIcon: Locator = await this.positionLocator + const automationIcon: Locator = this.positionLocator .getByText(automations[i].automation) .locator('..'); diff --git a/srcEarnProtocol/app.ts b/srcEarnProtocol/app.ts index 1a799fdc..0c830e39 100644 --- a/srcEarnProtocol/app.ts +++ b/srcEarnProtocol/app.ts @@ -1,48 +1,22 @@ import { Page } from '@playwright/test'; // import { Modals } from './modals'; -import { - // Borrow, - Earn, - Header, - // Homepage, - // Multiply, - // Portfolio, - // Position, - // Rays, -} from './pages'; +import { Earn, Header, LandingPage } from './pages'; export class App { readonly page: Page; - // readonly borrow: Borrow; - readonly earn: Earn; readonly header: Header; - // readonly homepage: Homepage; - - // readonly modals: Modals; - - // readonly multiply: Multiply; - - // readonly portfolio: Portfolio; - - // readonly position: Position; - - // readonly rays: Rays; + readonly landingPage: LandingPage; constructor(page: Page) { this.page = page; - // this.borrow = new Borrow(page); this.earn = new Earn(page); this.header = new Header(page); - // this.homepage = new Homepage(page); + this.landingPage = new LandingPage(page); // this.modals = new Modals(page); - // this.multiply = new Multiply(page); - // this.portfolio = new Portfolio(page); - // this.position = new Position(page); - // this.rays = new Rays(page); } async pause() { diff --git a/srcEarnProtocol/pages/index.ts b/srcEarnProtocol/pages/index.ts index e7eabc23..d4367999 100644 --- a/srcEarnProtocol/pages/index.ts +++ b/srcEarnProtocol/pages/index.ts @@ -1,4 +1,5 @@ import { Earn } from './earn'; import { Header } from './header'; +import { LandingPage } from './landingPage'; -export { Earn, Header }; +export { Earn, Header, LandingPage }; diff --git a/srcEarnProtocol/pages/landingPage/index.ts b/srcEarnProtocol/pages/landingPage/index.ts new file mode 100644 index 00000000..414a5a9b --- /dev/null +++ b/srcEarnProtocol/pages/landingPage/index.ts @@ -0,0 +1,38 @@ +import { expect, step } from '#earnProtocolFixtures'; +import { Page } from '@playwright/test'; +import { StrategiesCarousel } from './strategiesCarousel'; + +export class LandingPage { + readonly page: Page; + + readonly strategiesCarousel: StrategiesCarousel; + + constructor(page: Page) { + this.page = page; + this.strategiesCarousel = new StrategiesCarousel(page); + } + + @step + async shouldBeVisible() { + await expect( + this.page.getByText('Automated Exposure to DeFi'), + '"Automated Exposure..." should be visible' + ).toBeVisible(); + } + + @step + async open() { + await expect(async () => { + await this.page.goto('https://earn-protocol-landing-page-staging.oasisapp.dev/'); + await this.shouldBeVisible(); + }).toPass(); + } + + @step + async shouldShowStrategyCard() { + await expect( + this.page.locator('[class*="_strategyCardHeaderWrapper"]').nth(0), + 'Strategy card should be visible' + ).toBeVisible(); + } +} diff --git a/srcEarnProtocol/pages/landingPage/strategiesCarousel/activeSlide.ts b/srcEarnProtocol/pages/landingPage/strategiesCarousel/activeSlide.ts new file mode 100644 index 00000000..d7e913df --- /dev/null +++ b/srcEarnProtocol/pages/landingPage/strategiesCarousel/activeSlide.ts @@ -0,0 +1,16 @@ +import { Page } from '@playwright/test'; +import { StrategyCard } from 'srcEarnProtocol/pages/strategyCard'; + +export class ActiveSlide { + readonly page: Page; + + readonly strategyCard: StrategyCard; + + constructor(page: Page) { + this.page = page; + this.strategyCard = new StrategyCard( + page, + page.locator('[class*="_slideActive_"]').locator('[class*="_strategyCard_"]') + ); + } +} diff --git a/srcEarnProtocol/pages/landingPage/strategiesCarousel/index.ts b/srcEarnProtocol/pages/landingPage/strategiesCarousel/index.ts new file mode 100644 index 00000000..24aa1f3f --- /dev/null +++ b/srcEarnProtocol/pages/landingPage/strategiesCarousel/index.ts @@ -0,0 +1,30 @@ +import { Page } from '@playwright/test'; +import { ActiveSlide } from './activeSlide'; +import { expect, step } from '#earnProtocolFixtures'; + +export class StrategiesCarousel { + readonly page: Page; + + readonly activeSlide: ActiveSlide; + + constructor(page: Page) { + this.page = page; + this.activeSlide = new ActiveSlide(page); + } + + @step + async moveToNextStrategy(direction: 'Right' | 'Left') { + await this.page.locator(`[class*="_button${direction}_"]`).click(); + + // Button should be disabled after click + await expect(async () => { + expect(await this.page.locator(`[class*="_button${direction}_"]`).isDisabled()).toBeTruthy(); + }).toPass(); + // Button should be enabled back after a little while + await expect(async () => { + expect( + await this.page.locator(`[class*="_button${direction}_"]`).isDisabled() + ).not.toBeTruthy(); + }).toPass(); + } +} diff --git a/srcEarnProtocol/pages/strategyCard/header.ts b/srcEarnProtocol/pages/strategyCard/header.ts new file mode 100644 index 00000000..bca575a1 --- /dev/null +++ b/srcEarnProtocol/pages/strategyCard/header.ts @@ -0,0 +1,34 @@ +import { step } from '#noWalletFixtures'; +import { Locator, Page } from '@playwright/test'; + +export class Header { + readonly page: Page; + + readonly headerLocator: Locator; + + constructor(page: Page, cardLocator: Locator) { + this.page = page; + this.headerLocator = cardLocator.locator('[class*="_strategyCardHeaderWrapper"]'); + } + + @step + async getToken(): Promise { + const token = await this.headerLocator.getByTestId('strategy-token').innerText(); + return token; + } + + @step + async getNetwork(): Promise { + const network = await this.headerLocator + .getByTestId('strategy-network') + .getByRole('img') + .getAttribute('alt'); + return network.replace('network_', ''); + } + + @step + async getRisk(): Promise { + const risk = await this.headerLocator.getByText(' risk').innerText(); + return risk; + } +} diff --git a/srcEarnProtocol/pages/strategyCard/index.ts b/srcEarnProtocol/pages/strategyCard/index.ts new file mode 100644 index 00000000..7c0ed141 --- /dev/null +++ b/srcEarnProtocol/pages/strategyCard/index.ts @@ -0,0 +1,15 @@ +import { Locator, Page } from '@playwright/test'; +import { Header } from './header'; + +export class StrategyCard { + readonly page: Page; + + readonly header: Header; + + readonly cardLocator: Locator; + + constructor(page: Page, cardLocator: Locator) { + this.page = page; + this.header = new Header(page, cardLocator); + } +} diff --git a/tests/earnProtocol/landingPage.spec.ts b/tests/earnProtocol/landingPage.spec.ts new file mode 100644 index 00000000..b8a73a3e --- /dev/null +++ b/tests/earnProtocol/landingPage.spec.ts @@ -0,0 +1,72 @@ +import { expect, test } from '#earnProtocolFixtures'; + +test.describe('Landin page', async () => { + test('It should show strategy card', async ({ app }) => { + await app.landingPage.open(); + await app.landingPage.shouldShowStrategyCard(); + }); + + test('It should show strategy card to the right', async ({ app }) => { + let originalStrategyCard: { token: string; network: string; risk: string }; + let newStrategyCard: { token: string; network: string; risk: string }; + + await app.landingPage.open(); + + // Get strategy info for current active strategy in carousel + originalStrategyCard.token = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getToken(); + originalStrategyCard.network = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getNetwork(); + originalStrategyCard.risk = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getRisk(); + + // Select strategy to the right + await app.landingPage.strategiesCarousel.moveToNextStrategy('Right'); + + // Get strategy info for current active strategy in carousel + newStrategyCard.token = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getToken(); + newStrategyCard.network = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getNetwork(); + newStrategyCard.risk = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getRisk(); + + expect( + originalStrategyCard.token == newStrategyCard.token && + originalStrategyCard.network == newStrategyCard.network && + originalStrategyCard.risk == newStrategyCard.risk + ).not.toBeTruthy(); + }); + + test('It should show strategy card to the left', async ({ app }) => { + let originalStrategyCard: { token: string; network: string; risk: string }; + let newStrategyCard: { token: string; network: string; risk: string }; + + await app.landingPage.open(); + + // Get strategy info for current active strategy in carousel + originalStrategyCard.token = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getToken(); + originalStrategyCard.network = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getNetwork(); + originalStrategyCard.risk = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getRisk(); + + // Select strategy to the left + await app.landingPage.strategiesCarousel.moveToNextStrategy('Left'); + + // Get strategy info for current active strategy in carousel + newStrategyCard.token = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getToken(); + newStrategyCard.network = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getNetwork(); + newStrategyCard.risk = + await app.landingPage.strategiesCarousel.activeSlide.strategyCard.header.getRisk(); + + expect( + originalStrategyCard.token == newStrategyCard.token && + originalStrategyCard.network == newStrategyCard.network && + originalStrategyCard.risk == newStrategyCard.risk + ).not.toBeTruthy(); + }); +});