Functions are the building blocks of clean, reusable code. In test automation, you’ll use them everywhere — from page actions to custom assertions to utility helpers. This guide covers every function pattern in TypeScript with real Playwright examples.
📖 What You’ll Learn: Function declarations, arrow functions, optional & default parameters, rest parameters, return types, overloads, generics in functions, and async functions in Playwright.
🔧 Function Declarations & Expressions
// Function declaration
function greet(name: string): string {
return `Hello, ${name}!`;
}
// Function expression
const add = function(a: number, b: number): number {
return a + b;
};
// Arrow function (most common in modern TypeScript)
const multiply = (a: number, b: number): number => a * b;
// Void function — returns nothing
function logMessage(msg: string): void {
console.log(`[LOG]: ${msg}`);
}
console.log(greet('QA Engineer')); // Hello, QA Engineer!
console.log(add(5, 3)); // 8
console.log(multiply(4, 7)); // 28
⚙️ Optional, Default & Rest Parameters
// Optional parameter (use ?)
function createUser(name: string, email?: string): string {
return email ? `${name} (${email})` : name;
}
console.log(createUser('Deepesh')); // Deepesh
console.log(createUser('Deepesh', 'test@test.com')); // Deepesh (test@test.com)
// Default parameter
function wait(ms: number = 1000): void {
console.log(`Waiting ${ms}ms...`);
}
wait(); // Waiting 1000ms...
wait(3000); // Waiting 3000ms...
// Rest parameters (variable number of args)
function logAll(...messages: string[]): void {
messages.forEach((msg, i) => console.log(`${i + 1}. ${msg}`));
}
logAll('Step 1', 'Step 2', 'Step 3');
// Destructured parameters
function printConfig({ url, timeout = 30000 }: { url: string; timeout?: number }): void {
console.log(`URL: ${url}, Timeout: ${timeout}`);
}
printConfig({ url: 'https://sqatools.in' });
📝 Function Types & Callbacks
// Type alias for a function
type Validator = (value: string) => boolean;
const isEmail: Validator = (value) => value.includes('@');
const isNotEmpty: Validator = (value) => value.trim().length > 0;
console.log(isEmail('test@test.com')); // true
console.log(isNotEmpty('')); // false
// Callback functions
function runValidation(input: string, validator: Validator, onResult: (passed: boolean) => void): void {
const result = validator(input);
onResult(result);
}
runValidation('hello@test.com', isEmail, (passed) => {
console.log(passed ? '✅ Valid' : '❌ Invalid');
});
// Returning functions (higher-order)
function createMultiplier(factor: number): (n: number) => number {
return (n) => n * factor;
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
🧬 Generic Functions
// Generic function — works with any type
function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
console.log(firstElement([1, 2, 3])); // 1 (type: number)
console.log(firstElement(['a', 'b', 'c'])); // 'a' (type: string)
// Generic with constraint
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'Deepesh', role: 'SDET' };
console.log(getProperty(user, 'name')); // 'Deepesh'
// Generic async function
async function fetchData<T>(url: string): Promise<T> {
const response = await fetch(url);
return response.json() as Promise<T>;
}
💡 Generics let you write ONE function that works with strings, numbers, objects — anything. TypeScript figures out the type automatically when you call it.
⚡ Async Functions
// Async function returns a Promise
async function fetchTitle(url: string): Promise<string> {
const response = await fetch(url);
const html = await response.text();
const match = html.match(/<title>(.*)<\/title>/);
return match ? match[1] : 'No title found';
}
// Async arrow function
const delay = async (ms: number): Promise<void> => {
return new Promise(resolve => setTimeout(resolve, ms));
};
// Try-catch in async functions
async function safeRequest(url: string): Promise<string | null> {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.text();
} catch (error) {
console.error('Request failed:', error);
return null;
}
}
🎭 Functions in Playwright — Real Examples
import { test, expect, Page } from '@playwright/test';
// Reusable login helper function
async function login(page: Page, email: string, password: string): Promise<void> {
await page.goto('/login');
await page.fill('#email', email);
await page.fill('#password', password);
await page.click('#login-btn');
await expect(page.locator('.dashboard')).toBeVisible();
}
// Retry function for flaky operations
async function retry<T>(fn: () => Promise<T>, maxAttempts: number = 3): Promise<T> {
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
try {
return await fn();
} catch (error) {
if (attempt === maxAttempts) throw error;
console.log(`Attempt ${attempt} failed, retrying...`);
await new Promise(r => setTimeout(r, 1000));
}
}
throw new Error('Should not reach here');
}
// Using helper functions in tests
test('login and verify dashboard', async ({ page }) => {
await login(page, 'admin@sqatools.in', 'test123');
await expect(page).toHaveTitle(/Dashboard/);
});
test('retry flaky element click', async ({ page }) => {
await page.goto('https://sqatools.in');
await retry(async () => {
await page.click('.dynamic-button');
await expect(page.locator('.result')).toBeVisible();
});
});
❓ FAQ
🤔 When should I use arrow functions vs regular functions?
Use arrow functions for callbacks, short expressions, and class methods. Use regular functions when you need hoisting or a named function in stack traces. In Playwright, arrow functions are standard for test callbacks and helpers.
🤔 What is the difference between optional and default parameters?
Optional parameters (name?: string) can be omitted and will be undefined. Default parameters (name: string = 'Guest') have a fallback value when omitted. Default parameters are preferred when you have a sensible default.
🎯 Next Steps
- 📘 TypeScript Operators
- 📘 TypeScript Conditions
- 📘 TypeScript Loops
- 📘 TypeScript Arrays — Coming next!
- 🎬 SqaToolsByDY on YouTube
🎬 Watch the full TypeScript tutorial series on YouTube!
Subscribe to SqaToolsByDY • Practice on sqatools.in