【问题标题】:Nightwatch: Using of custom commands inside page objectsNightwatch:在页面对象中使用自定义命令
【发布时间】:2021-03-15 10:26:44
【问题描述】:

对于产品的新版本,我决定尝试使用页面对象方法而不是使用视图,但可能我开始使用错误。

我们有一个自定义命令,它只是等待一个元素并点击(waitAndClick.js):

exports.command = function(selector, callback) {
  return this
    .waitForElementPresent(selector, 30000)
    .click(selector, callback);
};

它在测试中完美运行:

const {client} = require('nightwatch-cucumber');
const {defineSupportCode} = require('cucumber');

defineSupportCode(({Given, Then, When}) => {
    Given(/^I enable Dashboard management$/, () => {
        return client.waitAndClick('[id=enableManagement]');
    });
});

但是当我试图在页面对象中使用它时,它会抛出一个错误:

module.exports = {
  url() {
    return this.api.launchUrl;
  },
  elements: {
    username: '[name="_Nitro_Login_username"]',
    password: '[name="_Nitro_Login_password"]',
    enter_button: '[title="Enter"]'
  },
  commands: [
    {
      loginAs(username, password) {
        return this.waitForElementVisible('@username', 50000)
          .setValue('@username', username)
          .setValue('@password', password)
          .waitAndClick('@enter_button')
          .waitForElementNotPresent('@enter_button', 50000);
      }
    }
  ]
};

我也试过 .api.waitAndClick('@enter_button'),结果一样。

以及错误信息:

运行点击命令时出错:提供的定位策略不是 支持:[title="enter"]。它必须是以下之一:

类名、css选择器、id、名称、链接文本、部分链接文本、标签 名称,xpath

at Object.exports.command (/Users/eaflor/dev/jive-next/test/ui/commands/waitAndClick.js:9:63)

at Object.F.command (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/api.js:274:31)

at Object.commandFn (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/api.js:287:24)

at AsyncTree.runCommand (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/queue.js:154:30)

at AsyncTree.runChildNode (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/queue.js:114:8)

at AsyncTree.walkDown (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/queue.js:80:10)

at AsyncTree.walkUp (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/queue.js:97:8)

at AsyncTree.walkDown (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/queue.js:90:12)

at AsyncTree.traverse (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/queue.js:73:8)

at F.onCommandComplete (/Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/core/queue.js:131:12)

at F.g (events.js:291:16)

at emitNone (events.js:86:13)

at F.emit (events.js:185:7)

at /Users/eaflor/dev/jive-next/node_modules/nightwatch/lib/api/client-commands/_locateStrategy.js:18:10

at _combinedTickCallback (internal/process/next_tick.js:67:7)

at process._tickCallback (internal/process/next_tick.js:98:9)

甚至可以在页面对象中使用自定义命令吗?

【问题讨论】:

    标签: javascript selenium nightwatch.js


    【解决方案1】:

    我找到了修复它的方法。为了在页面对象中使用自定义命令,您必须以类样式编写它们:http://nightwatchjs.org/guide#writing-custom-commands

    它应该是这样的:

    var util = require('util');
    var events = require('events');
    
    function waitAndClick() {
        events.EventEmitter.call(this);
    }
    
    util.inherits(waitAndClick, events.EventEmitter);
    
    waitAndClick.prototype.command = function(selector) {
        const api = this.client.api;
    
        api
                .waitForElementPresent(selector)
                .click(selector, () => {
                    this.emit('complete');
                })
        ;
    
        return this;
    };
    
    module.exports = waitAndClick;
    

    希望对某人有所帮助。

    【讨论】:

    • 谢谢 - 只是出于兴趣 - 如果在 pageObject 命令中使用此自定义命令,我们是返回调用此方法的 pageObject 还是 Nightwatch API 的实例?
    • @GrayedFox 从页面对象调用时,返回页面对象。当从页面对象部分调用时,将返回该部分。另请参阅github.com/nightwatchjs/nightwatch/wiki/… 上的“链接”。
    【解决方案2】:

    我还是 Nightwatch 的新手,但我在页面对象中使用如下命令:

    commands: [
        {
            login: function() {
                this.api
                    .waitForElementVisible('body', 2000)
                    .setValue(this.elements.username.selector, user.loginUser) //here I'm inputting username from json file into element that I've defined in this page object
                    .setValue(this.elements.password.selector, pass.loginPass) //here I did same thing with password
                    .pause(500)
                    .click(this.elements.submitButton.selector) //here I'm clicking on predefined button element               
            }
        }
    ]
    

    完美运行,可读性强。这是简单的登录命令。希望这会有所帮助。

    干杯

    【讨论】:

      【解决方案3】:

      在这里回答为时已晚,但可能会帮助其他面临类似问题的人。返回this 可以解决页面对象的链接问题。

      exports.command = function(selector, callback) {
        this
          .waitForElementPresent(selector, 30000)
          .click(selector, callback);
        return this;
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多