Wednesday, May 25, 2022

Playwright For Angular Frontend Applications

Playwright Automation Testing for Angular Websites


In this blogpost, we will discuss automation testing with Playwright on Angular Frontend.  

We have taken JetBlue application which is built on Angular 12 and is obviously developed in TypeScript programming language.

I’ll put the post in two points:
  •  Test automation framework with Playwright
  •  Integrate automation tests with CI  

Test automation framework with Playwright: 


Overview: 
I have used Typescript for developing the automation test. First things first, The locators are the key factor which will make Angular websites different to that of React.js and Vue.js frontends. As we know that AngularJS is a JavaScript front-end web framework which is more popular for using the open source automation testing framework called Protractor. Unfortunately both are deprecated now.

Now, this is a challenge for test automation for frontends which were already built on AngularJS with Protractor. 

How do we deal with Test Automation for this challenge?

All the AngularJS frontends are getting migrated to Angular applications which are developed on TypeScript. 

Regarding the test automation tooling some organisations are using Cypress and some others use Selenium

This is where Playwright also comes into place supporting Angular Frontends. 

Playwright's official website supports migration of existing tests on AngularJS from protractor and also angular applications.

Please see the link here : https://playwright.dev/docs/protractor

Coming back to our point on locators,

The website JetBlue considered in this scenario used locators like data-qaid for example "[data-qaid='TrueBlue']" which is a best practice in test automation to follow. Usually, we have the same locators like "data-test" or "data-test-id" or "data-testid" for automation testing purposes. If you don’t have these then, please ask your developers to add them for you in the DOM.

Basically, the advantage with playwright is that you can grab the locators with "text", "css", "id", "data-test-id", "xpath". No matter which locator you use, Playwright will consider all of these locators into one locator like below which is a benefit in terms of code readability.

const element = this.page.locator(selector);

Your selector can be anyone from these - xpath, id, css, text, data-test-id.

I haven't find the locators "[ng-model='...']" and "[ng-repeat='...']" on this JetBlue website, but still you can use these kind of AngularJS locators with Playwright as well.

I've written some sample locators below from the website.

export const iframe = "//iframe[@title='TrustArc Cookie Consent Manager']";
export const cookies = "//a[contains(text(),'Accept All Cookies')]";
export const logo = "jb-logo[class='db'] img[alt='JetBlue']";
export const navBar = ".w-100.bg-core-blue.page-margin";
export const bookTab = "//span[@class='pr2-ns'][text()='Book']";
export const manageTripsTab = "(//a[contains(@href,'/manage-trips')])[3]";
export const checkInTab = "(//a[contains(@href,'/checkin.jetblue.com')])[1]";
export const travelInfoTab = "//span[@class='pr2-ns'][text()='Travel Info']";
export const trueBlueProfileIcon = "[data-qaid='TrueBlue']";
export const isItSummerYetTitle = "span[class='white ng-star-inserted']";
export const flightsTab = "#jb-tab-id-0";
export const flightsAndHotelTab = "#jb-tab-id-1";
export const flightsAndCruiseTab = "#jb-tab-id-2";
export const carsTab = "#jb-tab-id-3";
export const staysTab = "#jb-tab-id-4";
export const useTrueBluePointsCheckBox =
"(//span[contains(@class,'checkbox-custom ba b--royal-blue')])[1]";
export const trueBluePointsLabel = "span[class='charcoal']";
export const firstTabBox = "(//jb-tabs[@id='first-tab'])[1]";
export const searchBox = "#jb-autocomplete-0-search";
export const tripType = "[data-qaid='tripType']";
export const tripTypeOneWay = "//span[contains(text(),'One-way')]";
export const tripTypeOneWaySelected = "//div[contains(text(),'One-way')]";
export const fromTab = "#jb-autocomplete-3-search";
export const toTab = "#jb-autocomplete-4-search";
export const departDateTab = "(//input[contains(@id,'jb-date-picker-input-id-')])[1]";
export const departDate = "//button[contains(@aria-label,'June 30, 2022')]";
export const doneButton = "button[role='button'][type='button']";
export const continueToFlightResultsButton = "[data-qaid='continueToNextWarningMessage']";

Once, you have your locators, you are good to go with designing the test automation framework. 

The framework using page object design pattern will be the same for Frontends built using React.js, Vue.js and Angular.

The only thing that matters for us with Angular applications on playwright when compared to React.js and Vue.js frontends is the Locators

The page classes and tests remain the same across all the React.js, Vue.js and Angular applications.

Desigining of Pages: The pages are designed using page classes with extends keyword. This will be common for React.js, Vue.js and Angular applications.


import { BasePage } from "./basePage";
import { expect } from "@playwright/test";

export class SearchPage extends BasePage {
constructor(page: Page) {
super(page);
}

async clickElement(selector: string): Promise<SearchPage> {
return await this.clickSvgElement(selector);
}

async verifyIsVisible(selector: any): Promise<SearchPage> {
const isVisible = await this.isElementVisible(selector);
expect(isVisible).toBeTruthy();
return isVisible;
}

async verifyIsEnabled(selector: any): Promise<SearchPage> {
const isEnabled = await this.isElementEnabled(selector);
expect(isEnabled).toBe(true);
return isEnabled;
}
}


Playwright key takeaways:
  • Handling Iframe elements
  • Handling svg locators
  • Opening a New Tab
  • Keywords async/await in the code
  • Running tests in headless mode on chrome, firefox, safari and edge.

  • Handling Iframe elements: Here is the code snippet from Base Page.

async waitAndClickIframeElement(
iframeLocator: string,
selector: string
): Promise<BasePage> {
const iframeElement = await this.page.frameLocator(iframeLocator);
await this.isElementVisible(iframeLocator);
return await iframeElement.locator(selector).click();
}

  • Handling svg locators: Here is the code snippet from the Base Page.

async clickSvgElement(selector: string): Promise<BasePage> {
return await this.page.dispatchEvent(selector, "click");
}

  • Opening a New Tab: Please have a look at my GitHub Repo: Playwright-JavaScript and Code snippet below:
const context = await browser.newContext()
const page = await context.newPage()

await page.goto(baseUrl)
await page.fill(username, testData.standard_user)
await page.fill(password, testData.password)
await page.click(loginButton)

const link = page.locator(facebookLink)
const [newPage] = await Promise.all([
context.waitForEvent('page'),
await link.click()
])
await newPage.waitForLoadState('networkidle')
expect(await newPage.title()).toContain(facebookTitle)
expect(newPage.url()).toBe(facebookUrl)

For Test automation framework, please take a look at my GitHub Repo: Playwright-Angular


Integrate automation tests with CI: 


I have integrated the automation tests with Bitbucket CI. However, you can use any other CI tools like Jenkins, GitLab etc...

Basically, Create a file with name "bitbucket-pipelines.yml" yaml file in your VS code in the root folder.

image: node:10.15.0

pipelines:
default:
- step:
name: Playwright-Automation-Tests-Angular-App
image: mcr.microsoft.com/playwright:v1.22.0-focal
script:
- npm install
- npx playwright install
- npm run test:firefox





Then, On Bitbucket --->





Link to Bitbucket pipelines: pipelines

So, I was getting questions from my friends and colleagues that whether Playwright supports Frontend Test Automation on Angular applications???

The answer is a simple Yes ! 
We can:)!!!!!

Concluding on this post, Playwright supports all JavaScript Frameworks - React.js, Vue.Js and Angular !!!

Happy Automation Testing Guys :) !





No comments:

Post a Comment

Robot Framework - Frontend Test Automation Framework generated by AI

  Robot Framework with Browser Library Web Test Automation Framework Developed With The Help Of AI Search Agent. In this article, we will di...