【问题标题】:How can I send a value to an input class that has the same name as 2 other classes?如何将值发送到与其他 2 个类同名的输入类?
【发布时间】:2020-03-06 14:16:26
【问题描述】:

我是自动化测试方面的初学者(如果我的尝试不好,请原谅我,我尝试 google 并经历了一堆对我来说似乎有意义的事情),我有一个项目一个反应/redux 前端。我正在使用 webdriver.io 进行自动化,因为其他解决方案(例如 testcafe 或 cypress)不适用于我们的授权流程。

前端很乱,它还没有 ID,并且类对于多个事物具有相同的名称,但我为此创建了一个功能请求。

与此同时,我想做的是将值发送到 3 个不同的字段。 以下是 Chrome 元素选项卡中的元素:

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

我想发送“电话”、“代理标识符”、“密码”的值,但我可能也会在此选项卡上的其他元素(接收语音和更新按钮)上遇到困难。

如果我尝试:

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

这可行,但仅适用于第一个字段,可能是因为它是第一个元素。对于第二个和第三个它不起作用,如何实现相同的事情,但对于所有 3 个元素?

我也尝试了前两个元素,因为我认为它可以工作:

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

但这对我来说没有多大意义,也不起作用。我很难理解这些选择器,没有 ID 或有些独特的类名肯定无济于事。

【问题讨论】:

  • 仅供参考,类名意味着可以重复使用多次。事实上,如果一个类名在应用程序中是唯一的,那就是一个危险信号。应为此目的使用 ID。在添加 ID 之前启动自动化可能为时过早?
  • 我同意现在还为时过早,但有人要求我开始做。我在这个 sprint 中大约有 1 周的时间无事可做。这可能是一次很好的(而且看起来很痛苦)的学习经历。
  • 我的意思是,你可以使用类似$("span.textfield-label").filter(el =&gt; el.textContent == 'Agent identifier'); 我猜?
  • 这不起作用,''(...).filter is not a function"。这可能是一个误导性错误,问题是它找不到那个选择器,我'在之前的测试中看到过,它有几乎相同的类,唯一的区别是它们有一个标题,所以我使用 longclassname[title='class title'] 并且它有效。但我做不到因为这些类没有标题。
  • 显然 webdriver 不是 jQuery :)。抱歉,我被 $() 语法误导了。

标签: javascript css automation webdriver-io


【解决方案1】:

无论谁编写了 HTML 表单,都让您处于极大的劣势。充分识别表单输入应该是作者的主要考虑因素。如果您处于执行 QA 测试的位置并且没有能力自己修改代码,那么您将不得不利用 JS 来获取元素。但是,您似乎并不具备这样做所需的所有 JS 编码技能。

根据您提供的示例方法,您可以尝试以下操作:

纯 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,
})

您可以从这里获取/设置输入值。这可能是重构,但对于 QA 测试,它应该可以正常工作。显然,这里更大的问题是您必须与开发人员沟通,他们在生成表单时需要遵循不同的做法。

【讨论】:

  • 我试过这个,但它不起作用,因为“文档未定义”。可能是因为 webdriver.io。你是绝对正确的,我提出了很多关于实践的问题,最近一个是缺少 ID,我会和产品负责人讨论优先考虑它,因为如果没有在一夜之间获得高级 JS 技能,我不会认为我可以在没有 ID 的情况下“完全自动化”产品。
  • @LiviuAvram 我添加了示例代码的 jQuery 版本。
【解决方案2】:

试试这个代码。

const extension = document.getElementsByClassName('textfield--valid-value ');

for (let i = 0; i < extension.length; i++) {
  extension[i].value = "value";
}

它将所有输入元素的值设置为'value'

【讨论】:

  • "文档未定义''。我认为 webdriver.io 不喜欢这种方法。
  • 哦,我看到你在使用 JS 库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 2022-06-17
相关资源
最近更新 更多