如何在 Katalon Studio 测试用例中处理 Zoho CRM 自动完成
How to handle a Zoho CRM autocomplete in Katalon Studio test cases
我对要测试的 Zoho 应用程序中这个始终存在的自动完成小部件陷入僵局。它会在正在测试的 CRM 页面上弹出,为了处理它,我使用了以下 util 方法:
public final class GeneralWebUIUtils {
// ... other utils
public static void HandleAutoComplete(TestObject textField, String input, TestObject loader, TestObject dropdownOption, boolean doScroll = false) {
WebUI.click(textField)
WebUI.setText(textField, input)
TimeLoggerUtil.LogAction({
WebUI.waitForElementVisible(loader, 3)
// TODO: somehow this is not working for state; // it ends up selecting the first dropdown value
return WebUI.waitForElementNotVisible(loader, 3)
},
"Loader",
"appear and disappear");
// TODO: do we really need if-condition here?
if (doScroll) {
this.ScrollDropdownOptionIntoView(dropdownOption)
}
WebUI.waitForElementVisible(dropdownOption, 3, FailureHandling.STOP_ON_FAILURE)
WebUI.click(dropdownOption)
}
public static void ScrollDropdownOptionIntoView(TestObject to) {
WebUI.executeJavaScript("arguments[0].scrollIntoView({block: 'center'})", [WebUiCommonHelper.findWebElement(to, 1)])
}
// ... other util methods
}
这似乎是答案,直到我断断续续处理了几个月...
...它 select “错误”的下拉选项!例如,在会员类别自动完成中,我们输入“会员资格”,在第一个会员类别下拉选项可用之前,它将 select [名称中带有“会员资格”的其他一些下拉选项]。
昨晚,我一直忙到凌晨 2 点才处理这个和正在使用它的测试用例。我最终将代码更改为:
public static void HandleAutoComplete(TestObject textField, String input, TestObject loader, TestObject dropdownOption, boolean doScroll = false) throws StepFailedException {
WebUI.click(textField)
WebUI.setText(textField, input)
TimeLoggerUtil.LogAction({
return WebUI.waitForElementNotVisible(loader, 3)
},
"Loader",
"disappear");
// TODO: do we really need if-condition here?
if (doScroll) {
this.ScrollDropdownOptionIntoView(dropdownOption)
}
TimeLoggerUtil.LogAction({
WebUI.waitForElementVisible(dropdownOption, 3);
return this.WaitForElementHasText(dropdownOption, input, 5, FailureHandling.STOP_ON_FAILURE);
},
"Dropdown option",
"become visible")
WebUI.verifyElementText(dropdownOption, input)
WebUI.click(dropdownOption)
}
public static boolean WaitForElementCondition(Closure<Boolean> onCheckCondition, TestObject to, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
final long startTime = System.currentTimeMillis()
boolean isConditionSatisfied = false;
while ((System.currentTimeMillis() < startTime + timeOut * 1000) && (!isConditionSatisfied)) {
isConditionSatisfied = onCheckCondition(to);
}
if ((!isConditionSatisfied) && (failureHandling.equals(FailureHandling.STOP_ON_FAILURE))) {
KeywordUtil.markFailedAndStop("Condition for TestObject '${to.getObjectId()}' not met after ${(System.currentTimeMillis() - startTime) / 1000} seconds");
}
return isConditionSatisfied;
}
public static boolean WaitForElementHasText(TestObject to, String expectedText, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
return this.WaitForElementCondition({ TestObject testObj ->
return WebUI.getText(testObj).contains(expectedText);
},
to,
timeOut,
failureHandling);
}
这真是太快了,它不会默默地做不正确的行为(即 select 错误的下拉选项),它会抛出异常。它应该只是工作! (当我们去检查它时,实际的下拉选项似乎还没有准备好检查...)
我尝试通过调整 WaitForElementHasText()
:
来补救它
public static boolean WaitForElementHasText(TestObject to, String expectedText, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
return this.WaitForElementCondition({ TestObject testObj ->
return WebUI.verifyElementPresent(testObj, 1) && WebUI.getText(testObj).contains(expectedText);
},
to,
timeOut,
failureHandling);
}
没有骰子。它有时仍然会失败,而且我似乎对此无能为力....
..或者有吗?
除了切换到处理起来更复杂的模态视图之外,我们如何一劳永逸地处理自动完成?
无论我多么努力,我都无法用传统的方法解决这个问题:使用策略模式。
为什么?因为,当我去记录 dropdownOption
和 loader
的初始状态时,它们完全相同,无论自动完成处理程序最终是成功还是失败。
看起来我无法控制dropdownOption
“闪烁”,即使我们等待它存在!
所以,我必须发挥创意:
public static boolean WaitForElementCondition(Closure<Boolean> onCheckCondition, Closure onContinue, TestObject to, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
final long startTime = System.currentTimeMillis()
boolean isConditionSatisfied = false;
while ((System.currentTimeMillis() < startTime + timeOut * 1000) && (!isConditionSatisfied)) {
isConditionSatisfied = onCheckCondition(to);
onContinue(isConditionSatisfied, to);
}
if ((!isConditionSatisfied) && (failureHandling.equals(FailureHandling.STOP_ON_FAILURE))) {
KeywordUtil.markFailedAndStop("Condition for TestObject '${to.getObjectId()}' not met after ${(System.currentTimeMillis() - startTime) / 1000} seconds");
}
return isConditionSatisfied;
}
public static boolean WaitForElementHasText(TestObject to, String expectedText, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
return this.WaitForElementCondition({ TestObject testObj ->
return WebUI.getText(testObj).contains(expectedText);
},
{ boolean success, TestObject tObj ->
if (!success) {
WebUI.waitForElementNotPresent(tObj, 1);
WebUI.waitForElementPresent(tObj, timeOut);
}
},
to,
timeOut,
failureHandling);
}
re-ran测试了几次,一切顺利!
我对要测试的 Zoho 应用程序中这个始终存在的自动完成小部件陷入僵局。它会在正在测试的 CRM 页面上弹出,为了处理它,我使用了以下 util 方法:
public final class GeneralWebUIUtils {
// ... other utils
public static void HandleAutoComplete(TestObject textField, String input, TestObject loader, TestObject dropdownOption, boolean doScroll = false) {
WebUI.click(textField)
WebUI.setText(textField, input)
TimeLoggerUtil.LogAction({
WebUI.waitForElementVisible(loader, 3)
// TODO: somehow this is not working for state; // it ends up selecting the first dropdown value
return WebUI.waitForElementNotVisible(loader, 3)
},
"Loader",
"appear and disappear");
// TODO: do we really need if-condition here?
if (doScroll) {
this.ScrollDropdownOptionIntoView(dropdownOption)
}
WebUI.waitForElementVisible(dropdownOption, 3, FailureHandling.STOP_ON_FAILURE)
WebUI.click(dropdownOption)
}
public static void ScrollDropdownOptionIntoView(TestObject to) {
WebUI.executeJavaScript("arguments[0].scrollIntoView({block: 'center'})", [WebUiCommonHelper.findWebElement(to, 1)])
}
// ... other util methods
}
这似乎是答案,直到我断断续续处理了几个月...
...它 select “错误”的下拉选项!例如,在会员类别自动完成中,我们输入“会员资格”,在第一个会员类别下拉选项可用之前,它将 select [名称中带有“会员资格”的其他一些下拉选项]。
昨晚,我一直忙到凌晨 2 点才处理这个和正在使用它的测试用例。我最终将代码更改为:
public static void HandleAutoComplete(TestObject textField, String input, TestObject loader, TestObject dropdownOption, boolean doScroll = false) throws StepFailedException {
WebUI.click(textField)
WebUI.setText(textField, input)
TimeLoggerUtil.LogAction({
return WebUI.waitForElementNotVisible(loader, 3)
},
"Loader",
"disappear");
// TODO: do we really need if-condition here?
if (doScroll) {
this.ScrollDropdownOptionIntoView(dropdownOption)
}
TimeLoggerUtil.LogAction({
WebUI.waitForElementVisible(dropdownOption, 3);
return this.WaitForElementHasText(dropdownOption, input, 5, FailureHandling.STOP_ON_FAILURE);
},
"Dropdown option",
"become visible")
WebUI.verifyElementText(dropdownOption, input)
WebUI.click(dropdownOption)
}
public static boolean WaitForElementCondition(Closure<Boolean> onCheckCondition, TestObject to, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
final long startTime = System.currentTimeMillis()
boolean isConditionSatisfied = false;
while ((System.currentTimeMillis() < startTime + timeOut * 1000) && (!isConditionSatisfied)) {
isConditionSatisfied = onCheckCondition(to);
}
if ((!isConditionSatisfied) && (failureHandling.equals(FailureHandling.STOP_ON_FAILURE))) {
KeywordUtil.markFailedAndStop("Condition for TestObject '${to.getObjectId()}' not met after ${(System.currentTimeMillis() - startTime) / 1000} seconds");
}
return isConditionSatisfied;
}
public static boolean WaitForElementHasText(TestObject to, String expectedText, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
return this.WaitForElementCondition({ TestObject testObj ->
return WebUI.getText(testObj).contains(expectedText);
},
to,
timeOut,
failureHandling);
}
这真是太快了,它不会默默地做不正确的行为(即 select 错误的下拉选项),它会抛出异常。它应该只是工作! (当我们去检查它时,实际的下拉选项似乎还没有准备好检查...)
我尝试通过调整 WaitForElementHasText()
:
public static boolean WaitForElementHasText(TestObject to, String expectedText, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
return this.WaitForElementCondition({ TestObject testObj ->
return WebUI.verifyElementPresent(testObj, 1) && WebUI.getText(testObj).contains(expectedText);
},
to,
timeOut,
failureHandling);
}
没有骰子。它有时仍然会失败,而且我似乎对此无能为力....
..或者有吗?
除了切换到处理起来更复杂的模态视图之外,我们如何一劳永逸地处理自动完成?
无论我多么努力,我都无法用传统的方法解决这个问题:使用策略模式。
为什么?因为,当我去记录 dropdownOption
和 loader
的初始状态时,它们完全相同,无论自动完成处理程序最终是成功还是失败。
看起来我无法控制dropdownOption
“闪烁”,即使我们等待它存在!
所以,我必须发挥创意:
public static boolean WaitForElementCondition(Closure<Boolean> onCheckCondition, Closure onContinue, TestObject to, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
final long startTime = System.currentTimeMillis()
boolean isConditionSatisfied = false;
while ((System.currentTimeMillis() < startTime + timeOut * 1000) && (!isConditionSatisfied)) {
isConditionSatisfied = onCheckCondition(to);
onContinue(isConditionSatisfied, to);
}
if ((!isConditionSatisfied) && (failureHandling.equals(FailureHandling.STOP_ON_FAILURE))) {
KeywordUtil.markFailedAndStop("Condition for TestObject '${to.getObjectId()}' not met after ${(System.currentTimeMillis() - startTime) / 1000} seconds");
}
return isConditionSatisfied;
}
public static boolean WaitForElementHasText(TestObject to, String expectedText, int timeOut, FailureHandling failureHandling = FailureHandling.STOP_ON_FAILURE) {
return this.WaitForElementCondition({ TestObject testObj ->
return WebUI.getText(testObj).contains(expectedText);
},
{ boolean success, TestObject tObj ->
if (!success) {
WebUI.waitForElementNotPresent(tObj, 1);
WebUI.waitForElementPresent(tObj, timeOut);
}
},
to,
timeOut,
failureHandling);
}
re-ran测试了几次,一切顺利!