I am trying to get the value selected from the dropdown using the below snippet of code:
Select dropdown = new Select(driver.findElement(By.xpath(prop.getProperty("items"))));
WebElement tmp = dropdown.getFirstSelectedOption();
tmp.getText();
String s = tmp.getText();
System.out.println(s);
When I run the application it gives me following error:
org.openqa.selenium.StaleElementReferenceException: Element not found
in the cache - perhaps the page has changed since it was looked up
Thank You
boolean flag = false;
Select dropdown = new Select(driver.findElement(By.xpath(prop.getProperty("items"))));
List<WebElement> list = dropdown.getOptions();
for (WebElement temp : list) {
if (temp.getText().equals(prop.getProperty("your value").toString())) {
flag = true;
}
}
Related
I need to get the Select Tag and Input Tag in web table for this I created the below code to get the Tag name in web table.
For this
Created a List of Elements to get the Number of rows in table.
For declare the variable as "i" to looping.
Find the Select tag in each row to sent the inputs in table.if the select tag presence in row pass the input value else pass different value in web table.
// web Table
WebElement table =d.findElement(By.xpath("//*[#id='ui-grid']/div/div/div/div[2]/table/tbody"));
List<WebElement> trcount = table.findElements(By.tagName("tr"));
int size = trcount.size();
System.out.println(size);
//Using size created the for loop to find each row available in table.
for(int i=1;i<size;i++) {
//Declare the Xpath to find the particular row
By tag = By.xpath("(//*[#id='ui-grid']/div/div/div/div[2]/table/tbody/tr/td/span/select)["+i+"]");
By Input_tag = By.xpath("(//*[#id='ui-grid']/div/div/div/div[2]/table/tbody/tr/td/span/input)["+i+"]");
List<WebElement> tdcount = trcount.get(i).findElements(tag);
String tag1 = tdcount.get(i).getTagName();
System.out.println(tag1);
if(tag1.equals("select")){
d.findElement(By.xpath(tag))Select level = new Select(d.FindElement(tag));
level.selectByVisibleText("YES");
}else {
d.findElement(Input_tag).sendKeys("12");
}
}
Expected Result:
If Web table presence Select tab then value selected from dropdown else Input Tag presence value should be passed.
Actual Result:
java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
//Get the number of count in web table.
WebElement table =d.findElement(By.xpath("//*[#id='ui-grid']/div/div/div/div[2]/table/tbody"));
List<WebElement> trcount = table.findElements(By.tagName("tr"));
int size = trcount.size();
System.out.println(size);
//Select particular tag(Select tag)
List<WebElement> Select = table.findElements(By.xpath("//*[#id='ui-grid']/div/div/div/div[2]/table/tbody/tr/td/span/select"));
int select_size = Select.size();
System.out.println(select_size);
//If web table have select tag perfrom below else to catch no search elements exceptions.
try{
for(int j=1;j<=select_size;j++) {
By tag = By.xpath("(//*[#class='ng-star-inserted']/span/select)["+j+"]");
System.out.println("Test");
}
}catch(Exception e){
System.out.println((e.getMessage()));
}
//Select particular tag(Input tag)
List<WebElement> Select1 = table.findElements(By.xpath("//*[#id='ui-grid']/div/div/div/div[2]/table/tbody/tr/td/span/input"));
int select_input = Select1.size();
System.out.println(select_input);
try{
for(int i=1;i<=select_input;i++) {
By tag1 = By.xpath("(//*[#class='ng-star-inserted']/span/input)["+i+"]");
System.out.println("Test");
d.findElement(tag1).sendKeys("12345");
Thread.sleep(3000);
//d.findElement(Accept_button).click();
}
}catch(Exception e){
System.out.println((e.getMessage()));
}
I have a webtable which has multiple rows. I want to create a loop such that it traverses all the rows of this table and click on column 1 elements of first row, then check inside that an Edit button exists or not. Then come back and click on next element and check the edit button. Then come back and repeat till all rows are traversed.
But in current code implemented by me, it is just traversing the first row and then exiting. Could someone help me with same.
viewDiscussionScope(driver, scope);
WebElement paginationLabel = WaitUtils.waitForElement(driver, By.cssSelector(".v-csslayout-cvr-c-pagination__header"));
if(paginationLabel.isDisplayed())
{
WebElement table = WaitUtils.waitForElement(driver, By.cssSelector("table.eds-o-table.cvr-c-table--list tbody"));
List<WebElement> rows = table.findElements(By.cssSelector("tr.eds-o-table__row"));
for(WebElement row: rows)
{
List<WebElement> tableCols = row.findElements(By.cssSelector("td.eds-o-table__cell:nth-of-type(1)"));
for(WebElement col : tableCols)
{
col.findElement(By.cssSelector(".v-label-eds-c-text--bold")).click();
WebElement messageField = WaitUtils.waitForElement(driver, By.cssSelector(".eds-o-media__body-eds-o-media__body--top .v-label-eds-u-flexitext.v-label-undef-w:nth-of-type(1)"));
String messageText = messageField.getText();
boolean editLabel = (driver.findElement(By.cssSelector(".eds-c-button-set-eds-c-button-set--align-right .v-button-eds-s-is-first")).getText()).equals("Edit");
if(!(editLabel))
{
LOG.info(messageText+" is not editable by the logged in user");
}
else
{
LOG.info(messageText+" is editable by the logged in user");
}
break;
}
break;
}
}
}
Remove break statement from your parent for loop!
for(WebElement row: rows)
{
List<WebElement> tableCols = row.findElements(By.cssSelector("td.eds-o-table__cell:nth-of-type(1)"));
for(WebElement col : tableCols)
{
// your code
}
// REMOVE => break;
}
}
You have 2 break that need to be removed and you don't need to loop through the td if you want to click only first td
if (paginationLabel.isDisplayed())
{
WebElement table = WaitUtils.waitForElement(driver, By.cssSelector("table.eds-o-table.cvr-c-table--list tbody"));
List<WebElement> rows = table.findElements(By.cssSelector("tr.eds-o-table__row"));
for (WebElement row : rows)
{
// get first td
WebElement tableCol = row.findElement(By.cssSelector("td.eds-o-table__cell:nth-of-type(1)"));
tableCol.findElement(By.cssSelector(".v-label-eds-c-text--bold")).click();
WebElement messageField = WaitUtils.waitForElement(driver, By.cssSelector(".eds-o-media__body-eds-o-media__body--top .v-label-eds-u-flexitext.v-label-undef-w:nth-of-type(1)"));
String messageText = messageField.getText();
boolean editLabel = (driver.findElement(By.cssSelector(".eds-c-button-set-eds-c-button-set--align-right .v-button-eds-s-is-first")).getText()).equals("Edit");
if (!(editLabel))
{
LOG.info(messageText + " is not editable by the logged in user");
}
else
{
LOG.info(messageText + " is editable by the logged in user");
}
}
}
first you need to find where is edit button located in table you can find its xpath, does of all edit buttons having same xpath if yes then your problem will be solved in you just need to find by findElements() method and store it into List and to get value of edit buttons or to check if is available or not you can call .get() method which will get all respected buttons of same xpath and by specifying index as .get(0),.get(1) or pass it in loop you get his value by .getText() method and check or perform actions on that
If you could provide the DOM of the table you trying to work on, i can help you better.
If i understood correctly your problem here is the solution, also, i strongly advice to use methods for small tasks, which will help you in the long run. Also, the selectors needs a better wraping, also the explicit wait needs a wrapper with his own methods.
try this:
if (paginationLabel.isDisplayed())
{
WebElement table = WaitUtils.waitForElement(driver, By.cssSelector("table.eds-o-table.cvr-c-table--list tbody"));
List<WebElement> rows = table.findElements(By.cssSelector("tr.eds-o-table__row"));
for (int i=1; i<=rows.size; i++)
{
// get first td
clickColumn(int i);
getMessageText(int i);
boolean editLabel = (driver.findElement(By.cssSelector(".eds-c-button-set-eds-c-button-set--align-right .v-button-eds-s-is-first")).getText()).equals("Edit");
if (!(editLabel))
{
LOG.info(messageText + " is not editable by the logged in user");
}
else
{
LOG.info(messageText + " is editable by the logged in user");
}
}
}
private clickColumn(int position) {
WebElement tableCol = row.findElement(By.cssSelector("td.eds-o-table__cell:nth-of-type(" + position + ")"));
tableCol.findElement(By.cssSelector(".v-label-eds-c-text--bold")).click();
}
private getMessageText(int position) {
WebElement messageField = WaitUtils.waitForElement(driver, By.cssSelector(".eds-o-media__body-eds-o-media__body--top .v-label-eds-u-flexitext.v-label-undef-w:nth-of-type(" + position + ")"));
String messageText = messageField.getText();
}
driver.findElement(By.id("lnkLogin")).click();
WebElement cmp = driver.findElement(By.id("txtCompanySearch"));
cmp.sendKeys("Demo Company");
driver.findElements(By.xpath(".//*[#id=\"TenantTBL\"]/tbody/tr[5]/td")).get(0).click();
This code above worked for me but it works as static xpath index for selecting,
but I want to get all rows which match my sendKeys value.
I have tried this but this is not working
ArrayList<Integer> numbers = new ArrayList<Integer>();
By elems = By.xpath(".//*[#id=\"TenantTBL\"]/tbody/tr");
WebElement select = driver.findElement(elems);
List<WebElement> matches = select.findElements(By.xpath(".//*[#id=\"TenantTBL\"]/tbody/tr"));
List<String> currentVals = new ArrayList<>();
for (WebElement match : matches) {
currentVals.add(match.getText());
}
When using . in xpath you are using current context, so
WebElement select = driver.findElement(By.xpath(".//*[#id=\"TenantTBL\"]/tbody/tr"));
List<WebElement> matches = select.findElements(By.xpath(".//*[#id=\"TenantTBL\"]/tbody/tr"));
Is the equivalent of
List<WebElement> matches = select.findElements(By.xpath(".//*[#id=\"TenantTBL\"]/tbody/tr//*[#id=\"TenantTBL\"]/tbody/tr"));
Basically you are looking for an element which is a child of itself. Just locate the elements directly
By elems = By.xpath(".//*[#id=\"TenantTBL\"]/tbody/tr");
List<WebElement> matches = driver.findElements(elems));
I want to know how to nest dropdowns using selenium webdriver using java,i.e., I have 2 dropdowns and can these dropdowns be nested one after the other?
After looping 2 times for a dropdown it is showing stale element reference error
I have written the following code:
Select drpdwns6 = new Select(driver.findElement(By.xpath("//*[#id=\"MainContent_ddlBillable\"]")));
List <WebElement> sels6 = drpdwns6.getOptions();
sels6.size();
for(int s6=0;s6<sels6.size();s6++) {
drpdwns6.selectByIndex(s6);
System.out.println("selected value"+s6);
Select drpdwns7 = new Select(driver.findElement(By.xpath("//*[#id=\"MainContent_ddlofflinestatus\"]")));
List <WebElement> sels7 = drpdwns7.getOptions();
sels7.size();
for(int s7=0;s7<sels7.size();s7++) {
drpdwns7.selectByIndex(s7);
System.out.println("selected value"+s7);
}
}
My guess is selecting the option from the dropdown refreshes the DOM, so the exception is thrown. You need to relocate the dropdown in each itreation
Select drpdwns6 = new Select(driver.findElement(By.id("MainContent_ddlBillable")));
int drpdwns6Size = drpdwns6.getOptions().size();
for(int s6 = 0 ; s6 < drpdwns6Size ; s6++) {
drpdwns6 = new Select(driver.findElement(By.id("MainContent_ddlBillable")));
drpdwns6.selectByIndex(s6);
System.out.println("selected value"+s6);
Select drpdwns7 = new Select(driver.findElement(By.id("MainContent_ddlofflinestatus")));
int drpdwns7Size = drpdwns7.getOptions().size();
for(int s7 = 0 ; drpdwns7Size ; s7++) {
drpdwns7 = new Select(driver.findElement(By.id("MainContent_ddlofflinestatus")));
drpdwns7.selectByIndex(s7);
System.out.println("selected value"+s7);
}
}
As a side note, if you have an id use By.id it instead of By.xpath
You get the Stale element exception whenever the element present in the DOM is deleted or removed or is not available.
The above answer (ie) relocating the element once the DOM is refreshed or you could use Webdriver wait, If an element is not attached to DOM then you could try using ‘try-catch block’ within ‘for loop’ like below
driver.manage().timeouts().implicitlywait(30,TimeUnit.SECONDS);
try{
Select drpdwns6 = new
Select(driver.findElementByXpath("//[#id=\"MainContent_ddlBillable\"]")));
List <WebElement> sels6AllOptions = drpdwns6.getOptions();
int count1=sels6AllOptions.size();
for(int s6=0;s6<count1;s6++)
{
drpdwns6.selectByIndex(s6);
}
}
catch(StaleElementException e1){
System.out.println("selected value"+s6);
}
try{
Select drpdwns7 = new Select(driver.findElement(By.xpath("//*[#id=\"MainContent_ddlofflinestatus\"]")));
List <WebElement> sels7AllOptions = drpdwns7.getOptions();
int count2=sels7AllOptions.size();
for(int s7=0;s7<count2;s7++) {
drpdwns7.selectByIndex(s7);
catch(StaleElementException e2){
System.out.println("selected value"+s7);
}
}
I try to retrieve text via foreach loop,as according to page wise. Flow is : It prints text of single row and as soon as it completes, it goes to second page and start again to retrieve text. Problem is, it retrieves data of first page multiple times like sometimes 2 or 3 or 4 times, How to control it for single time execution ?
if (driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']")).isEnabled()) {
int ilength = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']")).size();
Outer: for (int i1 = ilength; i1 > 0;) {
List<WebElement> findData = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']"));
for (WebElement webElement : findData) {
String printGroupName = webElement.getAttribute("value").toString();
System.out.println(printGroupName);
ilength--;
}
if (driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']")).isEnabled()) {
action.moveToElement(driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']"))).click().perform();
page.pagecallingUtility();
ilength = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']")).size();
} else {
break Outer;
}
}
} else {
List<WebElement> findAllGroupName = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']"));
for (WebElement webElement : findAllGroupName) {
String printGroupName = webElement.getAttribute("value").toString();
System.out.println(printGroupName);
}
}
Console Data, on which it retrieve information
Your loop can be simplified as below.
boolean newPageOpened = true;
while (newPageOpened) {
List<WebElement> findData = driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']"));
for (WebElement webElement : findData) {
if (webElement.isDisplayed()) {
String printGroupName = webElement.getAttribute("value").toString();
System.out.println(printGroupName);
}
}
WebElement nextButton = driver.findElement(By.xpath("//button[#ng-click='currentPage=currentPage+1']"));
if (nextButton.isEnabled()) {
action.moveToElement(nextButton).click().perform();
page.pagecallingUtility();
} else {
newPageOpened = false;
}
}
As for the contents of the fist page printing again and again, I suspect when you open the second page the contents of the first page are simply hidden in the page. So when you use driver.findElements(By.xpath("//input[#ng-attr-id='{{item.attr}}']")) the hidden first page elements are also found. The simple solution is to check if the element is displayed before printing it.