Summary for CSS Selector Strategies for Automated Browser Testing
<input id="email" value="">
#email (shorthand for [id="email"])
Look for any element on the page with a i.e. name attribute that's set to i.e. email.
<input name="email" value="">-->[name="email"]<input type="submit" value="Send">-->[type="submit"]<input type="checkbox" value="true">-->[type="checkbox"]<input name="email" placeholder="Email Address">-->[placeholder="Email Address"]<form name"some_form_name">-->[name="some_form_name"]<a href="/docs/">Docs</a>-->[href="/docs/"]
Suppose we want to click the radio input the value of 2:
<input type="radio" name="point" value="1">
<input type="radio" name="point" value="2">
<input type="radio" name="point" value="3">
[name="point"][value="2"]
<div class="some-class another-class">...</div>
.some-class.another-class
.class-name syntax is shorthand for [class*="class-name"]
<div class="username">Justin</div>
<span class="username">Justin</span>
In this case, using .username will match both elements, since both have that class. You could use div.username or span.username to pin it down to the one you want to target.
Space
Let's assume we want to target the <label> that contains "Justin". We can't use just label as our selector because that will match both elements. We need to narrow down the parent element first.
<div class="name">
<label>Justin</label>
</div>
<div class="email">
<label>[email protected]</label>
</div>
.name label
Find the <label> element somewhere inside of an element with a .name class.
#supportForm .comments textarea
Look for a <textarea> element, which is inside of an element with a .comments class, which is then inside of an element with an ID set to #supportForm.
Angle bracket
Using angle bracket means that the element is a "direct child" of the parent element. In other words, it's in precisely the next "level" of nested elements — not just anywhere inside.
<div class="comments">
<textarea></textarea>
</div>
<div class="comments">
<div class="something">
<textarea></textarea>
</div>
</div>
.comments textarea will match both <textarea> elements. However, if I use
.comments > textarea
it will only match only the first, since the second block has a <div> nested in between the two which breaks the "direct child" relationship.
- Is there an
idattribute? Use that. - Is there a
nameattribute? Use that. - Is there some other unique attribute that I can use, like
placeholder? Use that. - Can I use attribute operators to match a portion and uniquely identify this element, like a link's href? Use that.
- At this point I'll start looking at class names to see if anything looks usable.
- If there's nothing specific enough, I'll take what I have so far (which may be a useful attribute or class that just isn't specific enough or may be just the element tag) and I'll start stepping out and looking at the hierarchy outside of the element. The same logic applies when targeting parent elements, so this logic is recursive. Just keep in mind that you don't need to use the "direct" parent. You could jump back a few levels to a parent element that has an
idattribute or makes more sense semantically.
Further readings: