PAPracticeAutomation
Se

Java Β· JUnit 5

E-commerce with Selenium

Automate a full shopping journey β€” login, catalogue, cart, coupons, checkout and order history.

App under test

Nova Shop

URL
/shop
User
demo_user
Password
Demo@123
Coupons
SAVE10 Β· FLAT20
Declined card
4000 0000 0000 0002
Launch Nova Shop β†’

Scenarios to automate

Work top to bottom β€” each one adds a new technique.

  1. 1

    Valid & invalid login

    Beginner

    demo_user / Demo@123 succeeds; wrong password and empty fields show login-error.

  2. 2

    Locked-out user

    Beginner

    locked_user gets β€œSorry, this user has been locked out.”

  3. 3

    Slow login

    Intermediate

    slow_user takes ~3s β€” wait for the URL or product grid, never sleep.

  4. 4

    Route guard

    Beginner

    Visiting /shop/cart signed out redirects to /shop.

  5. 5

    Search, filter & sort

    Intermediate

    Assert product-count text, no-results state, and that product-price values are sorted.

  6. 6

    Cart badge & quantities

    Intermediate

    Add/remove from the grid, change qty in the cart, check line-total and totals maths.

  7. 7

    Coupons

    Intermediate

    SAVE10 = 10% off, FLAT20 = $20 off above $100, anything else is rejected.

  8. 8

    Checkout validation

    Intermediate

    Submit empty to collect error-* messages; fix them one by one.

  9. 9

    Declined card

    Advanced

    4000 0000 0000 0002 shows payment-error; switch to Cash on delivery and succeed.

  10. 10

    Order history

    Advanced

    Order id on the success page must appear in orders-table after navigation.

Sample Selenium suite

A working starting point written against this app's real data-testids.

NovaShopTest.java
import org.junit.jupiter.api.*;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.*;
import java.time.Duration;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import static org.openqa.selenium.support.ui.ExpectedConditions.*;

class NovaShopTest {
  static final String BASE = "http://localhost:3000";
  WebDriver driver;
  WebDriverWait wait;

  By tid(String id) { return By.cssSelector("[data-testid='" + id + "']"); }
  void type(String id, String text) { driver.findElement(tid(id)).sendKeys(text); }

  @BeforeEach
  void signIn() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    driver.get(BASE + "/shop");
    wait.until(elementToBeClickable(tid("username"))).sendKeys("demo_user");
    type("password", "Demo@123");
    driver.findElement(tid("login-button")).click();
    wait.until(urlContains("/shop/products"));
  }

  @AfterEach
  void tearDown() { driver.quit(); }

  @Test
  void buyHeadphonesWithCoupon() {
    wait.until(elementToBeClickable(tid("search-input"))).sendKeys("headphones");
    wait.until(numberOfElementsToBe(tid("product-card"), 1));
    driver.findElement(tid("add-to-cart-p1")).click();
    wait.until(textToBe(tid("cart-badge"), "1"));

    driver.findElement(tid("cart-link")).click();
    wait.until(elementToBeClickable(tid("coupon-input"))).sendKeys("SAVE10");
    driver.findElement(tid("apply-coupon")).click();
    wait.until(textToBePresentInElementLocated(tid("discount"), "$13.00"));

    driver.findElement(tid("checkout-button")).click();
    wait.until(elementToBeClickable(tid("first-name"))).sendKeys("Ada");
    type("last-name", "Lovelace");
    type("email", "ada@example.com");
    type("phone", "5551234567");
    type("address", "1 Analytical Way");
    type("city", "Austin");
    new Select(driver.findElement(tid("state"))).selectByVisibleText("Texas");
    type("zip", "73301");
    type("card-name", "Ada Lovelace");
    type("card-number", "4242424242424242");
    type("card-expiry", "1230");
    type("card-cvv", "123");
    driver.findElement(tid("accept-terms")).click();
    driver.findElement(tid("place-order")).click();

    // ~2s of "processing" β€” an explicit wait, not Thread.sleep.
    String orderId = wait.until(visibilityOfElementLocated(tid("order-id"))).getText();
    assertTrue(orderId.matches("NS-\\d+"), "Unexpected order id: " + orderId);
  }

  @Test
  void sortsByPriceLowToHigh() {
    new Select(wait.until(elementToBeClickable(tid("sort-select")))).selectByValue("price-asc");
    List<Double> prices = driver.findElements(tid("product-price")).stream()
        .map(e -> Double.parseDouble(e.getText().replace("$", ""))).toList();
    assertEquals(prices.stream().sorted().toList(), prices);
  }
}

Practising another tool?