2

在我正在测试验证码的系统中很少出现,但是当它出现时,在我提交表单后它出乎意料(我无法猜测何时)。表单数据被保留,用户只需要解决验证码(在我的情况下解决不是问题)。问题是我不知道验证码什么时候会出现,只是盲目地寻找[AfterStep]钩子中的每一个都是在脚上射击,因为它会阻止每一步隐含的等待时间。

我的解决方案是:

  1. 在我确认表单的每个步骤之后,我都会添加一个步骤And Fill captcha if necessary

这很糟糕,因为我在整个测试套件中添加了 50 个步骤,其中 49 个通常是无用的 +Driver.FindElement是一个阻塞调用,因此它将等待 49*20 秒等待永远不会出现的验证码。

  1. 当验证码在表单提交后出现时,浏览器会获取 HTTP 代码X,因此我可以在单独的线程中收听代码,一旦我点击代码X,我将查找验证码,填写并重新提交表单。

这很糟糕,因为我发现无休止的讨论表明 Selenium 不支持它并且我无法收听状态代码,我认为这在最近没有改变。

我可能会选择 1. 解决方案,因为这是我知道的唯一可行的解​​决方案,但我可能会遗漏一些东西。

问题:这个问题还有其他解决方案吗?

4

1 回答 1

0

您需要一个专门检测和处理验证码的类,然后在每次与页面交互时委托给该类:

class CaptchaHandler
{
    readonly IWebDriver driver;

    private bool IsCaptchaVisible
    {
        get
        {
            // detect if captcha is visible
        }
    }

    internal CaptchaHandler(IWebDriver driver)
    {
        this.driver = driver;
    }

    internal void SolveCaptchaIfVisible(Action action)
    {
        try
        {
            action();
        }
        catch (WebDriverException)
        {
            if (IsCaptchaVisible)
            {
                SolveCaptcha();
                action();
            }
            else
            {
                throw;
            }
        }
    }

    private bool SolveCaptcha()
    {
        // solve the captcha
    }
}

只需在SolveCaptchaIfVisible每次需要填写验证码时调用,并传递一个 lambda 表达式:

var handler = new CaptchaHandler(driver);

handler.SolveCaptchaIfVisible(() =>
{
    // Do something that might fail because captcha is blocking
});

这也为您提供了一个优化验证码检测方式的地方。

如果某些步骤似乎触发了验证码,请在步骤定义中初始化并使用此类。这种方法的好处是,如果您需要用纯 C# 编写 selenium 测试,您可以重用它,而无需中间的 Gherkin 层。

于 2020-06-07T17:17:17.057 回答