selenium span link li not working - selenium

I am new to selenium. I am practicing to write a test case on http://www.countdown.tfl.gov.uk. Below are the steps I followed:
a) I opened the browser to selenium Web Driver
b) Found the search text Box and enter H32 and clicked on search button to selenium.
Till this part it works fine.
Now on the page I am actually getting two records on the left side of the page under the search. I am actually trying to click on the first one i.e. "Towards Southall,Townhall" link. Nothing is happening.
Below is my code:
public class CountdownTest {
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver)
}
//open the countdowntfl page
private WebDriver openWebDriver(){
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.get("http://www.countdown.tfl.gov.uk");
return driver;
}
private void searchforBus(WebDriver driver,String search){
WebElement searchBox = driver.findElement(By.xpath("//input[#id='initialSearchField']"));
searchBox.sendKeys(search);
WebElement searchButton = driver.findElement(By.xpath("//button[#id='ext-gen35']"));
searchButton.click();
}
private void selectrouteDirection(WebDriver driver){
WebElement towardssouthallLink= driver.findElement(By.xpath("//span[#id='ext-gen165']']"));
((WebElement) towardssouthallLink).click();
}
}
Please help me.
Thanks.

Since you are getting NoSuchElement Exception now, you may try the following code with the usage of WebDriver explicit wait.
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement towardssouthallLink = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("(//*[#id='route-search']//li/span)[1]")));
towardssouthallLink.click();
Or WebDriver implicit wait
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("http://www.countdown.tfl.gov.uk");
Tips:
The search results need some time to be retrieved, so please use Explicit wait or Implicit wait.
Don't use locators like span[#id='ext-gen165'], they are ExtJs auto generated.
In this case, css selector can also be used: #route-search li:nth-of-type(1) > span

You aren't calling selectrouteDirection.
You probably want:
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver);
}
You also don't need to cast here:
((WebElement) towardssouthallLink).click();
It's already a WebElement anyway.

I found that id for those links are dynamically generated. ids are of the form 'ext-genXXX' where XXX is number which is dynamically generated hence varies each time.
Actually, you should try with linkText:
For 'Towards Southall, Town Hall'
driver.findElement(By.linkText("Towards Southall, Town Hall")).click
For 'Towards Hounslow, Bus Station'
driver.findElement(By.linkText("Towards Hounslow, Bus Station")).click
Here is a logic:
Get all elements which have id starts with 'ext-gen' & iterate over it & click on link with matching text. Following is Ruby code(sorry, I don't know Java well):
links = driver.find_elements(:xpath, "//span[starts-with(#id, 'ext-gen')]")
links.each do |link|
if link.text == "Towards Southall, Town Hall"
link.click
break
end
end

Related

How to wait until getAttribute return specific string (text) in selenium

I have a question.
In a page that I am testing their is a field, that include .
I want selenium to wait until
getWebDriver().findElement((locator)).getAttribute("value");
will return a certain text.
is their a way to selenium wait until getAttribute will return a custom text?
this is the dome
this is the screen
I want selenium to wait until BBBOOBP displayed.
you should use Selenium web driver explicit wait conditions to wait till element with text be present in DOM.
Official documentation with the sample in different languages:
https://www.selenium.dev/documentation/en/webdriver/waits/#explicit-wait
Let me know if that doesn't help you.
This is what solved my problem
public void waitForElementAttributeEqualsString(By locator, String expectedString)
{
WebDriver driver = getWebDriver();
WebElement element = driver.findElement(locator);
WebDriverWait wait = new WebDriverWait(driver, EXPLICIT_WAITE);
ExpectedCondition<Boolean> elementAttributeEqualsString = arg0 -> element.getAttribute("value").equals
(expectedString);
wait.until(elementAttributeEqualsString);
}

Getting error when trying to execute this code for MMT site

I have used the following code.I am getting NoSuchElementException error when I am trying to run this code for make my trip site
public class suggestiveDropdown_MMTsite {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
System.setProperty("webdriver.chrome.driver", "C:\\Webdriver\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.makemytrip.com/");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Actions a = new Actions(driver);
WebElement source = driver.findElement(By.id("fromCity"));
a.moveToElement(source).click().build().perform();
a.moveToElement(source).sendKeys("MUM").build().perform();
/*WebDriverWait w = new WebDriverWait(driver,5);
w.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.id("react-autowhatever-1")));*/
WebElement dropdown1 = driver.findElement(By.id("react-autowhatever-1-section-0-item-0"));
a.moveToElement(dropdown1).click().build().perform();
WebElement destination = driver.findElement(By.id("toCity"));
a.moveToElement(destination).click().build().perform();
a.moveToElement(destination).sendKeys("DEL").build().perform();
a.moveToElement(dropdown1).click().build().perform();
}
}
You need to re-identify dropdown1 as the second time it appears it's in a different location in the source an a different webelement.
I see your logic and why you think it would work as it has the same ID - but when you use your By you're returning a specific webelement from the DOM. Even though the ID is reused due to whatever javascript magic, the webelement is different (it's in a different position after all).
The two bits I'm talking about....
1/ This part of your code finds the object:
WebElement dropdown1 = driver.findElement(By.id("react-autowhatever-1-section-0-item-0"));
a.moveToElement(dropdown1).click().build().perform();
2/ It is no longer dropdown 1. It has the SAME ID, but it's a different webelement
a.moveToElement(dropdown1).click().build().perform();
Solution here is re-get the element and I suggest to rename it to help clarify the difference. Change your last line to something like this:
WebElement firstItemInToCity= driver.findElement(By.id("react-autowhatever-1-section-0-item-0"));
a.moveToElement(firstItemInToCity).click().build().perform();
I've had another look. This works for me:
driver.get("https://www.makemytrip.com/");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
//Actions a = new Actions(driver);
//from city:
WebElement source = driver.findElement(By.id("fromCity"));
source.click();
source.sendKeys("MUM");
//select first item in the list
WebElement dropdown1 = driver.findElement(By.id("react-autowhatever-1-section-0-item-0"));
dropdown1.click();
//Get the to city
WebElement destination = driver.findElement(By.id("toCity"));
destination.click();
destination.sendKeys("DEL");
//pick the first item in the list
WebElement firstItemInToCity= driver.findElement(By.id("react-autowhatever-1-section-0-item-0"));
firstItemInToCity.click();
You do not need to use the actions to interact. Using the selenium native interactions seems fine.
I did have increase the implicit timeout as the page is quote slow to load for me.

Click functionality is not working good all the time on CRM application

Sources: Selenium WebDriver, Chrome 73V, ChromeDriver, Java , testNG, CRM application , Eclipse
I am working on web application which is kind of CRM, loaded with tons of UI elements. One test case works today and fail tomorrow. FYI, I used fluent wait for my test cases.
I checked all the xpaths and they are good. On top of this I executed with Debug mode and tests are passing on debug mode.
They are randomly flaky and un-stable , I am not sure what to do to make them stable? I don't want to use thread.sleep , off course.
Below code (just for the idea) I used to click few elements of the page , sometime Action class works sometime doesn't and sometime Click function works sometime doesn't, not sure how to handle such weird scenario?
driver.findElement(By.name("submit")).sendKeys(Keys.ENTER);
OR
driver.findElement(By.name("submit")).sendKeys(Keys.RETURN);
OR
driver.findElement(By.name("submit")).click();
OR
WebElement webElement = driver.findElement(By.id("Your ID Here"));
Actions builder = new Actions(driver);
builder.moveToElement(webElement).click(webElement);
builder.perform();
OR
WebElement webElement = driver.findElement(By.id("Your ID here"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", webElement);
Thanks for your comments, Please see below, this is my fluent wait:
public static boolean waitForElementToBeVisibleOrClickable (WebDriver driver, WebElement element) {
boolean webElement = false;
try {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 30)
.ignoring(NoSuchElementException.class,
StaleElementReferenceException.class)
.pollingEvery(200);
wait.until(ExpectedConditions.visibilityOf(element));
**OR**
wait.until(ExpectedConditions.elementToBeClickable(element));
Log.info("Element is visible");
webElement = true;
} catch (Exception e) {
Log.error("Element is not visible");
webElement = false;
} finally {
driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
}
return webElement;
}
You defined method to wait, but you don't actually use it. You are locating the element using driver and immediately click it. You should also modify the wait to use it while locating the element, not afterwards
public WebElement waitForElement(By by) {
return wait.until(ExpectedConditions.visibilityOfElementLocated(by));
}
waitForElement(By.name("submit")).click();
You need to take care of the couple of things:
To invoke click() on an element you should always induce WebDriverWait for the elementToBeClickable().
You can find a relevant discussion in How to click a hyperlink without any link text
If the element is within a <form> tag, as an alternative you can use the submit() method.
You can find a detailed discussion in Selenium: submit() works fine, but click() does not
As per the documentation, 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.
You can find a detailed discussion in How to properly configure Implicit / Explicit Waits and pageLoadTimeout through Selenium?
Solution
Instead of using fluent wait you can induce WebDriverWait in conjunction with ExpectedConditions and an optimized code block will be:
public static boolean waitForElementToBeVisibleOrClickable (WebDriver driver, WebElement element) {
try {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
new WebDriverWait(driver, 30).until(ExpectedConditions.elementToBeClickable(element));
System.out.println("Element is clickable now");
} catch (TimeoutException e) {
System.out.println("Element isn't clickable");
} finally {
driver.manage().timeouts().implicitlyWait(45, TimeUnit.SECONDS);
}
return element;
}

Find Elements by Xpath not giving the correct element in Selenium Webdriver

In the following example, I have to click only for Jet Airways. It appears that the xpath selected is correct since it gives the right only from the selection.
http://i.imgur.com/8TiOgha.png
However when this same is being pulled by Selenium WebDriver, it says element not visible. But it still gives a Button with zero length text string. as given in watch window.
http://i.imgur.com/jrR0221.png
I would appreciate if anyone can help me to point if any error I am making since I am new to VBA
Not sure if your XPath is correct and is locating the right static element...
You may use this for locating 'Jet Airways'
//label[text()[contains(.,'Jet Airways')]]
Also, using .click(), try clicking on the 'Airlines' dropdown before locating the 'Airlines Dropdown' XPath
//span[#title='Airlines']
Update:
public class SkyScanner
{
static String chkBxXpth = "//label[#class='dropdown-item cfx']/input[#checked]";
public static void main(String[] args) throws InterruptedException
{
WebDriver driver = new FirefoxDriver();
Actions actions = new Actions(driver);
WebDriverWait wait = new WebDriverWait(driver, 30);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.get("http://skyscanner.cntraveller.com/en-GB/flights#/result?originplace=AUH&destinationplace=LHR");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//span[#title='Airlines']")));
driver.findElement(By.xpath("//span[#title='Airlines']")).click();
List<WebElement> chkBx = driver.findElements(By.xpath(chkBxXpth));
for(WebElement i : chkBx)
{
actions.moveToElement(i).click().perform();
}
driver.findElement(By.xpath("//label[text()[contains(.,'Jet Airways')]]")).click();
}
}

Why the select method is not working in the category field?

My Code:
public class asdadsd {
public static void main(String[] args) throws InterruptedException {
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://talentrack.in");
driver.findElement(By.xpath(".//*[#id='header']/div[2]/div[2]/div[2]/a/span")).click();
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[#id='userlogin']/div/div[4]/a[1]")));
driver.findElement(By.xpath(".//*[#id='userlogin']/div/div[4]/a[1]")).click();
WebElement name = driver.findElement(By.xpath(".//*[#id='name']"));
name.sendKeys("anyname");
//WebDriverWait wait = new WebDriverWait(driver, 20);
//wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("select[id='cat_id'][name='cat_id']")));
Thread.sleep(5000L);
//WebElement category = driver.findElement(By.cssSelector("select[id='cat_id'][name='cat_id']"));
WebElement category = driver.findElement(By.cssSelector("#cat_id"));
Select a =new Select(category);
a.selectByValue("5");
}
}
What is wrong with category drop-down ? I'm able to fill values in other drop-downs. Please Help me in getting rid of this.
Error:
Element is not currently visible and so may not be interacted with
Command duration or timeout: 13 milliseconds
I applied wait to, still it is not working.
#Kishan,
In your code WebDriver unable to select the dropdown because it found two matching element with your css selector. PFA the screenshot. So if you want to use css selector then you can use:
#cat_id[class='input-control modal-tab-selection placeholder-color'] instead of #cat_id.
WebElement category = driver.findElement(By.cssSelector("#cat_id[class='input-control modal-tab-selection placeholder-color']"));
Select a =new Select(category);
a.selectByValue("5");
I hope this will help.
WebElement category = driver.findElement(By.xpath(".//*[#id='cat_id'][#data-message='required']"));
Select a =new Select(category);
a.selectByValue("4");
Finally i got it..
This was the xpath which helped me to uniquely identify the dropdown. Thanks Vaibhav for your help. Never trust xpath, better create your own. ha ha..
Happy Learning. :-)