Snickbrack
Snickbrack

Reputation: 976

Selenium is returning an old state of PageSource and is not updating after Javascript Execution

I have a console program in C# with Selenium controlling a Chrome Browser Instance and I want to get all Links from a page.

But after the Page has loaded in Selenium the PageSource from Selenium ist different to the HTML of the Website I have navigated to. The Content of the Page is asynchronously loaded by JavaScript and the HTML is changed.

Even if I load the HTML of the Website like the following the HTML is still different to the one inside the Selenium controlled Browserwindow:

var html = ((IJavaScriptExecutor)driver).ExecuteScript("return document.getElementsByTagName('html')[0].outerHTML").ToString();

But why is the PageSource or the HTML returned by my JS still the same as it was when Selenium loaded the page?



EDIT: As @BinaryBob has pointed out I have now implemented a wait-function to wait for a desired element to change a specific attribute value. The Code looks like this:

private static void AttributeIsNotEmpty(IWebDriver driver, By locator, string attribute, int secondsToWait = 60)
{
    new WebDriverWait(driver, new TimeSpan(0, 0, secondsToWait)).Until(d => IsAttributeEmpty(d, locator, attribute));
}

private static bool IsAttributeEmpty(IWebDriver driver, By locator, string attribute)
{
    Console.WriteLine("Output: " + driver.FindElement(locator).GetAttribute(attribute));

    return !string.IsNullOrEmpty(driver.FindElement(locator).GetAttribute(attribute));
}

And the function call looks like this:

AttributeIsNotEmpty(driver, By.XPath("/html/body/div[2]/c-wiz/div[4]/div[1]/div/div/div/div/div[1]/div[1]/div[1]/a[1]"), "href");

But the condition is never met and the timeout is thrown. But inside the Chrome Browser (which is controlled by Selenium) the condition is met and the element has a filled href-Attribute.

Upvotes: 0

Views: 711

Answers (1)

Paperclip Bob
Paperclip Bob

Reputation: 396

I'm taking a stab at this. Are you calling wait.Until(ExpectedConditions...) somewhere in your code? If not, that might be the issue. Just because a FindElement method has returned does not mean the page has finished rendering.

For a quick example, this code comes from the Selenium docs site. Take note of the creation of a WebDriverWait object (line 1), and the use of it in the firstResult assignment (line 4)

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
driver.Navigate().GoToUrl("https://www.google.com/ncr");
driver.FindElement(By.Name("q")).SendKeys("cheese" + Keys.Enter);
IWebElement firstResult = wait.Until(ExpectedConditions.ElementExists(By.CssSelector("h3>div")));
Console.WriteLine(firstResult.GetAttribute("textContent"));

If this is indeed the problem, you may need to read up on the various ways to use ExpectedConditions. I'd start here: Selenium Documentation: WebDriver Waits

Upvotes: 1

Related Questions