🎭 Playwright Cheatsheet

Complete Guide from Basics to Advanced | Java Edition

⚙️ Setup & Installation Beginner

Maven Dependencies

<!-- Playwright Java --> <dependency> <groupId>com.microsoft.playwright</groupId> <artifactId>playwright</artifactId> <version>1.40.0</version> </dependency>

Install Browsers

# Install all browsers (Chromium, Firefox, WebKit)"install" # Install specific browser mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install chromium"

Basic Setup - Playwright Hierarchy

🎭 Playwright Hierarchy: Playwright → Browser → BrowserContext → Page

This hierarchy provides better isolation and efficiency compared to Selenium.
import com.microsoft.playwright.*; // 1. Create Playwright instance Playwright playwright = Playwright.create(); // 2. Launch browser Browser browser = playwright.chromium().launch(); // 3. Create browser context (isolated session)// 4. Create page Page page = context.newPage(); // Navigate page.navigate("https://example.com"); // Cleanup (reverse order) page.close(); context.close(); browser.close(); playwright.close();
💡 Playwright Advantage: BrowserContext provides isolation without launching new browsers, making tests faster and more efficient.

Browser Launch Options

// Chromium (default) Browser browser = playwright.chromium().launch(newfalse) .setSlowMo(100) // Slow down by 100ms ); // Firefox Browser browser = playwright.firefox().launch(); // WebKit (Safari engine) Browser browser = playwright.webkit().launch(); // Advanced options Browser browser = playwright.chromium().launch(newtrue) .setSlowMo(50) .setTimeout() .setDevtools(true) // Open DevTools .setArgs(Arrays.asList("--start-maximized"

Browser Context Options

BrowserContext context = browser.newContext(new// Viewport size .setViewportSize(1920, 1080) // User agent .setUserAgent("Custom User Agent") // Geolocation .setGeolocation(37.7749, -122.4194) .setPermissions(Arrays.asList("geolocation"// Timezone .setTimezoneId("America/New_York") // Locale .setLocale("en-US") // Color scheme .setColorScheme(ColorScheme.DARK) // Accept downloads .setAcceptDownloads(true) // Ignore HTTPS errors .setIgnoreHTTPSErrors(true) // Record video .setRecordVideoDir(Paths.get("videos/")) .setRecordVideoSize(1280, 720) // HTTP credentials .setHttpCredentials("username", "password") );

Mobile Emulation

import com.microsoft.playwright.options.devices; // Use predefined device BrowserContext context = browser.newContext( new Browser.NewContextOptions(devices.get("iPhone 12 Pro"// Available devices devices.get("iPhone SE") devices.get("iPhone 12") devices.get("iPhone 12 Pro") devices.get("iPhone 12 Pro Max") devices.get("Galaxy S9+") devices.get("Pixel 5") devices.get("iPad Pro 11")

📘 Basic Commands Beginner

Navigation

// Navigate to URL page.navigate("https://example.com"); // Navigate with options page.navigate("https://example.com", new Page.NavigateOptions() .setTimeout(30000) .setWaitUntil(WaitUntilState.NETWORKIDLE) ); // Go back page.goBack(); // Go forward page.goForward(); // Reload page.reload(); // Get current URL String url = page.url(); // Get page title String title = page.title(); // Get page content String html = page.content();

Wait Until States

State Description Use Case
LOAD Page load event fired Default, basic page load
DOMCONTENTLOADED DOM is ready Faster, DOM manipulation
NETWORKIDLE No network connections for 500ms SPA, AJAX heavy pages
COMMIT Navigation committed Rare, low-level control

Page Methods

// Wait for timeout page.waitForTimeout(3000); // 3 seconds (avoid if possible) // Wait for URL page.waitForURL("**/dashboard"); // Wait for load state page.waitForLoadState(LoadState.NETWORKIDLE); // Screenshot page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("screenshot.png"// Full page screenshot page.screenshot(new Page.ScreenshotOptions() .setPath(Paths.get("full.png")) .setFullPage(true) ); // PDF (Chromium only) page.pdf(new Page.PdfOptions().setPath(Paths.get("page.pdf"// Close page page.close();

🎯 Locators Beginner Better than Selenium

🎭 Playwright Locators vs Selenium: Playwright locators are lazy, auto-retry, and support chaining. They don't evaluate until an action is performed, making them more reliable.

Basic Locators (Recommended)

// By role (Recommended - Accessibility-first)new Page.GetByRoleOptions().setName("Submit")); // By text page.getByText("Sign Up"); page.getByText("Sign"); // Partial match // By label (form fields) page.getByLabel("Username"); page.getByLabel("Email Address"); // By placeholder page.getByPlaceholder("Enter email"); // By alt text (images) page.getByAltText("Company Logo"); // By title page.getByTitle("Close"); // By test ID (data-testid attribute) page.getByTestId("submit-button");

CSS and XPath Locators

// CSS selector page.locator("css=button.primary"); page.locator("button.primary"); // 'css=' is default // XPath page.locator("xpath=//button[@id='submit']"); page.locator("//button[@id='submit']"); // ID shorthand page.locator("#username"); // Class shorthand page.locator(".btn-primary");

Chaining Locators

// Filter by text page.locator("button").filter("Submit"// Filter by another locator page.locator("article").filter(".featured"// Find within locator (scoping) page.locator(".container").locator(// First/Last/Nth page.locator("li").first(); page.locator("li").last(); page.locator("li").nth(// Count int count = page.locator(// All text contents List<String> texts = page.locator("li"// All inner texts List<String> innerTexts = page.locator("li"

Locator Assertions

import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; // Visibility assertThat(page.locator("#message")).isVisible(); assertThat(page.locator(// Text content assertThat(page.locator("#message")).hasText("Success"); assertThat(page.locator("#message")).containsText("Succ"); // Count assertThat(page.locator("li")).hasCount(5); // Attributes assertThat(page.locator("input")).hasAttribute("type", "text"); assertThat(page.locator()).hasAttribute("href", "/home"); // Value assertThat(page.locator("input")).hasValue("test@example.com"); // CSS class assertThat(page.locator("button")).hasClass("active"); // Enabled/Disabled assertThat(page.locator("button")).isEnabled(); assertThat(page.locator(// Checked assertThat(page.locator("#agree")).isChecked();

Aria Roles (Accessibility Testing)

Role Element Example
BUTTON Buttons getByRole(AriaRole.BUTTON)
LINK Links getByRole(AriaRole.LINK)
TEXTBOX Input fields getByRole(AriaRole.TEXTBOX)
CHECKBOX Checkboxes getByRole(AriaRole.CHECKBOX)
RADIO Radio buttons getByRole(AriaRole.RADIO)
HEADING Headings getByRole(AriaRole.HEADING)
LISTITEM List items getByRole(AriaRole.LISTITEM)

🖱️ Element Interactions Intermediate

Basic Actions

// Click page.locator("button").click(); // Click with options page.locator("button").click(// Right click .setClickCount() // Double click .setDelay(// Delay between mousedown and mouseup .setForce(true) // Bypass actionability checks .setModifiers(Arrays.asList(KeyboardModifier.SHIFT)) ); // Double click page.locator("button").dblclick(); // Right click page.locator("button").click(// Fill input (auto-clears first) page.locator("#email").fill(// Type (character by character) page.locator("#search").type(); page.locator("#search").type(new Locator.TypeOptions().setDelay(100)); // Press key page.locator("#search").press(); page.locator("#search").press(); page.locator("#search").press(// Clear input page.locator("#email").clear(); // Check/Uncheck page.locator("#agree").check(); page.locator("#agree").uncheck(); page.locator("#agree").setChecked(// Focus page.locator("#email").focus(); // Hover page.locator(".menu").hover(); // Scroll into view page.locator("#footer").scrollIntoViewIfNeeded(); // Tap (touch devices) page.locator("button").tap();

Get Element Information

// Text content String text = page.locator("#message").textContent(); // Inner text (visible text only) String innerText = page.locator("#message"// Inner HTML String innerHTML = page.locator("#container"// Get attribute String href = page.locator("a").getAttribute("href"); String value = page.locator("input").getAttribute(// Input value String inputValue = page.locator("input").inputValue(); // Is visible boolean visible = page.locator(// Is hidden boolean hidden = page.locator(// Is enabled boolean enabled = page.locator(// Is disabled boolean disabled = page.locator(// Is checked boolean checked = page.locator(// Bounding box BoundingBox box = page.locator("#element").boundingBox(); double width = box.width; double height = box.height; double x = box.x; double y = box.y;

Dropdowns/Select

// Select by value page.locator("select").selectOption("value1"); // Select by label page.locator("select").selectOption(new SelectOption().setLabel("Option 1")); // Select by index page.locator("select").selectOption(new SelectOption().setIndex(2)); // Select multiple page.locator("select").selectOption(new String[]{"value1", "value2"});

File Upload

// Upload single file page.locator("input[type='file']").setInputFiles(Paths.get("file.pdf")); // Upload multiple files page.locator("input[type='file']").setInputFiles(new Path[]{ Paths.get("file1.pdf"), Paths.get(// Clear file input page.locator("input[type='file']").setInputFiles(new Path[0]);

Drag and Drop

// Drag and drop page.locator("#source").dragTo(page.locator("#target")); // Drag by coordinates page.locator("#draggable").dragTo(page.locator("#draggable"), new Locator.DragToOptions() .setTargetPosition(100, 200) );

Screenshots

// Element screenshot page.locator("#logo").screenshot("logo.png"// Full page screenshot page.screenshot(new Page.ScreenshotOptions() .setPath(Paths.get("fullpage.png")) .setFullPage(true) ); // Screenshot as bytes byte[] screenshot = page.screenshot();

⏰ Auto-Waiting Intermediate Major Advantage

🎭 Playwright's Auto-Waiting: Playwright automatically waits for elements to be actionable before performing actions. No explicit waits needed in most cases!

Actionability Checks (Automatic)

Before every action, Playwright performs these checks:
  • ✅ Element is attached to DOM
  • ✅ Element is visible
  • ✅ Element is stable (not animating)
  • ✅ Element receives events (not obscured)
  • ✅ Element is enabled
// No wait needed! Playwright waits automatically"button").click(); // Waits for button to be clickable // In Selenium, you'd need: // WebDriverWait wait = new WebDriverWait(driver, 10);// wait.until(ExpectedConditions.elementToBeClickable(button)); // button.click();

Explicit Waits (When Needed)

// Wait for selector page.waitForSelector("#message"); // Wait for selector with options page.waitForSelector("#message", new Page.WaitForSelectorOptions() .setState(WaitForSelectorState.VISIBLE) .setTimeout(// Wait for element to be hidden page.waitForSelector("#loading", new Page.WaitForSelectorOptions() .setState(WaitForSelectorState.HIDDEN) ); // Wait for element to be detached page.waitForSelector("#temp", new Page.WaitForSelectorOptions() .setState(WaitForSelectorState.DETACHED) ); // Wait for URL page.waitForURL("**/dashboard"); page.waitForURL(url -> url.contains(// Wait for load state page.waitForLoadState(LoadState.NETWORKIDLE); page.waitForLoadState(LoadState.DOMCONTENTLOADED); // Wait for function page.waitForFunction("() => document.querySelector('#message').innerText === 'Ready'"); // Wait for timeout (avoid if possible) page.waitForTimeout(1000); // 1 second // Wait for response page.waitForResponse("**/api/data", () -> { page.locator("button").click(); }); // Wait for request page.waitForRequest("**/api/submit", () -> { page.locator("button").click(); });

Polling/Retry

// Locators retry automatically (polling every 100ms by default) assertThat(page.locator("#status")).hasText("Complete"); // Custom timeout for assertion assertThat(page.locator("#message")) .hasText("Success", new LocatorAssertions.HasTextOptions() .setTimeout(10000) );

🚀 Advanced Features Advanced

Dialogs (Alerts/Confirms/Prompts)

// Handle dialog before it appears page.onDialog(dialog -> { System.out.println(dialog.message()); dialog.accept(); // or dialog.dismiss() }); // Handle prompt with input page.onDialog(dialog -> { dialog.accept("My Input"// Get dialog type page.onDialog(dialog -> { System.out.println(dialog.type()); // alert, confirm, prompt, beforeunload dialog.accept(); });

Frames/iFrames

// By name or ID FrameLocator frame = page.frameLocator("iframe[name='myframe']"); frame.locator("button").click(); // Nested frames page.frameLocator("#outer-frame") .frameLocator("#inner-frame") .locator("button") .click(); // Get all frames List<Frame> frames = page.frames(); // Get frame by URL Frame frame = page.frameByUrl("https://example.com/frame"

Multiple Pages/Windows

// Wait for new page Page newPage = context.waitForPage(() -> { page.locator(// Open new page Page newPage = context.newPage(); newPage.navigate(// Get all pages List<Page> pages = context.pages(); // Switch between pages pages.get(0).bringToFront(); // Close page newPage.close(); // Handle popup Page popup = page.waitForPopup(() -> { page.locator(

Network Interception

// Route API calls page.route("**/api/data", route -> { route.fulfill(new Route.FulfillOptions() .setStatus(200) .setBody() .setContentType("application/json") ); }); // Abort requests (e.g., block images) page.route("**/*.{png,jpg,jpeg}", route -> route.abort()); // Continue request with modifications page.route("**/api/**", route -> { route.continue_(new Route.ContinueOptions() .setHeaders(Map.of("Authorization", "Bearer token")) ); }); // Monitor requests page.onRequest(request -> { System.out.println(// Monitor responses page.onResponse(response -> { System.out.println(" - " + response.status()); }); // Wait for specific response Response response = page.waitForResponse("**/api/user", () -> { page.locator("button").click(); }); System.out.println(response.json());

Downloads

// Handle download Download download = page.waitForDownload(() -> { page.locator("a[download]").click(); }); // Get suggested filename String filename = download.suggestedFilename(); // Save download download.saveAs(Paths.get("downloads/" + filename)); // Get path to temporary file Path path = download.path();

Authentication & Storage State

// Save authentication state context.storageState(new BrowserContext.StorageStateOptions() .setPath(Paths.get(// Reuse authentication state BrowserContext context = browser.newContext(new// This loads cookies and local storage

Video Recording

// Enable video recording BrowserContext context = browser.newContext(new)) .setRecordVideoSize(1280, 720) ); // Video is saved when page/context closes

Tracing & Debugging

// Start tracing context.tracing().start(new Tracing.StartOptions() .setScreenshots(true) .setSnapshots(true) ); // Your test code here page.navigate("https://example.com"); // Stop tracing and save context.tracing().stop(new Tracing.StopOptions() .setPath(Paths.get("trace.zip"// View trace: npx playwright show-trace trace.zip

✨ Best Practices & Tips

Locator Strategy

✅ Recommended Locator Priority:
1. getByRole() - Accessibility-first, resilient
2. getByLabel() - For form fields
3. getByPlaceholder() - For inputs
4. getByText() - For text content
5. getByTestId() - For test-specific IDs
6. CSS/XPath - Last resort

Playwright vs Selenium Comparison

Feature Playwright Selenium
Auto-Waiting ✅ Built-in ❌ Manual explicit waits
Browser Support Chromium, Firefox, WebKit Chrome, Firefox, Safari, Edge
Speed ~50% faster Baseline
Network Interception ✅ Native support ❌ Requires browser DevTools
Mobile Emulation ✅ Built-in devices ✅ Chrome DevTools
Parallel Testing ✅ BrowserContext isolation ❌ Multiple browser instances
Maturity Newer (2020) Established (2004)
✅ DO:
  • Use accessibility locators (getByRole, getByLabel)
  • Leverage auto-waiting instead of explicit waits
  • Use BrowserContext for test isolation
  • Save and reuse authentication state
  • Use network interception for mocking APIs
  • Enable tracing for debugging
  • Use locator chaining for scoped selections
❌ DON'T:
  • Don't use waitForTimeout() unless absolutely necessary
  • Don't rely on CSS/XPath when semantic locators work
  • Don't create new browser instances for each test
  • Don't ignore actionability checks with force:true
  • Don't hardcode waits when auto-wait is available

Common Patterns

// Page Object Model with Playwright public class LoginPage { private final Page page; private final Locator usernameInput; private final Locator passwordInput; private final Locator loginButton; public LoginPage(Page page) { this.page = page; this.usernameInput = page.getByLabel("Username"); this.passwordInput = page.getByLabel("Password"); this.loginButton = page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Login")); } public void login(String username, String password) { usernameInput.fill(username); passwordInput.fill(password); loginButton.click(); } }

Performance Tips

🚀 Speed Up Your Tests:
  • Use BrowserContext instead of new browsers
  • Run tests in parallel with isolated contexts
  • Save authentication state to skip login
  • Use network interception to mock slow APIs
  • Set aggressive timeout values for fast failures
  • Use headless mode in CI/CD
  • Disable unnecessary resources (images, CSS)