Playwright Java in the Real World: Locators, Forms, Frames, Popups, POM and API Testing
Playwright Java — Zero to Hero | Part 2 of 3
Part 1 gave us the mental model:
Browser → BrowserContext → Page → Locator
Now we use it against real application problems.
1. Locator composition: identify the business object first
Suppose an enterprise table contains:
INC0001001 [Open] [Edit]
INC0001002 [Open] [Edit]
INC0001003 [Open] [Edit]
Do not immediately reach for:
page.getByRole(AriaRole.BUTTON).nth(5).click();Instead, locate the row using business identity:
Locator incident =
page.getByRole(AriaRole.ROW)
.filter(
new Locator.FilterOptions()
.setHasText("INC0001001")
);
incident.getByRole(
AriaRole.BUTTON,
new Locator.GetByRoleOptions()
.setName("Edit")
).click();The locator strategy is:
PAGE
↓
ROW
↓
FILTER BY BUSINESS DATA
↓
TARGET ACTION
This pattern is especially useful for ITSM, CRM, insurance and other enterprise applications with repeated components.
2. Forms
page.getByLabel("Username")
.fill("admin");
page.getByLabel("Password")
.fill("secret");
page.getByLabel("Remember me")
.check();
page.getByLabel("Country")
.selectOption("IN");Then:
page.getByRole(
AriaRole.BUTTON,
new Page.GetByRoleOptions()
.setName("Login")
).click();The test remains close to the user’s interaction with the application.
3. Frames
An iframe contains a separate document.
Use FrameLocator:
page.frameLocator("#payment-frame")
.getByLabel("Card number")
.fill("4111111111111111");Then:
page.frameLocator("#payment-frame")
.getByRole(
AriaRole.BUTTON,
new Page.GetByRoleOptions()
.setName("Pay")
)
.click();Think:
PAGE
↓
FRAME
↓
LOCATOR
4. Multiple pages and popups
When an action opens another page, synchronize with the event:
Page report = context.waitForPage(() -> {
page.getByText("Open report").click();
});
report.waitForLoadState();The key rule is:
WAIT FOR EVENT + TRIGGER ACTION
This prevents races.
5. Downloads
Download download =
page.waitForDownload(() -> {
page.getByText("Download report")
.click();
});Save it:
download.saveAs(
Paths.get(
"artifacts",
download.suggestedFilename()
)
);The Java API exposes suggestedFilename() for the
server-suggested name.
6. Page Object Model
The test should express business intent.
The Page Object should own UI mechanics.
public class LoginPage {
private final Page page;
private final Locator username;
private final Locator password;
private final Locator loginButton;
public LoginPage(Page page) {
this.page = page;
username =
page.getByLabel("Username");
password =
page.getByLabel("Password");
loginButton =
page.getByRole(
AriaRole.BUTTON,
new Page.GetByRoleOptions()
.setName("Login")
);
}
public void login(
String user,
String pass) {
username.fill(user);
password.fill(pass);
loginButton.click();
}
}Now the test becomes:
LoginPage loginPage =
new LoginPage(page);
loginPage.login(
"admin",
"secret"
);
assertThat(
page.getByText("Dashboard")
).isVisible();The Page Object is effectively an application API.
7. POM does not mean “selector dump”
Avoid making tests do this:
loginPage.username().fill(...);
loginPage.password().fill(...);
loginPage.loginButton().click();Prefer:
loginPage.login(user, password);For larger applications, introduce reusable components:
IncidentPage
├── HeaderComponent
├── NavigationComponent
├── IncidentForm
├── AttachmentComponent
└── ActivityComponent
This reduces duplication across pages.
8. API + UI
Playwright Java also exposes API testing through:
APIRequestContext
APIResponseFor example:
APIRequestContext api =
playwright.request().newContext();
APIResponse response =
api.post(
"https://example.com/api/login"
);
System.out.println(
response.status()
);API calls are useful for:
- creating test data
- cleanup
- authentication
- backend validation
- establishing application state
Then validate the actual user journey through the UI.
9. The hybrid model
TEST
│
┌───────┴───────┐
▼ ▼
API UI
│ │
SETUP VALIDATE
│ │
└───────┬───────┘
▼
ASSERT
Do not use APIs to hide the very UI feature you are supposed to test.
If login is the feature under test, test login through the UI.
10. Authentication state
A context can be initialized with stored authentication state:
BrowserContext context =
browser.newContext(
new Browser.NewContextOptions()
.setStorageState(
Paths.get("auth.json")
)
);This allows suitable tests to start authenticated without repeating the UI login flow.
11. Trace Viewer
When a test fails in CI, you want evidence.
Start tracing:
context.tracing().start(
new Tracing.StartOptions()
.setScreenshots(true)
.setSnapshots(true)
.setSources(true)
);Stop tracing:
context.tracing().stop(
new Tracing.StopOptions()
.setPath(
Paths.get("trace.zip")
)
);Think:
FAILURE
↓
TRACE
↓
ACTION TIMELINE
↓
SNAPSHOT
↓
SCREENSHOT
↓
SOURCE
↓
ROOT CAUSE
For CI, this is much more useful than only attaching the final screenshot.
12. A real-world enterprise test
LoginPage login =
new LoginPage(page);
IncidentPage incidents =
new IncidentPage(page);
login.login(
"admin",
"secret"
);
incidents.openIncident(
"INC0001001"
);
incidents.updatePriority(
"Critical"
);
incidents.save();
assertThat(
incidents.status()
).hasText("Updated");This reads like a business scenario instead of a collection of browser mechanics.
13. Part 2 interview questions
How do you handle dynamic tables?
Identify the row by meaningful business data, then locate the action inside the row.
How do you handle iframes?
Use FrameLocator and continue with Playwright locators
inside the frame.
How do you handle popups?
Wait for the page event while executing the action that triggers it.
How do you speed up a suite?
Use API-assisted setup, authentication state, efficient isolation and controlled parallel execution.
Why Page Objects?
To encapsulate UI mechanics behind reusable application-level actions.
How do you debug CI failures?
Use traces, screenshots, logs and other artifacts to establish evidence before changing the test.
Part 2 takeaway
LOCATE
↓
COMPOSE
↓
FORMS / TABLES / FRAMES
↓
POPUPS / DOWNLOADS
↓
PAGE OBJECTS
↓
API + UI
↓
TRACE
Part 3 turns these techniques into an enterprise framework.
Official references
- https://javadoc.io/doc/com.microsoft.playwright/playwright/latest/index.html
- https://playwright.dev/java/docs/locators
- https://playwright.dev/java/docs/writing-tests
- https://playwright.dev/java/docs/pom
- https://playwright.dev/java/docs/trace-viewer
- https://playwright.dev/java/docs/api-testing


Comments
Post a Comment