Popular Searches
Popular Course Categories
Popular Courses

Locators with Python

Selenium with Python

<div class="selenium-notes">

<h1>Locators with Python</h1>

<p><strong>Locators with Python</strong> are used in Selenium WebDriver to identify and interact with specific web elements on a web page. Before Selenium can click a button, enter text into an input field, select a checkbox, read text, or perform another action, it must first locate the required element in the DOM.</p>

<p>In Python Selenium automation, locators are commonly used with the <strong>find_element()</strong> and <strong>find_elements()</strong> methods. Selenium provides traditional locator strategies such as ID, Name, Class Name, Tag Name, Link Text, Partial Link Text, CSS Selector, and XPath.</p>

<p><strong>Course Resource:</strong> <a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">Selenium Training at JustAcademy</a> | <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Register for Course Demo</a></p>

<hr>

<h2>1. What is a Locator?</h2>

<p>A <strong>locator</strong> is a method or strategy used by Selenium WebDriver to identify one or more specific elements in the HTML DOM of a web page.</p>

<p>For example, consider the following HTML:</p>

<pre><code>&lt;input id="username" name="user" type="text"&gt;</code></pre>

<p>The element can be located using its ID:</p>

<pre><code>driver.find_element(By.ID, "username")</code></pre>

<p>Once the element is located, Selenium can perform actions such as:</p>

<pre><code>element.send_keys("testuser")</code></pre>

<hr>

<h2>2. Why Are Locators Important in Selenium?</h2>

<p>Locators are one of the most important concepts in Selenium automation because every interaction starts by identifying the target element.</p>

<ul>

<li>They identify web elements.</li>

<li>They allow Selenium to interact with buttons, inputs, links, checkboxes, and other elements.</li>

<li>They help automate real user workflows.</li>

<li>They are essential for writing reliable test cases.</li>

<li>Good locators make automation scripts easier to maintain.</li>

<li>Stable locators reduce test failures caused by changes in the UI.</li>

</ul>

<pre><code>Web Page

   |

   v

HTML DOM

   |

   v

Locator

   |

   v

Web Element

   |

   v

Selenium Action

   |

   +---- click()

   +---- send_keys()

   +---- clear()

   +---- get_attribute()

   +---- text</code></pre>

<hr>

<h2>3. Locators in Selenium Python</h2>

<p>Selenium Python uses the <strong>By</strong> class to specify locator strategies.</p>

<pre><code>from selenium.webdriver.common.by import By</code></pre>

<p>A typical locator statement looks like this:</p>

<pre><code>element = driver.find_element(By.ID, "username")</code></pre>

<p>Here:</p>

<ul>

<li><strong>driver</strong> represents the WebDriver browser session.</li>

<li><strong>find_element()</strong> searches for an element.</li>

<li><strong>By.ID</strong> specifies the locator strategy.</li>

<li><strong>"username"</strong> is the locator value.</li>

<li><strong>element</strong> stores the WebElement returned by Selenium.</li>

</ul>

<hr>

<h2>4. Selenium Locator Strategies</h2>

<p>Selenium WebDriver provides eight traditional locator strategies.</p>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Locator</th><th>Python Strategy</th><th>Example</th></tr>

<tr><td>ID</td><td>By.ID</td><td>By.ID, "username"</td></tr>

<tr><td>Name</td><td>By.NAME</td><td>By.NAME, "email"</td></tr>

<tr><td>Class Name</td><td>By.CLASS_NAME</td><td>By.CLASS_NAME, "login-btn"</td></tr>

<tr><td>Tag Name</td><td>By.TAG_NAME</td><td>By.TAG_NAME, "input"</td></tr>

<tr><td>Link Text</td><td>By.LINK_TEXT</td><td>By.LINK_TEXT, "Login"</td></tr>

<tr><td>Partial Link Text</td><td>By.PARTIAL_LINK_TEXT</td><td>By.PARTIAL_LINK_TEXT, "Log"</td></tr>

<tr><td>CSS Selector</td><td>By.CSS_SELECTOR</td><td>By.CSS_SELECTOR, "#username"</td></tr>

<tr><td>XPath</td><td>By.XPATH</td><td>By.XPATH, "//input[@id='username']"</td></tr>

</table>

<p>These eight traditional strategies are commonly used to identify elements in the DOM.</p>

<hr>

<h2>5. HTML DOM and Locators</h2>

<p>To understand locators, it is important to understand the basic structure of HTML.</p>

<pre><code>&lt;html&gt;

    &lt;body&gt;

        &lt;form&gt;

            &lt;input id="username" name="username" type="text"&gt;

            &lt;input id="password" name="password" type="password"&gt;

            &lt;button id="login"&gt;Login&lt;/button&gt;

        &lt;/form&gt;

    &lt;/body&gt;

&lt;/html&gt;</code></pre>

<p>In the above HTML:</p>

<ul>

<li><strong>id="username"</strong> can be used with ID locator.</li>

<li><strong>name="username"</strong> can be used with Name locator.</li>

<li><strong>input</strong> can be used with Tag Name.</li>

<li><strong>id="login"</strong> can be used with ID locator.</li>

<li>The button text <strong>Login</strong> can be used with XPath or other suitable strategies.</li>

</ul>

<hr>

<h2>6. ID Locator</h2>

<p>The <strong>ID locator</strong> identifies an element using its HTML <strong>id</strong> attribute.</p>

<h3>HTML Example</h3>

<pre><code>&lt;input id="username" type="text"&gt;</code></pre>

<h3>Python Selenium</h3>

<pre><code>from selenium.webdriver.common.by import By

 

username = driver.find_element(

    By.ID,

    "username"

)</code></pre>

<h3>Complete Example</h3>

<pre><code>username = driver.find_element(By.ID, "username")

username.send_keys("testuser")</code></pre>

<h3>Advantages</h3>

<ul>

<li>Simple syntax.</li>

<li>Easy to understand.</li>

<li>Useful when IDs are unique and stable.</li>

<li>Easy to maintain.</li>

</ul>

<h3>Important Point</h3>

<p>An ID is especially useful when it uniquely identifies the required element and remains stable across application changes.</p>

<hr>

<h2>7. Name Locator</h2>

<p>The <strong>Name locator</strong> identifies an element using its <strong>name</strong> attribute.</p>

<h3>HTML</h3>

<pre><code>&lt;input name="username" type="text"&gt;</code></pre>

<h3>Python</h3>

<pre><code>username = driver.find_element(

    By.NAME,

    "username"

)</code></pre>

<h3>Example</h3>

<pre><code>email = driver.find_element(

    By.NAME,

    "email"

)

 

email.send_keys("[email protected]")</code></pre>

<hr>

<h2>8. Class Name Locator</h2>

<p>The <strong>Class Name locator</strong> identifies an element using its class attribute.</p>

<h3>HTML</h3>

<pre><code>&lt;button class="login-button"&gt;

    Login

&lt;/button&gt;</code></pre>

<h3>Python</h3>

<pre><code>login_button = driver.find_element(

    By.CLASS_NAME,

    "login-button"

)</code></pre>

<h3>Click Example</h3>

<pre><code>login_button.click()</code></pre>

<h3>Important Rule</h3>

<p><strong>By.CLASS_NAME</strong> should be given a single class name, not a compound string containing multiple classes.</p>

<p>For example:</p>

<pre><code>&lt;button class="btn login-button primary"&gt;

    Login

&lt;/button&gt;</code></pre>

<p>Do not write:</p>

<pre><code>driver.find_element(

    By.CLASS_NAME,

    "btn login-button"

)</code></pre>

<p>Instead, use one class:</p>

<pre><code>driver.find_element(

    By.CLASS_NAME,

    "login-button"

)</code></pre>

<p>Or use a CSS selector for multiple class conditions:</p>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    ".btn.login-button.primary"

)</code></pre>

<hr>

<h2>9. Tag Name Locator</h2>

<p>The <strong>Tag Name locator</strong> identifies elements based on their HTML tag name.</p>

<h3>HTML</h3>

<pre><code>&lt;input type="text"&gt;

&lt;input type="password"&gt;

&lt;button&gt;Login&lt;/button&gt;</code></pre>

<h3>Find Input Elements</h3>

<pre><code>inputs = driver.find_elements(

    By.TAG_NAME,

    "input"

)</code></pre>

<h3>Iterate Through Elements</h3>

<pre><code>for input_element in inputs:

    print(input_element.get_attribute("type"))</code></pre>

<h3>Find Buttons</h3>

<pre><code>buttons = driver.find_elements(

    By.TAG_NAME,

    "button"

)

 

for button in buttons:

    print(button.text)</code></pre>

<hr>

<h2>10. Link Text Locator</h2>

<p><strong>Link Text</strong> is used to locate an anchor element using its exact visible text.</p>

<h3>HTML</h3>

<pre><code>&lt;a href="/login"&gt;Login&lt;/a&gt;</code></pre>

<h3>Python</h3>

<pre><code>login_link = driver.find_element(

    By.LINK_TEXT,

    "Login"

)

 

login_link.click()</code></pre>

<h3>Another Example</h3>

<pre><code>driver.find_element(

    By.LINK_TEXT,

    "Contact Us"

).click()</code></pre>

<hr>

<h2>11. Partial Link Text Locator</h2>

<p><strong>Partial Link Text</strong> identifies an anchor using a portion of its visible text.</p>

<h3>HTML</h3>

<pre><code>&lt;a href="/courses"&gt;

    Selenium Python Training

&lt;/a&gt;</code></pre>

<h3>Python</h3>

<pre><code>driver.find_element(

    By.PARTIAL_LINK_TEXT,

    "Selenium"

).click()</code></pre>

<p>If multiple links match, a singular <strong>find_element()</strong> call returns the first matching element.</p>

<hr>

<h2>12. CSS Selector</h2>

<p><strong>CSS Selector</strong> is a powerful locator strategy that uses CSS selector syntax to identify elements.</p>

<h3>HTML</h3>

<pre><code>&lt;input id="username" class="form-control" name="user"&gt;</code></pre>

<h3>ID Selector</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "#username"

)</code></pre>

<h3>Class Selector</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    ".form-control"

)</code></pre>

<h3>Attribute Selector</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input[name='user']"

)</code></pre>

<h3>Tag + ID</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input#username"

)</code></pre>

<h3>Tag + Class</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input.form-control"

)</code></pre>

<hr>

<h2>13. CSS Attribute Selectors</h2>

<p>CSS selectors can identify elements based on attributes.</p>

<h3>Exact Attribute</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input[name='username']"

)</code></pre>

<h3>Contains Attribute Value</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input[name*='user']"

)</code></pre>

<h3>Starts With Attribute Value</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input[name^='user']"

)</code></pre>

<h3>Ends With Attribute Value</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input[name$='name']"

)</code></pre>

<hr>

<h2>14. Multiple CSS Classes</h2>

<p>CSS selectors are useful when an element contains multiple classes.</p>

<h3>HTML</h3>

<pre><code>&lt;button class="btn login primary"&gt;

    Login

&lt;/button&gt;</code></pre>

<h3>CSS Selector</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    ".btn.login.primary"

)</code></pre>

<p>There should be no spaces between class names when the intention is to match one element that contains all those classes.</p>

<hr>

<h2>15. Child and Descendant CSS Selectors</h2>

<h3>HTML</h3>

<pre><code>&lt;div class="login-form"&gt;

    &lt;input id="username"&gt;

    &lt;input id="password"&gt;

&lt;/div&gt;</code></pre>

<h3>Descendant Selector</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    ".login-form input#username"

)</code></pre>

<h3>Direct Child Selector</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    ".login-form &gt; input#username"

)</code></pre>

<hr>

<h2>16. XPath</h2>

<p><strong>XPath</strong> is a powerful locator strategy that can identify elements using their attributes, text, hierarchy, relationships, and other conditions.</p>

<h3>Basic XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//input"

)</code></pre>

<h3>ID XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[@id='username']"

)</code></pre>

<h3>Name XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[@name='username']"

)</code></pre>

<hr>

<h2>17. XPath Using Multiple Attributes</h2>

<p>Multiple attributes can be combined using the <strong>and</strong> operator.</p>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[@type='text' and @name='username']"

)</code></pre>

<h3>Using OR</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[@id='username' or @name='username']"

)</code></pre>

<hr>

<h2>18. XPath Using Text</h2>

<p>XPath can locate elements according to their visible text.</p>

<h3>HTML</h3>

<pre><code>&lt;button&gt;Login&lt;/button&gt;</code></pre>

<h3>XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//button[text()='Login']"

)</code></pre>

<h3>Text with Link</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//a[text()='Contact Us']"

)</code></pre>

<hr>

<h2>19. XPath contains()</h2>

<p>The <strong>contains()</strong> function is useful when an attribute or text contains a known portion of the desired value.</p>

<h3>HTML</h3>

<pre><code>&lt;button class="btn-login-primary"&gt;

    Login

&lt;/button&gt;</code></pre>

<h3>XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//button[contains(@class,'login')]"

)</code></pre>

<h3>Contains Text</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//button[contains(text(),'Login')]"

)</code></pre>

<hr>

<h2>20. XPath starts-with()</h2>

<p>The <strong>starts-with()</strong> function is useful when an attribute value begins with a known string.</p>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[starts-with(@id,'user')]"

)</code></pre>

<p>For example, it can match IDs such as:</p>

<pre><code>user123

username

user-field</code></pre>

<hr>

<h2>21. XPath Parent Relationship</h2>

<p>XPath can locate an element based on its parent.</p>

<h3>HTML</h3>

<pre><code>&lt;div class="login"&gt;

    &lt;input id="username"&gt;

&lt;/div&gt;</code></pre>

<h3>XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//div[@class='login']/input"

)</code></pre>

<hr>

<h2>22. XPath Child Relationship</h2>

<pre><code>driver.find_element(

    By.XPATH,

    "//form[@id='login-form']/input"

)</code></pre>

<p>This selects an input element inside the specified form.</p>

<hr>

<h2>23. XPath Following Sibling</h2>

<p>XPath can use relationships between neighboring elements.</p>

<h3>HTML</h3>

<pre><code>&lt;label&gt;Username&lt;/label&gt;

&lt;input id="username"&gt;</code></pre>

<h3>XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//label[text()='Username']/following-sibling::input"

)</code></pre>

<hr>

<h2>24. XPath Parent Axis</h2>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[@id='username']/parent::*"

)</code></pre>

<p>The parent axis can be useful when the target element is easier to identify through a child element or when the relationship between elements is important.</p>

<hr>

<h2>25. XPath Ancestor</h2>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[@id='username']/ancestor::form"

)</code></pre>

<p>This can locate an ancestor form element containing the input.</p>

<hr>

<h2>26. XPath Index</h2>

<p>An index can be used when multiple elements match the same XPath.</p>

<pre><code>driver.find_element(

    By.XPATH,

    "(//input)[1]"

)</code></pre>

<p>Another example:</p>

<pre><code>driver.find_element(

    By.XPATH,

    "(//button)[2]"

)</code></pre>

<p>Indexes should be used carefully because adding or reordering elements in the UI can change which element is selected.</p>

<hr>

<h2>27. XPath normalize-space()</h2>

<p><strong>normalize-space()</strong> can help when visible text contains extra spaces or formatting whitespace.</p>

<pre><code>driver.find_element(

    By.XPATH,

    "//button[normalize-space()='Login']"

)</code></pre>

<hr>

<h2>28. find_element()</h2>

<p>The <strong>find_element()</strong> method returns the first matching WebElement found using the supplied locator.</p>

<pre><code>element = driver.find_element(

    By.ID,

    "username"

)</code></pre>

<hr>

<h2>29. find_elements()</h2>

<p>The <strong>find_elements()</strong> method returns a list of all matching elements.</p>

<pre><code>elements = driver.find_elements(

    By.TAG_NAME,

    "input"

)

 

for element in elements:

    print(element.get_attribute("name"))</code></pre>

<p>If no matching elements are found, <strong>find_elements()</strong> returns an empty list.</p>

<hr>

<h2>30. find_element() vs find_elements()</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>find_element()</th><th>find_elements()</th></tr>

<tr><td>Returns the first matching element.</td><td>Returns all matching elements.</td></tr>

<tr><td>Returns a WebElement.</td><td>Returns a list of WebElements.</td></tr>

<tr><td>Raises NoSuchElementException when no element is found.</td><td>Returns an empty list when no elements are found.</td></tr>

<tr><td>Useful for a specific target element.</td><td>Useful for collections of elements.</td></tr>

</table>

<hr>

<h2>31. Locating Multiple Elements</h2>

<p>Suppose a page contains several buttons:</p>

<pre><code>&lt;button&gt;Save&lt;/button&gt;

&lt;button&gt;Cancel&lt;/button&gt;

&lt;button&gt;Submit&lt;/button&gt;</code></pre>

<p>All buttons can be located using:</p>

<pre><code>buttons = driver.find_elements(

    By.TAG_NAME,

    "button"

)

 

for button in buttons:

    print(button.text)</code></pre>

<hr>

<h2>32. Locator with CSS and XPath Comparison</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>CSS Selector</th><th>XPath</th></tr>

<tr><td>Uses CSS selector syntax.</td><td>Uses XPath expressions.</td></tr>

<tr><td>Useful for IDs, classes, and attributes.</td><td>Useful for complex DOM relationships.</td></tr>

<tr><td>Supports CSS combinators.</td><td>Supports parent, child, ancestor, sibling, and other axes.</td></tr>

<tr><td>Compact for many common selectors.</td><td>Powerful for complex element relationships.</td></tr>

<tr><td>Uses CSS attribute matching syntax.</td><td>Supports functions such as contains() and starts-with().</td></tr>

</table>

<hr>

<h2>33. Choosing a Good Locator</h2>

<p>A good locator should identify the intended element reliably and remain stable when the application's UI changes.</p>

<h3>Preferred Characteristics</h3>

<ul>

<li>Unique.</li>

<li>Stable.</li>

<li>Readable.</li>

<li>Easy to maintain.</li>

<li>Independent of unnecessary styling details.</li>

<li>Less likely to change between application versions.</li>

</ul>

<hr>

<h2>34. Locator Priority</h2>

<p>There is no universal rule that one locator must always be used first. The best choice depends on the application's HTML and the stability of available attributes.</p>

<p>A practical approach is:</p>

<pre><code>Stable Unique ID

      ↓

Stable Name / Test Attribute

      ↓

Stable CSS Selector

      ↓

Simple XPath

      ↓

Complex XPath when necessary</code></pre>

<p>If an application provides dedicated stable attributes for automation, such attributes can be preferable to fragile selectors based on layout or styling.</p>

<hr>

<h2>35. Using Data Attributes</h2>

<p>Many applications provide custom attributes specifically for testing, such as <strong>data-testid</strong>, <strong>data-test</strong>, or similar attributes.</p>

<h3>HTML</h3>

<pre><code>&lt;button data-testid="login-button"&gt;

    Login

&lt;/button&gt;</code></pre>

<h3>CSS Selector</h3>

<pre><code>login_button = driver.find_element(

    By.CSS_SELECTOR,

    "[data-testid='login-button']"

)</code></pre>

<h3>XPath</h3>

<pre><code>login_button = driver.find_element(

    By.XPATH,

    "//button[@data-testid='login-button']"

)</code></pre>

<hr>

<h2>36. Dynamic IDs</h2>

<p>Some web applications generate IDs dynamically.</p>

<h3>Example</h3>

<pre><code>&lt;input id="user_839201"&gt;</code></pre>

<p>If the numeric portion changes on every page load, directly using the complete ID may make the locator fragile.</p>

<h3>XPath contains()</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//input[contains(@id,'user_')]"

)</code></pre>

<h3>CSS Attribute Starts With</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "input[id^='user_']"

)</code></pre>

<hr>

<h2>37. Dynamic Class Names</h2>

<p>Modern frameworks may generate classes that change frequently.</p>

<h3>Example</h3>

<pre><code>&lt;button class="button_a8f91 login-button"&gt;

    Login

&lt;/button&gt;</code></pre>

<p>If <strong>button_a8f91</strong> changes frequently but <strong>login-button</strong> remains stable, use the stable class:</p>

<pre><code>driver.find_element(

    By.CLASS_NAME,

    "login-button"

)</code></pre>

<p>Or:</p>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "button.login-button"

)</code></pre>

<hr>

<h2>38. Locating Form Elements</h2>

<h3>HTML</h3>

<pre><code>&lt;form id="login-form"&gt;

    &lt;input id="username" name="username" type="text" placeholder="Username"&gt;

    &lt;input id="password" name="password" type="password" placeholder="Password"&gt;

    &lt;button id="login"&gt;Login&lt;/button&gt;

&lt;/form&gt;</code></pre>

<h3>Python</h3>

<pre><code>username = driver.find_element(

    By.ID,

    "username"

)

 

password = driver.find_element(

    By.ID,

    "password"

)

 

login = driver.find_element(

    By.ID,

    "login"

)

 

username.send_keys("testuser")

password.send_keys("Test@123")

login.click()</code></pre>

<hr>

<h2>39. Locating Checkboxes</h2>

<h3>HTML</h3>

<pre><code>&lt;input

    type="checkbox"

    id="terms"

&gt;</code></pre>

<h3>Python</h3>

<pre><code>terms = driver.find_element(

    By.ID,

    "terms"

)

 

if not terms.is_selected():

    terms.click()</code></pre>

<hr>

<h2>40. Locating Radio Buttons</h2>

<h3>HTML</h3>

<pre><code>&lt;input

    type="radio"

    name="gender"

    value="male"

    id="male"

&gt;

 

&lt;input

    type="radio"

    name="gender"

    value="female"

    id="female"

&gt;</code></pre>

<h3>Python</h3>

<pre><code>male = driver.find_element(

    By.ID,

    "male"

)

 

male.click()</code></pre>

<hr>

<h2>41. Locating Dropdowns</h2>

<h3>HTML</h3>

<pre><code>&lt;select id="country"&gt;

    &lt;option value="in"&gt;India&lt;/option&gt;

    &lt;option value="us"&gt;United States&lt;/option&gt;

&lt;/select&gt;</code></pre>

<h3>Locate Dropdown</h3>

<pre><code>country_element = driver.find_element(

    By.ID,

    "country"

)</code></pre>

<p>For a standard HTML select element, Selenium's <strong>Select</strong> class can then be used.</p>

<pre><code>from selenium.webdriver.support.ui import Select

 

country = Select(

    driver.find_element(By.ID, "country")

)

 

country.select_by_visible_text("India")</code></pre>

<hr>

<h2>42. Locating Buttons</h2>

<h3>HTML</h3>

<pre><code>&lt;button id="submit"&gt;

    Submit

&lt;/button&gt;</code></pre>

<h3>ID</h3>

<pre><code>driver.find_element(

    By.ID,

    "submit"

).click()</code></pre>

<h3>XPath</h3>

<pre><code>driver.find_element(

    By.XPATH,

    "//button[text()='Submit']"

).click()</code></pre>

<h3>CSS</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "#submit"

).click()</code></pre>

<hr>

<h2>43. Locating Links</h2>

<h3>HTML</h3>

<pre><code>&lt;a href="/products"&gt;

    Products

&lt;/a&gt;</code></pre>

<h3>Link Text</h3>

<pre><code>driver.find_element(

    By.LINK_TEXT,

    "Products"

).click()</code></pre>

<h3>Partial Link Text</h3>

<pre><code>driver.find_element(

    By.PARTIAL_LINK_TEXT,

    "Prod"

).click()</code></pre>

<h3>CSS</h3>

<pre><code>driver.find_element(

    By.CSS_SELECTOR,

    "a[href='/products']"

).click()</code></pre>

<hr>

<h2>44. Locating Tables</h2>

<h3>HTML</h3>

<pre><code>&lt;table id="users"&gt;

    &lt;tr&gt;

        &lt;td&gt;Manish&lt;/td&gt;

        &lt;td&gt;QA&lt;/td&gt;

    &lt;/tr&gt;

&lt;/table&gt;</code></pre>

<h3>Locate Table</h3>

<pre><code>table = driver.find_element(

    By.ID,

    "users"

)</code></pre>

<h3>Locate Rows</h3>

<pre><code>rows = table.find_elements(

    By.TAG_NAME,

    "tr"

)

 

for row in rows:

    print(row.text)</code></pre>

<p>Selenium also supports finding elements from the context of an already located WebElement.</p>

<hr>

<h2>45. Finding Child Elements from a Parent Element</h2>

<p>Sometimes it is easier to first locate a parent element and then search for child elements inside it.</p>

<h3>HTML</h3>

<pre><code>&lt;div id="login-form"&gt;

    &lt;input name="username"&gt;

    &lt;input name="password"&gt;

&lt;/div&gt;</code></pre>

<h3>Python</h3>

<pre><code>login_form = driver.find_element(

    By.ID,

    "login-form"

)

 

inputs = login_form.find_elements(

    By.TAG_NAME,

    "input"

)

 

for input_element in inputs:

    print(input_element.get_attribute("name"))</code></pre>

<hr>

<h2>46. Locator Chaining Concept</h2>

<p>Locator chaining means first finding a parent element and then locating a child element within that parent.</p>

<pre><code>parent = driver.find_element(

    By.ID,

    "login-form"

)

 

username = parent.find_element(

    By.NAME,

    "username"

)

 

username.send_keys("testuser")</code></pre>

<hr>

<h2>47. Locators with Explicit Wait</h2>

<p>Locators are frequently combined with <strong>WebDriverWait</strong> and expected conditions when elements are loaded dynamically.</p>

<pre><code>from selenium.webdriver.common.by import By

from selenium.webdriver.support.ui import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

 

wait = WebDriverWait(driver, 10)

 

username = wait.until(

    EC.visibility_of_element_located(

        (By.ID, "username")

    )

)

 

username.send_keys("testuser")</code></pre>

<p>The locator is still the same; the wait controls when Selenium proceeds to interact with the located element.</p>

<hr>

<h2>48. Locators with element_to_be_clickable</h2>

<pre><code>login_button = WebDriverWait(

    driver,

    10

).until(

    EC.element_to_be_clickable(

        (By.ID, "login")

    )

)

 

login_button.click()</code></pre>

<hr>

<h2>49. Locators and Dynamic Web Applications</h2>

<p>Modern applications may use JavaScript frameworks and dynamically generate or update elements. Therefore, the locator should target a stable property whenever possible.</p>

<pre><code>Dynamic UI

   |

   +---- IDs may change

   +---- Classes may change

   +---- Elements may appear later

   +---- DOM may refresh

   |

   v

Choose Stable Locator

   |

   v

Use Appropriate Wait

   |

   v

Interact with Element</code></pre>

<hr>

<h2>50. Relative Locators</h2>

<p>Modern Selenium also supports relative locator capabilities in Python. Relative locators can identify an element based on its position relative to another element, such as above, below, to the left, to the right, or near another element.</p>

<h3>Import</h3>

<pre><code>from selenium.webdriver.support.relative_locator import locate_with</code></pre>

<h3>Example</h3>

<pre><code>username = driver.find_element(

    By.ID,

    "username"

)

 

password = driver.find_element(

    locate_with(By.TAG_NAME, "input").below(username)

)</code></pre>

<h3>Common Relative Relationships</h3>

<ul>

<li>above()</li>

<li>below()</li>

<li>to_left_of()</li>

<li>to_right_of()</li>

<li>near()</li>

</ul>

<hr>

<h2>51. When to Use Relative Locators</h2>

<p>Relative locators can be useful when an element has weak identifying attributes but has a reliable spatial relationship to another element.</p>

<pre><code>Known Element

      |

      +---- above

      |

      +---- below

      |

      +---- left

      |

      +---- right

      |

      +---- near

      |

      v

Target Element</code></pre>

<p>Traditional stable IDs, names, CSS selectors, or XPath expressions should still be considered when they provide a clearer and more maintainable identification method.</p>

<hr>

<h2>52. Locator Validation</h2>

<p>Before using a locator in a large automation suite, verify that it identifies the intended element.</p>

<h3>Example</h3>

<pre><code>element = driver.find_element(

    By.ID,

    "username"

)

 

print(element.tag_name)

print(element.get_attribute("id"))

print(element.get_attribute("name"))</code></pre>

<hr>

<h2>53. Testing a Locator</h2>

<p>One useful way to test a locator is to temporarily use <strong>find_elements()</strong> and inspect how many elements match.</p>

<pre><code>elements = driver.find_elements(

    By.CSS_SELECTOR,

    ".login-button"

)

 

print("Matching elements:", len(elements))</code></pre>

<p>If the intended locator should identify one unique element but the result contains several elements, the locator may need refinement.</p>

<hr>

<h2>54. Unique Locator</h2>

<p>A unique locator identifies exactly one intended element.</p>

<pre><code>element = driver.find_element(

    By.ID,

    "unique-username"

)</code></pre>

<p>For important interactions such as Login, Checkout, Submit, Delete, or Save, a stable and appropriately specific locator is generally desirable.</p>

<hr>

<h2>55. Ambiguous Locator</h2>

<p>An ambiguous locator matches multiple elements.</p>

<h3>Example</h3>

<pre><code>driver.find_elements(

    By.TAG_NAME,

    "button"

)</code></pre>

<p>This is not necessarily wrong. It is appropriate when the automation needs a collection of buttons. However, if the test needs one specific button, a more specific locator should usually be used.</p>

<hr>

<h2>56. Bad Locator Example</h2>

<p>Consider an XPath that depends heavily on the complete DOM hierarchy:</p>

<pre><code>//html/body/div[1]/div[2]/div[1]/form/div[2]/input</code></pre>

<p>This type of locator can become fragile when the page structure changes.</p>

<hr>

<h2>57. Better Locator Example</h2>

<p>If the target has a stable ID:</p>

<pre><code>//input[@id='username']</code></pre>

<p>Or:</p>

<pre><code>driver.find_element(

    By.ID,

    "username"

)</code></pre>

<p>The second version is concise and directly communicates the locator strategy.</p>

<hr>

<h2>58. Locator Best Practices</h2>

<ol>

<li>Prefer stable and meaningful attributes.</li>

<li>Use unique IDs when they are stable.</li>

<li>Use dedicated test attributes when the application provides them.</li>

<li>Use CSS selectors for concise attribute and class-based identification.</li>

<li>Use XPath when relationships or text-based conditions make it appropriate.</li>

<li>Avoid unnecessarily long XPath expressions.</li>

<li>Avoid selectors based purely on changing visual styles.</li>

<li>Keep locators centralized in Page Object classes for larger projects.</li>

<li>Validate that important locators identify the intended element.</li>

<li>Use explicit waits when elements are dynamically loaded.</li>

<li>Avoid relying on arbitrary timing delays.</li>

<li>Review locators when the application's DOM changes.</li>

</ol>

<hr>

<h2>59. Common Locator Mistakes</h2>

<ul>

<li>Using an incorrect ID.</li>

<li>Using multiple class names with By.CLASS_NAME.</li>

<li>Using unstable dynamic IDs.</li>

<li>Using absolute XPath unnecessarily.</li>

<li>Ignoring duplicate elements.</li>

<li>Using visible text that changes frequently.</li>

<li>Not checking whether the element is inside an iframe.</li>

<li>Not waiting for dynamically loaded elements.</li>

<li>Using an element locator before the required page has loaded.</li>

<li>Using a locator that depends on unnecessary DOM hierarchy.</li>

</ul>

<hr>

<h2>60. Locator Debugging</h2>

<p>When a locator fails, check the following:</p>

<pre><code>Locator Failure

      |

      +---- Is URL correct?

      |

      +---- Is element present?

      |

      +---- Is locator syntax correct?

      |

      +---- Is element inside iframe?

      |

      +---- Is page dynamically loading?

      |

      +---- Is locator unique?

      |

      +---- Has DOM changed?

      |

      +---- Is another element blocking interaction?

      |

      v

Fix Locator / Synchronization</code></pre>

<hr>

<h2>61. Common Locator Exceptions</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Exception</th><th>Possible Locator Problem</th></tr>

<tr><td>NoSuchElementException</td><td>Locator does not identify an available element.</td></tr>

<tr><td>InvalidSelectorException</td><td>XPath or CSS selector syntax is invalid.</td></tr>

<tr><td>TimeoutException</td><td>Element did not satisfy the expected condition within the wait.</td></tr>

<tr><td>StaleElementReferenceException</td><td>Previously located element is no longer attached to the current DOM.</td></tr>

</table>

<hr>

<h2>62. Complete Locator Example</h2>

<pre><code>from selenium import webdriver

from selenium.webdriver.common.by import By

 

driver = webdriver.Chrome()

 

try:

    driver.get(

        "https://www.selenium.dev/selenium/web/web-form.html"

    )

 

    text_box = driver.find_element(

        By.NAME,

        "my-text"

    )

 

    text_box.send_keys("Selenium Python")

 

    submit_button = driver.find_element(

        By.CSS_SELECTOR,

        "button"

    )

 

    submit_button.click()

 

    message = driver.find_element(

        By.ID,

        "message"

    )

 

    print("Message:", message.text)

 

finally:

    driver.quit()</code></pre>

<hr>

<h2>63. Complete Example Using Multiple Locators</h2>

<pre><code>from selenium import webdriver

from selenium.webdriver.common.by import By

 

driver = webdriver.Chrome()

 

try:

    driver.get("https://example.com")

 

    # ID

    username = driver.find_element(

        By.ID,

        "username"

    )

 

    # NAME

    email = driver.find_element(

        By.NAME,

        "email"

    )

 

    # CLASS NAME

    button = driver.find_element(

        By.CLASS_NAME,

        "submit-button"

    )

 

    # TAG NAME

    headings = driver.find_elements(

        By.TAG_NAME,

        "h1"

    )

 

    # CSS SELECTOR

    password = driver.find_element(

        By.CSS_SELECTOR,

        "input[type='password']"

    )

 

    # XPATH

    login = driver.find_element(

        By.XPATH,

        "//button[text()='Login']"

    )

 

    print("Headings:", len(headings))

 

finally:

    driver.quit()</code></pre>

<hr>

<h2>64. Practical Project: Login Page Locators</h2>

<p>Consider a login page with the following HTML:</p>

<pre><code>&lt;form id="login-form"&gt;

    &lt;input

        id="username"

        name="username"

        type="text"

        placeholder="Username"

    &gt;

    &lt;input

        id="password"

        name="password"

        type="password"

        placeholder="Password"

    &gt;

    &lt;button

        id="login"

        class="login-button"

    &gt;

        Login

    &lt;/button&gt;

&lt;/form&gt;</code></pre>

<h3>Using ID</h3>

<pre><code>username = driver.find_element(

    By.ID,

    "username"

)</code></pre>

<h3>Using Name</h3>

<pre><code>username = driver.find_element(

    By.NAME,

    "username"

)</code></pre>

<h3>Using CSS</h3>

<pre><code>username = driver.find_element(

    By.CSS_SELECTOR,

    "input#username"

)</code></pre>

<h3>Using XPath</h3>

<pre><code>username = driver.find_element(

    By.XPATH,

    "//input[@id='username']"

)</code></pre>

<h3>Login Button</h3>

<pre><code>login_button = driver.find_element(

    By.ID,

    "login"

)

 

login_button.click()</code></pre>

<hr>

<h2>65. Practical Project Flow</h2>

<pre><code>Open Login Page

       ↓

Inspect HTML

       ↓

Identify Stable Attributes

       ↓

Create Locators

       ↓

Find Username

       ↓

Find Password

       ↓

Find Login Button

       ↓

Enter Credentials

       ↓

Click Login

       ↓

Validate Dashboard

       ↓

End Test</code></pre>

<hr>

<h2>66. Page Object Model and Locators</h2>

<p>In a professional automation framework, locators are commonly stored inside Page Object classes instead of being repeated throughout every test.</p>

<pre><code>from selenium.webdriver.common.by import By

 

class LoginPage:

 

    USERNAME = (By.ID, "username")

    PASSWORD = (By.ID, "password")

    LOGIN_BUTTON = (By.ID, "login")

 

    def __init__(self, driver):

        self.driver = driver

 

    def enter_username(self, username):

        self.driver.find_element(

            *self.USERNAME

        ).send_keys(username)

 

    def enter_password(self, password):

        self.driver.find_element(

            *self.PASSWORD

        ).send_keys(password)

 

    def click_login(self):

        self.driver.find_element(

            *self.LOGIN_BUTTON

        ).click()</code></pre>

<h3>Test Code</h3>

<pre><code>login_page.enter_username("testuser")

login_page.enter_password("Test@123")

login_page.click_login()</code></pre>

<hr>

<h2>67. Locators in a Selenium Project Structure</h2>

<pre><code>selenium_project/

|

+-- pages/

|   +-- login_page.py

|   +-- home_page.py

|   +-- checkout_page.py

|

+-- tests/

|   +-- test_login.py

|   +-- test_search.py

|   +-- test_checkout.py

|

+-- utils/

|   +-- helpers.py

|

+-- requirements.txt</code></pre>

<p>The Page Object classes can contain the locators and page actions, while test files contain the test scenarios.</p>

<hr>

<h2>68. Locator Strategy Comparison</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Strategy</th><th>Best Used For</th><th>Example</th></tr>

<tr><td>ID</td><td>Stable unique IDs</td><td>By.ID, "username"</td></tr>

<tr><td>NAME</td><td>Stable name attributes</td><td>By.NAME, "email"</td></tr>

<tr><td>CLASS_NAME</td><td>Single stable class</td><td>By.CLASS_NAME, "login"</td></tr>

<tr><td>TAG_NAME</td><td>Finding elements by HTML tag</td><td>By.TAG_NAME, "button"</td></tr>

<tr><td>LINK_TEXT</td><td>Exact visible link text</td><td>By.LINK_TEXT, "Login"</td></tr>

<tr><td>PARTIAL_LINK_TEXT</td><td>Partial visible link text</td><td>By.PARTIAL_LINK_TEXT, "Log"</td></tr>

<tr><td>CSS_SELECTOR</td><td>CSS-based attributes, classes, and relationships</td><td>By.CSS_SELECTOR, "#login"</td></tr>

<tr><td>XPath</td><td>Complex attributes, text, and DOM relationships</td><td>By.XPATH, "//button[@id='login']"</td></tr>

</table>

<hr>

<h2>69. Interview Questions</h2>

<h3>Q1. What is a locator in Selenium?</h3>

<p>A locator is a strategy used to identify a specific web element or group of elements in the DOM.</p>

<h3>Q2. How many traditional locator strategies does Selenium WebDriver provide?</h3>

<p>Selenium provides eight traditional locator strategies: ID, Name, Class Name, Tag Name, Link Text, Partial Link Text, CSS Selector, and XPath.</p>

<h3>Q3. What is By in Selenium Python?</h3>

<p><strong>By</strong> is the Selenium Python class used to specify the locator strategy when finding elements.</p>

<h3>Q4. How do you locate an element by ID?</h3>

<pre><code>driver.find_element(

    By.ID,

    "username"

)</code></pre>

<h3>Q5. What is the difference between find_element() and find_elements()?</h3>

<p><strong>find_element()</strong> returns the first matching element, while <strong>find_elements()</strong> returns a list of matching elements.</p>

<h3>Q6. What happens if find_element() cannot find an element?</h3>

<p>It raises a <strong>NoSuchElementException</strong>.</p>

<h3>Q7. What happens if find_elements() cannot find any elements?</h3>

<p>It returns an empty list.</p>

<h3>Q8. What is the difference between CSS Selector and XPath?</h3>

<p>CSS Selector uses CSS selector syntax, while XPath uses XPath expressions and can represent complex DOM relationships and conditions.</p>

<h3>Q9. Can XPath locate an element using text?</h3>

<p>Yes.</p>

<pre><code>driver.find_element(

    By.XPATH,

    "//button[text()='Login']"

)</code></pre>

<h3>Q10. What is a dynamic locator?</h3>

<p>A dynamic locator is a locator designed to identify an element even when some parts of its attributes or DOM representation change between executions.</p>

<h3>Q11. What is a stable locator?</h3>

<p>A stable locator relies on an attribute or relationship that is expected to remain consistent across application changes.</p>

<h3>Q12. Can Selenium locate multiple elements?</h3>

<p>Yes. Use <strong>find_elements()</strong>.</p>

<h3>Q13. Can a WebElement be used to find child elements?</h3>

<p>Yes. A located WebElement can be used as the search context for another <strong>find_element()</strong> or <strong>find_elements()</strong> call.</p>

<h3>Q14. Why should absolute XPath generally be avoided?</h3>

<p>Absolute XPath depends heavily on the complete DOM hierarchy and can become fragile when the page structure changes.</p>

<h3>Q15. What is a test attribute?</h3>

<p>A test attribute is an HTML attribute intentionally provided to make automated element identification more stable, such as <strong>data-testid</strong>.</p>

<hr>

<h2>70. Quick Revision</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Concept</th><th>Syntax</th></tr>

<tr><td>Import By</td><td>from selenium.webdriver.common.by import By</td></tr>

<tr><td>ID</td><td>By.ID, "username"</td></tr>

<tr><td>Name</td><td>By.NAME, "username"</td></tr>

<tr><td>Class</td><td>By.CLASS_NAME, "login"</td></tr>

<tr><td>Tag</td><td>By.TAG_NAME, "button"</td></tr>

<tr><td>Link Text</td><td>By.LINK_TEXT, "Login"</td></tr>

<tr><td>Partial Link Text</td><td>By.PARTIAL_LINK_TEXT, "Log"</td></tr>

<tr><td>CSS</td><td>By.CSS_SELECTOR, "#username"</td></tr>

<tr><td>XPath</td><td>By.XPATH, "//input[@id='username']"</td></tr>

<tr><td>One Element</td><td>driver.find_element()</td></tr>

<tr><td>Multiple Elements</td><td>driver.find_elements()</td></tr>

<tr><td>Text XPath</td><td>//button[text()='Login']</td></tr>

<tr><td>Contains XPath</td><td>//button[contains(text(),'Login')]</td></tr>

<tr><td>CSS Attribute</td><td>input[name='username']</td></tr>

<tr><td>Relative Locator</td><td>locate_with(...)</td></tr>

</table>

<hr>

<h2>71. Locator Learning Flow</h2>

<pre><code>HTML Basics

    ↓

DOM Understanding

    ↓

By Class

    ↓

ID Locator

    ↓

Name Locator

    ↓

Class Name

    ↓

Tag Name

    ↓

Link Text

    ↓

Partial Link Text

    ↓

CSS Selector

    ↓

XPath

    ↓

find_element()

    ↓

find_elements()

    ↓

Dynamic Locators

    ↓

Explicit Wait + Locators

    ↓

Relative Locators

    ↓

Page Object Model

    ↓

Real-World Automation</code></pre>

<hr>

<h2>72. Practical Exercise</h2>

<p>Create a Selenium Python script that opens a test website and performs the following tasks:</p>

<ol>

<li>Find a text field using ID.</li>

<li>Find another field using Name.</li>

<li>Find a button using Class Name.</li>

<li>Find all links using Tag Name.</li>

<li>Find a navigation link using Link Text.</li>

<li>Find a link using Partial Link Text.</li>

<li>Find an element using CSS Selector.</li>

<li>Find an element using XPath.</li>

<li>Print the text of the located elements.</li>

<li>Click a button.</li>

<li>Take a screenshot after the operation.</li>

<li>Close the browser.</li>

</ol>

<hr>

<h2>73. Final Summary</h2>

<p><strong>Locators with Python</strong> are the foundation of Selenium WebDriver element interaction. Selenium first identifies an element using a locator and then performs an action on the returned WebElement.</p>

<p>The major traditional locator strategies are <strong>ID, Name, Class Name, Tag Name, Link Text, Partial Link Text, CSS Selector, and XPath</strong>. Selenium Python also supports relative locator capabilities.</p>

<p>For reliable automation, choose locators based on stable application attributes, avoid unnecessarily fragile selectors, use appropriate waits for dynamic content, and keep locators organized in Page Object classes in larger frameworks.</p>

<hr>

<h2>74. Course Resources</h2>

<p><strong>Selenium Training:</strong> <a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">https://www.justacademy.co/course-detail/selenium-training</a></p>

<p><strong>Register for Course Demo:</strong> <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">https://www.justacademy.co/register-for-course-demo</a></p>

<p><strong>Official Selenium Website:</strong> <a href="https://www.selenium.dev/" target="_blank" rel="noopener noreferrer">https://www.selenium.dev/</a></p>

</div>

Previous Next
whatsapp