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 but
Thread.sleep(time)
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.
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");
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...
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']"
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']"
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.