1

该问题与一般的 js 编程有关,但我将使用 nightwatch.js 作为示例来详细说明我的查询。

NightWatch JS 为其浏览器组件提供了各种链接方法,例如:-

 browser
    .setValue('input[name='email']','example@mail.com')
    .setValue('input[name='password']', '123456')
    .click('#submitButton')

但是,如果我正在编写从下拉列表中选择选项的方法,则需要多个步骤,并且如果表单中有多个下拉列表,它会变得非常混乱,例如:-

 browser
    .click(`#country`)
    .waitForElementVisible(`#india`)
    .click(`#india`)
    .click(`#state`)
    .waitForElementVisible(`#delhi`)
    .click(`#delhi`)

是否可以创建自定义链接方法来对这些已定义的方法进行分组?例如:

/* custom method */
const dropdownSelector = (id, value) {
    return this
        .click(`${id}`).
        .waitForElementVisible(`${value}`)
        .click(`${value}`)
} 

/* So it can be used as a chaining method */
browser
    .dropdownSelector('country', 'india')
    .dropdownSelector('state', 'delhi')

或者有没有其他方法可以解决我增加代码的可重用性和可读性的问题?

4

2 回答 2

0

我对 JS 有点陌生,所以无法告诉你一个理想的代码解决方案,不得不承认我不知道在这种情况下代理是什么。但是在 Nightwatch 和测试自动化的世界中,我通常会将我计划重用的多个步骤包装到页面对象中。在 pageObject 文件夹中创建一个新文件,并用您要重用的方法填充它

所以你的测试...

browser
.click(`#country`)
.waitForElementVisible(`#india`)
.click(`#india`)
.click(`#state`)
.waitForElementVisible(`#delhi`)
.click(`#delhi`)

成为另一个名为“myObject”的文件中的页面对象方法,例如...

selectLocation(browser, country, state, city) {
  browser
    .click(`#country`) <== assume this never changes?
    .waitForElementVisible(country)
    .click(country)
    .click(state)
    .waitForElementVisible(city)
    .click(city);
}

然后您的每个测试都继承该方法并自己定义这些值,但是您选择管理它...

const myObject = require ('<path to the new pageObject file>')

module.exports = {
  'someTest': function (browser) {
    const country = 'something' 
    const state = 'something'
    const city = 'something'

    myObject.selectLocation(browser);

您还可以将您的国家/州/城市设置为全局文件中的变量,并将它们设置为对所有内容都相同,但我不知道您想要多细化。

希望这有点道理:)

于 2019-09-03T14:26:54.727 回答
0

这是使用Proxy. 给定一些课程:

function Apple () 
{
  this.eat = function () 
  {
    console.log("I was eaten!");
    return this;
  }

  this.nomnom = function () 
  {
    console.log("Nom nom!");
    return this;
  }
}

以及一组“扩展方法”:

const appleExtensions = 
{
  eatAndNomnom () 
  {
    this.eat().nomnom();
    return this;
  }
}

我们可以创建一个函数,它返回 aProxy来选择从扩展对象中检索哪些属性以及从原始对象中检索哪些属性:

function makeExtendedTarget(target, extensions) 
{
  return new Proxy(target, 
  {
    get (obj, prop) 
    {
      if (prop in extensions)
      {
        return extensions[prop];
      }

      return obj[prop];
    }
  });
}

我们可以像这样使用它:

let apple = makeExtendedTarget(new Apple(), appleExtensions);
apple
  .eatAndNomnom()
  .eat();
// => "I was eaten!"
//    "Nom nom!"
//    "I was eaten!"

当然,这需要您makeExtendedTarget在想要创建新的Apple. 但是,我认为这是一个加分项,因为它非常清楚您创建了一个扩展对象,并且期望能够调用类 API 上通常不可用的方法。

当然,你是否应该这样做是一个完全不同的讨论!

于 2019-09-01T16:42:28.147 回答