【问题标题】:How can I check until an element is clickable using nightwatchjs?如何使用 nightwatchjs 检查元素是否可点击?
【发布时间】:2016-07-04 14:31:25
【问题描述】:

如何使用 nightwatch js 检查元素是否可点击?我想点击一个元素,但是当我运行 nightwatch 时,selenium 没有点击该元素,因为它还不能点击。

【问题讨论】:

  • 可点击是什么意思?元素是否被禁用?隐藏了吗?
  • 我想看一个相当于waitUntilElementIsEnabled() 的例子。 Selenium 中有一个助手,它在返回 true 之前结合了对 isEnabled 的检查和对 isVisible 的检查。

标签: nightwatch.js


【解决方案1】:

这样的事情应该可以工作。如果您有任何问题,请告诉我

var util = require('util');
var events = require('events');

/*
 * This custom command allows us to locate an HTML element on the page and then wait until the element is both visible
 * and does not have a "disabled" state.  It rechecks the element state every 500ms until either it evaluates to true or
 * it reaches maxTimeInMilliseconds (which fails the test). Nightwatch uses the Node.js EventEmitter pattern to handle 
 * asynchronous code so this command is also an EventEmitter.
 */

function WaitUntilElementIsClickable() {
  events.EventEmitter.call(this);
  this.startTimeInMilliseconds = null;
}

util.inherits(WaitUntilElementIsClickable, events.EventEmitter);

WaitUntilElementIsClickable.prototype.command = function (element, timeoutInMilliseconds) {
  this.startTimeInMilliseconds = new Date().getTime();
  var self = this;
  var message;

  if (typeof timeoutInMilliseconds !== 'number') {
    timeoutInMilliseconds = this.api.globals.waitForConditionTimeout;
  }

  this.check(element, function (result, loadedTimeInMilliseconds) {
    if (result) {
      message = '@' + element + ' was clickable after ' + (loadedTimeInMilliseconds - self.startTimeInMilliseconds) + ' ms.';
    } else {
      message = '@' + element + ' was still not clickable after ' + timeoutInMilliseconds + ' ms.';
    }
    self.client.assertion(result, 'not visible or disabled', 'visible and not disabled', message, true);
    self.emit('complete');
  }, timeoutInMilliseconds);

  return this;
};

WaitUntilElementIsClickable.prototype.check = function (element, callback, maxTimeInMilliseconds) {
  var self = this;

  var promises =[];
  promises.push(new Promise(function(resolve) {
    self.api.isVisible(element, function(result) {
      resolve(result.status === 0 && result.value === true);
    });
  }));

  promises.push(new Promise(function(resolve) {
    self.api.getAttribute(element, 'disabled', function (result) {
      resolve(result.status === 0 && result.value === null);
    });
  }));

  Promise.all(promises)
    .then(function(results) {
      var now = new Date().getTime();
      const visibleAndNotDisabled = !!results[0] && !!results[1];
      if (visibleAndNotDisabled) {
        callback(true, now);
      } else if (now - self.startTimeInMilliseconds < maxTimeInMilliseconds) {
        setTimeout(function () {
          self.check(element, callback, maxTimeInMilliseconds);
        }, 500);
      } else {
        callback(false);
      }
    })
    .catch(function(error) {
      setTimeout(function () {
        self.check(element, callback, maxTimeInMilliseconds);
      }, 500);
    });
};

module.exports = WaitUntilElementIsClickable;

将此代码作为文件添加到您的命令文件夹中。它应该被称为 waitUntilElementIsClickable.js 或任何你想要你的命令的东西。

用法是:

browser.waitUntilElementIsClickable('.some.css');

你也可以使用页面元素:

var page = browser.page.somePage();
page.waitUntilElementIsClickable('@someElement');

【讨论】:

  • 嘿,我在尝试你的代码,但它给出了语法错误waitForElementClickable.js:57 .then((results) =&gt; { ^^ SyntaxError: Unexpected token =&gt; 你能帮帮我吗?
  • 啊,代码部分是用 ES6 格式编写的,我更新了它应该可以使用纯 ES5
  • 我尝试使用您的函数,但夜间值守返回,因为 waitUntilElementsIsClickable 不是函数。为什么会出现这个错误?
【解决方案2】:

您可以将waitForElementVisible():enabled CSS 伪类结合使用。

例如,以下将等待最多 10 秒以使 #element 启用,然后单击它(请注意,如果该元素在 10 秒后未启用,则测试将失败):

browser
  .waitForElementVisible('#element:enabled', 10000)
  .click('#element');

【讨论】:

  • 这应该是最佳答案。当此功能已经存在时,无需编写自定义命令
【解决方案3】:

你能否展示一个示例元素,如果按钮不可点击,通常应该有一个属性名称“禁用”,这应该可以。

browser.assert.attributeEquals(yourCSS, 'disabled', true)

【讨论】:

  • 我想看一个相当于waitUntilElementIsEnabled()的例子。 Selenium 中有一个助手,它在返回 true 之前结合了对 isEnabled 的检查和对 isVisible 的检查。
【解决方案4】:

我无法发表评论,但 Alex R 建议的代码存在一些问题。

首先,该代码不适用于 Firefox,因为 geckodriver 不返回“状态”。所以这个:

resolve(result.status === 0 && result.value === true)

需要改成这样:

resolve(result.value === true).

二、行:

self.client.assertion(result, 'not visible or disabled', 'visible and not disabled', message, true);

不起作用,需要注释掉 为了让代码运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 2016-11-14
    • 1970-01-01
    相关资源
    最近更新 更多