# 🧪 Understanding Browser, Context, and Page in Playwright

When working in playwright , it is very important to understand the in-built fixtures such as Browser , context, page

> Just imagine how you will access a particular website.
> 
> 1. You will open a browser . This does the below tasks in the background
>     
>     1. Opens up your profile (so cookies, logged in sessions can be reused)
>         
>         ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1760077527827/4a227c64-7c95-4fb3-ac87-18006ef9d896.png align="center")
>         
>     2. Creates a new tab automatically
>         
>         ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1760077621226/05b8db82-1655-4eee-81a0-af9939e128f6.png align="center")
>         
> 2. you will hit the url in the url textbox
>     
>     1. ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1760077706896/73988002-125b-43b9-83ee-0ff3b72be627.png align="center")
>         

---

just like above, we can do the things manually in the playwright code but why not preferred

```typescript
test.only("validate orange hrm portal", async ({}) => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();
})
```

1. Playwright creates browser and context behind the scenes because all tests need the page for sure, code redundancy is removed with this.
    
2. This will overwrite the project configuration from playwright.config.json file and will execute in that browser mentioned in the test only . here it will be chromium. you have to make code change to run it in firefox, webkit
    

```typescript
import { test, expect } from "@playwright/test";

test.only("validate orange hrm portal", async ({ page }) => {
  await page.goto(
    "https://opensource-demo.orangehrmlive.com/web/index.php/dashboard/index"
  );
});
```

> Playwright decides which browser to open based on the playwright.config.json file

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1760079218807/c1966fc8-e7e3-4f63-9c4e-d9f399a8c0b2.png align="center")

---

Now let’s explore the Browser, context, page with examples

1. # Browser
    

This below code creates a browser but if you run this, you won’t see anything on the screen. because playwright is super-fast

```typescript
import { test, chromium, firefox, webkit } from "@playwright/test";
test.only("validate orange hrm portal", async ({}) => {
 const browser = await chromium.launch({ headless: false });
 const fireFox = await firefox.launch({ headless: false });
 const Safari = await webkit.launch({ headless: false });
})
```

2. # Context
    

This creates profile so each tests run in a new profile hence so isolated. But again this code won’t show anything on the screen

```typescript
test.only("validate orange hrm portal", async ({}) => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
})
```

3. # Page
    

Now when you create a page which is equal to a tab then it will show something on the UI

```typescript
test.only("validate orange hrm portal", async ({}) => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  await context.newPage();
})
```

But that also will be closed very quickly.

Run this to see the 3 browsers open

```typescript
import { test, chromium, firefox, webkit } from "@playwright/test";

test.only("validate orange hrm portal", async ({}) => {
  const chrome = await chromium.launch({ headless: false });
  const fireFox = await firefox.launch({ headless: false });
  const Safari = await webkit.launch({ headless: false });

  const chromeCntext= await chrome.newContext();
  const fireCntext= await fireFox.newContext();
  const safariCntext= await Safari.newContext();

  await chromeCntext.newPage();
  await fireCntext.newPage();
  await safariCntext.newPage();

});
```

---

Now comes the fun part, let’s see it visually the execution.

## Scenario1: playing with multiple page (tab)

```typescript
import { test, chromium, expect } from "@playwright/test";

test.only("validate orange hrm portal", async ({}) => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage(); //creating first page
  
  await page.goto(
    "https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"
  );
  await page.getByPlaceholder("Username").fill("Admin");
  await page.getByPlaceholder("Password").fill("admin123");
  await page.getByRole("button", { name: "Login" }).click();
  await expect(
    page.getByText("Employee Distribution by Sub Unit")
  ).toBeVisible();
  
 const page2 = await context.newPage(); //creating second page using same context
 await page2.goto(
    "https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"
  );
 await expect(
    page2.getByText("Employee Distribution by Sub Unit")
  ).toBeVisible();

});
```

### Code explanation

1. Have hit the HRM site
    
2. Logged in the site in the first page
    
3. Created a second page (Tab)
    
4. hitting the logged in URL in second page
    
    1. It got logged in already rather than asking me to login.
        
    2. **Because the sessions are shared between tabs**
        

**Output:**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1760078573711/68f00bf5-fb83-4797-b812-61c4bb79bb09.png align="center")

you see there are 2 tabs, the home page is visible in both the screens rather than login screen

---

## Scenario2: playing with multiple context (profile) and page (tab)

```typescript
import { test, chromium, expect } from "@playwright/test";

test.only("validate orange hrm portal", async ({}) => {
  const browser = await chromium.launch({ headless: false });
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.goto(
    "https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"
  );
  await page.getByPlaceholder("Username").fill("Admin");
  await page.getByPlaceholder("Password").fill("admin123");
  await page.getByRole("button", { name: "Login" }).click();
  await expect(
    page.getByText("Employee Distribution by Sub Unit")
  ).toBeVisible();
 const context2 = await browser.newContext(); //creating 2nd context here
  const page2 = await context2.newPage(); //creating 2nd page using 2nd context
 await page2.goto(
    "https://opensource-demo.orangehrmlive.com/web/index.php/auth/login"
  );
 await expect(
    page2.getByText("Employee Distribution by Sub Unit")
  ).toBeVisible();
});
```

### Code explanation

1. Have hit the HRM site
    
2. Logged in the site in the first page
    
3. Created new context (context2) which is like new profile or incognito session
    
4. Created a second page (Tab) using the second context
    
5. hitting the logged in URL in second page
    
    1. It is asking me to login.
        
    2. **Because the sessions are** *not* **shared between tabs**
        

**Output:**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1760079060744/2fcf6389-f877-4b2e-b176-708cccc25868.png align="center")

you see there are 2 browser contexts opened, the home page is visible in the first page but the second page is on the login screen

---

## Youtube link with demo

%[https://youtu.be/Ty4CDIZwwlA?si=9B74odm0wkd6xng7] 

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">I hope you learnt something new in here. Please subscribe to my channel and newsletter to encourage me to write more and more</div>
</div>
