0
0
Selenium Javatesting~15 mins

@FindBy annotations in Selenium Java - Build an Automation Script

Choose your learning style9 modes available
Verify login functionality using @FindBy annotations
Preconditions (2)
Step 1: Open the browser and navigate to the login page URL
Step 2: Locate the email input field using @FindBy annotation and enter 'user@example.com'
Step 3: Locate the password input field using @FindBy annotation and enter 'Password123!'
Step 4: Locate the login button using @FindBy annotation and click it
Step 5: Wait for the dashboard page to load
Step 6: Verify that the current URL contains '/dashboard'
✅ Expected Result: User is successfully logged in and redirected to the dashboard page with URL containing '/dashboard'
Automation Requirements - Selenium WebDriver with TestNG
Assertions Needed:
Verify the URL contains '/dashboard' after login
Best Practices:
Use @FindBy annotations to locate web elements
Use Page Object Model to organize page elements and actions
Use explicit waits to wait for page load or element visibility
Use meaningful method names and clear assertions
Automated Solution
Selenium Java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.time.Duration;

public class LoginPage {
    private WebDriver driver;
    private WebDriverWait wait;

    @FindBy(id = "email")
    private WebElement emailInput;

    @FindBy(id = "password")
    private WebElement passwordInput;

    @FindBy(id = "loginBtn")
    private WebElement loginButton;

    public LoginPage(WebDriver driver) {
        this.driver = driver;
        this.wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        PageFactory.initElements(driver, this);
    }

    public void enterEmail(String email) {
        wait.until(ExpectedConditions.visibilityOf(emailInput));
        emailInput.clear();
        emailInput.sendKeys(email);
    }

    public void enterPassword(String password) {
        wait.until(ExpectedConditions.visibilityOf(passwordInput));
        passwordInput.clear();
        passwordInput.sendKeys(password);
    }

    public void clickLogin() {
        wait.until(ExpectedConditions.elementToBeClickable(loginButton));
        loginButton.click();
    }
}

public class LoginTest {
    private WebDriver driver;
    private LoginPage loginPage;

    @BeforeClass
    public void setUp() {
        // Initialize WebDriver (e.g., ChromeDriver) here
        driver = new org.openqa.selenium.chrome.ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://example.com/login");
        loginPage = new LoginPage(driver);
    }

    @Test
    public void testSuccessfulLogin() {
        loginPage.enterEmail("user@example.com");
        loginPage.enterPassword("Password123!");
        loginPage.clickLogin();

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        wait.until(ExpectedConditions.urlContains("/dashboard"));

        String currentUrl = driver.getCurrentUrl();
        Assert.assertTrue(currentUrl.contains("/dashboard"), "URL should contain '/dashboard' after login");
    }

    @AfterClass
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

This code uses the @FindBy annotation to locate the email input, password input, and login button elements on the login page. The LoginPage class represents the login page using the Page Object Model pattern, which helps keep the code organized and reusable.

In the LoginTest class, the test opens the browser, navigates to the login page, and uses the LoginPage methods to enter credentials and click the login button. It then waits explicitly for the URL to contain '/dashboard' to confirm successful login. Finally, it asserts that the URL is correct.

Explicit waits ensure the test waits for elements to be ready before interacting, avoiding flaky tests. The test cleans up by closing the browser after running.

Common Mistakes - 4 Pitfalls
Using hardcoded locators inside test methods instead of @FindBy annotations
Not using explicit waits before interacting with elements
{'mistake': 'Using Thread.sleep() to wait for elements', 'why_bad': "Thread.sleep() is inefficient and slows tests unnecessarily; it also doesn't handle dynamic wait times.", 'correct_approach': 'Use explicit waits that wait only as long as needed.'}
{'mistake': 'Not initializing PageFactory in the Page Object constructor', 'why_bad': "Without PageFactory.initElements(), @FindBy elements won't be initialized and will cause NullPointerException.", 'correct_approach': 'Call PageFactory.initElements(driver, this) in the constructor.'}
Bonus Challenge

Now add data-driven testing with 3 different sets of login credentials (valid and invalid) using TestNG data provider.

Show Hint