HTML tag attributes, USE THEM!
Tags: qa, webdev, automation, html
Published: 2024-04-19 19:06:21

Repeatability in most applications that I test is mostly overlooked, misunderstood, or incorrectly implemented. I would like to cover a specific aspect of repeatability for automated tests in web applications and how making some small additions can speed up testing, increase the quality of your tests immensely, and make your QA engineer very happy. 


Let's run through a common problem where a lack of detail can slow testing down and make brittle tests:


Code Snippet:
`
<span class="ant-input-affix-wrapper ant-input css-amq5gd">. 
  <input placeholder="Hit Enter for search" class="ant-input css-amq5gd" type="text" value="">
    <span class="ant-input-suffix">
      <span class="ant-input-clear-icon ant-input-clear-icon-hidden" role="button" tabindex="-1">
      </span>
  </span>
</span>
`

The details:
- This code is for an input element.
- It will trigger a search through a table of records filtering results.
- The input is nested inside a `<span>` that controls functionality of the search. 
- We have a clear button that will remove the text if there is any present.

The issues:
- There is no ID attribute on the `<input>` tag. 
- There is no ID on the clear `<span>`
- The placeholder text is not consistently capitalized.

---

When writing an automated test how do you hook into this element?
For Selenium we have the following ways to find an element on a page: 



    ID = "id"
    XPATH = "xpath"
    LINK_TEXT = "link text"
    PARTIAL_LINK_TEXT = "partial link text"
    NAME = "name"
    TAG_NAME = "tag name"
    CLASS_NAME = "class name"
    CSS_SELECTOR = "css selector"

Out of our options there are only two that we can really use to find the search element, XPATH or CSS_SELECTOR because we don't have an ID. Ignore the other selectors.

So, what would a query look like to find that element?

XPATH:
    `//input[@placeholder="Hit Enter for search" and @type="text"]`

CSS_SELECTOR:
    `input[placeholder="Hit Enter for search"]`

What is the problem here? 

When we decide to change the placeholder text this test will fail. We could change the relative query for the class because we know there is only one input tag below the span which would look like this: 

    `driver.find_element(By.XPATH, '//span[@class="ant-input-affix-wrapper ant-input css-amq5gd"]//input')` 


    `driver.find_element` is the class method within selenium webdriver to find an element on a webpage.

If the styling changes, well then, the test will break again because that class is generated dynamically by the JS framework.

Another approach could be to only look for part of the span's class which would look like this:

    `driver.find_element(By.XPATH, '//span[contains(@class, 'ant-input-affix-wrapper')]//input')`

Then again if there is another input on the page this will break so we still have to add the placeholder text on the input:

    `driver.find_element(By.XPATH, '//span[contains(@class, 'ant-input-affix-wrapper')]//input[@placeholder="Hit Enter for search"]')`

With all this workaround querying the most impactful thing we could do is to go into the frontend and update the input element with an ID so the query could be simplified to:

    `driver.find_element(By.ID, "searchInputForTable")`

---

Attributes are a very powerful and underutilized aspect of Hypermedia that has gotten lost in the bloated ecosystem of frontend development where devs rely more on the JS framework to generate code for them rather than understand what really happens when a project is compiled. I am also guilty of this so...


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qor2e7unmt2koc0uryjg.png)

But in all seriousness the ability to create custom JS components is fantastic at speeding up your development but the benefit of speed is usually at the cost of quality. Spending the time to add information about the component you are generating can have a huge timesaving effect down the line.