简体   繁体   中英

Selenium script in C# does not find element

I recorded a script using the Selenium Chrome IDE, and exported it as a C#, NUnit class. When I run the test in Visual Studio, it fails to find an element. It's clearly there on the screen and if I run it using the Selenium IDE it works perfectly. Here is my test;

[Test]
Public void login()
{
    driver.Navigate().GoToUrl("https://www.oracle.com/uk/cloud/sign-in.html");
    driver.Manage().Window.Maximize();
    driver.FindElement(By.LinkText("I accept all cookies"), 5).Click();
    }
}

I have copied an extension to let me wait for the element to be present more easily;

public static class WebDriverExtensions
{
    public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
    {
        if (timeoutInSeconds > 0)
        {
            var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
            return wait.Until(drv => drv.FindElement(by));
        }
        return driver.FindElement(by);
    }
}

I also tried;

driver.FindElement(By.ClassName("call"), 5).Click();

What am I doing wrong?

EDIT *** Exception Message;

OpenQA.Selenium.WebDriverTimeoutException : Timed out after 5 seconds
  ----> OpenQA.Selenium.NoSuchElementException : no such element: Unable to 
locate element: {"method":"css selector","selector":".call"}
  (Session info: chrome=85.0.4183.83)

Stack trace;

DefaultWait`1.ThrowTimeoutException(String exceptionMessage, Exception lastException)
DefaultWait`1.Until[TResult](Func`2 condition)
WebDriverExtensions.FindElement(IWebDriver driver, By by, Int32 timeoutInSeconds) line 16
LoginTest.login() line 54
--NoSuchElementException
RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
RemoteWebDriver.FindElement(String mechanism, String value)
RemoteWebDriver.FindElementByClassName(String className)
<>c__DisplayClass20_0.<ClassName>b__0(ISearchContext context)
By.FindElement(ISearchContext context)
RemoteWebDriver.FindElement(By by)
<>c__DisplayClass0_0.<FindElement>b__0(IWebDriver drv) line 16
DefaultWait`1.Until[TResult](Func`2 condition)

Your cookie accept button is in an iframe .

With webdriver you need to switch your driver into that frame to be able to access the elements within.

You need to:

  1. identify the frmae
  2. Switch to the frame
  3. Click your button
  4. switch back to the "default content" (the main bit) of the page

As for a wait strategy - There are explicit waits and implicit waits. For simplicity I've thrown an an implicit wait. This is just simpler and less code. (there are lots of tutorials on there on this)

I've checked your site and it looks like that frame has a good title.

This xpath looks good to get the frame:

//iframe[@title='TrustArc Cookie Consent Manager']

Putting it together for you:

            var driver = new ChromeDriver();
            driver.Url = "https://www.oracle.com/uk/cloud/sign-in.html";
            
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(30);

            var iframe = driver.FindElement(By.XPath("//iframe[@title='TrustArc Cookie Consent Manager']"));
            driver.SwitchTo().Frame(iframe);
            driver.FindElement(By.LinkText("I accept all cookies")).Click();
            driver.SwitchTo().DefaultContent();
            

That works for me. Any problems please let me know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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