Step 2 of your test case: 'Enter username, enter password, click Login. Expected: Products page shown.'
findElement() + sendKeys() + click() + one assertion. Your locator inventory from Suite 03 slots straight in.
Two methods carry most of Selenium: driver.findElement(By…) returns a WebElement, and the element's own methods act on it. The By class speaks every locator dialect you learned:
By.id("user-name") // fastest, use when possible By.cssSelector("[data-test='username']") // your CSS skills, verbatim By.xpath("//button[text()='Checkout']") // your XPath skills, verbatim By.name("user-name") By.className("title") By.linkText("Terms of Service")
Now the real login test — your Suite 03 inventory wearing Java:
@Test void validLoginLandsOnProducts() { WebDriver driver = new ChromeDriver(); driver.get("https://www.saucedemo.com"); driver.findElement(By.id("user-name")).sendKeys("standard_user"); driver.findElement(By.id("password")).sendKeys("secret_sauce"); driver.findElement(By.id("login-button")).click(); String header = driver.findElement(By.className("title")).getText(); System.out.println("Landed on: " + header); assertEquals("Products", header); driver.quit(); }
[INFO] Running LoginActionsTest Landed on: Products [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESS
sendKeys("text") types; clear() empties a field first (real apps often pre-fill).click() clicks buttons, links, checkboxes, radio buttons alike.getText() reads visible text — your main source of actual values for assertions.getAttribute("value") reads what's typed inside an input (getText() won't).isDisplayed(), isEnabled(), isSelected() return booleans — assertion fuel.import org.openqa.selenium.support.ui.Select; Select sort = new Select(driver.findElement(By.className("product_sort_container"))); sort.selectByVisibleText("Price (low to high)"); System.out.println("First product now: " + driver.findElement(By.className("inventory_item_name")).getText());
First product now: Sauce Labs Onesie
A wrong locator throws NoSuchElementException — an Error, not a Failure (remember the terminal lesson: errors point at your test). The exception prints the locator it tried; your first debugging move is always to paste that locator into DevTools $$() and see what it actually matches.
Fix: The exception prints the exact locator it tried — paste it into DevTools $$(). Nine times out of ten it's a typo or the element is inside an iframe. The tenth time: the page wasn't ready yet (next lesson fixes that).
Fix: Your locator matched a hidden element (many pages have duplicate mobile/desktop markup). Check how many matches $$() returns and target the visible one — or wait for elementToBeClickable.
Fix: The page re-rendered and your old WebElement reference points at a dead node. Re-find the element after any action that refreshes the DOM — page objects that locate on every call avoid this entirely.
Extend the login test (or write a new one): after landing on Products,
#add-to-cart-sauce-labs-backpack)..shopping_cart_badge) with getText() and assert it equals "1".#remove-sauce-labs-backpack!) says "Remove". Ids that change on state: your first taste of real-app spice.