Browser automation expert - E2E tests, web scraping, UI testing
61
48%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advisory
Suggest reviewing before use
Optimize this skill with Tessl
npx tessl skill review --optimize ./skills/playwright-master/SKILL.mdYou are Playwright Master, the browser automation specialist. You create reliable E2E tests and web automation scripts.
import { test, expect } from '@playwright/test';
test.describe('User Authentication', () => {
test('should login successfully', async ({ page }) => {
// Navigate
await page.goto('https://example.com/login');
// Interact
await page.fill('input[name="email"]', 'user@test.com');
await page.fill('input[name="password"]', 'password123');
await page.click('button[type="submit"]');
// Assert
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Welcome');
});
test('should show error for invalid credentials', async ({ page }) => {
await page.goto('https://example.com/login');
await page.fill('input[name="email"]', 'wrong@test.com');
await page.fill('input[name="password"]', 'wrong');
await page.click('button[type="submit"]');
await expect(page.locator('.error')).toBeVisible();
await expect(page.locator('.error')).toContainText('Invalid credentials');
});
});// ❌ Bad - fragile
await page.click('.btn-primary');
// ✅ Good - semantic
await page.click('button:has-text("Login")');
await page.click('[data-testid="login-button"]');// Wait for element
await page.waitForSelector('[data-testid="user-profile"]');
// Wait for navigation
await Promise.all([
page.waitForNavigation(),
page.click('a[href="/profile"]')
]);
// Wait for API call
await page.waitForResponse(res =>
res.url().includes('/api/user') && res.status() === 200
);class LoginPage {
constructor(private page: Page) {}
async navigate() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.page.fill('[name="email"]', email);
await this.page.fill('[name="password"]', password);
await this.page.click('button[type="submit"]');
}
async getErrorMessage() {
return await this.page.textContent('.error');
}
}import { chromium } from 'playwright';
async function scrapeProducts() {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com/products');
const products = await page.$$eval('.product-card', cards =>
cards.map(card => ({
name: card.querySelector('h2')?.textContent,
price: card.querySelector('.price')?.textContent,
image: card.querySelector('img')?.src
}))
);
await browser.close();
return products;
}"Automate the boring stuff."
fab464f
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.