# “Advanced Assertions in Playwright: poll() vs toPass() Explained”

I am sure you might have come across the scenario where there is a synchronous step present, and you want to assert for some condition but unfortunately the condition will become true after a while but not instantly.

> Here is the scenario:
> 
> A report is expected to come from some source, and it takes time to receive.
> 
> Since this step which is verifying the report file’s presence is a synchronous one and it is not going to retry and fail in first attempt itself

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

test('file presence check', () => {
  const exists = existsSync('downloads/report.pdf'); 
  // as per scenario , file is going to arrive late at this destination
  expect(exists).toBeTruthy();
});
```

## Bad solution:

waiting for 1 minutes by default.

```typescript
import {test,expect,page} from "@playwright/test";
import { existsSync } from 'fs';

test('file presence check',async ({page}) => {
  // as per scenario , file is going to arrive late at this destination
  await page.waitForTimeout(1*60*1000);
 const exists = existsSync('downloads/report.pdf'); 
  expect(exists).toBeTruthy();
});
```

1. If file arrives early, still test will wait for 1 minutes.
    
2. Using complex for loops or while loops
    
    unnecessary code complexity
    

---

## ToPass() assertion

This assertion is going to retry executing a block of code until all the assertions inside the block is passed.

```typescript
import {test,expect,page} from "@playwright/test";
import { existsSync } from 'fs';

test('file presence check', async () => {
  await expect(() => {
    const exists = existsSync('downloads/report.pdf');
    expect(exists).toBeTruthy();
//here i have only one assertion
  }).toPass();
});
```

Why it is better:

1. Assertion is going to pass and move to next steps for execution so timing is saved
    
2. No complex looping code is required.
    

---

## Poll() assertion

It is similar to the Pass() but here it works on single assertion. it returns a value, and assertion is done on it.

**Scenario:**

let’s assume you have a field and it is value is changing and you want to check if it is greater than 5

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

test('Number validateion', async () => {
  const count = await page.locator('.notification-badge').textContent();
  const countInNumber = parseInt(count || '0');
  expect(countInNumber).toBeGreaterThan(5);
});
```

> Here also it is not wise to use the waitforTimeout for any other loops for the same reason we discussed before

## The better solution would be

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

test('Number validateion', async () => {
  await expect.poll(async () => {
      const count = await page.locator('.notification-badge').textContent();
      return parseInt(count || '0');
  }).toBeGreaterThan(5);
});
```

---

## Understanding the difference

This 2 may seem almost close with no difference but based on my experience this is what i have understood as the differences between this 2.

| **<mark>Poll()</mark>** | **<mark>ToPass()</mark>** |
| --- | --- |
| 1\. it returns single value | it doesn’t return value. |
| 2.The assertion is done on the returned value | Multiple assertions can be placed inside this block |
| 3.Cleaner for value tracking | Suitable for multiple assertions |

---

%[https://youtu.be/EkhSMoT01_8] 

Thanks for reading my blog and hope you have learnt something new here.

please subscribe to my newsletter for more.
