How can I send a value to an input class that has the same name as 2 other classes?

Liviu Avram :

I'm a beginner in terms of automation testing (please forgive me if my attempts are bad, I tried to google and went through a bunch of things that seemed to make sense for me), and I have a project that has a react/redux front end. I am using webdriver.io for automation because other solutions such as testcafe or cypress didn't work with our authorization flow.

The front end is messy, it doesn't have IDs yet and classes have identical names for multiple things, but I create a feature request for that.

In the meantime, what I want to do is send values to 3 different fields. Here are the elements form the Chrome elements tab:

<div class="user-settings">
<div class="table">
    <div class="row">
        <div class="cell">
            <label class="textfield-with-label textfield-with-label--full-width"><span class="textfield-label">Phone</span>
                <input type="text" class="textfield textfield--valid-value textfield--raised textfield--full-width" value="">
            </label>
        </div>
    </div>
    <div class="row">
        <div class="cell">
            <label class="textfield-with-label textfield-with-label--full-width"><span class="textfield-label">Agent identifier</span>
                <input type="text" class="textfield textfield--valid-value textfield--raised textfield--full-width" value="">
            </label>
        </div>
    </div>
    <div class="row">
        <div class="cell">
            <label class="textfield-with-label textfield-with-label--full-width"><span class="textfield-label">Password</span>
                <input type="password" class="textfield textfield--valid-value textfield--raised textfield--full-width" value="">
            </label>
        </div>
    </div>
    <div class="row">
        <div class="cell">
            <label class="checkboxfield-with-label"><span class="checkboxfield-label">Receive voice calls</span>
                <input type="checkbox" class="checkboxfield">
            </label>
        </div>
    </div>
    <div class="row">
        <div class="update-action">
            <div class="update-button">
                <button type="text" class="action-button action-button--icon action-button--text action-button--settings action-button--tick" title="Update"><i class="icon-wrapper icon-tick" aria-hidden="true"><svg focusable="false" role="img" viewBox="0 0 48 48"><use xlink:href="#icon-tick"></use></svg></i><span class="action-button__text">Update</span></button>
            </div>
        </div>
    </div>
</div>

I want to send values for "Phone", "Agent Identifier", "Password" but I will probably struggle with other elements on this tab (Receive voice and Update button) as well.

If I try:

const Extension = $('input.textfield textfield--valid-value.textfield--raised.textfield--full-width');
Extension.setValue('value');

This works, but just for the first field, probably because it's the first element. For the second and 3rd it will not work, how can achieve the same thing, but for all 3 elements?

I also tried this for the first 2 elements because I thought it could work:

const AgentID = $("span.textfield-label='Agent identifier'");
AgentID.setValue('value2');

But this doesn't make much sense to me and it doesn't work. I am struggling to understand these selectors and having no IDs or somewhat unique class names surely doesn't help.

Miaplacidus :

Whomever wrote the form HTML left you at a significant disadvantage. Adequately ID-ing form inputs should be a primary consideration of the author. If you are in a position where you are performing QA testing and do not have the ability to modify the code yourself, you will have to harness JS to get the elements. However, you do not appear to have all the JS coding skills needed to do so.

Based on what you provided as an example approach, you can try this:

Plain HTML/JS
JSFiddle Example

const parentElements = Array.from(document.querySelectorAll('.textfield-with-label'))

const formUI = parentElements
.reduce((_formUI, parentElement) => {
  let spanText = parentElement.querySelector('span').innerHTML
  switch(spanText) {
    case 'Agent identifier': 
      _formUI.agentID = parentElement.querySelector('input')
      break
    case 'Phone':
      _formUI.phone = parentElement.querySelector('input')
      break
    case 'Password':
      _formUI.password = parentElement.querySelector('input')
      break
  }
  return _formUI
}, {
  phone: null,
  agentID: null,
  password: null,
})

jQuery
jsFiddle Example

const $parentElements = Array.from($('.textfield-with-label'))

const formUI = $parentElements
.reduce((_formUI, parentElement) => {
  let $parentElement = $(parentElement)
  let spanText = $(parentElement).find('span').text()
  switch(spanText) {
    case 'Agent identifier': 
      _formUI.agentID = $parentElement.find('input')
      break
    case 'Phone':
      _formUI.phone = $parentElement.find('input')
      break
    case 'Password':
      _formUI.password = $parentElement.find('input')
      break
  }
  return _formUI
}, {
  phone: null,
  agentID: null,
  password: null,
})

From here you get/set the input values. This could probably be refactors, but for QA testing it should work fine. Obviously the larger issue here is that you have to communicate to the developer that they need to follow a different practice when generating forms.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=29887&siteId=1