Popular Searches
Popular Course Categories
Popular Courses

Starts-with()

XPath in Selenium

<div class="selenium-notes">

<h1>Starts-with() in XPath</h1>

<p><strong>starts-with()</strong> is an XPath function used in Selenium to locate web elements when an attribute value or text begins with a specific string. It is especially useful for handling dynamic web elements where the beginning portion of an attribute remains stable while the remaining portion changes.</p>

<p>XPath is an important locator technique used with Selenium WebDriver. JustAcademy's Selenium training curriculum includes locators such as XPath and CSS selectors as part of Selenium WebDriver and element automation.</p>

<p>For more Selenium learning resources, visit <a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">Selenium Training Course</a> and explore the <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Selenium Course Demo</a>.</p>

<hr>

<h2>1. What is starts-with() in XPath?</h2>

<p>The <strong>starts-with()</strong> function checks whether a string starts with a specified value. In Selenium automation, it can be used to create XPath expressions for elements whose attributes or text begin with a known value.</p>

<p>For example, suppose an input element has a dynamic ID:</p>

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

<p>If the numeric portion of the ID changes dynamically but <strong>user_</strong> always remains constant, starts-with() can be used:</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<p>This XPath can locate the input element without depending on the complete dynamic ID.</p>

<hr>

<h2>2. Basic Syntax of starts-with()</h2>

<p>The basic XPath syntax is:</p>

<pre><code>starts-with(string, substring)</code></pre>

<p>When used with an HTML attribute:</p>

<pre><code>//tagname[starts-with(@attribute,'value')]</code></pre>

<p>Example:</p>

<pre><code>//input[starts-with(@id,'user')]</code></pre>

<p>This expression selects an input element whose <strong>id</strong> attribute starts with <strong>user</strong>.</p>

<hr>

<h2>3. Understanding the Syntax</h2>

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

<tr><th>Part</th><th>Meaning</th></tr>

<tr><td>//</td><td>Searches for matching elements anywhere in the document.</td></tr>

<tr><td>input</td><td>Specifies the HTML element.</td></tr>

<tr><td>starts-with()</td><td>Checks whether a string starts with a specified value.</td></tr>

<tr><td>@id</td><td>Refers to the id attribute.</td></tr>

<tr><td>'user'</td><td>The expected starting text.</td></tr>

</table>

<hr>

<h2>4. Why is starts-with() Used in Selenium?</h2>

<p>Modern web applications frequently generate dynamic attribute values. An element may have an ID such as:</p>

<pre><code>user_1001

user_1002

user_1003</code></pre>

<p>The complete ID changes, but the beginning remains the same. Instead of creating separate XPath expressions for every value, starts-with() can identify the common pattern.</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<hr>

<h2>5. starts-with() with ID Attribute</h2>

<p>The most common use of starts-with() is locating elements using dynamic IDs.</p>

<p>HTML:</p>

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

<p>XPath:</p>

<pre><code>//input[starts-with(@id,'username_')]</code></pre>

<p>This XPath matches an input whose ID begins with <strong>username_</strong>.</p>

<hr>

<h2>6. starts-with() with Name Attribute</h2>

<p>The function can also be used with the <strong>name</strong> attribute.</p>

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

<p>XPath:</p>

<pre><code>//input[starts-with(@name,'user_login_')]</code></pre>

<p>This is useful when the name attribute contains a stable prefix and a dynamic suffix.</p>

<hr>

<h2>7. starts-with() with Class Attribute</h2>

<p>starts-with() can be applied to the class attribute when the class value has a predictable beginning.</p>

<pre><code>&lt;button class="btn-primary-submit"&gt;Submit&lt;/button&gt;</code></pre>

<p>XPath:</p>

<pre><code>//button[starts-with(@class,'btn-primary')]</code></pre>

<p>However, class attributes may contain multiple class names. Therefore, class-based XPath expressions should be created carefully.</p>

<hr>

<h2>8. starts-with() with Placeholder</h2>

<p>The <strong>placeholder</strong> attribute can also be used.</p>

<pre><code>&lt;input placeholder="Enter your username here" type="text"&gt;</code></pre>

<p>XPath:</p>

<pre><code>//input[starts-with(@placeholder,'Enter your')]</code></pre>

<p>This matches the input because its placeholder starts with <strong>Enter your</strong>.</p>

<hr>

<h2>9. starts-with() with Type Attribute</h2>

<p>starts-with() can technically be used with attributes such as type.</p>

<pre><code>//input[starts-with(@type,'text')]</code></pre>

<p>For static values, however, exact matching is generally simpler:</p>

<pre><code>//input[@type='text']</code></pre>

<p>starts-with() is most useful when the attribute contains dynamic or variable values.</p>

<hr>

<h2>10. starts-with() with Text</h2>

<p>starts-with() can be used with element text when the visible text begins with a known value.</p>

<pre><code>//button[starts-with(text(),'Login')]</code></pre>

<p>Example HTML:</p>

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

<p>The XPath can match the button because its text starts with <strong>Login</strong>.</p>

<hr>

<h2>11. starts-with() with normalize-space()</h2>

<p>Whitespace can sometimes affect text-based XPath expressions. The <strong>normalize-space()</strong> function can be combined with starts-with() to remove unnecessary leading and trailing whitespace and normalize internal whitespace.</p>

<pre><code>//button[starts-with(normalize-space(text()),'Login')]</code></pre>

<p>This is useful when HTML contains extra whitespace around the visible text.</p>

<hr>

<h2>12. starts-with() with the Dot Operator</h2>

<p>The dot <strong>.</strong> represents the string value of the current node. It is useful when an element contains nested elements.</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<p>Example:</p>

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

  &lt;span&gt;Login&lt;/span&gt;

  &lt;span&gt;Now&lt;/span&gt;

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

<p>Using <strong>.</strong> can be more reliable than text() when the visible text is distributed across descendant elements.</p>

<hr>

<h2>13. starts-with() with Nested Elements</h2>

<p>Consider the following HTML:</p>

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

  &lt;span&gt;Login&lt;/span&gt;

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

<p>An XPath using the button's complete string value can be:</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<p>This is useful when the target element contains child elements.</p>

<hr>

<h2>14. Dynamic ID Example</h2>

<p>Suppose a web application generates IDs such as:</p>

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

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

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

<p>The stable part is <strong>email_</strong>.</p>

<pre><code>//input[starts-with(@id,'email_')]</code></pre>

<p>This XPath can identify elements whose ID begins with the specified prefix.</p>

<hr>

<h2>15. Dynamic Button ID Example</h2>

<p>Suppose a button has:</p>

<pre><code>&lt;button id="submit_78452"&gt;Submit&lt;/button&gt;</code></pre>

<p>Use:</p>

<pre><code>//button[starts-with(@id,'submit_')]</code></pre>

<p>The XPath does not depend on the changing numeric suffix.</p>

<hr>

<h2>16. Dynamic Link Example</h2>

<p>Suppose links have dynamic href values:</p>

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

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

<p>XPath:</p>

<pre><code>//a[starts-with(@href,'/products/')]</code></pre>

<p>This can locate links whose href begins with the specified path.</p>

<hr>

<h2>17. starts-with() with href</h2>

<p>The href attribute is frequently useful for starts-with() when URLs share a common beginning.</p>

<pre><code>//a[starts-with(@href,'https://example.com/products')]</code></pre>

<p>This expression targets links whose href starts with the specified URL.</p>

<hr>

<h2>18. starts-with() with aria-label</h2>

<p>Modern web applications frequently use accessibility attributes such as <strong>aria-label</strong>.</p>

<pre><code>&lt;button aria-label="Search products"&gt;🔍&lt;/button&gt;</code></pre>

<p>XPath:</p>

<pre><code>//button[starts-with(@aria-label,'Search')]</code></pre>

<p>This can be useful when the visible text is unavailable or represented by an icon.</p>

<hr>

<h2>19. starts-with() with data-* Attributes</h2>

<p>Applications often use custom data attributes for JavaScript and testing.</p>

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

<p>XPath:</p>

<pre><code>//button[starts-with(@data-testid,'login-button-')]</code></pre>

<p>This can be useful when the test ID contains a dynamic suffix.</p>

<hr>

<h2>20. starts-with() with Multiple Conditions</h2>

<p>starts-with() can be combined with other XPath conditions using <strong>and</strong>.</p>

<pre><code>//input[starts-with(@id,'user_') and @type='text']</code></pre>

<p>This selects an input whose ID starts with <strong>user_</strong> and whose type is <strong>text</strong>.</p>

<hr>

<h2>21. starts-with() with OR Condition</h2>

<p>The <strong>or</strong> operator can be used when more than one starting pattern is acceptable.</p>

<pre><code>//input[starts-with(@id,'user_') or starts-with(@id,'username_')]</code></pre>

<p>This XPath matches elements whose ID begins with either prefix.</p>

<hr>

<h2>22. starts-with() with Element Type</h2>

<p>Always use the most appropriate element type when possible.</p>

<pre><code>//button[starts-with(@id,'submit_')]</code></pre>

<p>This is generally more specific than:</p>

<pre><code>//*[starts-with(@id,'submit_')]</code></pre>

<p>The second expression searches across all elements and may produce multiple matches.</p>

<hr>

<h2>23. starts-with() with Parent-Child Relationship</h2>

<p>starts-with() can be combined with parent-child relationships.</p>

<pre><code>//form//input[starts-with(@id,'user_')]</code></pre>

<p>This searches for input elements inside a form where the ID starts with <strong>user_</strong>.</p>

<hr>

<h2>24. starts-with() with Descendant Elements</h2>

<p>The descendant axis can be used to find matching elements at any level below a parent.</p>

<pre><code>//div[@class='login-form']//input[starts-with(@id,'user_')]</code></pre>

<p>This approach helps narrow the search to a specific section of the page.</p>

<hr>

<h2>25. starts-with() with Parent Selection</h2>

<p>You can first identify a child element and then navigate to its parent.</p>

<pre><code>//input[starts-with(@id,'username_')]/parent::div</code></pre>

<p>This selects the parent div of an input whose ID starts with <strong>username_</strong>.</p>

<hr>

<h2>26. starts-with() with Ancestor</h2>

<p>The ancestor axis can be used when the required parent structure is higher in the DOM.</p>

<pre><code>//input[starts-with(@id,'username_')]/ancestor::form</code></pre>

<p>This locates the form containing the matching input.</p>

<hr>

<h2>27. starts-with() with Following-Sibling</h2>

<p>starts-with() can be combined with sibling relationships.</p>

<pre><code>//label[starts-with(normalize-space(.),'Username')]/following-sibling::input</code></pre>

<p>This can locate an input that follows a label whose text starts with <strong>Username</strong>.</p>

<hr>

<h2>28. starts-with() with Table Data</h2>

<p>It can be used when table cell text begins with a known value.</p>

<pre><code>//tr[td[starts-with(normalize-space(.),'John')]]</code></pre>

<p>This finds a table row containing a cell whose text starts with <strong>John</strong>.</p>

<hr>

<h2>29. starts-with() with Dropdown Options</h2>

<p>Example:</p>

<pre><code>&lt;option&gt;India - Mumbai&lt;/option&gt;

&lt;option&gt;India - Delhi&lt;/option&gt;

&lt;option&gt;United States&lt;/option&gt;</code></pre>

<p>XPath:</p>

<pre><code>//option[starts-with(normalize-space(.),'India')]</code></pre>

<p>This identifies options whose text starts with <strong>India</strong>.</p>

<hr>

<h2>30. starts-with() with Search Results</h2>

<p>Suppose search results display names beginning with a known prefix:</p>

<pre><code>&lt;div class="result"&gt;Apple iPhone&lt;/div&gt;

&lt;div class="result"&gt;Apple MacBook&lt;/div&gt;</code></pre>

<p>XPath:</p>

<pre><code>//div[@class='result' and starts-with(normalize-space(.),'Apple')]</code></pre>

<hr>

<h2>31. starts-with() in Selenium Java</h2>

<p>In Selenium Java, the XPath expression is passed to <strong>By.xpath()</strong>.</p>

<pre><code>WebElement username = driver.findElement(By.xpath("//input[starts-with(@id,'username_')]"));

username.sendKeys("admin");</code></pre>

<hr>

<h2>32. Using starts-with() with click()</h2>

<p>A dynamic button can be located and clicked using starts-with().</p>

<pre><code>driver.findElement(By.xpath("//button[starts-with(@id,'submit_')]")).click();</code></pre>

<hr>

<h2>33. Using starts-with() with sendKeys()</h2>

<p>For dynamic input fields:</p>

<pre><code>driver.findElement(By.xpath("//input[starts-with(@id,'username_')]")).sendKeys("admin");</code></pre>

<hr>

<h2>34. Using starts-with() with getText()</h2>

<p>starts-with() can locate an element and Selenium can then retrieve its text.</p>

<pre><code>String text = driver.findElement(By.xpath("//div[starts-with(normalize-space(.),'Welcome')]")).getText();

System.out.println(text);</code></pre>

<hr>

<h2>35. Using starts-with() with getAttribute()</h2>

<p>You can retrieve an attribute after locating the element.</p>

<pre><code>WebElement element = driver.findElement(By.xpath("//input[starts-with(@id,'user_')]"));

String id = element.getAttribute("id");

System.out.println(id);</code></pre>

<hr>

<h2>36. Using starts-with() with findElements()</h2>

<p>When multiple elements match the same prefix, use <strong>findElements()</strong>.</p>

<pre><code>List&lt;WebElement&gt; elements = driver.findElements(By.xpath("//input[starts-with(@id,'user_')]"));

System.out.println(elements.size());</code></pre>

<hr>

<h2>37. starts-with() with Explicit Wait</h2>

<p>Dynamic elements may not be immediately available. Explicit waits can be combined with starts-with() XPath.</p>

<pre><code>WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

WebElement loginButton = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[starts-with(@id,'login_')]")));

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

<hr>

<h2>38. starts-with() in Page Object Model</h2>

<p>In the Page Object Model, dynamic XPath expressions can be stored in page classes.</p>

<pre><code>By usernameField = By.xpath("//input[starts-with(@id,'username_')]");

By loginButton = By.xpath("//button[starts-with(@id,'login_')]");

public void login(String username) {

    driver.findElement(usernameField).sendKeys(username);

    driver.findElement(loginButton).click();

}</code></pre>

<hr>

<h2>39. starts-with() for Dynamic Web Applications</h2>

<p>Dynamic applications may generate changing IDs, classes, URLs, or other attributes. If a stable prefix exists, starts-with() can help create a locator that does not depend on the changing suffix.</p>

<p>Example:</p>

<pre><code>profile_1001

profile_1002

profile_1003</code></pre>

<p>XPath:</p>

<pre><code>//div[starts-with(@id,'profile_')]</code></pre>

<hr>

<h2>40. Dynamic ID Pattern Example</h2>

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

<tr><th>Dynamic ID</th><th>Common Prefix</th><th>XPath</th></tr>

<tr><td>user_101</td><td>user_</td><td>//input[starts-with(@id,'user_')]</td></tr>

<tr><td>user_202</td><td>user_</td><td>//input[starts-with(@id,'user_')]</td></tr>

<tr><td>login_501</td><td>login_</td><td>//button[starts-with(@id,'login_')]</td></tr>

<tr><td>order_789</td><td>order_</td><td>//div[starts-with(@id,'order_')]</td></tr>

</table>

<hr>

<h2>41. starts-with() vs Exact Attribute Matching</h2>

<p>Exact matching checks the complete attribute value.</p>

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

<p>starts-with() checks only the beginning.</p>

<pre><code>//input[starts-with(@id,'username_')]</code></pre>

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

<tr><th>Method</th><th>Purpose</th></tr>

<tr><td>@id='value'</td><td>Matches the complete attribute value.</td></tr>

<tr><td>starts-with(@id,'value')</td><td>Matches an attribute beginning with the specified value.</td></tr>

</table>

<hr>

<h2>42. starts-with() vs contains()</h2>

<p><strong>starts-with()</strong> checks the beginning of a string, while <strong>contains()</strong> checks whether the specified value occurs anywhere in the string.</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<pre><code>//input[contains(@id,'user_')]</code></pre>

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

<tr><th>Function</th><th>Matching Behavior</th></tr>

<tr><td>starts-with()</td><td>Value must occur at the beginning.</td></tr>

<tr><td>contains()</td><td>Value can occur anywhere.</td></tr>

</table>

<hr>

<h2>43. starts-with() vs text()</h2>

<p>The <strong>text()</strong> function can be used for exact text matching.</p>

<pre><code>//button[text()='Login']</code></pre>

<p>starts-with() can be used when the beginning is known but the remaining text changes.</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<p>For example, this can match text such as <strong>Login Now</strong>, <strong>Login to Continue</strong>, or <strong>Login as Admin</strong>.</p>

<hr>

<h2>44. starts-with() vs Partial Link Text</h2>

<p>Selenium provides <strong>By.partialLinkText()</strong> for partial matching of link text. XPath starts-with() can provide more flexible conditions involving text and attributes.</p>

<pre><code>driver.findElement(By.partialLinkText("Product")).click();</code></pre>

<p>XPath alternative:</p>

<pre><code>driver.findElement(By.xpath("//a[starts-with(normalize-space(.),'Product')]")).click();</code></pre>

<hr>

<h2>45. starts-with() vs CSS Attribute Prefix Selector</h2>

<p>CSS selectors also support prefix matching with <strong>^=</strong>.</p>

<pre><code>input[id^='user_']</code></pre>

<p>Equivalent XPath:</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

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

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

<tr><td>starts-with(@id,'user_')</td><td>[id^='user_']</td></tr>

</table>

<hr>

<h2>46. starts-with() with Multiple Attributes</h2>

<p>Multiple starts-with() conditions can be combined.</p>

<pre><code>//input[starts-with(@id,'user_') and starts-with(@name,'username_')]</code></pre>

<p>This is useful when both attributes follow predictable naming patterns.</p>

<hr>

<h2>47. starts-with() with OR Patterns</h2>

<p>Sometimes different versions of an application may generate different prefixes.</p>

<pre><code>//input[starts-with(@id,'user_') or starts-with(@id,'usr_')]</code></pre>

<p>This XPath supports both patterns.</p>

<hr>

<h2>48. Case Sensitivity of starts-with()</h2>

<p>XPath string comparisons are case-sensitive. For example:</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<p>This does not automatically match text beginning with <strong>login</strong> or <strong>LOGIN</strong>.</p>

<p>For case-insensitive matching, XPath can use <strong>translate()</strong>.</p>

<pre><code>//button[starts-with(translate(normalize-space(.),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'login')]</code></pre>

<hr>

<h2>49. Case-Insensitive Attribute Matching</h2>

<p>Case-insensitive matching can also be applied to attributes.</p>

<pre><code>//input[starts-with(translate(@id,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'user_')]</code></pre>

<p>This converts uppercase letters to lowercase before performing the comparison.</p>

<hr>

<h2>50. starts-with() with normalize-space()</h2>

<p>A robust text-based expression can combine starts-with() and normalize-space().</p>

<pre><code>//div[starts-with(normalize-space(.),'Order')]</code></pre>

<p>This is helpful when the page contains extra whitespace around the displayed text.</p>

<hr>

<h2>51. starts-with() with Nested Span Text</h2>

<p>Consider:</p>

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

&lt;span&gt;Continue&lt;/span&gt;

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

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

<pre><code>//button[starts-with(normalize-space(.),'Continue')]</code></pre>

<p>The dot represents the string value of the button and can include descendant text.</p>

<hr>

<h2>52. starts-with() with Labels</h2>

<p>Suppose:</p>

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

<p>XPath:</p>

<pre><code>//label[starts-with(normalize-space(.),'Username')]</code></pre>

<p>This matches the label because its text begins with <strong>Username</strong>.</p>

<hr>

<h2>53. starts-with() with Form Elements</h2>

<p>Example:</p>

<pre><code>//form[starts-with(@id,'registration_')]//input</code></pre>

<p>This identifies input elements inside a form whose ID begins with <strong>registration_</strong>.</p>

<hr>

<h2>54. starts-with() for Login Automation</h2>

<p>A login page may contain dynamic identifiers.</p>

<pre><code>//input[starts-with(@id,'username_')]

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

//button[starts-with(@id,'login_')]</code></pre>

<p>Selenium example:</p>

<pre><code>driver.findElement(By.xpath("//input[starts-with(@id,'username_')]")).sendKeys("admin");

driver.findElement(By.xpath("//input[starts-with(@id,'password_')]")).sendKeys("admin123");

driver.findElement(By.xpath("//button[starts-with(@id,'login_')]")).click();</code></pre>

<hr>

<h2>55. starts-with() for Registration Automation</h2>

<p>Dynamic registration fields can be located using stable prefixes.</p>

<pre><code>driver.findElement(By.xpath("//input[starts-with(@id,'firstName_')]")).sendKeys("John");

driver.findElement(By.xpath("//input[starts-with(@id,'lastName_')]")).sendKeys("Smith");

driver.findElement(By.xpath("//input[starts-with(@id,'email_')]")).sendKeys("[email protected]");</code></pre>

<hr>

<h2>56. starts-with() for Search Automation</h2>

<p>A search result can be located using text that starts with a known word.</p>

<pre><code>WebElement result = driver.findElement(By.xpath("//div[starts-with(normalize-space(.),'Selenium')]"));

System.out.println(result.getText());</code></pre>

<hr>

<h2>57. starts-with() for Product Automation</h2>

<p>Example product elements:</p>

<pre><code>&lt;div id="product_101"&gt;Laptop&lt;/div&gt;

&lt;div id="product_102"&gt;Mobile&lt;/div&gt;</code></pre>

<p>XPath:</p>

<pre><code>//div[starts-with(@id,'product_')]</code></pre>

<hr>

<h2>58. starts-with() for Order Automation</h2>

<p>Dynamic order IDs can be handled using a stable prefix.</p>

<pre><code>//div[starts-with(@id,'order_')]</code></pre>

<p>For example:</p>

<pre><code>order_1001

order_1002

order_1003</code></pre>

<hr>

<h2>59. starts-with() with Text and Attribute</h2>

<p>Multiple conditions can improve locator precision.</p>

<pre><code>//button[starts-with(@id,'submit_') and starts-with(normalize-space(.),'Submit')]</code></pre>

<p>This requires both the ID and visible text to start with the specified values.</p>

<hr>

<h2>60. starts-with() with Class and Text</h2>

<pre><code>//button[starts-with(@class,'btn') and starts-with(normalize-space(.),'Login')]</code></pre>

<p>This combines a class prefix with a text prefix.</p>

<hr>

<h2>61. Avoiding Overly Broad starts-with() XPath</h2>

<p>A broad XPath such as:</p>

<pre><code>//*[starts-with(@id,'user')]</code></pre>

<p>may match many elements.</p>

<p>A more specific expression is:</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<p>Using a specific element type and stable prefix generally makes the locator easier to understand and maintain.</p>

<hr>

<h2>62. Checking Multiple Matching Elements</h2>

<p>Before using a starts-with() XPath in a test, verify how many elements it matches.</p>

<pre><code>List&lt;WebElement&gt; elements = driver.findElements(By.xpath("//input[starts-with(@id,'user_')]"));

System.out.println("Matches: " + elements.size());</code></pre>

<p>If several elements are returned unexpectedly, refine the XPath.</p>

<hr>

<h2>63. Testing starts-with() in Chrome DevTools</h2>

<p>XPath expressions can be tested in Chrome DevTools using the <strong>$x()</strong> function.</p>

<pre><code>$x("//input[starts-with(@id,'user_')]")</code></pre>

<p>If the XPath is correct, Chrome returns the matching DOM elements.</p>

<hr>

<h2>64. Validating a Text-Based starts-with() XPath</h2>

<pre><code>$x("//button[starts-with(normalize-space(.),'Login')]")</code></pre>

<p>This allows you to verify whether the expected button is returned before adding the XPath to Selenium code.</p>

<hr>

<h2>65. starts-with() in Dynamic Tables</h2>

<p>Suppose a table contains dynamically generated row IDs:</p>

<pre><code>&lt;tr id="row_1001"&gt;...&lt;/tr&gt;

&lt;tr id="row_1002"&gt;...&lt;/tr&gt;</code></pre>

<p>XPath:</p>

<pre><code>//tr[starts-with(@id,'row_')]</code></pre>

<hr>

<h2>66. Selecting a Specific Row with starts-with()</h2>

<p>starts-with() can be combined with text conditions.</p>

<pre><code>//tr[starts-with(@id,'row_') and td[starts-with(normalize-space(.),'John')]]</code></pre>

<p>This selects a row whose ID starts with <strong>row_</strong> and contains a table cell beginning with <strong>John</strong>.</p>

<hr>

<h2>67. starts-with() with Index</h2>

<p>An index can be applied when multiple elements match.</p>

<pre><code>(//input[starts-with(@id,'user_')])[1]</code></pre>

<p>This selects the first matching input.</p>

<p>Indexing should be used carefully because the order of elements can change.</p>

<hr>

<h2>68. starts-with() with Last Matching Element</h2>

<pre><code>(//input[starts-with(@id,'user_')])[last()]</code></pre>

<p>This selects the last matching input element.</p>

<hr>

<h2>69. starts-with() with Position</h2>

<pre><code>(//button[starts-with(@id,'submit_')])[2]</code></pre>

<p>This selects the second matching button.</p>

<hr>

<h2>70. starts-with() in Page Object Model Example</h2>

<pre><code>public class LoginPage {

    private WebDriver driver;

    private By username = By.xpath("//input[starts-with(@id,'username_')]");

    private By password = By.xpath("//input[starts-with(@id,'password_')]");

    private By loginButton = By.xpath("//button[starts-with(@id,'login_')]");

    public LoginPage(WebDriver driver) {

        this.driver = driver;

    }

    public void login(String user, String pass) {

        driver.findElement(username).sendKeys(user);

        driver.findElement(password).sendKeys(pass);

        driver.findElement(loginButton).click();

    }

}</code></pre>

<hr>

<h2>71. starts-with() with Explicit Wait in POM</h2>

<pre><code>private By loginButton = By.xpath("//button[starts-with(@id,'login_')]");

public void clickLogin() {

    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

    WebElement button = wait.until(ExpectedConditions.elementToBeClickable(loginButton));

    button.click();

}</code></pre>

<hr>

<h2>72. Real-World Automation Flow</h2>

<ol>

<li>Open the application.</li>

<li>Inspect the required element.</li>

<li>Identify the dynamic attribute.</li>

<li>Find the stable beginning of the attribute.</li>

<li>Create a starts-with() XPath.</li>

<li>Validate the XPath in DevTools.</li>

<li>Check whether the XPath returns the expected number of elements.</li>

<li>Use the XPath with Selenium WebDriver.</li>

<li>Perform the required action such as click(), sendKeys(), or getText().</li>

<li>Use explicit waits when the element is dynamically loaded.</li>

</ol>

<hr>

<h2>73. Common Mistake: Using Complete Dynamic ID</h2>

<p>Suppose the ID changes from:</p>

<pre><code>username_12345</code></pre>

<p>to:</p>

<pre><code>username_67890</code></pre>

<p>This XPath is fragile:</p>

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

<p>A prefix-based XPath is more appropriate when the prefix is stable:</p>

<pre><code>//input[starts-with(@id,'username_')]</code></pre>

<hr>

<h2>74. Common Mistake: Incorrect Prefix</h2>

<p>If the actual value is:</p>

<pre><code>user_123</code></pre>

<p>This will not match:</p>

<pre><code>//input[starts-with(@id,'username_')]</code></pre>

<p>The correct prefix is:</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<hr>

<h2>75. Common Mistake: Case Mismatch</h2>

<p>XPath matching is case-sensitive.</p>

<p>For:</p>

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

<p>This matches:</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<p>But this does not match the same text:</p>

<pre><code>//button[starts-with(normalize-space(.),'login')]</code></pre>

<hr>

<h2>76. Common Mistake: Using starts-with() When Exact Match Is Better</h2>

<p>If the attribute value is stable and unique, exact matching can be clearer.</p>

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

<p>There is no need to use:</p>

<pre><code>//input[starts-with(@id,'user')]</code></pre>

<p>unless partial matching is actually required.</p>

<hr>

<h2>77. Common Mistake: Broad Text Matching</h2>

<p>This expression may match several elements:</p>

<pre><code>//*[starts-with(normalize-space(.),'Login')]</code></pre>

<p>A more specific locator is:</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<hr>

<h2>78. Common Mistake: Ignoring Multiple Matches</h2>

<p>starts-with() may return multiple elements when the same prefix is used repeatedly.</p>

<pre><code>List&lt;WebElement&gt; matches = driver.findElements(By.xpath("//input[starts-with(@id,'user_')]"));

System.out.println(matches.size());</code></pre>

<p>Always verify uniqueness before relying on a locator.</p>

<hr>

<h2>79. Common Mistake: Overusing Indexes</h2>

<p>This expression depends on element position:</p>

<pre><code>(//button[starts-with(@id,'login_')])[1]</code></pre>

<p>If the page structure changes, the first matching button may change. Prefer a more specific relationship or stable attribute whenever possible.</p>

<hr>

<h2>80. Best Practices for starts-with()</h2>

<ul>

<li>Use starts-with() when the beginning of an attribute or text is stable.</li>

<li>Prefer stable attributes over generated values.</li>

<li>Use a specific element type when possible.</li>

<li>Combine starts-with() with other conditions when necessary.</li>

<li>Use normalize-space() for text matching when whitespace may vary.</li>

<li>Validate XPath expressions in browser DevTools.</li>

<li>Check the number of matching elements before using the locator.</li>

<li>Avoid unnecessarily broad expressions.</li>

<li>Avoid indexes unless there is no better stable relationship.</li>

<li>Use explicit waits for dynamically loaded elements.</li>

<li>Keep XPath expressions readable in Page Object classes.</li>

</ul>

<hr>

<h2>81. Advantages of starts-with()</h2>

<ul>

<li>Useful for dynamic attribute values.</li>

<li>Can avoid hardcoding changing suffixes.</li>

<li>Works with attributes and text.</li>

<li>Can be combined with AND and OR conditions.</li>

<li>Can be combined with XPath axes.</li>

<li>Useful for dynamic IDs and URLs.</li>

<li>Useful in real-world Selenium automation.</li>

<li>Can make locators more flexible when a stable prefix exists.</li>

</ul>

<hr>

<h2>82. Limitations of starts-with()</h2>

<ul>

<li>It only checks the beginning of a string.</li>

<li>It is case-sensitive unless additional XPath functions are used.</li>

<li>It can return multiple elements if the prefix is not unique.</li>

<li>It should not be used when an exact stable locator is already available.</li>

<li>It can become fragile if the prefix itself changes.</li>

<li>Broad text-based expressions can match unexpected elements.</li>

</ul>

<hr>

<h2>83. When Should You Use starts-with()?</h2>

<ul>

<li>When an ID has a stable prefix and dynamic suffix.</li>

<li>When a name attribute starts with a predictable value.</li>

<li>When a URL starts with a known path.</li>

<li>When visible text begins with a known phrase.</li>

<li>When generated attributes contain stable prefixes.</li>

<li>When working with dynamic web applications.</li>

<li>When an exact attribute value is not stable.</li>

</ul>

<hr>

<h2>84. When Should You Avoid starts-with()?</h2>

<ul>

<li>When a stable unique ID is available.</li>

<li>When the complete attribute value is static.</li>

<li>When the prefix is not unique.</li>

<li>When the beginning of the value changes frequently.</li>

<li>When a more stable parent-child relationship is available.</li>

<li>When a simple CSS selector provides a clearer locator.</li>

</ul>

<hr>

<h2>85. Practical Exercise</h2>

<p>Consider the following HTML:</p>

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

    &lt;input id="user_12345" type="text" placeholder="Enter username"&gt;

    &lt;input id="pass_98765" type="password" placeholder="Enter password"&gt;

    &lt;button id="login_56789"&gt;Login to Account&lt;/button&gt;

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

<p>Create XPath expressions using starts-with().</p>

<p>Username:</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<p>Password:</p>

<pre><code>//input[starts-with(@id,'pass_')]</code></pre>

<p>Login button:</p>

<pre><code>//button[starts-with(@id,'login_')]</code></pre>

<p>Login button using text:</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<hr>

<h2>86. Practical Selenium Exercise</h2>

<pre><code>WebDriver driver = new ChromeDriver();

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

WebElement username = driver.findElement(By.xpath("//input[starts-with(@id,'user_')]"));

username.sendKeys("admin");

WebElement password = driver.findElement(By.xpath("//input[starts-with(@id,'pass_')]"));

password.sendKeys("admin123");

WebElement login = driver.findElement(By.xpath("//button[starts-with(@id,'login_')]"));

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

<hr>

<h2>87. Real-World Example: Dynamic E-Commerce Application</h2>

<p>Suppose an e-commerce application generates product IDs like:</p>

<pre><code>product_1001

product_1002

product_1003</code></pre>

<p>XPath:</p>

<pre><code>//div[starts-with(@id,'product_')]</code></pre>

<p>If the product name also begins with a known value, additional conditions can be used:</p>

<pre><code>//div[starts-with(@id,'product_') and starts-with(normalize-space(.),'Laptop')]</code></pre>

<hr>

<h2>88. Real-World Example: Dynamic Order Page</h2>

<p>Suppose order containers use IDs such as:</p>

<pre><code>order_10001

order_10002

order_10003</code></pre>

<p>XPath:</p>

<pre><code>//div[starts-with(@id,'order_')]</code></pre>

<p>Specific order text can be combined with the dynamic prefix.</p>

<pre><code>//div[starts-with(@id,'order_') and starts-with(normalize-space(.),'Order')]</code></pre>

<hr>

<h2>89. Quick Reference</h2>

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

<tr><th>Requirement</th><th>XPath</th></tr>

<tr><td>Dynamic ID</td><td>//input[starts-with(@id,'user_')]</td></tr>

<tr><td>Dynamic Name</td><td>//input[starts-with(@name,'user_')]</td></tr>

<tr><td>Dynamic Class</td><td>//button[starts-with(@class,'btn-')]</td></tr>

<tr><td>Dynamic Href</td><td>//a[starts-with(@href,'/products/')]</td></tr>

<tr><td>Text Prefix</td><td>//button[starts-with(normalize-space(.),'Login')]</td></tr>

<tr><td>Placeholder Prefix</td><td>//input[starts-with(@placeholder,'Enter')]</td></tr>

<tr><td>ARIA Label Prefix</td><td>//button[starts-with(@aria-label,'Search')]</td></tr>

<tr><td>Data Attribute Prefix</td><td>//button[starts-with(@data-testid,'login-')]</td></tr>

<tr><td>Multiple Conditions</td><td>//input[starts-with(@id,'user_') and @type='text']</td></tr>

</table>

<hr>

<h2>90. Important XPath Patterns</h2>

<pre><code>//input[starts-with(@id,'user_')]

//button[starts-with(@id,'login_')]

//a[starts-with(@href,'/products/')]

//input[starts-with(@name,'email_')]

//button[starts-with(normalize-space(.),'Login')]

//div[starts-with(normalize-space(.),'Order')]

//input[starts-with(@placeholder,'Enter')]

//button[starts-with(@aria-label,'Search')]

//tr[starts-with(@id,'row_')]

//option[starts-with(normalize-space(.),'India')]</code></pre>

<hr>

<h2>91. Interview Questions</h2>

<h3>Q1. What is starts-with() in XPath?</h3>

<p>starts-with() is an XPath string function used to check whether a string begins with a specified value. In Selenium, it is commonly used to locate elements with dynamic attributes or text.</p>

<h3>Q2. What is the syntax of starts-with()?</h3>

<pre><code>starts-with(string, substring)</code></pre>

<h3>Q3. How do you locate an element with a dynamic ID?</h3>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<h3>Q4. Can starts-with() be used with text?</h3>

<p>Yes. For example:</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<h3>Q5. What is the difference between starts-with() and contains()?</h3>

<p>starts-with() checks the beginning of a string, whereas contains() checks whether a value occurs anywhere in the string.</p>

<h3>Q6. Is starts-with() case-sensitive?</h3>

<p>Yes. XPath string matching is case-sensitive unless functions such as translate() are used to normalize the case.</p>

<h3>Q7. Can starts-with() be combined with AND?</h3>

<p>Yes.</p>

<pre><code>//input[starts-with(@id,'user_') and @type='text']</code></pre>

<h3>Q8. Can starts-with() be used with attributes other than ID?</h3>

<p>Yes. It can be applied to attributes such as name, class, href, placeholder, aria-label, data-testid, and other attributes.</p>

<h3>Q9. Can starts-with() be used with normalize-space()?</h3>

<p>Yes. A common text-based expression is:</p>

<pre><code>//button[starts-with(normalize-space(.),'Login')]</code></pre>

<h3>Q10. How can you test starts-with() XPath in Chrome?</h3>

<p>Use the browser console:</p>

<pre><code>$x("//input[starts-with(@id,'user_')]")</code></pre>

<hr>

<h2>92. Interview Scenario</h2>

<p><strong>Question:</strong> A username field has IDs such as <strong>username_123</strong>, <strong>username_456</strong>, and <strong>username_789</strong>. How would you locate it?</p>

<p><strong>Answer:</strong></p>

<pre><code>//input[starts-with(@id,'username_')]</code></pre>

<p>If multiple elements match, add another stable condition such as the element type, placeholder, form relationship, or another reliable attribute.</p>

<hr>

<h2>93. Learning Checklist</h2>

<ul>

<li>Understand what starts-with() means.</li>

<li>Learn the starts-with() syntax.</li>

<li>Practice starts-with() with ID.</li>

<li>Practice starts-with() with name.</li>

<li>Practice starts-with() with class.</li>

<li>Practice starts-with() with href.</li>

<li>Practice starts-with() with placeholder.</li>

<li>Practice starts-with() with text.</li>

<li>Understand normalize-space().</li>

<li>Understand the difference between text() and dot.</li>

<li>Combine starts-with() with AND.</li>

<li>Combine starts-with() with OR.</li>

<li>Use starts-with() with XPath axes.</li>

<li>Test XPath using Chrome DevTools.</li>

<li>Use starts-with() with Selenium Java.</li>

<li>Use starts-with() with explicit waits.</li>

<li>Apply starts-with() in Page Object Model.</li>

<li>Understand its limitations.</li>

<li>Avoid unnecessary indexes.</li>

<li>Verify locator uniqueness.</li>

</ul>

<hr>

<h2>94. Key Points to Remember</h2>

<ul>

<li><strong>starts-with()</strong> checks whether a string begins with a specified value.</li>

<li>It is especially useful for dynamic web elements.</li>

<li>It can be used with attributes and text.</li>

<li>It is useful when the beginning of an attribute remains stable.</li>

<li>It is case-sensitive.</li>

<li>normalize-space() can improve text-based matching.</li>

<li>The dot operator can help when text is contained inside child elements.</li>

<li>AND and OR can be used to create more precise conditions.</li>

<li>Always verify whether the XPath returns a unique element.</li>

<li>Prefer stable and meaningful locator strategies.</li>

</ul>

<hr>

<h2>95. Selenium Training Resource</h2>

<p>To continue learning Selenium WebDriver, locators, WebElements, TestNG, Page Object Model, automation frameworks, and real-world automation projects, explore the <a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">JustAcademy Selenium Training Course</a>.</p>

<p>You can also explore the <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Selenium Training Demo Registration</a> for the course.</p>

<hr>

<h2>96. Conclusion</h2>

<p>The <strong>starts-with()</strong> XPath function is an important technique for Selenium automation when web elements contain dynamic values but have a predictable beginning. It is particularly useful for dynamic IDs, names, URLs, placeholders, accessibility attributes, data attributes, and text patterns.</p>

<p>A strong Selenium automation tester should understand when to use starts-with(), when to use contains(), when exact attribute matching is better, and how to combine XPath functions with relationships and other conditions. With proper validation and stable locator design, starts-with() can be a useful part of maintainable Selenium automation scripts.</p>

<p>For structured Selenium learning covering WebDriver, locators, TestNG, POM, automation frameworks, cross-browser testing, and real-time projects, visit <a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">Selenium Training</a> or register for the <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Selenium Course Demo</a>.</p>

</div>

Previous Next
whatsapp