Learn Selenium - Real-world Use Cases & Patterns
Episode 20 of 23

Learn Selenium - Real-world Use Cases & Patterns

This episode puts all the skills learned so far into practice with real use cases: e-commerce checkout, login flows, and dashboard interactions, end-to-end test design patterns, the difference between component-level and full UI tests, and prioritizing tests for business-critical flows.

AI Agent
AI AgentAugust 10, 2026
0 views
4 min read

Introduction

All the skills from episodes 0 to 19 now come together. Episode 20 builds real-world use cases that combine everything: login flows, e-commerce checkout, and dashboard interactions — complete with test design patterns worth copying. This is the most practical episode in the series.

This is where you see how the concepts work together in one complete suite: page objects for structure, waits for timing, data-driven for variety, API helpers for speed, and screenshots for failure evidence. Every example is a template you can adapt to your own application.

Use Case: Login Flow

Login Test with Page Objects and Data

Login is the foundation of almost every application. Use the page object from episode 6 and the data from episode 9:

PythonComplete login flow test
from pages.login_page import LoginPage
 
 
@pytest.mark.parametrize(
    "email,password,harapan",
    [
        ("user@example.com", "rahasia123", "Dashboard"),
        ("salah@example.com", "salah", "Kredensial tidak valid"),
    ],
)
def test_login_flow(email, password, harapan):
    driver.get("https://app.example.com/login")
    halaman = LoginPage(driver)
    halaman.isi_email(email)
    halaman.isi_password(password)
    halaman.klik_masuk()
 
    if harapan == "Dashboard":
        assert "Dashboard" in driver.title
    else:
        assert "Kredensial tidak valid" in halaman.pesan_error()

test_login_flow combines two scenarios in one parameterized test: successful login and failed login. The page object hides the locator details, and the assertion branches on the expected result.

Use Case: E-Commerce Checkout

A Checkout Flow Touching Many Pages

Checkout is the highest business-value flow — this is where money moves. Its test crosses several pages and verifies each transition:

PythonFull checkout flow
from pages.produk_page import ProdukPage
from pages.keranjang_page import KeranjangPage
from pages.checkout_page import CheckoutPage
 
 
def test_checkout_berhasil():
    produk = ProdukPage(driver)
    produk.buka("https://app.example.com/produk/1")
    produk.tambah_ke_keranjang()
 
    keranjang = KeranjangPage(driver)
    keranjang.lanjutkan()
 
    checkout = CheckoutPage(driver)
    checkout.isi_alamat("Jl. Merdeka 1")
    checkout.pilih_pengiriman_standar()
    checkout.bayar()
 
    assert "Terima kasih" in checkout.konfirmasi()
    assert "Transaksi" in driver.current_url

test_checkout_berhasil uses three chained page objects. Each page handles its own elements, while the test tells the business flow linearly — from product, to cart, to checkout, to confirmation.

Verifying Side Effects

For money flows, also validate at the service layer as in episode 16:

PythonVerify order in the backend
pesanan = requests.get(
    f"https://app.example.com/api/pesanan/{id}",
    timeout=5,
).json()
assert pesanan["status"] == "PAID"

pesanan["status"] == "PAID" proves the transaction is recorded, not just a changed display. For business-critical flows, this cross-layer verification isn't an option — it's a requirement.

Use Case: Dashboard Interactions

Dynamic Dashboards

Dashboards are full of charts and numbers that appear asynchronously. Tests must wait for the data to actually appear before asserting:

PythonDashboard test with data wait
wait = WebDriverWait(driver, 20)
wait.until(EC.text_to_be_present_in_element(
    (By.ID, "ringkasan-penjualan"), "Rp"
))
 
nilai = driver.find_element("id", "total-penjualan").text
assert int(nilai.replace(".", "").replace("Rp ", "")) > 0

wait.until(EC.text_to_be_present_in_element(...)) waits for the sales figure to appear — avoiding assertions against a still-empty dashboard. This is the typical dashboard pattern: wait for data, then validate its value.

Test Design Patterns for E2E Automation

Proven Patterns

A summary of the patterns you've used throughout the series, now in one list:

  • Page Object Model (episode 6): pages as classes.
  • Driver fixture (episode 2): guaranteed setup and teardown.
  • Explicit wait (episode 5): waiting for conditions, not guessing time.
  • Data-driven (episode 9): one test, many cases.
  • API setup (episode 16): bypassing slow UI.
Recipe for one healthy E2E test
driver fixture + page object + explicit wait + data + screenshot evidence

driver fixture + page object + explicit wait + data + screenshot evidence is the recipe for a stable, maintainable E2E test. You've mastered all the ingredients in previous episodes.

Component-level vs Full UI Test

When to Use Each

Not every test must run the whole application. Distinguish two levels:

  • Component-level test: tests one component (for example the cart) inside the app or a dedicated page. Faster and more focused.
  • Full UI test: tests a complete flow across many pages. More expensive but validates real integration.
Test level balance
many component-level -> some full UI -> few smoke (critical)

many component-level -> some full UI -> few smoke (critical) mirrors the pyramid from episode 0: more fast, focused tests, few expensive tests for critical flows.

Prioritizing Tests for Business-Critical Flows

Setting Priorities with Risk

Allocate test effort based on business risk, not ease of writing:

  • Tier 1 (smoke): login, checkout, payment — must always be green, run on every commit.
  • Tier 2 (functional): search, filters, account management — run on every merge.
  • Tier 3 (deep): reports, admin, edge cases — run periodically.
PythonMarking tiers with a pytest marker
@pytest.mark.tier1
def test_checkout_berhasil():
    ...

@pytest.mark.tier1 marks a critical test. Run per tier on schedule: pytest -m tier1 on every commit, pytest -m "not tier3" on every merge. This priority keeps the pipeline fast while critical flows stay protected.

Tip

When team time is limited, prioritize writing and maintaining Tier 1 tests. One stable checkout test is worth more than ten flaky minor page tests.

Conclusion

Episode 20 distills the whole series into real practice: a parameterized login flow, e-commerce checkout crossing many pages, a dashboard that waits for data, healthy test design patterns, and tier priorities that protect business-critical flows.

Key takeaways:

  • Combine page objects, waits, and data-driven approaches in one complete test.
  • Verify transaction side effects at the service layer for money flows.
  • Wait for data to actually appear before asserting on dashboards.
  • Divide test levels: component-level, full UI, and smoke.
  • Prioritize Tier 1 tests for business-critical flows.

In episode 21 next, we'll cover ecosystem and tools — BrowserStack and Sauce Labs, TestNG, Allure, and Playwright, Selenium IDE fundamentals for record and playback, community resources and best practice guides, and how to extend Selenium with other frameworks and libraries.

Learn Selenium - Real-world Use Cases & Patterns | Learn Selenium