selenium get current url after loading a page
Asked Answered
F

3

31

I'm using Selenium Webdriver in Java. I want to get the current url after clicking the "next" button to move from page 1 to page 2. Here's the code I have:

    WebDriver driver = new FirefoxDriver();
    String startURL = //a starting url;
    String currentURL = null;
    WebDriverWait wait = new WebDriverWait(driver, 10);

    foo(driver,startURL);

    /* go to next page */
    if(driver.findElement(By.xpath("//*[@id='someID']")).isDisplayed()){
        driver.findElement(By.xpath("//*[@id='someID']")).click();  
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='someID']")));
        currentURL = driver.getCurrentUrl();
        System.out.println(currentURL);
    }   

I have both the implicit and explicit wait calls to wait for the page to be fully loaded before I get the current url. However, it's still printing out the url for page 1 (it's expected to be the url for page 2).

Francoise answered 26/4, 2013 at 17:48 Comment(1)
BTW, the docs (now?) say not to mix implicit/explicit waits due to it making the wait time unpredictable. Relevant quote: WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds. From: seleniumhq.org/docs/04_webdriver_advanced.jsp#implicit-waitsCounteract
Y
31

Like you said since the xpath for the next button is the same on every page it won't work. It's working as coded in that it does wait for the element to be displayed but since it's already displayed then the implicit wait doesn't apply because it doesn't need to wait at all. Why don't you use the fact that the url changes since from your code it appears to change when the next button is clicked. I do C# but I guess in Java it would be something like:

WebDriver driver = new FirefoxDriver();
String startURL = //a starting url;
String currentURL = null;
WebDriverWait wait = new WebDriverWait(driver, 10);

foo(driver,startURL);

/* go to next page */
if(driver.findElement(By.xpath("//*[@id='someID']")).isDisplayed()){
    String previousURL = driver.getCurrentUrl();
    driver.findElement(By.xpath("//*[@id='someID']")).click();  
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

    ExpectedCondition e = new ExpectedCondition<Boolean>() {
          public Boolean apply(WebDriver d) {
            return (d.getCurrentUrl() != previousURL);
          }
        };

    wait.until(e);
    currentURL = driver.getCurrentUrl();
    System.out.println(currentURL);
} 
Yarrow answered 26/4, 2013 at 18:31 Comment(7)
I tried that, but an error popped out and said I need to make currentURL final. but then I won't be able to update itFrancoise
I'm not a Java developer so I'm not sure about the syntax. The error you're getting sounds like it can be one of two things, either you need to pass currentURL into the expected condition somehow, which I don't know how to do or you need a different variable to store the url in since you change it later. I've updated my answer for the last approach, can you try that?Yarrow
You can also try to declare previousURL as finalYarrow
Great to hear it, did you have to add final or did adding previousURL fix it?Yarrow
Has anyone seen a similar approach like this, but for Python?Inseparable
In no case you should compare strings with !=. This should be !string1.equals(string2) instead.Inquisitionist
Not a Java expert, I did my best to C#.Net code into Java syntax in order to show the general idea of how to accomplish what the op wantedYarrow
L
2

Page 2 is in a new tab/window ? If it's this, use the code bellow :

try {

    String winHandleBefore = driver.getWindowHandle();

    for(String winHandle : driver.getWindowHandles()){
        driver.switchTo().window(winHandle);
        String act = driver.getCurrentUrl();
    }
    }catch(Exception e){
   System.out.println("fail");
    }
Ligneous answered 7/4, 2014 at 13:39 Comment(0)
E
0

It's been a little while since I coded with selenium, but your code looks ok to me. One thing to note is that if the element is not found, but the timeout is passed, I think the code will continue to execute. So you can do something like this:

boolean exists = driver.findElements(By.xpath("//*[@id='someID']")).size() != 0

What does the above boolean return? And are you sure selenium actually navigates to the expected page? (That may sound like a silly question but are you actually watching the pages change... selenium can be run remotely you know...)

Eurhythmy answered 26/4, 2013 at 18:0 Comment(1)
Yes selenium actually navigates to the next page as I was watching it. And I think I've figured out why it didn't work. It's because the xpath I passed in is the xpath for the "next" button which is on every page. So I can't use that to stop the driver from waiting for the next page to load... if that makes sense to you. However, I don't understand why the implicit call won't work either. Is there any other way around it?Francoise

© 2022 - 2024 — McMap. All rights reserved.