12. Mastering Async/Await for Automation Workflows

Why Playwright is 100% Asynchronous

Browsers run out-of-process from Node.js. When your script executes page.click("#submit"), Node sends a WebSocket message to the browser, the browser scrolls, clicks, and sends a response back. Therefore, every Playwright operation returns Promise<void> or Promise<T>.

---

The Golden Rule: Never Forget await

// ❌ WRONG: page.click returns a Promise. Without await, Node fires and moves to the next line immediately!
page.click("button#login");
page.fill("input#code", "1234"); // Fails because page hasn't navigated or button click didn't finish!

// ✅ CORRECT:
await page.click("button#login");
await page.fill("input#code", "1234");

---

Sequential vs Parallel Execution in Automation

// Sequential: Task B relies on Task A
async function loginWorkflow() {
  await fillUsername();
  await fillPassword();
  await clickSubmit();
}

// Parallel: Tasks are completely independent (e.g., preparing two API preconditions)
async function prepareTestData() {
const [userResponse, inventoryResponse] = await Promise.all([
fetch("https://api.test/user"),
fetch("https://api.test/inventory"),
]);
return { userResponse, inventoryResponse };
}

---

Async Retry Utility Pattern

Automation tests occasionally encounter transient network delays. A strongly typed async retry function:
export async function retryOperation<T>(
  action: () => Promise<T>,
  retries: number = 3,
  delayMs: number = 1000
): Promise<T> {
  let lastError: unknown;
  for (let attempt = 1; attempt <= retries; attempt++) {
    try {
      return await action();
    } catch (err) {
      lastError = err;
      if (attempt < retries) {
        await new Promise((resolve) => setTimeout(resolve, delayMs));
      }
    }
  }
  throw lastError;
}

Task

  • Implement an asynchronous test helper function waitForCondition:
  • 1. Repeatedly poll predicate() until it resolves to true.
  • 2. Throw an Error when timeoutMs expires.
💡Common doubts
Did you like the problem?
Lesson 12 of 36
TypeScript
Loading code editor…
Next