Accessibility-First Semantic Locators
Traditional Selenium tests rely heavily on brittle CSS selectors or complex XPaths that break whenever the DOM hierarchy changes:
// Brittle — breaks on CSS redesigns:
find(By.cssSelector("div.modal > form button.btn-primary")).click();
TestFly introduces Playwright-style Semantic Locators that target the accessibility tree—interacting with the page exactly as a real human perceives it:
getByRole(Role.BUTTON).withName("Submit").click();
getByLabel("Email address").type("user@testfly.io");
getByPlaceholder("Search products…").type("laptop");
getByText("Forgot password?").click();
getByTestId("checkout-cta").click();
Every semantic locator returns an auto-waiting, chainable Locator instance with zero Thread.sleep().
Clean Page Objects with BasePage
BasePage provides wait-backed helper methods (type, click, getText, getAttribute, isDisplayed):
package io.testfly.examples.pages;
import io.testfly.test.BasePage;
import io.testfly.locator.Role;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LoginPage extends BasePage {
private static final By USERNAME = By.id("username");
private static final By PASSWORD = By.id("password");
public LoginPage(WebDriver driver) {
super(driver);
}
public void login(String user, String pass) {
type(USERNAME, user);
type(PASSWORD, pass);
getByRole(Role.BUTTON).withName("Sign In").click();
}
}
Advanced Synchronization with WaitEngine
When writing custom wait conditions, WaitEngine centralizes explicit waits using timeouts.explicit from testfly.yml:
import io.testfly.wait.WaitEngine;
// Centralized explicit wait conditions:
WaitEngine.waitForVisible(By.id("dashboard-banner"));
WaitEngine.waitForClickable(By.id("pay-button"));
WaitEngine.waitForInvisible(By.cssSelector(".loading-spinner"));
Top comments (0)