Test dynamically loaded content with Selenium Web Driver
Asked Answered
P

3

9

I am working on a system that has a web based frontend that I am testing with Selenium. On one page the content is dynamically loaded when scrolling down (maybe you know that from Facebook's friend-list), because it is one of the requirements.

Scrolling down with Selenium Webdriver (I use Chrome) should be no problem via Javascript. But there is a problem with the dynamically added content. How can I make the Webdriver find those elements?

I tried the following to scroll down until no more content is loaded:

int oldSize = 0;
int newSize = 0;
do {
  driver.executeScript("window.scrollTo(0,document.body.scrollHeight)");
  newSize = driver.findElementsBy(By.cssSelector("selector").size();
} while(newSize > oldSize);

But though the page scrolls down the first time and some now content is loaded correctly, they will not be found by the drivers' findElementsBy(By) function.

Has someone ever faced this problem?? I'd be very glad if someone could help me figuring a solution for that!

Regards, Benjamin

Paulus answered 2/10, 2012 at 14:23 Comment(1)
I will have to scroll down in order to load the elements (via ajax). As I said I use Chromedriver.Paulus
C
5

I would recommend using WebDriverWait with ExpectedConditons.

//scroll down with Javascript first
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("selector")));
//interact with your element
element.click()

Take a look at the guidance provided by Selenium Official page: http://seleniumhq.org/docs/04_webdriver_advanced.html

Cyclostyle answered 2/10, 2012 at 19:10 Comment(1)
+1. not bad approach but seems to me better choose fluent wait for this case.Maressa
M
1

try using fluent wait in particular. The main feature is:

An implementation of the Wait interface that may have its timeout and polling interval configured on the fly. Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.

public WebElement fluentWait(final By locator){
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                .withTimeout(30, TimeUnit.SECONDS)
                .pollingEvery(5, TimeUnit.SECONDS)
                .ignoring(NoSuchElementException.class);

        WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
            public WebElement apply(WebDriver driver) {
                        return driver.findElement(locator);
                }
                }
);
                           return  foo;              }     ;

The method described returns you web element you can operate with. So the approach be the following: 1) you need to find the selectors of elements you expect to be rendered after scrolling e.g.

String cssSelector = "blablabla"

2) scroll down with js 3)

WebElement neededElement  = fluentWait(cssSelector);
neededElement.click();
//neededElement.getText().trim();

you can get more info about fluent wait here

Maressa answered 4/10, 2012 at 14:6 Comment(5)
I have only one question - How does one do new Function<WebDriver,WebElement> in Java considering there is no function templating? The above example is mentioned in selenium javadocs as well, but javac will give me a cannot find symbol:class Function - I would like to understand what part I have missed in grasping to enable me to use above approach straight off the bat.Tilton
could you clarify me a lil bit: what do you mention saying function templating in Java ?Maressa
i'm not sure what exactly you mean saying 'function templating' but new Function<WebDriver, WebElement>() { creates instance of anonymous class being passed to wait.until Function is defined in selnium API. until(com.google.common.base.Function<? super T,V> isTrue) Repeatedly applies this instance's input value to the given function until one of the following occurs: the function returns neither null nor false, the function throws an unignored exception, the timeout expires, the current thread is interrupted Any complie issues - it seems you haven't setUp IDE settings properly (IMHO)Maressa
selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/… try to get about newFunction defined in selenium API hereMaressa
You're right, I was confused with two three concepts :) thanks for the patient answerTilton
B
0

I think the problem is waiting for the dynamic content to finish loading. Try to wait 3 seconds just before findElementsBy? In C# the code would be Thread.Sleep(3000);

Bratislava answered 2/10, 2012 at 17:14 Comment(2)
good idea, tried it out... findElements still deliveres just the elements that were loaded from the beginning onPaulus
@Benjamin: Have you tried a longer time like 5 seconds? Could you verify in SeleniumIDE that the css selector works when the element do present? I would make a test in IDE, but it's tricky to simulate scroll - you can try keyPress | xpath=/html/body/ | 34 (keycode 34 is pagedown), then waitForElementPresent...Bratislava

© 2022 - 2024 — McMap. All rights reserved.