简体   繁体   English

Selenium C# 不等待

[英]Selenium C# does not wait

I'm working on an ASP.NET MVC college project and some part of the project requires to automate the process of submitting a problem on codeforces.com the problem is that when selenium does not wait until the element is presented so I get an error :我正在处理一个 ASP.NET MVC 大学项目,该项目的某些部分需要自动化在 codeforces.com 上提交问题的过程,问题是当 selenium 没有等到元素出现时,我得到一个错误:

OpenQA.Selenium.StaleElementReferenceException: 'stale element reference: element is not attached to the page document

and while debugging everything is working fine without any error.并且在调试时一切正常,没有任何错误。 I have tried a lot of things to solve it but in the end all methods end with that error or something like that.我尝试了很多方法来解决它,但最终所有方法都以该错误或类似的错误结束。

Some of the methods I used: * wait until * use dummy action to wait like Maximize and Minimize * System Sleep我使用的一些方法: * 等到 * 使用虚拟操作来等待,例如最大化和最小化 * 系统睡眠

And here is my code这是我的代码

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Support;
using NUnit.Framework;

namespace AutoCodeforces
{
    [TestClass]
    public class Automate
    {
        IWebDriver chromeDriver = new ChromeDriver();
        [TestMethod]
        public void OpenCodeforces()
        {


            string handle = "A4AJudge";
            string password = "A4A123456789";
            string ProblemID = "33A";
            string LangValue = "54";
            string code = @"#include <iostream> #include <algorithm> #include <string> #include <cstdio> #include <vector> using namespace std; int a[1000], i, n, m, j, l, k, ans; int main() { scanf(" + @"% d % d % d" + @", &n, &m, &k); for (i = 0; i < m; i++) a[i] = 1000001; for (i = 0; i < n; i++) { scanf(" + " % d % d" + ", &j, &l); j--; a[j] = min(a[j], l); } for (i = 0; i < m; i++) ans += a[i]; ans = min(ans, k); cout << ans << endl; return 0; }";

            chromeDriver.Navigate().GoToUrl("http://codeforces.com/enter");
            chromeDriver.Manage().Window.Maximize();
            chromeDriver.FindElement(By.Id("handleOrEmail")).SendKeys(handle);
            chromeDriver.FindElement(By.Id("password")).SendKeys(password);
            chromeDriver.FindElement(By.ClassName("submit")).Click();


            //WebDriverWait wait = new WebDriverWait(chromeDriver, TimeSpan.FromMinutes(1));

            //IWebElement element = wait.Until(driver => driver.FindElement(By.XPath("//a[@href='/problemset']")));

            chromeDriver.FindElement(By.XPath("//a[@href='/problemset']")).Click();

            //element = wait.Until(driver => driver.FindElement(By.XPath("//a[@href='/problemset/submit']")));
            chromeDriver.FindElement(By.XPath("//a[@href='/problemset/submit']")).Click();

            //element = wait.Until(driver => driver.FindElement(By.XPath("//input[@name='submittedProblemCode']")));
            chromeDriver.FindElement(By.XPath("//input[@name='submittedProblemCode']")).SendKeys(ProblemID);



            IWebElement selecElement = chromeDriver.FindElement(By.Name("programTypeId"));
            SelectElement language = new SelectElement(selecElement);
            language.SelectByValue(LangValue);

            chromeDriver.FindElement(By.Id("sourceCodeTextarea")).SendKeys(code);

            chromeDriver.FindElement(By.ClassName("submit")).Click();

            //chromeDriver.Close();
            //chromeDriver.Quit();
        }       
    }
}

Any help, please?请问有什么帮助吗?

I don't think your wait is "explicit" enough here -- You'll want to invoke wait.Until on the ExpectedConditions class, not just on driver.FindElement() returning an element.我认为您的等待在这里不够“明确”——您需要在ExpectedConditions类上调用wait.Until ,而不仅仅是在driver.FindElement()返回元素上。

ExpectedConditions for C# specifically is contained in an external namespace now -- standard Selenium bindings have been deprecated. ExpectedConditions ,C# 的ExpectedConditions专门包含在外部命名空间中——标准 Selenium 绑定已被弃用。 You will need the DotNetSeleniumExtras.WaitHelpers NuGet package for this to work.您将需要DotNetSeleniumExtras.WaitHelpers NuGet 包才能使其工作。 I will provide an alternative solution that does not require an additional dependency.我将提供一个不需要额外依赖的替代解决方案。

Using DotNetSeleniumExtras.WaitHelpers and ExpectedConditions :使用DotNetSeleniumExtras.WaitHelpersExpectedConditions

WebDriverWait wait = new WebDriverWait(chromeDriver, TimeSpan.FromMinutes(1));

IWebElement element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(chromeDriver.FindElement(By.XPath("//a[@href='/problemset']"))));

Without using any external dependencies, invoking IWebElement.IsDisplayed() attribute:不使用任何外部依赖,调用IWebElement.IsDisplayed()属性:

WebDriverWait wait = new WebDriverWait(chromeDriver, TimeSpan.FromMinutes(1));

var isDisplayed = wait.Until(chromeDriver => chromeDriver.FindElement(By.XPath("//a[@href='/problemset']")).Displayed);

chromeDriver.FindElement(By.XPath("//a[@href='/problemset']")).Click();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM