在自定义助手中处理断言
Handling assertions in a custom helper
我已经开始使用 CodeceptJs,而且我已经很容易地开始工作了。我目前正在将它与 NightmareJs 一起使用,一切似乎都很好。
我正在测试的特定区域是一个画廊,它通过 JSONP 从界面获取数据,创建一个包含在 <div>
s 中的图像列表。
我正在实施的部分测试如下所示:
Feature('gallery')
Scenario('clicking on an element adds "selected" class', (I) => {
I.amOnPage('/')
I.seeElement('#gallery .col-md-3')
I.click('#gallery .col-md-3')
I.seeElement('#gallery .selected')
})
现在因为元素可以是任意数字,它目前静默地使用第一个元素,但为了给它更多的熵,我想随机选择一个元素,如下所示
Scenario('clicking on an element adds "selected" class', (I) => {
I.amOnPage('/')
I.seeMoreThanElements('#gallery .col-md-3', 1)
I.clickOnRandomElement('#gallery .col-md-3')
I.seeElement('#gallery .selected')
})
或者更好,如果我可以获取元素列表,这样我就可以决定单击哪个元素,例如:
Scenario('clicking on an element adds "selected" class', (I) => {
I.amOnPage('/')
I.seeMoreThanElements('#gallery .col-md-3', 1)
const elements = I.grabRandomElement('#gallery .col-md-3')
const random = getRandomInt(1, elements.length)
I.click(`#gallery .col-md-3:nth-child(${random})`)
I.seeElement(`#gallery .col-md-3.selected:nth-child(${random})`)
})
当前可用的助手不允许我执行某些特定操作,因此我开始按照 http://codecept.io/helpers/
指南中所述实现自定义处理程序
在我的配置中,我有以下内容:
"helpers": {
"Nightmare": {
"url": "http://localhost:3000"
},
"DOMElements": {
"require": "./__tests__/helpers/domelements_helper.js"
}
}
和 domelements_helper.js
目前看起来如下所示:
'use strict'
let assert = require('assert')
class DOMElements extends Helper {
seeMoreThanElements (locator, count) {
this.helpers['Nightmare']._locate(locator).then(function (els) {
return assert(els.length >= count, `Found more than ${count} elements`)
})
}
}
module.exports = DOMElements
这显然行不通。这是我有点困惑的地方。
首先,我正在使用默认的 Node.js 断言库,如果有任何需要,我很乐意转向更强大的东西,如 Protractor 或 Chai-as-promised,但是越苗条越好。
其次,文档明确说明如下:
any helper method should return a value in order to be added to promise chain
这真的没有意义...我应该 return 一个承诺还是应该在 then()
声明中处理整个事情?作为 return 一个基本值并没有真正起到多大作用。即便如此,我该如何处理失败的断言?
我还在代码库中看到了 Nightmare 客户端脚本,但我不知道它是否对我的案例有用,因为我刚刚开始挖掘代码库以便更好地理解如何自定义和扩展 CodeceptJs。
非常感谢任何指点
由于似乎没有人能做到这一点,我将添加一个答案,因为我似乎已经通过浏览代码库找到了这个东西的工作原理,并且对它的工作原理有了更多的了解。
tl;dr: 快速解决方案如下:
/* __tests__/helpers/domelements_helper.js */
const assert = require('assert')
class DOMElements extends Helper {
seeMoreThanElements (locator, count) {
return this.helpers['Nightmare']._locate(locator)
.then((elementsArray) => {
if (elementsArray.length < count) {
return assert.fail(elementsArray.length, count, `Found more than ${count} elements`)
}
})
}
}
module.exports = DOMElements
整个事情的工作方式是通过承诺,你必须适当地处理失败,这样整个系统才能优雅地失败(大概)。
特别是 _locate()
returns 一个 promise 并且所有事情都必须异步处理,尽管从设计上讲这似乎很尴尬并且它使事情特别难以实现,至少在当前状态。
我已经开始使用 CodeceptJs,而且我已经很容易地开始工作了。我目前正在将它与 NightmareJs 一起使用,一切似乎都很好。
我正在测试的特定区域是一个画廊,它通过 JSONP 从界面获取数据,创建一个包含在 <div>
s 中的图像列表。
我正在实施的部分测试如下所示:
Feature('gallery')
Scenario('clicking on an element adds "selected" class', (I) => {
I.amOnPage('/')
I.seeElement('#gallery .col-md-3')
I.click('#gallery .col-md-3')
I.seeElement('#gallery .selected')
})
现在因为元素可以是任意数字,它目前静默地使用第一个元素,但为了给它更多的熵,我想随机选择一个元素,如下所示
Scenario('clicking on an element adds "selected" class', (I) => {
I.amOnPage('/')
I.seeMoreThanElements('#gallery .col-md-3', 1)
I.clickOnRandomElement('#gallery .col-md-3')
I.seeElement('#gallery .selected')
})
或者更好,如果我可以获取元素列表,这样我就可以决定单击哪个元素,例如:
Scenario('clicking on an element adds "selected" class', (I) => {
I.amOnPage('/')
I.seeMoreThanElements('#gallery .col-md-3', 1)
const elements = I.grabRandomElement('#gallery .col-md-3')
const random = getRandomInt(1, elements.length)
I.click(`#gallery .col-md-3:nth-child(${random})`)
I.seeElement(`#gallery .col-md-3.selected:nth-child(${random})`)
})
当前可用的助手不允许我执行某些特定操作,因此我开始按照 http://codecept.io/helpers/
指南中所述实现自定义处理程序在我的配置中,我有以下内容:
"helpers": {
"Nightmare": {
"url": "http://localhost:3000"
},
"DOMElements": {
"require": "./__tests__/helpers/domelements_helper.js"
}
}
和 domelements_helper.js
目前看起来如下所示:
'use strict'
let assert = require('assert')
class DOMElements extends Helper {
seeMoreThanElements (locator, count) {
this.helpers['Nightmare']._locate(locator).then(function (els) {
return assert(els.length >= count, `Found more than ${count} elements`)
})
}
}
module.exports = DOMElements
这显然行不通。这是我有点困惑的地方。
首先,我正在使用默认的 Node.js 断言库,如果有任何需要,我很乐意转向更强大的东西,如 Protractor 或 Chai-as-promised,但是越苗条越好。
其次,文档明确说明如下:
any helper method should return a value in order to be added to promise chain
这真的没有意义...我应该 return 一个承诺还是应该在 then()
声明中处理整个事情?作为 return 一个基本值并没有真正起到多大作用。即便如此,我该如何处理失败的断言?
我还在代码库中看到了 Nightmare 客户端脚本,但我不知道它是否对我的案例有用,因为我刚刚开始挖掘代码库以便更好地理解如何自定义和扩展 CodeceptJs。
非常感谢任何指点
由于似乎没有人能做到这一点,我将添加一个答案,因为我似乎已经通过浏览代码库找到了这个东西的工作原理,并且对它的工作原理有了更多的了解。
tl;dr: 快速解决方案如下:
/* __tests__/helpers/domelements_helper.js */
const assert = require('assert')
class DOMElements extends Helper {
seeMoreThanElements (locator, count) {
return this.helpers['Nightmare']._locate(locator)
.then((elementsArray) => {
if (elementsArray.length < count) {
return assert.fail(elementsArray.length, count, `Found more than ${count} elements`)
}
})
}
}
module.exports = DOMElements
整个事情的工作方式是通过承诺,你必须适当地处理失败,这样整个系统才能优雅地失败(大概)。
特别是 _locate()
returns 一个 promise 并且所有事情都必须异步处理,尽管从设计上讲这似乎很尴尬并且它使事情特别难以实现,至少在当前状态。