Published On

Java Interview Prep

Episode 1: From 'Just Works' to 'Works like a Charm'

Welcome to the debut episode of my Quality Engineering journey! Today, we're diving into a small snippet of Java code that leverages Selenium. It's like opening a box of chocolates—you never know what you're gonna get, but I promise it won't be boring. Let’s take a closer look at the code, sprinkle in some wit, and see how we can turn this functional piece into a polished gem.

package com.selenium.automate;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class Login {
    public static void main(String[] args) throws InterruptedException {
        WebDriver driver = new FirefoxDriver();
        driver.manage().window().maximize();
        driver.get("https://www.mybank.com/");
        Thread.sleep(2000);
        WebElement l = driver.findElement(By.xpath("//*[@id=\"login\"]"));
        WebElement p = driver.findElement(By.id("pass"));
        WebElement Login = driver.findElement(By.xpath("//*[@id=\"u_0_d_Nf\"]"));
        l.sendKeys("RunForestRun@gmail.com");
        p.sendKeys("1Forest1");
        // ...
    }
}

The First Look: Functionally Okay, but We Can Do Better

So, we have a driver, we maximize the window, navigate to a URL, wait for a bit, locate our login and password elements, and then send our credentials. Simple and sweet, like Forrest running across America. But just like Forrest, we’re not here to do things the simple way. We’re here to make them awesome. Let’s take this from "just works" to "works like a charm."

1. Avoid Thread.sleep()

Ah, the classic Thread.sleep(). It’s like waiting at a stop sign when there’s no traffic. Inefficient and boring. Let’s replace it with something a bit more intelligent.

import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;

// Later in the code...
WebDriverWait wait = new WebDriverWait(driver, 10);

2. Improve Element Locators

Using By.xpath("//*[@id=\"login\"]") can be fragile. IDs and names are often more reliable. Also, let’s give those variables more descriptive names.

WebElement usernameField = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("login")));
WebElement passwordField = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("pass")));
WebElement loginButton = wait.until(ExpectedConditions.elementToBeClickable(By.id("loginButton")));

3. Handling Secure Data

Hardcoding credentials in your code? That's a one-way ticket to getting hacked (and maybe fired). Let's use environment variables instead.

String username = System.getenv("MYBANK_USERNAME");
String password = System.getenv("MYBANK_PASSWORD");
usernameField.sendKeys(username);
passwordField.sendKeys(password);

4. Embrace the POM

Let’s encapsulate our page elements into a Page Object Model for better readability and maintenance. It’s like turning a messy bedroom into a clean, organized space—Marie Kondo would be proud.

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

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

    private By usernameLocator = By.id("login");
    private By passwordLocator = By.id("pass");
    private By loginButtonLocator = By.id("loginButton");

    public void enterUsername(String username) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(usernameLocator)).sendKeys(username);
    }

    public void enterPassword(String password) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(passwordLocator)).sendKeys(password);
    }

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

Polished Code

package com.selenium.automate;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Login {
    public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.manage().window().maximize();
        driver.get("https://www.mybank.com/");

        LoginPage loginPage = new LoginPage(driver);
        loginPage.enterUsername(System.getenv("MYBANK_USERNAME"));
        loginPage.enterPassword(System.getenv("MYBANK_PASSWORD"));
        loginPage.clickLogin();

        // Add more interactions and assertions here

        driver.quit();
    }
}

class LoginPage {
    private WebDriver driver;
    private WebDriverWait wait;

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

    private By usernameLocator = By.id("login");
    private By passwordLocator = By.id("pass");
    private By loginButtonLocator = By.id("loginButton");

    public void enterUsername(String username) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(usernameLocator)).sendKeys(username);
    }

    public void enterPassword(String password) {
        wait.until(ExpectedConditions.visibilityOfElementLocated(passwordLocator)).sendKeys(password);
    }

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

Conclusion

And there you have it! We took a simple, functional Selenium script and transformed it into a robust, maintainable, and secure piece of code. Remember, in Quality Engineering, it's not just about making it work—it's about making it work well. Stay tuned for more episodes where we continue to refine and enhance our code, one snippet at a time.

Until next time.

Comments