如何使用 webdriverIO 获取即时文本
How to get immediate text with webdriverIO
我有 html DOM 这样的:
<div class="alert alert-danger">
<button class="close" aria-hidden="true" data-dismiss="alert" type="button">×</button>
Your username or password was incorrect.
</div>
我想要 Your username or password was incorrect.
文本。
如果我这样做:
$('.global-alerts div.alert-danger').getText()
然后我得到这个×
。
有没有办法在 div
元素中获取唯一的文本部分?
我设法做了这样的事情:
getErrorMessageText() {
return browser.execute(function () {
const selector = '.global-alerts div.alert-danger';
// @ts-ignore
return $(selector).contents().not($(selector).children()).text().trim();
});
}
而且有效。
但是有人有更好的主意吗?或者更多类似 webdriverIO 的方法?
如果你用这样的东西行得通吗?
var innerHTML = $('.global-alerts div.alert-danger').getHTML(false);
false
参数指示是否在输出中包含选择器元素标签。
认真解决
除了使用 execute 从页面“抓取”该信息外,我看不到任何其他方法。
然而,我会把它放在浏览器命令中(要么在配置“之前”挂钩中执行,要么添加一个在之前挂钩中添加命令的服务)
这就是我最终考虑将打字稿作为主要语言,忽略 jQuery 的使用,并考虑到您使用 before hook:
/**
* Gets executed before test execution begins. At this point you can access to all global
* variables like `browser`. It is the perfect place to define custom commands.
* @param {Array.<Object>} capabilities list of capabilities details
* @param {Array.<String>} specs List of spec file paths that are to be run
* @param {Object} browser instance of created browser/device session
*/
before: function (_capabilities: any, _specs: any, browser: WebdriverIO.Browser) {
browser.addCommand(
'getNodeText',
async function() {
return this.execute(
(selector: string) =>
Array.from( document.querySelector(selector).childNodes || [])
.filter((n: HTMLElement) => n.nodeType === n.TEXT_NODE)
.map(n => n.textContent)
.reduce(function(f, c) {return f+c;}, '')
.replace('\n', '')
.trim(),
this.selector
);
},
true
);
},
使用这种方法,typescript 可能会抱怨传递给 webdriver 以执行的函数,因此您可以正确编写它,或者将它移动到 .js 文件并完成它。
只需注意 document.querySelector(selector),理论上,它不应该为 null,因为该命令是在 webdriver 已经找到的元素上执行的。
你抓取文本的方式就是await (await $('.alert.alert-danger').getNodeText())
;
这应该是 return 节点本身的完整字符串,而不是任何子节点。
注意:如果您最终得到一个元素,例如:<div id="mytxt">my text style is <strong>strong</strong> and <italic> italic </italic>. - html fan</div>
并执行此 getNodeText(),您可能最终得到值 my text style is and . - html fan
。
“不要被太多打扰”的解决方案
这种方法还会检查“x”按钮是否仍然存在。
await expect($('.global-alerts div.alert-danger')).toHaveText('xYour username or password was incorrect.')
我有 html DOM 这样的:
<div class="alert alert-danger">
<button class="close" aria-hidden="true" data-dismiss="alert" type="button">×</button>
Your username or password was incorrect.
</div>
我想要 Your username or password was incorrect.
文本。
如果我这样做:
$('.global-alerts div.alert-danger').getText()
然后我得到这个×
。
有没有办法在 div
元素中获取唯一的文本部分?
我设法做了这样的事情:
getErrorMessageText() {
return browser.execute(function () {
const selector = '.global-alerts div.alert-danger';
// @ts-ignore
return $(selector).contents().not($(selector).children()).text().trim();
});
}
而且有效。
但是有人有更好的主意吗?或者更多类似 webdriverIO 的方法?
如果你用这样的东西行得通吗?
var innerHTML = $('.global-alerts div.alert-danger').getHTML(false);
false
参数指示是否在输出中包含选择器元素标签。
认真解决
除了使用 execute 从页面“抓取”该信息外,我看不到任何其他方法。 然而,我会把它放在浏览器命令中(要么在配置“之前”挂钩中执行,要么添加一个在之前挂钩中添加命令的服务) 这就是我最终考虑将打字稿作为主要语言,忽略 jQuery 的使用,并考虑到您使用 before hook:
/**
* Gets executed before test execution begins. At this point you can access to all global
* variables like `browser`. It is the perfect place to define custom commands.
* @param {Array.<Object>} capabilities list of capabilities details
* @param {Array.<String>} specs List of spec file paths that are to be run
* @param {Object} browser instance of created browser/device session
*/
before: function (_capabilities: any, _specs: any, browser: WebdriverIO.Browser) {
browser.addCommand(
'getNodeText',
async function() {
return this.execute(
(selector: string) =>
Array.from( document.querySelector(selector).childNodes || [])
.filter((n: HTMLElement) => n.nodeType === n.TEXT_NODE)
.map(n => n.textContent)
.reduce(function(f, c) {return f+c;}, '')
.replace('\n', '')
.trim(),
this.selector
);
},
true
);
},
使用这种方法,typescript 可能会抱怨传递给 webdriver 以执行的函数,因此您可以正确编写它,或者将它移动到 .js 文件并完成它。 只需注意 document.querySelector(selector),理论上,它不应该为 null,因为该命令是在 webdriver 已经找到的元素上执行的。
你抓取文本的方式就是await (await $('.alert.alert-danger').getNodeText())
;
这应该是 return 节点本身的完整字符串,而不是任何子节点。
注意:如果您最终得到一个元素,例如:<div id="mytxt">my text style is <strong>strong</strong> and <italic> italic </italic>. - html fan</div>
并执行此 getNodeText(),您可能最终得到值 my text style is and . - html fan
。
“不要被太多打扰”的解决方案
这种方法还会检查“x”按钮是否仍然存在。
await expect($('.global-alerts div.alert-danger')).toHaveText('xYour username or password was incorrect.')