Skip to content

Instantly share code, notes, and snippets.

@burczan
Last active December 3, 2019 08:46
Show Gist options
  • Save burczan/4b4a76c23704320db7edd2ae3430379e to your computer and use it in GitHub Desktop.
Save burczan/4b4a76c23704320db7edd2ae3430379e to your computer and use it in GitHub Desktop.
CSS selectors summary

Summary for CSS Selector Strategies for Automated Browser Testing

IDs:

<input id="email" value="">

#email (shorthand for [id="email"])

Attributes:

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"]

Class names:

<div class="some-class another-class">...</div>
.some-class.another-class

.class-name syntax is shorthand for [class*="class-name"]

Element tags:

<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.

Targeting using hierarchy:

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.

How do I know when to use the different methods?

  1. Is there an id attribute? Use that.
  2. Is there a name attribute? Use that.
  3. Is there some other unique attribute that I can use, like placeholder? Use that.
  4. Can I use attribute operators to match a portion and uniquely identify this element, like a link's href? Use that.
  5. At this point I'll start looking at class names to see if anything looks usable.
  6. 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 id attribute or makes more sense semantically.

Further readings:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment