Typing into the input field using sendkeys.
Auto-suggestion comes. The html element is as follows:
<div angucomplete-alt id="ac-{{row.RowId}}" placeholder="Search materials..." maxlength="50" pause="100" selected-object="selectedCon" ng-click="selectedConRow(row)" local-data="materialsConsumables" search-fields="MaterialName" title-field="MaterialName" initial-value="row.materialSelected" minlength="1" input-class="autocomplete" match-class="highlight"></div>
Collecting all the suggestions into a “List” and selecting one of the elements when match occurs with my desired string.
Value is selected and populated into the input field
Fills all other mandatory fields
Clicks “Submit”. But error showing that this input field is empty though it has a value. (P.S.: manually it works, there’s no problem with the application itself.)
Code::
String producttoSelect = "0007950137 - BSS 500ML GLASS -CDN";
WebElement ConProduct1 = objDriver.findElement(By.xpath("//*[#class=\"con_Material ng-isolate-scope\"]/div/input"));
ConProduct1.sendKeys("0007950137 - BSS 500ML GLASS -CDN");
try {
Thread.sleep(5000);
} catch (Exception e) {
}
List<WebElement> productList = objDriver.findElements(By.xpath("//*[#class=\"con_Material ng-isolate-scope\"]/div/div"));
for (WebElement optionP : productList) {
System.out.println(optionP.getText());
if (optionP.getText().equals(producttoSelect)) {
System.out.println("Trying to select Product: " + optionP.getText());
optionP.click();
break;
}
}
Instead of thread.sleep, try using Explicit wait until the list is populated:
By aaa = By.xpath("//*[#class=\"con_Material ng-isolate-scope\"]/div/div");
List<WebElement> suggestList =
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(aaa));
Related
I need to write a selenium with java code where I need to perform all image font and size check but there is a pagination
where the default page set is 50 what if I need to perform font and size check in each page. I have attached my code but it will
check only first page.
Scenario:
1.On Parent page only 50 links are displayed I need to click on each record and perform font/size check in same page
I need to again click on next page and perform same font/size check after completing it should navigate to parent page and
again click on other records and vice versa but again we have pagination on parent page as well.
List<WebElement> list=driver.findElements(By.xpath("//a[#class='primary-cell-text link']"));
System.out.println(list.size());
//Here Pagination code is required ???
ArrayList<String> hrefs = new ArrayList<String>(); //List for storing all href values
for (WebElement var : list) {
System.out.println(var.getText()); // fetch the text present between the anchor tags
System.out.println(var.getAttribute("href"));
hrefs.add(var.getAttribute("href"));
System.out.println("*************************************");
}
//Navigating to each link
int i=0;
for (String href : hrefs) {
driver.navigate().to(href);
System.out.println((++i)+": navigated to URL with href: "+href);
Thread.sleep(3000); // To check if the navigation is done properly.
System.out.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
Thread.sleep(5000);
//Here Pagination code is required ????
//Below code is to perform action
List<WebElement> block=driver.findElements(By.xpath("//*[text()='High' or text()='Medium' or text()='Low']/preceding-sibling::div"));
for(int b=0;b<block.size();b++) {
System.out.println(block.get(b).getCssValue("height"));
System.out.println(block.get(b).getCssValue("width"));
String h=block.get(b).getCssValue("height");
String w=block.get(b).getCssValue("width");
if(h.equals("16px") && w.equals("16px")) {
System.out.println("Height/Width is Matching ");
}
else {
System.out.println("height/Width not matching");
}
}
Thread.sleep(3000);
//High Color Check
List<WebElement> high=driver.findElements(By.xpath("//*[text()='High']/preceding-sibling::div"));
for(int h=0;h<high.size();h++) {
WebElement hvar=driver.findElement(By.xpath(("(//*[text()='High']/preceding-sibling::div)["+(h + 1)+"]")));
String highColor=hvar.getCssValue("background-color");
System.out.println(highColor);
String hexHighcolor=Color.fromString(highColor).asHex();
System.out.println(hexHighcolor);
if(hexHighcolor.equals("#e11900")) {
System.out.println(": High color is matching i.e:#e11900");
}
else {
System.out.println(": Low color is not matching :#e11900");
}
}
You have to add logic for going to the next page like in web pages, we can either scroll down further or click on next page to perform pagination.
So for all pages that you have got, you can call a separate function to check your css values onto them.
I am trying to get all drop downs from a web page and select a value from them in one go.
I have attached a code snippet which gets all the dropdowns which are bootstrapped and under tag on the web page.
I want to access children of each ul tag which are under li tag and click on any of those children.
I am attaching the screen shot taken from web site.
It always says element not interactable eventhough it is clikable element.
Please help.
Application screenshot
Code:
List<WebElement> dropDowns = webDriver.findElements(By.xpath("//ul[contains(#class,'dropdown')]"));
try{Thread.sleep(5000);}catch (Exception e){};
for(WebElement webElement : dropDowns){
try{
List<WebElement> elementList = webElement.findElements(By.xpath("//ul[contains(#class,'dropdown')]//li"));
for (int i = 0 ; i < elementList.size();i++){
elementList.get(i).click();
Thread.sleep(3000);
}
}
catch (Exception e){
System.out.println("-----------Error----------");
continue ;
}
}
try{Thread.sleep(10000);}
catch (Exception e){}
webDriver.quit();
}
I see below issues in your code.
You are trying to use the webElement from dropDowns list which will through stale element exception if you use webElement in the for loop.
Your code will perform the operation on the first operation on the first dropdwn all the times as you are not getting the downdown based on the index.
you mentioned you want to select an item in the list but you are clicking on the each item in the dropdown.
Please try with the below logic.
int dropDowns = webDriver.findElements(By.xpath("//ul[contains(#class,'dropdown')]")).size();
try{Thread.sleep(5000);}catch (Exception e){};
JavascriptExecutor js = (JavascriptExecutor) webDriver;
for(int dropdownIndex =0; dropdownIndex < dropDowns; dropdownIndex++){
WebElement dropdown = webDriver.findElements(By.xpath("//ul[contains(#class,'dropdown')]")).get(dropdownIndex);
try{
List<WebElement> elementList = dropdown.findElements(By.xpath(".//li"));
for (int i = 0 ; i < elementList.size();i++){ // not sure if you really want to click each item in the dropdown, hence not modified this part.
WebElement item = elementList.get(i);
js.executeScript("arugments[0].click()",item);
Thread.sleep(3000);
}
}
catch (Exception e){
System.out.println("-----------Error----------");
continue ;
}
}
I am coding a program in Java using WebDriver and am having a little bit of trouble getting the text after the select webElement.
The HTML code for the part of the website that I want is as follows:
<select name="language" id="langSelect" style="width:100px;">
<option value="1" >Français</option>
</select>
</div>
<div id="content">
<div id="Pagination"></div>
<div id="mid">
</div>
</div>
The textbox class codes for a search bar and a drop down bar of languages
My Java code is currently able to open chrome using the chrome driver and is able to type into the search bar. I am however not able to get the text that results from the entry.
Image
In the image here, I entered "avoir" into the search bar, and I want all of the text inside the boxes after which do not seem to have any id's or names to be used inside the xpath.
Can someone please help me in finding how to get and save the text from those fields after the dropdown language menu?
Thank you in advance!
The code I have so far:
//import statements not shown
public class WebScraper {
public WebScraper() {
}
public WebDriver driver = new ChromeDriver();
public void openTestSite() {
driver.navigate().to(the URL for the website);
}
public void enter(String word) {
WebElement query_editbox =
driver.findElement(By.id("query"));
query_editbox.sendKeys(word);
query_editbox.sendKeys(Keys.RETURN);
}
public void getText() {
//List<WebElement> searchResults =
driver.findElements(By.xpath("//div[#id='mid']/div"));
// Writer writer = new BufferedWriter(new
OutputStreamWriter(new FileOutputStream("status.txt"),
"utf-8"));
//int[] index = {0};
WebElement result=driver.findElement(By.id("mid"));
System.out.println(result.getText());
}
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.chrome.driver", "chromedriver");
System.out.println("Hello");
WebScraper webSrcaper = new WebScraper();
webSrcapper.openTestSite();
webSrcapper.enter("avoir");
webSrcapper.getText();
System.out.println("Hello");
}
}
I have specified three approaches to extract the text from the result box. Please check all the approaches and use the required approach.
If you want to extract all the text, then you can find the element of the result box and then you can get the Text from that.
WebElement result=driver.findElement(By.id("mid"));
System.out.println(result.getText());
If you want to extract the Text based on the Section by section, then you can go with the below approach,
List<WebElement> sectionList=driver.findElements(By.xpath("//div[#id='mid']/div"));
int i=0;
for(WebElement element:sectionList){
System.out.println("Section "+i+":"+element.getText());
i++;
}
If you want to extract the text from specific section, then you can do with the below approach
List<WebElement> sectionList=driver.findElements(By.xpath("//div[#id='mid']/div"));
int i=0;
//Inorder to get the Section 3 Content
int section=2;
for(WebElement element:sectionList){
if(section==i){
System.out.println("Section "+i+":"+element.getText());
}
i++;
}
Edit: To address followup question
I would suggest to use some explicit wait after doing some action which resulting in some element rendering. In your code, after doing some modification, I am getting the result as expected.
In openTestSite method, I have just added the explicit wait to ensure the page load after loading the URL
In enter method, actually you are getting the autocomplete suggestion after entering the query value .So, we need to just select the value from the autocomplete.
In getText method, Search result is taking more time.So, we need to add some explicit wait using any one of the dynamically loading element locator.
Code:
openTestSite Method:
public void openTestSite() {
//driver.navigate().to(the URL for the website);
driver.get("https://wonef.fr/try/");
driver.manage().window().maximize();
//Explicit wait is added after the Page load
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.titleContains("WoNeF"));
}
enter Method:
public void enter(String word) {
WebElement query_editbox =
driver.findElement(By.id("query"));
query_editbox.sendKeys(word);
//AutoComplete is happening even after sending the Enter Key.
// So, Value needs to be selected from the autocomplete
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#class='autocomplete']/div")));
List<WebElement> matchedList=driver.findElements(By.xpath("//div[#class='autocomplete']/div"));
System.out.println(matchedList.size());
for(WebElement element : matchedList){
if(element.getText().equalsIgnoreCase(word)){
element.click();
}
}
//query_editbox.sendKeys(Keys.RETURN);
}
getText Method:
public void getText() {
WebDriverWait wait=new WebDriverWait(driver,20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#id='mid']/div")));
WebElement result=driver.findElement(By.id("mid"));
System.out.println(result.getText());
}
I have tested with the above modified code and it is working fine.
In order to inspect the relevant results for your query, common strategy would be to load a list of search results:
List<WebElement> searchResults = driver.findElements(By.xpath("//div[#id='mid']/div"));
Now you can use stream to iterate over the list and extract your relevant text, by getting the text from child elements of each result:
int[] index = {0};
searchResults.stream().forEach(result -> {
System.out.println("Printing query result of index: " + index[0]);
result.findElements(By.xpath(".//*")).stream().forEach(webElement -> {
try {
System.out.println(webElement.getText());
} catch (Exception e) {
// Do nothing
}
});
index[0]++;
});
And you would get the output:
List <WebElement> elementCount = dropdown.getOptions();
System.out.println(elementCount.size());
for(int i=0;i<elementCount.size();i++)
{
System.out.println("Value of i is: "+i);
WebDriverWait wait = new WebDriverWait(dri10,500+(elementCount.size()*500));
WebElement element1 = wait.until(ExpectedConditions.elementToBeClickable(By.id("Select Role")));
dropdown.selectByIndex(i); //when the value of i becomes 2 an exception is displayed
Thread.sleep(100+(elementCount.size()*400));
String approle=dri10.findElement(By.id("Select Role")).getText();
String assigrole=s1.getCell(3,16).getContents(); //Fetching data from excel
if(approle.equals(assigrole))
{
dri10.findElement(By.id("Submenu")).click();
}
}
Exception Details: org.openqa.selenium.StaleElementReferenceException: Element not found in the cache - perhaps the page has changed since it was looked up
Command duration or timeout: 146 milliseconds
This exception is thrown when there are js updates on your element.
To avoid this exception, I usually surround my code with :
try{
//some code
}catch (StaleElementReferenceException e){
//retry it
}
I created some functions to avoid it. You can retry multiple time if the app is calling js multiple time also.
There is a button. When you click on this button, a drop down menu having two option appears. How to verify this scenario using selenium in java.
<div class="hpDropDownButton">
<button class="button ng-binding">Holidays Operation</button>
<ul>
<li>
<a class="ng-binding" ng-click="uploadHolidays()">Upload Holidays</a>
</li>
<li>
<a class="ng-binding" ng-click="deleteHolidays()">Delete Holidays</a>
</li>
</ul>
Click on the button
Now :-
Boolean dropdownPresent = driver.findElement("YOUR LOCATOR OF DROPDOWN").isDisplayed();
if(dropdownPresent==true)
{
System.out.println("Dropdown is appearing");
}
else{
System.out.println("Dropdown is not appearing");
}
Hope it will help you :)
You are asking to verify whole scenario. You need to first understand what Selenium-WebDriver is. Refer this tutorial for more explanation.
However you can follow below code,
WebDriver driver = new FirefoxDriver();
String appUrl = "your url";
driver.get(appUrl);
// maximize the browser window
driver.manage().window().maximize();
// upto code from your button
WebElement button_element = driver.findElement(button_locator);
button_element.click();
// to verify a drop down menu having two option appears
boolean flag = isPresent(dropdown_locator);
if (flag) {
// code bases on dropdown displayed
}
else {
// code bases on dropdown not displayed
}
To verify if element is present or not use this method
public boolean isPresent(String locator) {
return findElements(locator).size() > 0 ? true : false;
}
First of all collect all the Drop down values in List, List values = Upload Holidays#Delete Holidays
Then click on Dropdown WebElement, by using DropdownFieldName = driver.findElement(by.xpath(//button[#class='button ng-binding'])).click();
Take the couunt of dropdown values, by drptotalCount = driver.findElements(by.xpath(//a[#class='button ng-binding']));
Now you have expected DropDown values and count of Dropdown Values.
You can take a reference from below code:
checkDropDownValues(String DropdownFieldName, String values){
driver.findElement(By.xath(DropdownFieldName)).click();
WebElement drptotalCount = driver.findElements(by.xpath(//a[#class='button ng-binding']));
int numberOfDropDown = drptotalCount.size();
List<String> allDropDownValues = Arrays.asList(values.split("#"));
for (int colCount = 1; colCount <= numberOfDropDown; colCount++) {
boolean flag = false;
Actualvalue = driver.findElement(By.xpath(drptotalCount + "[.=" + allDropDownValues.get(colCount) +"]"])).getText();
String expectedValues = allDropDownValues.get(colCount);
if(expectedValues.equalIgnoreCase(Actualvalue))
{
flag = true;
}
Assert.assertTrue("Column values doesn't match", flag);
}
}
Click the button (which should be straight forward)
it seems you have some asynchronous call or a delay
Wait for the drop-down 'div.hpDropDownButton' is beeing displayed using WebDriverWait:
WebElement myDynamicDropDown = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.CssSelector("div.myDynamicDropDown")))
continue ..
http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp