
在进行web ui自动化测试时,我们经常会遇到内容被分割成多页显示的情况。某些应用界面可能不提供显式的“下一页”按钮,而是要求用户通过键盘操作(例如按下enter键)来加载后续内容。同时,判断何时到达最后一页的逻辑也可能不是通过简单的页面元素可见性,而是通过某个特定元素的内容变化或消失来决定。例如,一个消息列表可能在还有更多数据时显示“xx more data to view”,而在没有更多数据时,该提示信息会消失或变为其他内容。这种场景对自动化脚本的条件循环和动态交互提出了更高的要求。
Karate框架为处理这类动态UI交互提供了强大的waitUntil函数。waitUntil允许我们传入一个JavaScript函数作为参数,Karate会周期性地执行这个函数,直到该函数返回true。一旦函数返回true,waitUntil就会停止执行并继续后续的测试步骤。这使得它非常适合实现带有条件判断的循环逻辑。
为了解决上述分页数据采集的挑战,我们可以利用waitUntil结合一个自定义的JavaScript函数来模拟用户操作并收集数据。
首先,我们需要一个变量来存储从各个页面收集到的数据。在Karate中,可以使用* def来定义一个空数组:
* def allData = []
接下来,我们将定义一个名为loopContent的JavaScript函数。这个函数将被传递给waitUntil,并包含判断页面状态、执行翻页操作和提取数据的逻辑。
函数设计原则:
针对我们的场景,假设页面通过.messageNumber元素的存在与否来判断是否还有更多数据。当.messageNumber元素消失时,表示已到达最后一页。
* def loopContent =
"""
function() {
// 检查是否已到达最后一页(例如,通过特定元素是否存在来判断)
// 如果 .messageNumber 不存在,则表示已到达最后一页
if (!exists('.messageNumber')) {
// 提取当前页面的数据
let list = locateAll('form div', x => {
let id = x.attribute('id');
return id ? id.startsWith('line1_R') : false
});
let data = list.map(x => x.text.trim());
allData.push(data); // 将数据添加到 allData 数组
return true; // 返回 true,通知 waitUntil 停止循环
}
// 如果 .messageNumber 仍然存在,说明还有更多数据,执行翻页操作
input('body', Key.ENTER); // 模拟按下 Enter 键
// 不返回任何值(或返回 false),waitUntil 将继续循环
}
"""代码解析:
定义好loopContent函数后,我们就可以通过waitUntil来执行它了:
* waitUntil(loopContent)
Karate会反复调用loopContent函数,直到它返回true。在此过程中,每次调用loopContent都会检查页面状态,如果不是最后一页,就执行Enter键操作。
循环结束后,allData数组将包含从所有页面收集到的数据。我们可以打印出来进行验证:
* print allData
将上述步骤整合,完整的Karate测试脚本片段如下:
# 假设已经导航到目标页面
# ...
* def allData = []
* def loopContent =
"""
function() {
// 检查是否已到达最后一页
// 示例:当页面上不再存在 .messageNumber 元素时,停止循环
if (!exists('.messageNumber')) {
// 提取当前页面的数据
let list = locateAll('form div', x => {
let id = x.attribute('id');
return id ? id.startsWith('line1_R') : false
});
let data = list.map(x => x.text.trim());
allData.push(data); // 将数据添加到 allData 数组
return true; // 返回 true,通知 waitUntil 停止循环
}
// 如果仍有更多数据,执行翻页操作
input('body', Key.ENTER); // 模拟按下 Enter 键
// 不返回任何值,waitUntil 将继续循环
}
"""
* waitUntil(loopContent)
* print allData上述实现中,数据提取allData.push(data)只发生在!exists('.messageNumber')条件满足时,即在检测到最后一页时才提取数据。这意味着,如果前几页的数据结构与最后一页不同,或者需要在每次翻页后都提取数据,这种方式可能会导致数据遗漏或无法捕获所有中间页面的数据。
如果实际需求是在每次翻页后都提取当前页的数据,那么loopContent函数需要调整为在每次循环中都提取数据,并确保只添加新加载的内容,避免重复。
更常见的场景是: 每次翻页后,页面上会加载新的数据行,而旧的数据行可能仍然存在或被替换。如果页面每次翻页都只是追加新的数据,并且旧数据保持不变,那么在waitUntil循环的每次迭代中都提取数据并进行去重是一个稳妥的选择。
如果loopContent函数在每次循环中都提取数据,或者由于页面特性导致数据在allData中可能存在重复,Karate提供了一个便捷的内置函数karate.distinct()来处理数组去重:
* def cleanedData = karate.distinct(allData) * print cleanedData
这可以在数据采集完成后,对allData进行一次清理,确保最终数据集的唯一性。
本教程以.messageNumber元素消失作为结束条件。在实际应用中,您需要根据页面的具体HTML结构和业务逻辑,选择最准确、最稳定的结束标志。这可能是一个文本内容的变化(例如“no more data to view”),一个按钮的禁用状态,或者某个特定元素的完全消失。
如果页面设计是每次翻页都替换掉部分内容,并且只在最后一页才显示完整的、最终的数据,那么上述示例的逻辑是合适的。但如果页面是累积加载数据(即每次翻页都追加新行),且需要收集所有累积的数据,那么loopContent可能需要更复杂的逻辑来识别并只push新加载的数据行,这可能需要跟踪上一次循环的数据状态,或者利用页面上新元素的唯一标识符。
通过结合Karate的waitUntil函数和灵活的JavaScript条件逻辑,我们可以有效地应对UI自动化中复杂的分页和动态交互场景。这种方法不仅能够模拟用户行为(如按下Enter键),还能根据页面元素的动态变化来智能判断循环的终止条件,从而实现对多页内容的精准采集。在实际应用中,根据具体页面的数据加载和显示机制,合理设计loopContent函数,并辅以数据去重等后处理步骤,将大大提升自动化测试脚本的健壮性和效率。
以上就是Karate UI自动化:利用waitUntil和条件逻辑处理分页数据采集的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号