🔥 Playwright Pro Tip: How do you inject custom client-side logic or dynamic data directly into your browser context? Essential for testing complex states inaccessible via standard UI.
📌 Problem Statement
When direct UI or network mocking falls short, inject client-side logic to:
• Invoke internal JavaScript functions.
• Seed localStorage, sessionStorage, or global variables.
• Mock browser APIs (e.g., Date.now()) for predictable results.
• Trigger events hard to simulate via Playwright's high-level APIs.
💡 Solution & Code Walkthrough
Playwright bridges Node.js with client-side JS. page.exposeFunction() lets you expose a Node.js function to the browser's window object. Client-side code calls it; Playwright executes your Node.js logic, returning the result.
✅ page.exposeFunction() for Dynamic Data & Logic:
Ideal for dynamic test data or simulating backend calls from your Node.js script directly to the client-side.
import { test, expect } from '@playwright/test';
test('injects and calls exposed client-side function', async ({ page }) => {
// 1. Expose Node.js fn 'getClientConfig' to browser's window
await page.exposeFunction('getClientConfig', async () => {
return { env: 'test', flag: true, userId: 'testUser123' }; // Simulate dynamic config
});
// 2. Navigate (or use empty page)
await page.goto('data:text/html,<script>window.config = {};</script><h1>App</h1><p id="output"></p>');
// 3. Client-side JS calls exposed fn
await page.evaluate(async () => {
const config = await window.getClientConfig(); // Call exposed Node.js function
document.getElementById('output').textContent = `Config: ${JSON.stringify(config)}`;
window.clientSideConfig = config; // Store globally
});
// 4. Assert client-side state
const outputText = await page.textContent('#output');
expect(outputText).toContain('env":"test');
expect(outputText).toContain('flag":true');
const clientSideConfig = await page.evaluate(() => window.clientSideConfig);
expect(clientSideConfig).toEqual({ env: 'test', flag: true, userId: 'testUser123' });
});
🔑 Key Takeaways
• exposeFunction() bridges Node.js and browser JS for two-way communication.
• Great for dynamic data, mocking API responses, or simulating backend.
• addInitScript() injects scripts before page loads (e.g., for global mocks, localStorage).
❌ Use sparingly; prioritize standard Playwright APIs first.
❓ Quick Summary Q&A
Q: Why inject client-side logic?
A: Test internal functions, seed states, or mock browser APIs.
Q: What does exposeFunction() do?
A: Exposes a Node.js function to the browser's window object for two-way comms.
TAGS: playwright, javascript, e2e testing, automation, web development, client-side, dynamic data
────────────────────────────────────────
🚀 Supercharge your skills! Download our app today for more expert tips & tricks.
────────────────────────────────────────
📲 𝐅𝐑𝐄𝐄 𝐌𝐎𝐁𝐈𝐋𝐄 𝐀𝐏𝐏 — 𝟔𝟎𝟎+ 𝐒𝐃𝐄𝐓 𝐐&𝐀𝐬
Practice real-world interview scenarios offline on the free QA Automation & SDET Prep app:
🤖 𝐆𝐨𝐨𝐠𝐥𝐞 𝐏𝐥𝐚𝐲 (𝐀𝐧𝐝𝐫𝐨𝐢𝐝):
https://play.google.com/store/apps/details?id=com.app.seleniuminterviewquestions&referrer=utm_source%3Ddevto%26utm_medium%3Darticle%26utm_campaign%3Dselenium_20261027
🍎 𝐀𝐩𝐩 𝐒𝐭𝐨𝐫𝐞 (𝐢𝐎𝐒):
https://apps.apple.com/app/id6786760948?pt=128640464&ct=devto_selenium_20261027&mt=8
────────────────────────────────────────
────────────────────────────────────────
Top comments (0)