在页面对象api和主要的守夜人api之间切换

时间:2017-08-29 18:00:40

标签: javascript selenium-webdriver nightwatch.js

我正在使用带有夜视仪的页面对象模型进行测试。难以与元素交互,因此被迫执行一些jquery。 Execute不是页面对象api中可用的命令子集的一部分,因此为了使用它,我必须调用完整的nightwatch命令api。 (关于https://github.com/nightwatchjs/nightwatch/wiki/Page-Object-API的更多相关信息)我的问题是如何在执行语句后返回页面对象api。

我的页面对象是这样的:

elements: {
  nameInput: 'input[name="name"]',
  billingEmail: 'input[name="billingEmail"]',
  licenseNumber: 'input[name="licenses.total"]',
  licensePrice: 'input[name="subscription.price"]',
  hardwareModel: 'input[name="model"]',
  hardwareQuantity: 'input[name="quantity"]',
  hardwarePrice: 'input[name="price"]',
  customerEmail: 'input[name="customerEmail"]',
  createButton: 'button[name="createAccount"]',
  cancelButton: 'button[name="cancel"]',
},


inputClientDetails (name, email) {
    this
      .waitForElementVisible('body', 10000)
      .setValue('@nameInput', name)
      .setValue('@billingEmail', email)
      .setValue('@licenseNumber', '10')
      .setValue('@licensePrice', '9.99')
      .api.execute(function () {
          $('.datepicker--wrapper').find('input[type=text]').val('2017-08-30').trigger($.Event("keydown", {keyCode: 40}));
      })
      .setValue('@hardwareModel', 'Test model')
      .setValue('@hardwarePrice', '9.99')
      .setValue('@hardwareQuantity', '10')
      .setValue('@customerEmail', email)
      .click('@createButton')
    return this.api;
},

当我运行测试时,我收到错误: 错误:无法找到元素:" @ hardwareModel"使用:css选择器

当我在页面对象中没有执行语句时,没有问题。那么在访问主要的守夜人api后可以返回页面对象api吗?我尝试在函数中添加一个return语句但是没有用。

2 个答案:

答案 0 :(得分:2)

致电.api.whatever()后,  您通过链接调用的函数也使用.api(这是浏览器)。

更好的方法是将您的功能分成两部分,而不是将整个事物链接起来。

inputClientDetails (name, email) {
var client=this.api;
this
  .waitForElementVisible('body', 10000)
  .setValue('@nameInput', name)
  .setValue('@billingEmail', email)
  .setValue('@licenseNumber', '10')
  .setValue('@licensePrice', '9.99')
//now use client-browser
client.execute(function () {
      $('.datepicker--wrapper').find('input[type=text]').val('2017-08-30').trigger($.Event("keydown", {keyCode: 40}));
  })
//Now back to page object
this.setValue('@hardwareModel', 'Test model')
  .setValue('@hardwarePrice', '9.99')
  .setValue('@hardwareQuantity', '10')
  .setValue('@customerEmail', email)
  .click('@createButton')
return this.api;
//either this.api or this doesn't matter, but this.api if you still have other chained function based on browser.
}

答案 1 :(得分:1)

此问题有两种选择:

第一名:api将返回this.api而不是this页面对象,因此我们只能通过page

来调用此页面对象
inputClientDetails (name, email) {
this
  .waitForElementVisible('body', 10000)
  .setValue('@nameInput', name)
  .setValue('@billingEmail', email)
  .setValue('@licenseNumber', '10')
  .setValue('@licensePrice', '9.99')
  .api.execute(function () {
      $('.datepicker--wrapper').find('input[type=text]').val('2017-08-30').trigger($.Event("keydown", {keyCode: 40}));
  })
  .page.yourPage().setValue('@hardwareModel', 'Test model') 
  .page.yourPage().setValue('@hardwarePrice', '9.99')
  .page.yourPage().setValue('@hardwareQuantity', '10')
  .page.yourPage().setValue('@customerEmail', email)
  .page.yourPage().click('@createButton')
return this.api;

},

第二:你可以分割你的功能,较小的功能应该返回this页面对象而不是this.api

inputClientDetails (name, email) {
    this
      .waitForElementVisible('body', 10000)
      .setValue('@nameInput', name)
      .setValue('@billingEmail', email)
      .setValue('@licenseNumber', '10')
      .setValue('@licensePrice', '9.99')
      .callExecute()
      .setValue('@hardwareModel', 'Test model')
      .setValue('@hardwarePrice', '9.99')
      .setValue('@hardwareQuantity', '10')
      .setValue('@customerEmail', email)
      .click('@createButton')
    return this.api;
},

callExecute(){
      this.api.execute(function () {
          $('.datepicker--wrapper').find('input[type=text]').val('2017-08-30').trigger($.Event("keydown", {keyCode: 40}));
      });
     return this;
}