I’m learning Playwright Java and tried the following code to get the src attribute of the same image using both querySelector() and locator(). Both return the same result:
```java
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium()
.launch(new BrowserType.LaunchOptions().setHeadless(false).setSlowMo(50));
Page page = browser.newPage();
page.navigate("https://playwright.dev/");
String srcImage1 = page.querySelector("//*[@id=\"docusaurus_skipToContent_fallback\"]/main/center/img")
.getAttribute("src");
String srcImage2 = page.locator("//*[@id=\"docusaurus_skipToContent_fallback\"]/main/center/img")
.getAttribute("src");
System.out.println(srcImage1);
System.out.println(srcImage2);
browser.close();
}
What is the actual difference between `querySelector()` and `locator()`? Which one is better to use in Playwright Java?
The main difference is that querySelector() grabs a single element snapshot at the moment it’s called, whereas locator() creates a live reference to the element.
That means if the DOM changes after your page loads, querySelector() may break or return null, but locator() will keep working and retry automatically.
I usually stick to locator() in tests because it integrates nicely with Playwright’s auto-waiting and built-in assertions:
String src = page.locator("img#docusaurus_skipToContent_fallback").getAttribute("src");
It’s safer for dynamic pages or when elements appear after some network calls.
I found querySelector() is fine for simple DOM snapshots, but it doesn’t do any waiting. So if your element isn’t immediately available,
you need extra waits. locator(), on the other hand, has auto-wait built-in:
page.locator("img#logo").waitFor();
Plus, locator() allows you to chain filters, check count, and perform actions on multiple elements. I consider it the recommended approach for modern Playwright tests.
Think of querySelector() as a quick-and-dirty snapshot , good for one-off DOM inspection or static elements. locator() is your long-term test-friendly tool. It adapts if the element appears later, moves, or changes attributes.
In my experience, switching from querySelector() to locator() solved flaky tests caused by delayed renders or animations.
So for Playwright Java, I’d recommend using locator() almost exclusively for real tests.