在js中制作一组自定义的定义链接方法
Making a custom group of defined chaining methods in js
问题是一般的js编程问题,不过我会以nightwatch.js为例来详细说明我的问题。
NightWatch JS 为其浏览器组件提供了多种链接方法,例如:-
browser
.setValue('input[name='email']','example@mail.com')
.setValue('input[name='password']', '123456')
.click('#submitButton')
但是,如果我正在为 select 下拉菜单中的一个选项编写方法,它需要多个步骤,并且如果表单中有多个下拉菜单,它会变得非常混乱,例如:-
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')
或者有没有其他方法可以解决我的问题,提高代码的可重用性和可读性?
这是使用 Proxy
的好地方。给定一些 class:
function Apple ()
{
this.eat = function ()
{
console.log("I was eaten!");
return this;
}
this.nomnom = function ()
{
console.log("Nom nom!");
return this;
}
}
和一组"extension methods":
const appleExtensions =
{
eatAndNomnom ()
{
this.eat().nomnom();
return this;
}
}
我们可以创建函数,其中 returns Proxy
到 select 哪些属性是从扩展对象中检索的,哪些是从原始对象中检索的:
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!"
当然,这需要您在任何想创建新的 Apple
时调用 makeExtendedTarget
。但是,我认为这是一个加号,因为它非常清楚地表明您创建了一个 扩展 对象,并且期望能够调用通常在 class 上不可用的方法] API.
当然,您是否应该这样做是完全不同的讨论!
我对 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);
您还可以将您的国家/州/城市设置为全局文件中的变量,并将它们设置为对所有内容都相同,但我不知道您想要多细化。
希望说得通:)
问题是一般的js编程问题,不过我会以nightwatch.js为例来详细说明我的问题。
NightWatch JS 为其浏览器组件提供了多种链接方法,例如:-
browser
.setValue('input[name='email']','example@mail.com')
.setValue('input[name='password']', '123456')
.click('#submitButton')
但是,如果我正在为 select 下拉菜单中的一个选项编写方法,它需要多个步骤,并且如果表单中有多个下拉菜单,它会变得非常混乱,例如:-
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')
或者有没有其他方法可以解决我的问题,提高代码的可重用性和可读性?
这是使用 Proxy
的好地方。给定一些 class:
function Apple ()
{
this.eat = function ()
{
console.log("I was eaten!");
return this;
}
this.nomnom = function ()
{
console.log("Nom nom!");
return this;
}
}
和一组"extension methods":
const appleExtensions =
{
eatAndNomnom ()
{
this.eat().nomnom();
return this;
}
}
我们可以创建函数,其中 returns Proxy
到 select 哪些属性是从扩展对象中检索的,哪些是从原始对象中检索的:
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!"
当然,这需要您在任何想创建新的 Apple
时调用 makeExtendedTarget
。但是,我认为这是一个加号,因为它非常清楚地表明您创建了一个 扩展 对象,并且期望能够调用通常在 class 上不可用的方法] API.
当然,您是否应该这样做是完全不同的讨论!
我对 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);
您还可以将您的国家/州/城市设置为全局文件中的变量,并将它们设置为对所有内容都相同,但我不知道您想要多细化。
希望说得通:)