[ PROMPT_NODE_25036 ]
page-objects
[ SKILL_DOCUMENTATION ]
# Playwright Java – 页面对象模式
## 组件模式 (可复用的子页面对象)
对于重复出现的 UI 组件(导航栏、模态框、表格),请创建组件类:
java
// 可复用的表格组件 — 传入定位器根节点
public class DataTable extends BasePage {
private final Locator tableRoot;
public DataTable(Page page, Locator tableRoot) {
super(page);
this.tableRoot = tableRoot;
}
public int getRowCount() {
return tableRoot.locator("tbody tr").count();
}
public String getCellValue(int row, int col) {
return tableRoot.locator("tbody tr")
.nth(row)
.locator("td")
.nth(col)
.innerText();
}
public void clickRowAction(int row, String actionLabel) {
tableRoot.locator("tbody tr")
.nth(row)
.getByRole(AriaRole.BUTTON, new Locator.GetByRoleOptions().setName(actionLabel))
.click();
}
public DataTable sortByColumn(String columnHeader) {
tableRoot.getByRole(AriaRole.COLUMNHEADER,
new Locator.GetByRoleOptions().setName(columnHeader)).click();
return this;
}
}
// 在页面对象中的用法:
public class UsersPage extends BasePage {
public final DataTable usersTable;
private final Locator searchInput;
private final Locator addUserButton;
public UsersPage(Page page) {
super(page);
usersTable = new DataTable(page, page.locator("#users-table"));
searchInput = page.getByPlaceholder("Search users…");
addUserButton = page.getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName("Add User"));
}
@Override protected String getUrl() { return "/admin/users"; }
public UsersPage searchFor(String query) {
searchInput.fill(query);
searchInput.press("Enter");
page.waitForResponse("**/api/users**", () -> {});
return this;
}
}
---
## 模态框 / 对话框组件
java
public class ConfirmDialog extends BasePage {
private final Locator dialog;
private final Locator confirmButton;
private final Locator cancelButton;
private final Locator titleText;
public ConfirmDialog(Page page) {
super(page);
dialog = page.getByRole(AriaRole.DIALOG);
confirmButton = dialog.getByRole(AriaRole.BUTTON, new Locator.GetByRoleOptions().setName("Confirm"));
cancelB