Selenium C#代码可以工作,但需要等待或延迟

Selenium C#代码可以工作,但需要等待或延迟,c#,selenium,selenium-webdriver,automated-tests,selenium-chromedriver,C#,Selenium,Selenium Webdriver,Automated Tests,Selenium Chromedriver,通过添加一个while(ele==null)循环,我让代码在调试器之外的大部分时间运行和工作。很难看。这让我觉得我需要使用包装器超越FindElements()函数,但不知道如何增加延迟。上有一个示例,但它是用JavaScript编写的。我把这个例子放在下面的代码中。有人能在这方面指导我吗 public void WriteAPost() { ele = driver.FindElements(By.CssSelector(".a8

通过添加一个while(ele==null)循环,我让代码在调试器之外的大部分时间运行和工作。很难看。这让我觉得我需要使用包装器超越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;
        });
    }
public void writePost()
{
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();
睡眠(3000);
ele=driver.SwitchTo().ActiveElement();
PClipboard.SetText(“用于文本区域的Post文本”);
ele.SendKeys(OpenQA.Selenium.Keys.Control+'v');
睡眠(3000);
ele=driver.findelelements(By.XPath(“//div[@role='button']”);
while(ele==null)
{
ele=driver.findelelements(By.XPath(“//div[@role='button']”);
}
ele.Click();
睡眠(3000);
driver.Quit();
}
静态级PCP插板
{
公共静态void SetText(字符串p_Text)
{
线程STAThread=新线程(
代表()
{
//为剪贴板使用完全限定的名称,否则它将被删除
//最终会自己打电话。
System.Windows.Forms.Clipboard.SetText(p_Text);
});
SetApartmentState(ApartmentState.STA);
statthread.Start();
statthread.Join();
}
}
}
//Javascript FindElements()包装器
/// 
///允许您执行FindElements调用,但要为此单一查找明确指定自己的超时
/// 
/// 
///如果不希望超时,可以传入TimeSpan.FromSeconds(0)以在没有立即匹配的元素时返回空列表。但是你也可以使用原来的方法
/// 
///用于执行查找的IWebDriver实例
///用于查找匹配元素的By表达式
///指定等待元素可用的时间跨度
公共静态只读集合FindElements(此IWebDriver驱动程序,按findBy,TimeSpan超时)
{
var wait=新的WebDriverWait(驱动程序,超时);
返回等待时间((d)=>
{
var元素=d.FindElements(findBy);
返回(elements.Count>0)
?元素
:null;
});
}

您可以等待条件满足:

new WebDriverWait(driver, timeout).Until(ExpectedConditions.ElementExists((By.Id(id))));
或者您可以隐式等待:

driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(timeInSeconds);
我只是不知道该在代码中的什么地方等待


就个人而言,我的Selenium代码充满了“测试失败报告”测试和try-catch块,它们报告了失败发生的位置。如果您以这种方式对代码进行建模,它将缩小问题范围,并提示您需要等待的位置。

谢谢。我只是不知道该在代码中的什么地方等待。我逐行调试代码,找到了所有元素。但是,在不进行调试的情况下运行代码是行不通的。尝试在每个需要在浏览器中运行导航或脚本的操作之后使用驱动程序等待…我没有得到正确的结果。。。你到底被困在哪里了?我修改了上面的代码,一次只做一点,发现了持续的失败。它与FindElements()调用的中断有关。请阅读我的问题描述。谢谢大家。这肯定是FindElements()调用,我用
ele=driver.FindElements(By.CssSelector(“.a8c37x1j.ni8dbmo4.stjgntxs.l9j0dhe7.ltmttdrg.g0qnabr5.ojkyduve”))替换了上面的代码;ele.Click()取代了必须使用foreach循环,当我中断FindElements()代码时,按Step Over(F10),然后继续将文本区域设置为文本。如果我删除断点,ele为null。关于如何解决这个问题有什么想法吗?我刚刚更新了我的问题描述和代码片段。请参阅新的描述和代码snipperts。基本上,我认为我需要为Selenium FindElements()方法创建一个包装器。