Best approach to use when values are dynamically created?



  • I'm looking for some advice on how to select a WebElement. When I click a button that creates a new 'page', the given value is dynamic, in that it is totally random and not sequential. I would expect it to follow something like: page 1 = 0, page 2 = 1, page 3 = 2, etc.

    By default I begin with a page. Although when I trigger a button to create new pages the values appear as follows:

    <select class="j-currentPage f-feature-A" name="currentPage">  <option value="c3">New Page</option>  <option value="c277">New Page 2</option>  <option value="c383">New Page 3</option>  <option selected="" value="c461">New Page 4</option>  </select>
    

    So when I attempt to use the following:

     List option = chrome.findElements(By.tagName("option"));
    
        option.get(0).click();
        option.get(1).click();
        option.get(0).click();
    

    It's obviously failing as the values are c277, c346 etc etc, and there is no way of knowing what the values will be in a new session as they will always be different.

    The stacktrace is throwing a StaleElementReferenceException because its not in the DOM.

    How can I select each page when the values are completely random?

    I'm using Webdriver and JUnit4.

    EDIT

    Test method: to create some new pages.

    @Saumya public void createANewPage(){
        WebDriverWait wait = new WebDriverWait(chrome, 60);
    
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));
    
        WebElement newPage = chrome.findElement(By.cssSelector("span.j-addViewBtn.ss-layers"));
        newPage.click();
    
        List option = chrome.findElements(By.tagName("option"));
    
        option.get(1).click();
    
        option.get(0).click();
    }
    

    Then a few tests later I want to call back the created page(s)

    @Test
    public void goToPage(){
    
        new WebDriverWait(chrome, 60).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));
        List option = chrome.findElements(By.tagName("option"));
    
        option.get(0).click();
        option.get(1).click();
        option.get(0).click();
    }
    

    I receive a org.openqa.selenium.StaleElementReferenceException at the point of the third option.get(0).click();

    However I feel as though I'm approaching this the wrong way as the values are dynamically created




  • If the element you are interacting with is being replaced in the DOM, which appears to be the case since you're getting a stale element exception, you'll need to find the element again rather than re-using the existing one. So for example, you would do this:

    chrome.findElements(By.tagName("option")).get(0).click();
    chrome.findElements(By.tagName("option")).get(1).click();
    chrome.findElements(By.tagName("option")).get(0).click();
    

    Another option would be to put it in a try/catch block and refresh only if an exception is caught. I found a good example of a generic method of waiting for all of your elements here: https://gist.github.com/djangofan/5112655

    Whether the element is being generated dynamically or not is really kind of irrelevant, this happens any time an element is removed from the DOM and then re-added (including if you navigate to a new page and then back to the original page).



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2