Automation at scale often struggles with two pain points:
Slow test development (boilerplate code, selectors, retries).
Flaky tests due to fragile locators.
With Model Context Protocol (MCP), we can connect Playwright to an AI server that assists in writing, fixing, and maintaining automation tests. In this blog, we’ll set up MCP with Playwright to automate real-world scenarios on Amazon.com.
🔹 1. Prerequisites
Make sure you have the following installed:
Node.js (>=18)
Playwright
MCP server implementation (e.g., mcp-server
or custom server)
OpenAI/GitHub Copilot or another LLM provider
Install Playwright
npm init playwright@latest
Add TypeScript config if needed:
npm install -D typescript ts-node @types/node
🔹 2. Folder Structure
playwright-amazon/
┣ tests/
┃ ┣ amazon-search.spec.ts
┃ ┣ amazon-cart.spec.ts
┣ mcp/
┃ ┣ server.ts
┃ ┣ config.json
┣ playwright.config.ts
┗ package.json
🔹 3. MCP Server Setup
Your MCP server is the middleware between Playwright and the LLM. It provides structured prompts like “Suggest resilient Playwright locator for Add to Cart button”.
Example MCP Config (mcp/config.json)
{
"name": "playwright-mcp",
"description": "MCP server for Playwright automation",
"capabilities": {
"selectors": true,
"code-gen": true
},
"llmProvider": "openai",
"llmModel": "gpt-4o-mini"
}
Example MCP Server (mcp/server.ts)
import express from 'express';
import bodyParser from 'body-parser';
import { generateLocator } from './utils/locator-generator';
const app = express();
app.use(bodyParser.json());
app.post('/locator', async (req, res) => {
const { request, context } = req.body;
const locator = await generateLocator(request, context);
res.json({ locator });
});
app.listen(4000, () => console.log('MCP server running on port 4000'));
🔹 4. Playwright + MCP Integration
We’ll call MCP server from within our Playwright tests whenever we need AI-assisted selectors or snippets.
Utility to Call MCP (tests/utils/mcp-client.ts)
import axios from 'axios';
export async function getLocator(request: string, context: string): Promise<string> {
const response = await axios.post('http://localhost:4000/locator', { request, context });
return response.data.locator;
}
🔹 5. Example Test – Amazon Search
tests/amazon-search.spec.ts
import { test, expect } from '@playwright/test';
import { getLocator } from './utils/mcp-client';
test('Amazon Search for Laptop', async ({ page }) => {
await page.goto('https://www.amazon.com');
// Get locator dynamically from MCP
const searchBox = await getLocator("Search input field", "amazon-homepage");
await page.fill(searchBox, 'Laptop');
const searchButton = await getLocator("Search button", "amazon-homepage");
await page.click(searchButton);
// Validate results
const results = page.locator('span.a-size-medium');
await expect(results.first()).toBeVisible();
});
Here MCP generates resilient locators, so even if Amazon updates their DOM slightly, the AI can adapt.
🔹 6. Example Test – Add to Cart
tests/amazon-cart.spec.ts
import { test, expect } from '@playwright/test';
import { getLocator } from './utils/mcp-client';
test('Add product to Amazon Cart', async ({ page }) => {
await page.goto('https://www.amazon.com');
// Search product
const searchBox = await getLocator("Search input field", "amazon-homepage");
await page.fill(searchBox, 'iPhone 15');
const searchButton = await getLocator("Search button", "amazon-homepage");
await page.click(searchButton);
// Click first result
const firstResult = await getLocator("First product link", "amazon-search-results");
await page.click(firstResult);
// Add to cart
const addToCart = await getLocator("Add to Cart button", "amazon-product-page");
await page.click(addToCart);
// Validate cart
const cartCount = page.locator('#nav-cart-count');
await expect(cartCount).toHaveText('1');
});
🔹 7. Benefits
✅ Resilient selectors – MCP auto-generates robust locators.
✅ Reduced flaky tests – Fewer selector breakages on UI changes.
✅ Faster automation – Engineers describe tests; AI scaffolds code.
✅ Scalable – Can plug into CI/CD for continuous improvement.
🔹 Conclusion
Using MCP with Playwright transforms how we build automation. Instead of spending hours debugging fragile selectors, engineers can focus on test strategy, while MCP + AI handles the scaffolding.
Top comments (1)
Flaky tests in automation can be a real pain, usually caused by things like timing issues, elements changing, or just bad network stability. To fix this, I focus on stabilizing the environment, throwing in retry mechanisms, and making sure everything’s synced up right. Dynamic selectors and well-timed waits are key to cutting down on the flakiness. When it comes to managing selectors in Playwright, I stick to solid ones like data-testid or CSS selectors. And, I gotta say, AI tools like MCP are a game-changer-they help make selectors more resilient by adjusting to UI changes on the fly. This is a lifesaver when you're dealing with fluctuating elements or complex web pages. Plus, using AI in test development speeds things up, automatically generating selectors and suggesting test tweaks. This makes tests more reliable and takes a ton of manual effort off your plate.