首页 > 解决方案 > Selenium C# 代码有效,但需要等待或延迟

问题描述

通过添加一个 while(ele == null) 循环,我让代码大部分时间都在调试器之外运行和工作。很难看。这使我认为我需要使用包装器覆盖 FindElements() 函数,但不知道如何执行此操作以增加一些延迟。在 Selenium Webdriver 中的 Explicit Wait for findElements 中有一个示例,但它是用 JavaScript 编写的。我把这个例子放在下面的代码中。有人可以指导我吗?

        public void WriteAPost()
        {
           ele = driver.FindElements(By.CssSelector(".a8c37x1j.ni8dbmo4.stjgntxs.l9j0dhe7.ltmttdrg.g0qnabr5.ojkyduve")).FirstOrDefault(x => x.Text == "Create Post");

            while(ele == null)
            {
                ele = driver.FindElements(By.CssSelector(".a8c37x1j.ni8dbmo4.stjgntxs.l9j0dhe7.ltmttdrg.g0qnabr5.ojkyduve")).FirstOrDefault(x => x.Text == "Create Post");
            }

            ele.Click();
            Thread.Sleep(3000);

            ele = driver.SwitchTo().ActiveElement();

            PClipboard.SetText("Post text to use for Text Area");
            ele.SendKeys(OpenQA.Selenium.Keys.Control + 'v');

            Thread.Sleep(3000);

            ele = driver.FindElements(By.XPath("//div[@role = 'button']")).FirstOrDefault(x => x.Text == "Post");

            while (ele == null)
            {
                ele = driver.FindElements(By.XPath("//div[@role = 'button']")).FirstOrDefault(x => x.Text == "Post");
            }

            ele.Click();
            Thread.Sleep(3000);

            driver.Quit();
     }

    static class PClipboard
    {
        public static void SetText(string p_Text)
        {
            Thread STAThread = new Thread(
                delegate ()
                {
                    // Use a fully qualified name for Clipboard otherwise it
                    // will end up calling itself.
                    System.Windows.Forms.Clipboard.SetText(p_Text);
                });
            STAThread.SetApartmentState(ApartmentState.STA);
            STAThread.Start();
            STAThread.Join();
        }
    }
}

// Javascript FindElements() wrapper

    /// <summary>
    /// Allows you to execute the FindElements call but specify your own timeout explicitly for this single lookup
    /// </summary>
    /// <remarks>
    /// If you want no timeout, you can pass in TimeSpan.FromSeconds(0) to return an empty list if no elements match immediately. But then you may as well use the original method
    /// </remarks>
    /// <param name="driver">The IWebDriver instance to do the lookup with</param>
    /// <param name="findBy">The By expression to use to find matching elements</param>
    /// <param name="timeout">A timespan specifying how long to wait for the element to be available</param>
    public static ReadOnlyCollection<IWebElement> FindElements(this IWebDriver driver, By findBy, TimeSpan timeout)
    {
        var wait = new WebDriverWait(driver, timeout);
        return wait.Until((d) =>
        {
            var elements = d.FindElements(findBy);
            return (elements.Count > 0)
                ? elements
                : null;
        });
    }

标签: c#seleniumselenium-webdriverautomated-testsselenium-chromedriver

解决方案


您可以等待满足一个条件:

new WebDriverWait(driver, timeout).Until(ExpectedConditions.ElementExists((By.Id(id))));

或者您可以隐式等待:

driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(timeInSeconds);

推荐阅读