I want to check whether option in the dropdown is selected or not. Webdriver should wait until value is selected and after that perform the next operation. I tried to use elementToBeSelected / elementSelectionStateToBe but i could not make it. How to use this?
Using WebDriverWait with ExpectedCondition "elementToBeSelected" should do what you want (it calls elementSelectionStateToBe with parameter true).
If it doesn't work for you, check that the passing argument is indeed the WebElement of option you want to have selected.
The code could look like as follows:
WebElement option = driver.findElement(By.xpath("path/to/your/option[2]"));
new WebDriverWait(driver, 10)
.until(ExpectedConditions.elementToBeSelected(option));
Another option for you is creating your own condition with anonymous class, that can be for example equality of values.
final Select select = new Select(driver.findElement(By.xpath("path/to/your/select"));
new WebDriverWait(driver, 10)
.until(new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
// this will get actual selected option and compare its value with expected value
return select.getFirstSelectedOption().getAttribute("value").equals(expectedValue);
}
});
try
WebElement searchDDwn = driver.findElement(By.xpath(".//*[#id='edit-source']"));
Select dropdown= new Select(searchDDwn);
dropdown.selectByValue("Website");
WebElement selected = dropdown.getFirstSelectedOption();
boolean elementToBeSelected = wait.until(ExpectedConditions.elementToBeSelected(selected));
System.out.println("elementToBeSelected results"+elementToBeSelected);
Related
I am trying to perform an explicit wait in Katalon (which uses Groovy). I have the following code :
// wait on page change to "Dashboard"
WebDriverWait dashboardChangeWait = new WebDriverWait(driver, 3)
/* This is causing the following Exception :
* - GroovyCastException : Attempt to cast 'true' with class 'java.lang.Boolean' to class
* 'org.openqa.selenium.WebElement'
* */
WebElement element = dashboardChangeWait.until(
ExpectedConditions.textToBe(By.cssSelector('.breadcrumb-item.active'), "DASHBOARD"))
which is giving me a GroovyCastException. I know that WebDriverWait.until takes a Function (yay, JavaScript-like coding!) argument, and that ExpectedConditions.textToBe returns a ExpectedCondition<Boolean> and until's signature is V org.openqa.selenium.support.ui.FluentWait.until(Function<Object, Object<V>> arg0) . Is there a way to perform this type of wait in Katalon, that avoids this issue?
You were pretty close. The ExpectedConditions method textToBe() is defined as follows:
public static ExpectedCondition<java.lang.Boolean> textToBe(By locator, java.lang.String value)
An expectation for checking WebElement with given locator has specific text
Parameters:
locator - used to find the element
value - used as expected text
Returns:
Boolean true when element has text value equal to #value
So you just need to change the return type to boolean instead of WebElement as follows:
Boolean status = dashboardChangeWait.until(ExpectedConditions.textToBe(By.cssSelector('.breadcrumb-item.active'), "DASHBOARD"))
I'm new to Selenium, TestNG and Stackoverflow.
After sendkeys, I want to do some validation. If the validation is true, then the assert is true. I know this is not the right way to write the Assert method.
WebDriver driver;
#DataProvider(name= "testdata")
public static Object[][] loginData(){
return new Object[][]{{"username1", "123"}, {"username2", "4211"}};
}
#BeforeTest
public void configure(){
....
}
#Test(dataProvider = "testdata")
public void testmethod(String uname, String password){
WebElement usernameTextbox = driver.findElement(By.id("username"));
usernameTextbox.sendKeys(uname);
WebElement passwordTextbox = driver.findElement(By.id("username"));
passwordTextbox.sendKeys(uname);
driver.manage().timeouts().implicitlyWait(2, TimeUnit.MICROSECONDS);
Assert.assertTrue(if(usernameTextbox.contains("[a-zA-Z0-9]+") && passwordTextbox.contains("[0-9]+") == true));
PS: Any inputs will be appreciated.
Try implementing explicit wait in Your code. What that mean, is that You wait for some condition to be set, here is example how to manage this:
But my suggestion is that You assert if there are some error messages (labels, span, or whatever that appears saying something is wrong with email or pass)
So here is how I would do it:
WebDriver driver;
#DataProvider(name= "testdata")
public static Object[][] loginData(){
return new Object[][]{{"username1", "123"}, {"username2", "4211"}};
}
#BeforeTest
public void configure(){
driver = new WebDriver();
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS); //this is wait which will wait until driver throws exception (that is not found eg."NoSuchElementException")
}
#Test(dataProvider = "testdata")
public void testmethod(String uname, String password){
WebElement usernameTextbox = driver.findElement(By.id("usernameID"));
usernameTextbox.sendKeys(uname);
WebElement passwordTextbox = driver.findElement(By.id("passwordID"));
passwordTextbox.sendKeys(password); //here is where You've sent wrong param
// if You know You will get error label or something use this
WebDriverWait wait = new WebDriverWait(driver, 10); //wait for max 10 sec, and wait for error element defined bellow
WebElement errorElement = wait.until(ExpectedConditions. presenceOfElementLocated(By.id("someErrorElementId"))); //(or ExpectedConditions.textToBePresentInElement(..)), see what better suites You
// If You're expecting error than use this assert
Assert.assertTrue(errorElement.isDisplayed(),"There should be error message!")
// but If You're expecting that there should not be any error than use this assert
Assert.assertFalse(errorElement.isDisplayed(),"There shouldn't be no error messages!")
}
tweak this code, but basicaly this is the logic.
So to try to answer the original question your code could look like below:
1. Using the getAttribute("value")
2. Building the assertion - you don't need to wrap the condition in an if as the contains() function will return true or false for you:
WebDriver driver;
#DataProvider(name= "testdata")
public static Object[][] loginData(){
return new Object[][]{{"username1", "123"}, {"username2", "4211"}};
}
#BeforeTest
public void configure(){
....
}
#Test(dataProvider = "testdata")
public void testmethod(String uname, String password){
WebElement usernameTextbox = driver.findElement(By.id("username"));
usernameTextbox.sendKeys(uname);
WebElement passwordTextbox = driver.findElement(By.id("username"));
passwordTextbox.sendKeys(uname);
driver.manage().timeouts().implicitlyWait(2, TimeUnit.MICROSECONDS);
Assert.assertTrue(usernameTextbox.getAttribute("value").contains("[a-zA-Z0-9]+") && passwordTextbox.getAttribute("value").contains("[0-9]+"));
HTH
As per your question just after invoking sendKeys() you want to do some assertions.
At this point it is worth to mention that when you invoke sendKeys() on a <input> node/tag/field the HTML DOM is not immediately updated with the value / characters which you have just entered in majority of the cases (of-coarse there are exceptional cases). Moving forward when you invoke click() or submit()on a <button> or similar <input> element, the associated onclick event of this <input> element updates the HTML DOM and the value / characters previously sent through sendKeys() are adjusted within the HTML DOM.
Unless the value / characters are not accommodated within the DOM Tree Selenium won't be able to interact with them.
As per your code block, you have populated the passwordTextbox field with the String value of uname as follows :
passwordTextbox.sendKeys(uname);
This value / characterset is still volatile and editable (can be overwritten/cleared/deleted) as follows :
passwordTextbox.clear();
passwordTextbox.sendKeys("Emma E");
Essentially, Assert methods can be invoked on text those are part of the HTML DOM. As an example you can use the following Assert for a Page Heading, Table Heading, etc :
Assert.assertTrue(if(pageHeaderElement.contains("[a-zA-Z0-9]+") && tableHeaderElement.contains("[0-9]+") == true));
What is the return type of driver.findelement
and what is the return type of driver.getwindowhandles()?
findElement()
findElement() method finds the first WebElement using the given method. So it returns a WebElement.
An Example :
WebElement field = driver.findElement(By.xpath("//button[#class='btn']"));
getwindowhandles()
getwindowhandles() method returns a set of window handles which can be iterated over all open windows through the WebDriver instance by passing them to switchTo() function.
An Example :
Set<String> mySet= driver.getWindowHandles();
In C# FindElement() returns a WebElement, which is the representation of an element on a page:
WebElement frame = driver.findElement(By.tagName("iframe"));
WindowHandles() returns a string representation of the window handle of the current driver:
foreach (string handle in driver.WindowHandles) {
driver.SwitchTo().Window(handle);
}
This link saved me lots of time when I worked in selenium years ago.
List<webelement> lt = driver.findElements(By.locator);
Set<String> set= driver.getWindowHandles();
driver.findelement returns WebElement
driver.getwindowhandles returns Set of Windows
findelement returns the object of the first matching element of the specified locator. So, it's return type is an object.
findelements's return type is an array.
Signature of findElement methid is as below.
WebElement findElement(By by)
So it should return reference of WebElement Interface.
I want to verify if the google search results contain the specific text or not.
Following is my code:
public static void main(String[] args) {
System.out.println("setting the driver path");
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Arushi\\Desktop\\Arushi\\Selenium\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("http://google.com");
driver.manage().window().maximize();
WebElement textbox = driver.findElement(By.name("q"));
textbox.sendKeys("stack");
WebElement button = driver.findElement(By.name("btnG"));
button.click();
String bodyText = driver.findElement(By.tagName("body")).getText();
Assert.assertTrue("Text not found!", bodyText.contains("stackoverflow.com"));
But the above code does not give correct result. The getText() method gets the body text of the page "google.com" instead of the page loaded after performing the search.
I want to know 2 things:
1. Why does getText() above is picking up the body text from google.com
2. What is the correct way to search for the specific text in the google search results.
Note: I also tried driver.getPageSource().contains() method but even that's not giving the correct result.
I would attack this by identifying the exact elements that represent search results on the DOM, then loop over each instance of a search result to validate the text for my search term. Simply searching the full page for some text opens up some opportunities for inaccurate results.
By looking at the DOM of a google search result page, we can see that each of the search results live in a node with class .rc. Children of that node, with classes .r and .s represent the result name and description, respectively.
I'll assume for this example that you'd like to check the search result names for your search term, but you should be able to easily refactor the code below to your specific needs.
public static void main(String[] args) {
// First, let's declare our search term
private String searchTerm = "Selenium";
// Then, let's start our WebDriver and navigate to google
WebDriver driver = new ChromeDriver();
driver.get("http://www.google.com");
driver.manage().window().maximize();
// Next, we'll execute the search
WebElement searchField = driver.findElement(By.name("q"));
searchField.sendKeys(searchTerm);
WebElement searchButton = driver.findElement(By.name("btnK"));
searchButton.click();
// Now, let's gather our search results
List<WebElement> results = driver.findElements(By.cssSelector(".r"));
// Finally, we'll loop over the list to verify each result link contains our term
for (int i = 0; i < results.size(); i++) {
Assert.assertTrue(results.get(i).getText().contains(searchTerm), "Search result validation failed at instance [ + i + ].");
}
}
You may need to add any appropriate waits. This can also be further tweaked to ensure each result will be evaluated before a final pass/fail with a full output of each individual result that did not match the term, but I'll leave that to you to implement. Hopefully this will be a good start for you.
I am using Selenium WebDriver and its was working all fine and today i am getting either timeout if i use the below code or getting the error Unable to find element with id == //*[#id='ctl00_ContentPlaceHolder1_AddControl1_txtName']
i try to use this:
public IWebElement GetElementId(string id)
{
//return Driver.FindElement(By.Id(id));
Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(TimeOut));
return Driver.FindElement(By.Id(id));
}
and tried this:
public IWebElement GetElementId(string id)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement category = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Id(el_id));
});
}
I am still couldn't figured how to avoid time-out or element not found error
any help?
Try using the FluentWait class:
public WebElement fluentWait( final By locator ) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class, StaleElementReferenceException.class);
// use a "custom" ExpectedCondition
WebElement foo = wait.until( new Function<WebDriver, WebElement>() {
public WebElement apply( WebDriver driver ) {
return driver.findElement( locator );
}
});
// usually use one of the built-in ExpectedCondtions
// WebElement foo = wait.until(
// ExpectedConditions.visibilityOfElementLocated( locator );
return foo;
};
you can read about fluent wait here
Or if not check thoroughly if you found locator properly.
Hope this helps you)
You are using xpath but in the findElement you are using By.Id change it as
By.xpath("//*[#id='ctl00_ContentPlaceHolder1_AddeCardControl1_txtName']")
OR
By.id("ctl00_ContentPlaceHolder1_AddeCardControl1_txtName")
If it still shows timeout error then try by specifying the element name too in the xpath like
//div[#id='element_id']
because specifying like this
//*[#id='ctl00_ContentPlaceHolder1_AddeCardControl1_txtName']
may took time by searching all the elements id attribute so if you specify the particular element then the searching time will be minimized.
If it doesn't works then check whether that your xpath is correct or not.