Back to All Questions
Question 56 of 100
Locators
Advanced
What is the difference between locator() and querySelector()?
The Answer
`locator()` is Playwright's lazy, auto-waiting, strict selector. `querySelector()` (via `page.$`) is an immediate DOM query that returns an `ElementHandle` β it does NOT auto-wait and is considered a legacy API.
Deep Dive Explanation
The Playwright team strongly recommends never using `ElementHandle` (the object returned by `page.$`). It's a snapshot of the DOM at a point in time and becomes stale. Locators always re-query the DOM on each action, making them inherently fresh.
example.spec.ts
// locator() - RECOMMENDED (lazy, retries, strict)
const btn = page.locator('button#submit');
await btn.click(); // Waits for button to be actionable
// page.$() - LEGACY (immediate, returns null if not found)
const el = await page.$('button#submit'); // Returns null if not ready yet
if (el) {
await el.click(); // NO auto-waiting
}
// page.evaluate with querySelector - for reading values only
const value = await page.evaluate(() => {
return document.querySelector('#output')?.textContent;
});