Playwright - yelenagotraining/E2EFrameworks GitHub Wiki

Fixing issue above

Automation Test Strategy

Playwright

E2E automation framework that contains improvements that other frameworks are trying to achieve.

Test Automation Tools and Principals.. in general

  • Support Modern Web Browsers and Platforms
  • Chrome
  • Edgechrome
  • Safari
  • Firefox
  • etc.
  • Support for Modern Languages and Bindings
  • Support for Modern Application Tech Stacks
  • Support of extensibility by 3rd parties
  • CI/CD support out of the box, Docker or any modern platform integration
  • Open source or open source to a certain degree

Playwright

Node library which provides a high-level API to control Chrome, Firefox, and Webkit with a single API.

Playwright now supports following language bindings: JS & TS Python C# Go Java

What does playwright have? Auto wait that can span scenarios and pages. Intercept which can be used to get performance details.

Selenium vs Playwright

System Requirements

  • NodeJS

Playwright installation

  • Playwright is easy to install: npm i -D playwright

To start a new project

  • Create a new directory
  • Open it in visual studio code
  • create a new file called package.json
  • Add following code:
{
    "devDependencies": {
        "playwright": "1.7.0"
    }
}
  • run following command to install package: npm install
  • npm install will download all the necessary packages including drivers needed to interact with the browser
Downloading chromium v833159 - 90.1 Mb [====================] 100% 0.0s
chromium v833159 downloaded to C:\Users\YelenaGouralnik\AppData\Local\ms-playwright\chromium-833159
Downloading firefox v1221 - 75.4 Mb [=================   ] 84% 3.6s
  • Add a file called SimpleTest.js First line of code is: const {chromium} = require('playwright'); If you control click on 'playwright' you'll see all the imports

Then we are writing an async block:

(async() => {

  //inside this block
  const browser = await chromium.launch({
    headless:false
  });
  const page = await browser.newPage();
  await page.goto("https://executeautomation.com");
  await page.screenshot({path: `ea.png`})
  await browser.close();
})();
  • As you can see there are a lot of awaits in here. Every action is starts with an Await statement which means, by default, we will wait until something happens.
  • Also, you can see the headless is set to false. Which means once we run this test, a browser will open
    • Setting this to true, will leave the browser closed
  • To run the test type: node simpletest.js

Working with Playwright CLI

  • Many automation tools have record and playback, playwright has sort of an R and P tool, which is called Playwright CLI.
  • Details can be found on https://playwright.dev/docs/cli/
  • on the command line type npx playwright codegen wikipedia.org
    • This will open a recorder which will record all your actions
    • Copy and paste it into a file

Using record and playback tool will teach you how to use selectors and how to interact with playwrightjs.

Playwright JS debugging

  • set environment variable PWDEBUG=1
  • in your code call page.Pause(): await page.pause();
  • run your test with node searchforzhitomir.js
  • playwright inspector will open
  • you can click step over to debug the test.

Playwright History

Playwright start out as a tool called puppeteer. visit puppeteer page Puppeteer was supported by google, now it's supported by microsoft. All the puppeteer code is now in playwright.

Playwright Browser Interface

Browser

  • in selenium we identify web driver object and then invoke browser from that web driver.
  • Here in playwright it's a little different, here we invoke browser. Within browser we invoke page.
  • Create browser.js file
  • Copy and paste following code into browser.js:
const {firefox} = require('playwright');

(async() => {

  //inside this block

  const browser = await firefox.launch({
    headless:false,
    slowMo:1000,
    devtools: true
  });
  const context = await browser.newContext();
  const page = await context.newPage();
  //const page = await browser.newPage();

  await page.goto("https://executeautomation.com");
  await page.screenshot({path: `ea.png`})
  await browser.close();
})();

We can change browser option by adding parameters into the launch section.

Browser Context

  • Browser Context - context within existing open browser. Context of a browser is an incognito version of browser.
  • multiple browser contexts can be opened.
const {firefox} = require('playwright');

(async() => {

  //inside this block

  const browser = await firefox.launch({
    headless:false,
  //  slowMo:1000,
  //  devtools: true
  });
  const context = await browser.newContext();
  
  const context1 = await browser.newContext();
  const pageOne = await context1.newPage();
  await pageOne.goto("https://executeautomation.com");
  //await pageOne.screenshot({path: `ea.pngOne`});

  const page = await context.newPage();
  //const page = await browser.newPage();

  await page.goto("https://executeautomation.com");
  await page.screenshot({path: `ea.png`});
  
  await context.close();
  await context1.close();

  await browser.close();
})();

Recording integratedtm carrier login.

npx playwright codegen https://uat.integratedtm.dev/login

  • Modifying script to run as cellphone immulator
const { chromium, devices } = require('playwright');
const iPhone = devices['iPhone 11 Pro Max'];
(async () => {
  const browser = await chromium.launch({
    headless: false
  });
  const context = await browser.newContext({
      ...iPhone,
      permissions:['geolocation'],
      geolocation: {"longitude": 48.858455, "latitude": 2.294474},
    }

  );
  // Open new page
  const page = await context.newPage(

  );
  // Go to https://uat.integratedtm.dev/login
  await page.goto('https://uat.integratedtm.dev/login');
  // Click input[name="undefined"]
  await page.click('input[name="undefined"]');
  // Click input[name="undefined"]
  await page.click('input[name="undefined"]');
  // Fill input[name="undefined"]
  await page.fill('input[name="undefined"]', '[email protected]');
  // Press Tab
  await page.press('input[name="undefined"]', 'Tab');
  // Click input[type="password"]
  await page.click('input[type="password"]');
  // Fill input[type="password"]
  await page.fill('input[type="password"]', 'xxxxxxx');
  // Click button:has-text("Sign in")
  await Promise.all([
    page.waitForNavigation(/*{ url: 'https://uat.integratedtm.dev/carriers/admin-home' }*/),
    page.click('button:has-text("Sign in")')
  ]);
  // Click text=Shipping4 >> :nth-match(span, 2)
  await page.click('text=Shipping4 >> :nth-match(span, 2)');
  // ---------------------
  await context.close();
  await browser.close();
})();

create a new file Page and Frames

Selectors

Selectors are the heart and soul of UI automation testing tools, the easier it is to identify a control, the better it will be for test automation engineers to work with.

If playwright is extended by any other tools, such as codeceptJS, it will be easier to use playwright mechanism to identify controls. Playwright uses CSS Selectors by default. https://github.com/yelenagotraining/E2EFrameworks/blob/main/SelectorCSSEngine.PNG Xpath https://github.com/yelenagotraining/E2EFrameworks/blob/main/SelectorsXpathEngine.PNG

Text https://github.com/yelenagotraining/E2EFrameworks/blob/main/SelectorsTextEngine.PNG Id Name If a selector starts with either // or .. then the engine consider them as Xpaths. Shadow DOMs are supported by default in playwright using css:light engine

Record playback of sample page

npx playwright codegen http://eaapp.somee.com/

  • Record login
  • Look at the selectors.

Working with different operation on controls

While selectors are used to identify the UI elements from DOM, and the operation are the next thing we need to perform on the UI elements.

The most common operation we do in any UI elements are:

  • Type (Fill in playwright)
  • Click
  • Hover
  • Check/Option

Playwright element selector reference: https://playwright.dev/docs/selectors/?_highlight=selec#quick-guide Control Playground to experiment with operations

https://demowf.aspnetawesome.com/

Playwright Autowait

Playwright has automatic waiting in place, which checks most of the boxes for you to explicitly wat for an event to happen. Playwright calls this Actionability checks. Playwright does a range of actionability checks on the elements before performing certain actions.

  • If an element takes extra long to load we can: await page.waitForSelector('text="EmployeeList"')
  • Timeout on page level:
 const browser = await chromium.launch({
    headless: false,
    timeout: 40000
  });

await page.waitForFunction()

Playwright Test Runner

  • Installation: npm i -D @playwright/test
  • Create a folder called testrunner
  • Create a file testrunner.spec.ts
import {it, describe, expect} from "@playwright/test"

it("first test for simple demo", ()=> {
    console.log("hello test");
})
  • to run all the tests: change to a directory where test are, run npx folio, in the command line you'll se a message: 'Running 1 test using 1 worker'
  • Add another it block:

If you just type npx folio, it will run the test against all four browsers

  • Add another it block:
it("Validate user can login as customer admin", async ({context}) => {
    var page = await context.newPage();
    await page.goto("http://www.neowin.net");

})
  • Run npx folio again:
    • You will see 'Running 4 tests using 4 workers' because by default test runs against all browsers
  • if you run `npx folio testrunner\testrunnerdemo.spec.ts --param browserName=firefox
    • You will only see two workers because you sepcified a browser.

So what is folio?

A customizable test framework to build your own test frameworks. Foundation for the playwright test runner. Folio is based on the concept of the test fixtures. Test fixtures are used to establish environment for each test, giving the test just enough, and no more than that.

Inline fixture

import {folio} from '@playwright/test'

const fixtures = folio.extend();

fixtures.browserOptions.override(async({}, run) => {
    await run({
        headless: false
    });
});
const {it} = fixtures.build();

it("run the bsic test", async ({context}) => {
    var page = await context.newPage();
    await page.goto("https://neowin.net")

})
  • To run: cd to where test is
  • npx folio .\inlinefixture.spec.ts

Tracing - generates performance tracing

await browser.startTracing(page, {path:trace.json, screenshots:true}); Before browser closes await browser.stopTracing();

Running a test command line with browser and headless as parameter

`npx folio LoginTest.spec.ts --param browserName=Chrome headful

Video Capture

  • In playwright, video capture comes in two formats on context level or on page level.
  • Context Level
 const context = await browser.newContext({
      ...iPhone,
      permissions:['geolocation'],
      geolocation: {"longitude": 48.858455, "latitude": 2.294474},
      recordVideo: {dir: "./recordings",

},
     
    
    }

  );

Install test json server

`npm install -g json-server