定义页面元素
声明元素
大多数情况下,您需要在页面上定义元素,以便您的测试可以通过命令和断言与它们交互。使用 `elements` 属性可以轻松实现这一点,以便所有元素都定义在一个地方。尤其是在大型集成测试中,使用 `elements` 将极大地帮助保持测试代码 DRY。
在 CSS 和 XPath 定位策略之间切换是在内部处理的,因此您无需在测试中调用 `useXpath()` 或 `useCss()`。默认的 `locateStrategy` 是 CSS,但您也可以指定 XPath
nightwatch/pages/examplePage.js
module.exports = {
elements: {
searchBar: {
selector: 'input[type=text]'
},
submit: {
selector: '//[@name="q"]',
locateStrategy: 'xpath'
}
}
};
或者,如果您创建的元素使用与默认值相同的定位策略,您可以使用简写形式
nightwatch/pages/examplePage.js
module.exports = {
elements: {
searchBar: 'input[type=text]'
}
};
使用页面元素
使用 `elements` 属性,您可以通过“@ 前缀”来引用元素的名称(而不是选择器),而不是在调用元素命令和断言(`click()` 等)时使用选择器。
可选地,您可以定义一个对象数组
nightwatch/pages/examplePage.js
var sharedElements = {
mailLink: 'a[href*="mail.google.com"]'
};
module.exports = {
elements: [
sharedElements,
{ searchBar: 'input[type=text]' }
]
};
将 `elements` 和 `url` 放在一起,假设您在上面定义了以下内容,并将其保存为 `googlePage.js` 文件
nightwatch/pages/googlePage.js
module.exports = {
url: 'https://google.com',
elements: {
searchBar: {
selector: 'input[type=text]'
},
submit: {
selector: '//[@name="q"]',
locateStrategy: 'xpath'
}
}
};
在您的测试中,您将按如下方式使用它
tests/sampleTest.js
describe('sample test with page objects', function() {
it('Test', function (browser) {
var google = browser.page.google();
google.navigate()
.assert.title('Google')
.assert.visible('@searchBar')
.setValue('@searchBar', 'nightwatch')
.click('@submit');
browser.end();
});
});
元素属性
为了在与页面对象元素交互方面提供更大的灵活性,元素可以指定为一个对象,该对象至少需要包含 `selector` 属性。除了选择器之外,还可以指定其他属性。以下是完整列表
- `selector` - 元素选择器名称(例如:`@searchBar`)
- `locateStrategy` - 例如 'css selector'
- `index` - 用于在导致返回多个元素的查询中定位特定元素。通常,仅使用第一个元素(索引 = 0),但使用 `index` 属性,您可以指定结果中的任何元素。
- `abortOnFailure` - 用于在使用 `waitForElement*` 命令时覆盖此设置
- `timeout` - 用于在使用 `waitForElement*` 命令或断言时覆盖默认超时
- `retryInterval` - 用于在使用 `waitForElement*` 命令或断言时覆盖默认重试间隔
- `suppressNotFoundErrors` - 一些元素命令,如 `click()` 或 `getText()`,如果无法找到元素,将抛出 `NoSuchElement` 错误,导致测试失败。如果将此选项设置为 `true`,则忽略此错误。
筛选元素
假设在上面的示例中,`searchBar` 元素选择器返回 3 个元素,您对第二个元素感兴趣。
nightwatch/pages/googlePage.js
module.exports = {
elements: {
searchBar: {
selector: 'input[type=text]',
index: 1
}
}
};
您也可以通过在命令中将元素指定为一个对象选择器来覆盖页面元素中定义的内容,该选择器也可以接收 `index`
tests/sampleTest.js
describe('sample test with page objects', function() {
it('Test', function (browser) {
var google = browser.page.google();
google
.navigate()
.assert.title('Google');
google.waitForElementVisible('@searchBar') // 2nd input element
google.waitForElementVisible({selector:'@searchBar', index:1}, function(result){}); // 1st div
google.click('@submit');
browser.end();
});
});
伪选择器
使用命名页面对象元素(以“@”开头)时,您也可以使用 CSS 伪选择器(以 `v1.1` 开头)。
tests/sampleTest.js
module.exports = {
'Test': function (browser) {
google.waitForElementVisible('@searchBar:first-child');
google.waitForElementVisible('@searchBar:nth-child(1)');
}
};