microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
66.83k stars 3.67k forks source link

[Question] #4050

Closed splurgeop closed 4 years ago

splurgeop commented 4 years ago

I am trying to implement POM with playwright and stuck at very basic level of how to pass the object across the pages.

Here is my sample code

feature file login.feature

Given I Login to admin-site with 'username' and 'password' Then login is sucessfull And I click on 'book' flight link Then the flight booking page is displayed

Given I am on flight booking page And I book a flight for 2 perks And .....

Given ...... And .....

Now I have implemented the POM with the following classes login.ts export class login{ page;Page bcontext:BrowserContext; constructor(page,browsercontext){ this.page = page this.bcontext=browsercontext; } //login related funtions like fillusername/password and clicklogin button async enterusername(username:string,async () => { await this.page.fill(username); }) }

adminpage.ts export class admin{ constructor(page,browsercontext){

} //admin page related functionality }

step_definition.ts

adminpage ad = new adminpage("how to pass page and browsercontext") loginpage lp = new loginpage("how to pass page and browsercontext") Given(/I Login to admin site with {string} and {string}/,() =>{

})

now i want to pass the page and browsercontext to all the poms(adminpage.ts,loginpage.ts) one solution is create the page/browsercontext /browser in stepdefinition.ts and inside the steps call the class

example : step_definition.ts let page=chromium.launch(); let bcontext=page.newcontext(); let browser;= bcontext.newPage()

Given(/I Login to admin site with {string} and {string}/,() =>{

let admin = new admin(page,bcontext) })

is there any other solution to implement the same.

I am looking to have a base class and all other page extends the base page.But i dont know how this will happen in TS using base page.Any help is appreciated.

basepage.ts

export class basepage{ let page=chromium.launch(); let bcontext=page.newcontext(); let browser;= bcontext.newPage() constructor(page,bcontext){} this.page =page; ..... }

loginpage.ts export class loginpage extends basepage{ page context constructor(page:Page,bcotext:broswercontext){ super(page,bcotext); this.page=page; this.context = bcontext; } }

my idea is how to implement base page and all other class extend it .Any example would be appreciated

dgozman commented 4 years ago

Are you writing a test? If so, what test runner do you use? Code organization around POMs is usually influenced by the test runner or testing tool of choice.

See a basic POM example in our docs. Depending on the test runner, the test() code will be different, but POM classes could be reused as is.

For example, If you are just writing a standalone script, what you proposed seems to work:


class BasePage {
  constructor(page) {
    this.page = page;
    this.context = page.context();
  }
}

class LoginPage extends BasePage {
  async goto() {
    await this.page.goto('https://my-site.com/login');
  }
  async doLogin() {
    await this.page.fill('#username', 'User Name');
    ...
  }
}

class AdminPage extends BasePage {}

async function test() {
  const browser = await playwright.chromium.launch();
  const context = await browser.newContext();
  const loginPage = new LoginPage(await context.newPage());
  await loginPage.goto();
  await loginPage.doLogin();
  // Assuming that login page navigates to admin page after successful login.
  const adminPage = new AdminPage(loginPage.page);
}

Does this answer your question?

splurgeop commented 4 years ago

@dgozman That was indeed helpful. my test runner is jest but with jest i cant run BDD like case so have to use cucumber as my runner and the test are written in BDD i am looking to pass the context as well but along with page.I will take a look on how to pass and will come back if i face any issue.

Thanks Om