1

I am learning Selenium Webdriver using Java. As a learning example, I tried to open MakeMyTrip, access International Flights page and click on One Way radio button in Google Chrome. I tried different ways to locate this radio button but it's still not working. Please find below my code sample.

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class TryRadioClass {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.setProperty("webdriver.chrome.driver", "Chrome exe path");
        WebDriver driver=new ChromeDriver(); 
        driver.get("http://www.makemytrip.com/international-flights");
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
        boolean displayFlag = driver.findElement(By.linkText("ONE WAY")).isDisplayed();
        System.out.println("Display Flag :- "+displayFlag);
        boolean enableFlag = driver.findElement(By.linkText("ONE WAY")).isEnabled();
        System.out.println("Enable Flag :- "+enableFlag);
        if(displayFlag==true && enableFlag==true)
        {
            WebElement element=driver.findElement(By.linkText("ONE WAY"));
            element.click();
            System.out.println("Tried to click One Way");
        }
    }

}

Can anyone please help me to resolve this issue?

Swapnil Luktuke
  • 10,385
  • 2
  • 35
  • 58
Manasi
  • 717
  • 8
  • 18
  • 30

8 Answers8

5

Use below code :-

    if(displayFlag==true && enableFlag==true)
    {
        try{
        Thread.sleep(5000);
        }
        catch(Exception ex)
        {
            System.out.println(ex.getMessage());
        }
        WebElement element=driver.findElement(By.xpath("//span[@class='radio_state']"));
        JavascriptExecutor executor = (JavascriptExecutor) driver;
        executor.executeScript("arguments[0].click();", element);
        System.out.println("Tried to click One Way");
    }

enjoy .. get back to me if still getting any issue :)

Shubham Jain
  • 16,610
  • 15
  • 78
  • 125
  • Thanks a lot :) It is working now. Is it due to Thread.Sleep? because after addition of this try-catch block my previous xpaths are also working fine. – Manasi Aug 31 '15 at 10:17
  • Yes actually make my trip dynamic page made changes for a moment. to make it stable we need to wait for a while :) – Shubham Jain Aug 31 '15 at 11:59
  • 1
    Please don't use this code. `Thread.sleep()` is not the proper way to do this and should be avoided in most scenarios. What if 5s isn't enough of a sleep? Your test fails. What if the link is available in 100ms? The test still waits 5s anyway slowing down your test. I don't understand the try/catch around the sleep either. Why use JSE to click a link? You should just use `element.click()`. This code may work but none of this is a best practice. I'll add an answer with the proper way to do this. – JeffC Aug 31 '15 at 15:44
  • I accepts that thread.sleep is not a good practice .. instead of it you can also try with driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS); @Jeff -> thread.sleep needs exception handler. So either handle it like that while you can also handle exception by other ways also .. thanks – Shubham Jain Aug 31 '15 at 16:01
  • He's already got implicitWait set... but that's not really a best practice either because it slows down your test if you ever test for the presence of elements. 45s is a really, really long wait too... – JeffC Aug 31 '15 at 16:03
1

Clicking on link sometimes might skip checking the radio button. Try clicking on the radio button (or input html tag) directly rather than clicking on the anchor tag. Here's an example -

WebElement ele=driver.findElement(By.xpath("//input[@value='one_way']"));
ele.click();

Hope this helps.

giri-sh
  • 6,934
  • 2
  • 25
  • 50
  • I updated my code with below xpath, WebElement ele=driver.findElement(By.xpath("//[@id='one_way_button1']/span/input")); ele.click(); But now it gives "element not visible" exception. – Manasi Aug 31 '15 at 09:12
  • @Saisha Above xpath didn't work? You missed to give the type for `id` . Change your xpath to `//*[@id='one_way_button1']/span/input` – giri-sh Aug 31 '15 at 10:10
  • Thanks Girish.This xpath is working now along with thread.sleep – Manasi Aug 31 '15 at 10:22
1
  1. Try to never use Thread.sleep(time)
  2. Never use general Exception catching.

Instead of it try this, what is more safe:

public Boolean isDisplayed() {
    try {
        wait.withTimeout(20).until(new ExpectedCondition<Boolean>() {
            @Nullable @Override public Boolean apply(WebDriver input) {
              return videoComponent.isDisplayed();
            }
        });
    } catch (TimeoutException e) {
        return false;
    }
    return true;
}

This code will check markup within 20 seconds until it return true.
If not, after 20 sec it will return false.

Always specify Exception type, which you want to catch. In other cases it is useless.

user3666197
  • 1
  • 6
  • 50
  • 92
  • Instead of using the grave (`) to mark code, indent each line with 4 spaces and it will create a block of code. – JeffC Aug 31 '15 at 16:04
  • I am not too familiar with java, not sure how to add this code in my class.Should I create new method? and then pass variables to this? tried to add this as new method but it gave error for wait and videoComponent variables. – Manasi Sep 02 '15 at 09:52
  • @Saisha To create an wait object first you need to create am WebDriver instance: WebDriver driver = new FirefoxDriver(); and then add wait: WebDriverWait wait = new WebDriverWait(driver, 10); – mateusz sanko Sep 02 '15 at 10:16
  • You've got some live examples here: [link](https://gist.github.com/djangofan/5112655) – mateusz sanko Sep 02 '15 at 10:23
0

As per my check, the specific radio button has following structure:

<a id="one_way_button1" href="javascript:void(0);" onclick="change_trip_type('one_way_button', 'trip_type', 'o');" class="one_way_button trip_type row first seg_text" tabindex="1">

    <span class="radio_state">
        <input type="radio" name="way_fields" value="one_way">
    </span> ONE WAY

</a>

So what you are gonna to click is not the tag a which contains 'ONE WAY' but the span inside. You may have a try to locate the span by using xpath

"//a[text()='ONE WAY']/span[@class='radio_state']"
J.Lyu
  • 932
  • 7
  • 16
  • Tried this xpath but getting "no such element" exception. – Manasi Aug 31 '15 at 09:18
  • @Saisha Please copy the text from you firebug&google dev tool, the text 'ONE WAY' may has space around – J.Lyu Aug 31 '15 at 09:20
  • @Saisha try driver.findElement(By.xpath("//a[@id='one_way_button1']/span[@class='radio_state']")); – J.Lyu Aug 31 '15 at 09:31
  • For above xpath I am getting "No such element" error. – Manasi Aug 31 '15 at 09:40
  • @Saisha No idea. I have tested "//a[@id='one_way_button1']/span[@class='radio_state‌​'] and it works well. Maybe due to your browser or configuration things. – J.Lyu Aug 31 '15 at 09:46
0

Try below xpath.

//*[@id="one_way_button1"]/span/input

It should work.

driver.findElement(By.xpath(//*[@id=\"one_way_button1\"]/span/input)).click();
Mayur Shah
  • 518
  • 3
  • 8
  • I tried `driver.findElement(By.xpath("//*[@id=\"one_way_button1\"]/span/input")).click();` but getting "Element not visible " error. – Manasi Aug 31 '15 at 09:40
  • Can you use webdriver wait? WebDriverWait wait = new WebDriverWait(driver,25); wait.untilElementIsVisible(driver.findElement(By.xpath("//*[@id=\"one_way_button1\"]/span/input")); – Mayur Shah Aug 31 '15 at 09:45
0

We have found in the past that with a radio and a click that the above happens (Sometimes it clicks it sometimes it does not) and as we try and steer clear of wait for tasks/Thread.Sleep (Due to then timing issues it then can cause on different environments). This alone can become a giant headache quick in using thread.sleeps :p

We have personally found that sometimes the best solution is to send a click then a (Sendkeys.Enter or a Sendkeys.Space) or just send the (Sendkeys.Enter or a Sendkeys.Space) only and don't use the click with a radio. Especially on pages that use Telerik controls. This then tends to work on multiple machines/environments without the need to add a Thread.Sleep and make every test which uses that step take way longer than it needs to (Trust me when you have 1000's of tests that 5s thread.sleep soon adds up if a lot of tests use the same method)

Just throwing in another possible solution into the mix...

MajorShots
  • 50
  • 5
0

This is the more proper way to do this and I just tested it and it works fine. The best practice is to wait for the element to be clickable. You do that using WebDriverWait with ExpectedConditions. What this will do is wait up to 20s for the element to appear, when it does execution continues. This is a big advantage over Thread.sleep().

driver.get("http://www.makemytrip.com/international-flights");
driver.manage().window().maximize();
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement oneWayRadioButton = wait.until(ExpectedConditions.elementToBeClickable(By.id("one_way_button1")));
oneWayRadioButton.click();
System.out.println("Clicked One Way");
JeffC
  • 22,180
  • 5
  • 32
  • 55
  • 3
    I tried above code but it is not working :( It did not give any exception. Also "Clicked one way" is printed, but element is not clicked on browser. – Manasi Sep 02 '15 at 09:50
0

I tried many different ways to force selenium to wait for the radio button to be visible but it kept timing out. I eventually had to settle for clicking the label for:

WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = driver.findElement(selector);
wait.until(ExpectedConditions.elementToBeClickable(element));
element.click();

Where selected is defined by:

By selector = By.cssSelector(cssSelector);

With HTML looking like this:

...
<div class="multi-choice">
    <input id="wibble" type="radio" name="wobble" value="TEXT">
    <label for="wibble">Wobble</label>
</div>
...

And an example string cssSelector of:

String cssSelector = "label[for='wibble']"
theINtoy
  • 3,388
  • 2
  • 37
  • 60