CSS attribute and pseudo-class selectors in Selenium Java - Build an Automation Script
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.time.Duration; public class SearchTest { private WebDriver driver; private WebDriverWait wait; @BeforeEach public void setUp() { driver = new ChromeDriver(); wait = new WebDriverWait(driver, Duration.ofSeconds(10)); driver.get("http://example.com"); } @Test public void testSearchInputAndFirstResultHighlight() { // Locate search input using CSS attribute selector WebElement searchInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input[name='search']"))); assertNotNull(searchInput, "Search input field should be present"); // Enter text 'Selenium' searchInput.sendKeys("Selenium"); // Locate search button using CSS attribute selector and click WebElement searchButton = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button[type='submit']"))); searchButton.click(); // Wait for search results container to be visible WebElement resultsList = wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("ul#results"))); // Locate first search result using :first-child pseudo-class WebElement firstResult = resultsList.findElement(By.cssSelector("li:first-child")); assertNotNull(firstResult, "First search result should be present"); // Verify first result has 'highlight' class String classes = firstResult.getAttribute("class"); assertTrue(classes != null && classes.contains("highlight"), "First result should have 'highlight' class"); } @AfterEach public void tearDown() { if (driver != null) { driver.quit(); } } }
This test uses Selenium WebDriver with Java to automate the manual test case.
In setUp(), we open the browser and navigate to the homepage.
We locate the search input using a CSS attribute selector input[name='search'] and verify it is present.
We enter the text 'Selenium' into the input.
We locate the search button using button[type='submit'] and click it.
We wait explicitly for the search results list with id 'results' to appear.
We then find the first result using the CSS pseudo-class selector li:first-child inside the results list.
Finally, we check that the first result has the CSS class 'highlight' to confirm it is highlighted.
Explicit waits ensure elements are ready before interacting, avoiding flaky tests.
Assertions confirm the elements are found and the highlight class is present, matching the expected result.
In tearDown(), we close the browser to clean up.
Now add data-driven testing with 3 different search inputs: 'Selenium', 'Java', and 'Testing'
Practice
<input> elements with a type attribute equal to "text"?Solution
Step 1: Understand attribute selectors
The selectorinput[type='text']matchesinputelements whosetypeattribute exactly equalstext.Step 2: Differentiate other selectors
^=means starts with,$=means ends with, and*=means contains. These do not require exact match.Final Answer:
input[type='text'] -> Option DQuick Check:
Exact attribute match = input[type='text'] [OK]
- Confusing ^= (starts with) with = (exact match)
- Using $= or *= when exact match is needed
- Forgetting to quote attribute values
<a> elements with an href attribute containing the word "login"?Solution
Step 1: Understand the *= attribute selector
The selectora[href*='login']matchesaelements whosehrefattribute contains the substringloginanywhere.Step 2: Differentiate other selectors
^=matches start,$=matches end, and=matches exact. We want contains, so*=is correct.Final Answer:
a[href*='login'] -> Option AQuick Check:
Contains substring = *= [OK]
- Using ^= or $= instead of *= for substring match
- Forgetting quotes around attribute values
- Using = which requires exact match
<ul> <li>Item 1</li> <li class="active">Item 2</li> <li>Item 3</li> <li class="active">Item 4</li> </ul>
What will the CSS selector
li.active:first-of-type select?Solution
Step 1: Understand
:first-of-typepseudo-class:first-of-typeselects the first sibling of its type (here, the firstli) regardless of class.Step 2: Combine with class selector
The selectorli.active:first-of-typelooks for anlithat is both.activeand the firstli. The firstlihas no class, so no match.Final Answer:
No elements, because first-of-type ignores class -> Option CQuick Check:
first-of-type ignores class, so no match [OK]
:first-of-type matches first element type ignoring classes [OK]- Assuming :first-of-type matches first element with class
- Confusing :first-child with :first-of-type
- Ignoring that class must match too
<button> elements that are disabled using a CSS selector in Selenium. Which selector is incorrect and will cause your test to fail?Solution
Step 1: Identify valid selectors for disabled buttons
button:disabledandbutton[disabled]correctly select disabled buttons.button[disabled='disabled']also works if attribute equals 'disabled'.Step 2: Spot invalid pseudo-class
:enableis not a valid CSS pseudo-class. The correct one is:enabled.Final Answer:
button:enable -> Option AQuick Check:
Invalid pseudo-class = :enable [OK]
- Using :enable instead of :enabled
- Assuming [disabled='true'] works (it must match exact value)
- Confusing attribute selector syntax
<input> elements with various name attributes:<input name="user_email"> <input name="user_password"> <input name="admin_email"> <input name="admin_password">
Which CSS selector will select only the
input elements whose name attribute ends with "_email"?Solution
Step 1: Understand $= attribute selector
The selectorinput[name$='_email']matchesinputelements whosenameattribute ends exactly with_email.Step 2: Differentiate other selectors
*=matches contains anywhere,^=matches starts with, and=matches exact. We want ends with, so$=is correct.Final Answer:
input[name$='_email'] -> Option BQuick Check:
Ends with substring = $= [OK]
- Using *= or ^= instead of $= for ends with
- Forgetting quotes around attribute values
- Using = which requires exact match
Ready to prove it?
Pass the test and this pattern moves unknown
