如何在 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);
    }

没有骰子。它有时仍然会失败,而且我似乎对此无能为力....

..或者有吗?

除了切换到处理起来更复杂的模态视图之外,我们如何一劳永逸地处理自动完成?

无论我多么努力,我都无法用传统的方法解决这个问题:使用策略模式。

为什么?因为,当我去记录 dropdownOptionloader 的初始状态时,它们完全相同,无论自动完成处理程序最终是成功还是失败。

看起来我无法控制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测试了几次,一切顺利!