Skip to content

Commit

Permalink
Merge branch '1194-feature-create-playwright-page-object-model-for-th…
Browse files Browse the repository at this point in the history
…e-e2e-tests' of https://github.com/podkrepi-bg/frontend into 1194-feature-create-playwright-page-object-model-for-the-e2e-tests
  • Loading branch information
DanielTakev committed Dec 16, 2022
2 parents b18b16b + 7f48285 commit 3bb8a19
Show file tree
Hide file tree
Showing 14 changed files with 330 additions and 94 deletions.
2 changes: 1 addition & 1 deletion e2e/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
node_modules/
/playwright/.cache/
/test-results/
/playwright-report/
/playwright/.cache/
/e2e-reports/
24 changes: 12 additions & 12 deletions e2e/data/localization.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import bgLocalizationCommonJson from '../../public/locales/bg/common.json';
import enLocalizationCommonJson from '../../public/locales/en/common.json';
import bgLocalizationCommonJson from '../../../frontend/public/locales/bg/common.json';
import enLocalizationCommonJson from '../../../frontend/public/locales/en/common.json';

import bgLocalizationIndexJson from '../../public/locales/bg/index.json';
import enLocalizationIndexJson from '../../public/locales/en/index.json';
import bgLocalizationIndexJson from '../../../frontend/public/locales/bg/index.json';
import enLocalizationIndexJson from '../../../frontend/public/locales/en/index.json';

import bgLocalizationSupportJson from '../../public/locales/bg/support.json';
import enLocalizationSupportJson from '../../public/locales/en/support.json';
import bgLocalizationSupportJson from '../../../frontend/public/locales/bg/support.json';
import enLocalizationSupportJson from '../../../frontend/public/locales/en/support.json';

import bgLocalizationValidationJson from '../../public/locales/bg/validation.json';
import enLocalizationValidationJson from '../../public/locales/en/validation.json';
import bgLocalizationValidationJson from '../../../frontend/public/locales/bg/validation.json';
import enLocalizationValidationJson from '../../../frontend/public/locales/en/validation.json';

import bgLocalizationCampaignsJson from '../../public/locales/bg/campaigns.json';
import enLocalizationCampaignsJson from '../../public/locales/en/campaigns.json';
import bgLocalizationCampaignsJson from '../../../frontend/public/locales/bg/campaigns.json';
import enLocalizationCampaignsJson from '../../../frontend/public/locales/en/campaigns.json';

import bgLocalizationOneTimeDonationJson from '../../public/locales/bg/one-time-donation.json';
import enLocalizationOneTimeDonationJson from '../../public/locales/en/one-time-donation.json';
import bgLocalizationOneTimeDonationJson from '../../../frontend/public/locales/bg/one-time-donation.json';
import enLocalizationOneTimeDonationJson from '../../../frontend/public/locales/en/one-time-donation.json';

// All these constants are used in the E2E test pages to manipulate web elements in a respective language
// Common localization terms
Expand Down
8 changes: 3 additions & 5 deletions e2e/pages/web-pages/base.page.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { expect, Locator, Page } from '@playwright/test';

// Here we define all base methods, which are inherited into the other pages
export class BasePage {

protected page: Page;
Expand Down Expand Up @@ -53,11 +52,11 @@ export class BasePage {
* @param {any} options
* @param {number} timeoutParam
*/
async waitForElementToBeReadyBySelector(elementSelector: string, options?: any, timeoutParam: number = 10000): Promise<void> {
async waitForElementToBeReadyBySelector(elementSelector: string, options: any, timeoutParam: number = 10000): Promise<void> {
if (options) {
await this.page.locator(elementSelector, options).first().waitFor({state: 'visible', timeout: timeoutParam});
await this.page.locator(elementSelector, options).waitFor({state: 'visible', timeout: timeoutParam});
} else {
await this.page.locator(elementSelector).first().waitFor({state: 'visible', timeout: timeoutParam});
await this.page.waitForSelector(elementSelector, {state: 'visible', timeout: timeoutParam});
}
}

Expand Down Expand Up @@ -374,7 +373,6 @@ export class BasePage {
* @param {string} elementSelector
*/
async getCountOfElementsBySelector(elementSelector: string): Promise<number> {
await this.waitForElementToBePresentedBySelector(elementSelector);
return this.page.locator(elementSelector).count();
}

Expand Down
15 changes: 7 additions & 8 deletions e2e/pages/web-pages/campaigns/campaigns.page.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, Locator, Page } from '@playwright/test';
import { LanguagesEnum } from '../../../data/enums/languages.enum';
import { bgLocalizationCampaigns, enLocalizationCampaigns } from '../../../data/localization';
import { bgLocalizationCampaigns, bgLocalizationIndex, enLocalizationCampaigns } from '../../../data/localization';
import { HomePage } from '../home.page';


Expand Down Expand Up @@ -39,14 +39,13 @@ export class CampaignsPage extends HomePage {
* @param {LanguagesEnum} language, the default is BG
*/
async clickCampaignSchoolChildrenVarna(language: LanguagesEnum = LanguagesEnum.BG): Promise<void> {
await this.clickH5HeadingByText(language, this.campaignSchoolVarnaText, null);
await this.clickH5HeadingByText(language, this.campaignSchoolVarnaText);
}

/**
* Get filter buttons count on the Campaigns page
*/
async getFilterButtonsCount(): Promise<number> {
await this.waitForElementToBeReadyBySelector(this.filterButtonsCommonSelector);
return this.getCountOfElementsBySelector(this.filterButtonsCommonSelector);
}

Expand All @@ -55,7 +54,7 @@ export class CampaignsPage extends HomePage {
* @param {LanguagesEnum} language - the default value is BG
*/
async isCampaignsHeadingVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH1HeadingVisible(language, this.bgMainCampaignsHeading, this.enMainCampaignsHeading);
return this.isH1HeadingVisible(this.bgMainCampaignsHeading, this.enMainCampaignsHeading, language);
}

/**
Expand All @@ -71,31 +70,31 @@ export class CampaignsPage extends HomePage {
* @param {LanguagesEnum} language - the default value is BG
*/
async isSchoolChildrenVarnaHeadingVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH1HeadingVisible(language, this.campaignSchoolVarnaText, null);
return this.isH1HeadingVisible(this.campaignSchoolVarnaText, null, language);
}

/**
* Open campaign "Crisis Center - New Life Chance" H5 heading link on the main Campaigns page
* @param {LanguagesEnum} language, the default is BG
*/
async clickCampaignCrisisCenter(language: LanguagesEnum = LanguagesEnum.BG): Promise<void> {
await this.clickH5HeadingByText(language, this.campaignCrisisCenterText, null);
await this.clickH5HeadingByText(language, this.campaignCrisisCenterText);
}

/**
* Check if "Crisis Center - New Life Chance" campaign H1 heading is visible on the Campaigns page
* @param {LanguagesEnum} language - the default value is BG
*/
async isCrisiCenterHeading1Visible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH1HeadingVisible(language, this.campaignCrisisCenterText, null);
return this.isH1HeadingVisible(this.campaignCrisisCenterText, null, language);
}

/**
* Check if "Crisis Center - New Life Chance" campaign H4 heading is visible on the Campaigns page
* @param {LanguagesEnum} language - the default value is BG
*/
async isCrisiCenterHeading4Visible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH4HeadingVisible(language, this.campaignCrisisCenterText, null);
return this.isH4HeadingVisible(this.campaignCrisisCenterText, null, language);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion e2e/pages/web-pages/campaigns/donation.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,6 @@ export class DonationPage extends CampaignsPage {
* @param {LanguagesEnum} language - the default value is BG
*/
async isSuccessfulDonationTitleVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH4HeadingVisible(language, this.bgSuccessfulDonationTitle, this.enSuccessfulDonationTitle);
return this.isH4HeadingVisible(this.bgSuccessfulDonationTitle, this.enSuccessfulDonationTitle, language);
}
}
11 changes: 5 additions & 6 deletions e2e/pages/web-pages/header.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,15 @@ export class HeaderPage extends BasePage {

/**
* Click on the header submenu navigation link by text
* @param {LanguagesEnum} language
* @param {string} navTextBg
* @param {string} navTextEn
* @param {LanguagesEnum} language
*/
async clickHeaderSubmenuNavLink(language: LanguagesEnum, navTextBg: string, navTextEn: string): Promise<void> {
async clickHeaderSubmenuNavLink(navTextBg: string, navTextEn: string, language: LanguagesEnum): Promise<void> {
await this.waitForElementToBePresentedBySelector(this.headerSubmenuLinks);
if (language === LanguagesEnum.BG) {
await this.waitForElementToBeReadyBySelector(this.headerSubmenuLinks, {hasText: navTextBg});
await this.clickElement(this.headerSubmenuLinks, {hasText: navTextBg});
} else if (language === LanguagesEnum.EN) {
await this.waitForElementToBeReadyBySelector(this.headerSubmenuLinks, {hasText: navTextEn});
await this.clickElement(this.headerSubmenuLinks, {hasText: navTextEn});
} else {
throw new Error("Invalid language selection. Please, check 'languages.enum.ts'.");
Expand All @@ -94,7 +93,7 @@ export class HeaderPage extends BasePage {
*/
async clickCampaignsHeaderNavButton(language: LanguagesEnum = LanguagesEnum.BG): Promise<void> {
await this.clickHeaderNavLink(this.bgCampaignsNavLink, this.enCampaignsNavLink, language);
await this.clickHeaderSubmenuNavLink(language, this.bgAllCampaignsNavLink, this.enAllCampaignsNavLink);
await this.clickHeaderSubmenuNavLink(this.bgAllCampaignsNavLink, this.enAllCampaignsNavLink, language);
}

/**
Expand All @@ -111,7 +110,7 @@ export class HeaderPage extends BasePage {
*/
async clickJoinUsHeaderNavButton(language: LanguagesEnum = LanguagesEnum.BG): Promise<void> {
await this.clickAboutUsHeaderNavButton(language);
await this.clickHeaderSubmenuNavLink(language, this.bgJoinUsNavLink, this.enJoinUsNavLink);
await this.clickHeaderSubmenuNavLink(this.bgJoinUsNavLink, this.enJoinUsNavLink, language);
}

/**
Expand Down
88 changes: 49 additions & 39 deletions e2e/pages/web-pages/home.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,63 +70,73 @@ export class HomePage extends BasePage {
}

/**
* Check if Heading is visible by CSS Selector and text with timeout
* @param {string} elementSelector
* @param {LanguagesEnum} language
* Check if H1 heading is visible by text with timeout
* @param {string} headingBg
* @param {string | null} headingEn
* @param {LanguagesEnum} language
*/
async isHeadingVisibleBySelector(elementSelector: string, language: LanguagesEnum, headingBg: string, headingEn: string | null): Promise<boolean> {
await this.waitForElementToBePresentedByLocator(this.page.locator(elementSelector).first());
async isH1HeadingVisible(headingBg: string, headingEn: string | null, language: LanguagesEnum): Promise<boolean> {
await this.waitForElementToBePresentedByLocator(this.page.locator(this.containerRootElement).first());
if (language === LanguagesEnum.BG) {
return this.isElementVisibleBySelectorWithTimeout(elementSelector, {hasText: headingBg});
return this.isElementVisibleBySelectorWithTimeout(this.h1HeadingsSelector, {hasText: headingBg});
} else if (language === LanguagesEnum.EN) {
return this.isElementVisibleBySelectorWithTimeout(elementSelector, {hasText: headingEn});
return this.isElementVisibleBySelectorWithTimeout(this.h1HeadingsSelector, {hasText: headingEn});
} else {
throw new Error("Language not found!");
}
}

/**
* Check if H1 heading is visible by text with timeout
* @param {LanguagesEnum} language
* @param {string} headingBg
* @param {string | null} headingEn
*/
async isH1HeadingVisible(language: LanguagesEnum, headingBg: string, headingEn: string | null): Promise<boolean> {
return this.isHeadingVisibleBySelector(this.h1HeadingsSelector, language, headingBg, headingEn);
}


/**
* Check if H4 heading is visible by text with timeout
* @param {LanguagesEnum} language
* @param {string} headingBg
* @param {string | null} headingEn
* @param {LanguagesEnum} language
*/
async isH4HeadingVisible(language: LanguagesEnum, headingBg: string, headingEn: string | null): Promise<boolean> {
return this.isHeadingVisibleBySelector(this.h4HeadingsSelector, language, headingBg, headingEn);
async isH4HeadingVisible(headingBg: string, headingEn: string | null, language: LanguagesEnum): Promise<boolean> {
await this.waitForElementToBePresentedByLocator(this.page.locator(this.containerRootElement).first());
if (language === LanguagesEnum.BG) {
return this.isElementVisibleBySelectorWithTimeout(this.h4HeadingsSelector, {hasText: headingBg});
} else if (language === LanguagesEnum.EN) {
return this.isElementVisibleBySelectorWithTimeout(this.h4HeadingsSelector, {hasText: headingEn});
} else {
throw new Error("Language not found!");
}
}

/**
* Check if H5 heading is visible by text with timeout
* @param {LanguagesEnum} language
* @param {string} headingBg
* @param {string | null} headingEn
* @param {LanguagesEnum} language
*/
async isH5HeadingVisible(language: LanguagesEnum, headingBg: string, headingEn: string | null): Promise<boolean> {
return this.isHeadingVisibleBySelector(this.h5HeadingsSelector, language, headingBg, headingEn);
async isH5HeadingVisible(language: LanguagesEnum, headingBg: string | null, headingEn?: string): Promise<boolean> {
await this.waitForElementToBePresentedByLocator(this.page.locator(this.containerRootElement).first());
if (language === LanguagesEnum.BG) {
return this.isElementVisibleBySelectorWithTimeout(this.h5HeadingsSelector, {hasText: headingBg});
} else if (language === LanguagesEnum.EN) {
return this.isElementVisibleBySelectorWithTimeout(this.h5HeadingsSelector, {hasText: headingEn});
} else {
throw new Error("Language not found!");
}
}

/**
* Check if H6 heading is visible by text with timeout
* @param {LanguagesEnum} language
* @param {string} headingBg
* @param {string | null} headingEn
* @param {LanguagesEnum} language
*/
async isH6HeadingVisible(language: LanguagesEnum, headingBg: string, headingEn: string | null): Promise<boolean> {
return this.isHeadingVisibleBySelector(this.h6HeadingsSelector, language, headingBg, headingEn);
async isH6HeadingVisible(language: LanguagesEnum, headingBg: string | null, headingEn?: string): Promise<boolean> {
await this.waitForElementToBePresentedByLocator(this.page.locator(this.containerRootElement).first());
if (language === LanguagesEnum.BG) {
return this.isElementVisibleBySelectorWithTimeout(this.h6HeadingsSelector, {hasText: headingBg});
} else if (language === LanguagesEnum.EN) {
return this.isElementVisibleBySelectorWithTimeout(this.h6HeadingsSelector, {hasText: headingEn});
} else {
throw new Error("Language not found!");
}
}

/**
* Check if H6 homepage FAQ heading is visible with timeout
* @param {LanguagesEnum} language
Expand Down Expand Up @@ -166,9 +176,9 @@ export class HomePage extends BasePage {
* Click H5 heading by text
* @param {LanguagesEnum} language
* @param {string} headingBg
* @param {string | null} headingEn
* @param {string} headingEn
*/
async clickH5HeadingByText(language: LanguagesEnum = LanguagesEnum.BG, headingBg: string, headingEn: string | null): Promise<void> {
async clickH5HeadingByText(language: LanguagesEnum = LanguagesEnum.BG, headingBg: string, headingEn?: string): Promise<void> {
if (await this.isH5HeadingVisible(language, headingBg, headingEn)) {
if (language === LanguagesEnum.BG) {
await this.scrollToElementCenterBySelector(this.h5HeadingsSelector, {hasText: headingBg});
Expand Down Expand Up @@ -207,35 +217,35 @@ export class HomePage extends BasePage {
}

/**
* Check if "How we work" heading is visible with timeout
* Check if 'Kak raboti Podkrepi/How we work' heading is visible with timeout
* @param {LanguagesEnum} language - the default value is BG
*/
async isHowWeWorkHeadingVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH4HeadingVisible(language, this.bgHowDoesPodkrepiWork, this.enHowDoesPodkrepiWork);
return this.isH4HeadingVisible(this.bgHowDoesPodkrepiWork, this.enHowDoesPodkrepiWork, language);
}

/**
* Check if "Who is behind Podkrepi" heading is visible with timeout
* Check if 'Koi stoi zad Podkrepi/Who is behind Podkrepi' heading is visible with timeout
* @param {LanguagesEnum} language - the default value is BG
*/
async isTeamSectionHeadingVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH4HeadingVisible(language, this.bgTeamSection, this.enTeamSection);
return this.isH4HeadingVisible(this.bgTeamSection, this.enTeamSection, language);
}

/**
* Check if "Join Podkrepi" heading is visible with timeout
* Check if 'Prisyedinete se kym Podkrepi/Join Podkrepi' heading is visible with timeout
* @param {LanguagesEnum} language - the default value is BG
*/
async isJoinPodkrepiSectionHeadingVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH4HeadingVisible(language, this.bgJoinPodkrepiSection, this.enJoinPodkrepiSection);
return this.isH4HeadingVisible(this.bgJoinPodkrepiSection, this.enJoinPodkrepiSection, language);
}

/**
* Check if "FAQ" heading is visible with timeout
* Check if 'Chesto zadavani vyprosi/FAQ' heading is visible with timeout
* @param {LanguagesEnum} language - the default value is BG
*/
async isFaqSectionHeadingVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH4HeadingVisible(language, this.bgFaqSection, this.enFaqSection);
return this.isH4HeadingVisible(this.bgFaqSection, this.enFaqSection, language);
}

/**
Expand All @@ -247,7 +257,7 @@ export class HomePage extends BasePage {
}

/**
* Check if "What is Podkrepi" FAQ list item is visible with timeout
* Check if 'What is Podkrepi' FAQ list item is visible with timeout
*/
async isPodkrepiFaqListAnswerVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<void> {
const faqAnswerText = await this.getTextOfHomeH6FaqAnswer(language);
Expand Down
2 changes: 1 addition & 1 deletion e2e/pages/web-pages/support.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export class SupportPage extends HomePage {
* @param {string} language
*/
async isThankYouSupportH4HeadingVisible(language: LanguagesEnum = LanguagesEnum.BG): Promise<boolean> {
return this.isH4HeadingVisible(language, this.bgThankYouForSupportH4, this.enThankYouForSupportH4);
return this.isH4HeadingVisible(this.bgThankYouForSupportH4, this.enThankYouForSupportH4, language);
}

/**
Expand Down
Loading

0 comments on commit 3bb8a19

Please sign in to comment.