Could you please help me for finding an element in webdriver:
Suppose we have two drop downs one is client and second facility. Also, without selecting client we cannot select facility as its disabled.
We've selected client value from drop down.
Now I've written a script for a new tab.
After that, I've to find facility field through ID but it shows element is not found, then could you please help me for the same?
..
Attached is the screen shot for your reference.
Could you please check?
Continue with previous question Select options from Autopopulate text boxes using Selenium webdriver
When you are using same cssSelector second time, it locates first dropdown element which is invisible at that time. you need to use more specific locator as below using label text :-
WebElement facility = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("facility")))
facility.sendKeys("Ho")
List<WebElement> facilityOptions = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(".//div[label[text() = 'Ordering Location']]/ul[#class = 'typeahead dropdown-menu']//a")))
facilityOptions.get(0).click()
Full working example code :-
driver.get("https://bioceptbetaweb.azurewebsites.net/Account/Login");
driver.manage().window().maximize()
WebDriverWait wait = new WebDriverWait(driver, 60)
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username"))).sendKeys("ajay.kumar#technossus.com");
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("password"))).sendKeys("Ajay#123");
wait.until(ExpectedConditions.elementToBeClickable(By.id("btn-Login"))).click();
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Place a New Order"))).click();
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("loaderDiv")));
//this sleep is required because after invisibility of loader focus goes to first input which is Requisition Number
//If you are filling form from first input no need to for this sleep
//if you want to input directly to client field need to sleep to avoid focus first
Thread.sleep(3000);
WebElement client = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("client")));
client.sendKeys("Ho");
List<WebElement> dropdownOptions = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(".//div[label[text() = 'Client']]/ul[#class = 'typeahead dropdown-menu']//a")));
dropdownOptions.get(0).click();
WebElement facility = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("facility")));
facility.sendKeys("Ho");
List<WebElement> facilityOptions = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(".//div[label[text() = 'Ordering Location']]/ul[#class = 'typeahead dropdown-menu']//a")));
facilityOptions.get(0).click();
Related
I'm trying to automate a website which is not under my control, so I can't change its HTML and CSS. I need to select an option from a combo box.
I can successfully find a "select ../>" element but when I try to select an option via SelectByText, ByValue, ByIndex it results in the ElementNotVisibleException. The html is pretty complex on that page and I believe that developers assigned "display:none" by a css-style. I can navigate to the "div" which contains that combo box and click on it via Actions but it doesn't help to select an option after that. After such a click I see for a second the options on the screen and then the combo box collapses.
Is it possible at all to overcome such a problem?
Since Selenium API tries to be "user-centric" it will not allow interaction with non-visible elements. There are two approaches you can try:
1) Click on the select element, then perform an explicit wait for the option to become visible. This is useful if the page is using JavaScript to display the select options which can cause slight delay.
By bySelect = By.id("id_of_select_element");
By byOption = new ByChained(bySelect, By.xpath(".//option[contains(text(), 'text_of_option')]");
WebElement select = driver.findElement(bySelect);
select.click();
try {
// wait at-most 5 seconds for element to become visible
WebElement option = new WebDriverWait(driver, 5)
.until(ExpectedConditions.visibilityOfElementLocated(byOption)));
} catch(TimeoutException t) {
System.err.println("Timed out while waiting for dropdown to become visible: " + byOption.toString());
}
2) If the above doesn't work, you can be a little more invasive and execute some JavaScript to force the option to be selected. This is only recommended as a last resort.
public void selectDropdownByText(WebDriver driver, WebElement select, String text) {
((JavascriptExecutor) driver).executeScript(
"var select = arguments[0]; for(var i = 0; i < select.options.length; i++) {if(select.options[i].text == arguments[1]) {select.options[i].selected = true; }}", select, text);
}
ok, Element is not visible exception is thrown because of "user-centric" behavior of selenium,
In my working experience i found out that,
Selenium is not able to select element which are not visible to clients.
I mean can't select those who not appears on UI Window,
Still those are you can inspect on HTML DOM but cant access through selenium.
When those are visible on screen you can very well select those elements.
solution is before finding out select tag you must click on it to get visible full options tags.
Clicking makes all options that needs to be selected are now visible to clients.
Then you find that select element and then select options under select tag. when those List of options are completely visible on screen.
I am trying to find out the no. of orders in the following picture using
//*[#id='past-orders-tab']/div[contains(#class,'physical')]
but it is returning zero using .size() ( storing in List[WebElement])
.When i picked one order using findelement() ,it is working fine. Here's the page source code
How to correct it?
You should try using WebDriverWait to wait until there is at least one element present on a web page as below :-
WebDriverWait wait = new WebDriverWait(driver, 10);
List<WebElement> ord = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector("#past-orders-tab > div.physical")));
My Selenium web driver is not clicking on this tree node. I don't know exactly what we say it tree node or something else so this is image and I highlighted the element.
This right arrow part on which I want to click
And this is my code:
//wait.until(ExpectedConditions.elementToBeClickable(By.id("iconDiv")));
WebElement taskdropElementid = driver.findElement(By.id("iconDiv"));
System.out.println(taskdropElementid.getAttribute("class"));
if(taskdropElementid.getAttribute("class").equals("RightArrow"))
taskdropElementid.click();
Printing statement is giving me output dropdown. I think it should give RightArrow and when I am uncommenting wait part then it is continuously wait for the element to be clickable.
What am I doing wrong?
Printing statement is giving me output dropdown
That means there are multiple elements with the same id iconDiv and unfortunately you're locating other element instead which has class name dropdown.
If you want to locate element with class name RightArrow, You should try using By.cssSelector() to locate it uniquely as below :-
WebElement taskdropElementid = driver.findElement(By.cssSelector("div#iconDiv.RightArrow"));
taskdropElementid.click();
Before posting this, I've thoroughly researched all possible syntax available for this and got no avail.
The closest I had was using this code where the dropdown actually appeared but didn't select my desired option:
new WebDriverWait(driver,10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("html/body/form/table/tbody/tr[4]/td/div/fieldset/table/tbody/tr/td[1]/table/tbody/tr[3]/td[2]/select")));
driver.findElement(By.xpath("html/body/form/table/tbody/tr[4]/td/div/fieldset/table/tbody/tr/td[1]/table/tbody/tr[3]/td[2]/select")).sendKeys("Local Move");
new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("html/body/form/table/tbody/tr[4]/td/div/fieldset/table/tbody/tr/td[1]/table/tbody/tr[3]/td[2]/select"))).click();
I spent a significant amount of time today figuring this one out but I really failed on this one big time.
WebElement dropDownListBox = driver.findElement(By.xpath("html/body/form/table/tbody/tr[4]/td/div/fieldset/table/tbody/tr/td[1]/table/tbody/tr[3]/td[2]/select"));
Select clickThis = new Select(dropDownListBox);
Thread.sleep(5000L);
clickThis.selectByValue("1078");
It seems I needed Thread.sleep to let the system display the options completely before selenium can find the option I want for it to choose from.
Thanks guys!
To select a value from drop down. You need to use Select class from web driver.
driver.findElement(By.xpath("html/body/form/table/tbody/tr[4]/td/div/fieldset/table/tbody/tr/td[1]/table/tbody/tr[3]/td[2]/select")).sendKeys("Local Move");
Instead of the above line use this
WebElement ele = driver.findElement(By.xpath("html/body/form/table/tbody/tr[4]/td/div/fieldset/table/tbody/tr/td[1]/table/tbody/tr[3]/td[2]/select"));
Select dropdown = new Select(ele);
dropdown.selectByVisibleText("Local Move");
// Can select the dropdown using `index` and `value`
dropdown.selectByValue("Local Move");
dropdown.selectByIndex("1234");
To select a value from dropdown you should find the dropdown element by id then by value in the dropdown.
Try this:
new Select(driver.findElement(By.id("Dropdownid"))).selectByVisibleText("Text name");
I was working on reading mails from gmail using webdriver and in between I hit upon this difference between By.id and By.tagname.
I am trying to get access to a "table" whose id is ":pg". So I could
Either use By.id(":pg")
OR use By.tagname("table") and search for an element with id :pg
Here is the code for both cases.
By.id:
WebDriver webDriver = new FirefoxDriver();
webDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
webDriver = webDriver.switchTo().frame("canvas_frame");
WebElement table1 = webDriver.findElement(By.id(":pg"));`
Above code, I directly get the element which has id ":pg"
By.tagname:
WebDriver webDriver = new FirefoxDriver();
webDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
List<WebElement> tables = webDriver.findElements(By.tagName("table"));
for(WebElement table2: tables){
String id = table2.getAttribute("id");
System.out.println("id: "+ id);
if(id != null && id.equals(":pg")){
System.out.println("FOUND IT!!!");
}
}
Above code, I find all elements with the tagname of table and then see which one has the id ":pg".
Both these code snippets are essentially doing the same but using different ways(By.id or By.tagname). However, the first snippet of code which uses By.id always succeeds while the second snippet of code which uses By.tagname fails almost always. (It will work with additional waiting however)
Why is this difference between By.id and By.tagname?
Thanks,
Chris.
The :pg element is not present on the page initially.
Using By.Tag, selenium will not wait for the :pg element.
Because By.Id example is more specific, selenium will continue checking if the :pg element exists until the implicit wait (5 seconds) times out.
By.Tag is not specific at all. On findElements(By.tagName("table"), Selenium will return an array of all the tables that are present immediately after the page loads. As the :pg element is not present yet, it will not be in the array.
To answer your question, yes it is better to use By.Id because:
1. It is more specific.
2. Saves lines of code
3. Forces selenium to wait for the element to exist.
It is better to use By.Id according to your question.
By.tag is not used for specific data, it actually will search and return an array of all the tables with the specified tag name. On the other hand using id you can get the appropriate output for identifying/locating element.
Go for tag only if id, name or class is not specified and the best way can be By.cssSelector if no element is found.
Thanks