I need to create function which need to validate all column titles on Web UI which are Name, Age, Gender and Height:
I got xpath of column title ready:
List<Webelement> allLinks= driver.findElements(By.xpath("//button[#class='sort-header-btn']"));
individual working xpath is:
//button[#class='sort-header-btn' and contains(text(),'Name')]
I can't store every xpath individually like this. I decide to iterate every xpath:
Iterator<WebElement> itr = allLinks.iterator();
while(itr.hasNext()) {
if(itr.next().getText().contains("Name")){
System.out.println("Name column is validated");
break;
}
else{
System.out.println("Name column is not validated");
break;
}
if(itr.next().getText().contains("Gender")){
System.out.println("Gender column is validated");
break;
}
else{
System.out.println("Gender column is not validated");
break;
}
//same way I follow remaining columns
}
Is this is the correct way to do it?
Related
I am unable to locate dynamic web element location for drop down list
public void selectClassofService(String value) throws InterruptedException
{
driver.findElement(By.xpath("/html/body/div[1]/div/div/div/div[3]/div[2]/div[2]/div/div/div/div[2]/div[2]/div[2]/form/div[5]/div/div[2]/div/div/div[1]/input")).click();
List<WebElement> list = driver.findElements(By.xpath("/html/body/div[1]/div/div/div/div[3]/div[2]/div[2]/div/div/div/div[2]/div[2]/div[2]/form/div[5]/div/div[2]/div/div/div[1]/input"));
System.out.println("Size of the list size =" + list.size());
for (int i = 0; i < list.size(); i++) {
System.out.println("names of the divisions " + list.get(i).getText());
if (list.get(i).getText().contains(value)) {
list.get(i).click();
break;
}
}
this is my sample html code
<ui class="vs_dropdown-menu" role="listbox">
<l1 class=vs_dropdown-option role="option">sample pack </l1>
<l2 class=vs_dropdown-option vs vs_dropdown-option--highlight role="option">sample pack </l2>
<l3 class=vs_dropdown-option role="option">sample pack2 </l3>
First of all, Stop writing too long xpaths. there are better ways to access an element instead of doing that creepy things.
String dropdownXpath = "//input[#class='vs_dropdown-menu' and #role='listbox']";
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath(dropdownXpath))).click();
List<WebElement> myList = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath(dropdownXpath + "//li[#class='vs_dropdown-option' and #role='option']")));
for (WebElement element:myList)
{
System.out.println("names of the divisions " + element.getText());
if(element.getText().contains("Mumbai"));
element.click();
}
if it's not possible to access dropdown like above, just get the parent div's Id like this:
String dropdownXpath = "//div[#id='some-id']input[#class='vs_dropdown-menu' and #role='listbox']";
don't waste your time by crawling html tags to find an element.
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();
}
Trying to enter pin number in dynamic text field. Pin number text field changes every time the website is loaded. Need help to write logic for entering the pin number in 3 text field. There is 4 pin number but I get option to enter pin number in 3 text field.
Screenshot and code reference
As per your posted HTML. you can try with indexes if its same type of field.
Use below code:
driver.findElement(By.cssSelector("div[class='field-set'] input.input-pin:nth-child(1)")).sendKeys("your value"); // for first text box
driver.findElement(By.cssSelector("div[class='field-set'] input.input-pin:nth-child(2)")).sendKeys("your value"); // for Second text box
driver.findElement(By.cssSelector("div[class='field-set'] input.input-pin:nth-child(3)")).sendKeys("your value"); // for third text box
Please change the index in div[class='field-set'] input.input-pin:nth-child(index) as per textbox in page UI position.
UPDATE
If you are not sure which textbox have to accept value then use below logic
public static void main(String[] args) {
// first you need to store your testdata in a collection
Map<String,String> pinCodes = new HashMap<String, String>();
pinCodes.put("pin1", "2");
pinCodes.put("pin2", "3");
pinCodes.put("pin3", "3");
pinCodes.put("pin4", "4");
// you can remove the values as per you need suppose you only want `pin1` `pin2` then remove `pinCodes.put("pin3", "3");` and `pinCodes.put("pin4", "4");` from above code
enterPinCode(pincodes); //call method to enter the values in corresponding text-boxes
}
public void enterPinCode(Map<String,String> pinCodes) {
for (Entry<String, String> entry : pinCodes.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
switch (key) {
case "pin1" :
driver.findElement(By.cssSelector("div[class='field-set'] input.input-pin:nth-child(1)")).sendKeys(value);
break;
case "pin2" :
driver.findElement(By.cssSelector("div[class='field-set'] input.input-pin:nth-child(2)")).sendKeys(value);
break;
case "pin3" :
driver.findElement(By.cssSelector("div[class='field-set'] input.input-pin:nth-child(3)")).sendKeys(value);
break;
case "pin4" :
driver.findElement(By.cssSelector("div[class='field-set'] input.input-pin:nth-child(4)")).sendKeys(value);
break;
default :
System.out.println("pincode textbox key not found");
break;
}
}
}
OR if checkbox are dynamic on webpage then replace below code in switch statement :
switch (key) {
case "pin1" :
List<WebElement> box1 = driver.findElements(By.cssSelector("div[class='field-set'] input[placeholder='1st']"));
if(!box1.isEmpty()) {
box1.get(0).sendKeys(value);
}
break;
case "pin2" :
List<WebElement> box2 = driver.findElements(By.cssSelector("div[class='field-set'] input[placeholder='2nd']"));
if(!box2.isEmpty()) {
box2.get(0).sendKeys(value);
}
break;
case "pin3" :
List<WebElement> box3 = driver.findElements(By.cssSelector("div[class='field-set'] input[placeholder='3rd']"));
if(!box3.isEmpty()) {
box3.get(0).sendKeys(value);
}
break;
case "pin4" :
List<WebElement> box4 = driver.findElements(By.cssSelector("div[class='field-set'] input[placeholder='4th']"));
if(!box4.isEmpty()) {
box4.get(0).sendKeys(value);
}
break;
default :
System.out.println("pincode textbox key not found");
break;
}
This code will send the pin-code in corresponding pin-code textbox if available on webpage.
In my application on users profile page, user has:
Name: XYZ
Age: ##
Address: st.XYZ
and so on...
When an element is missing (example age) other row takes its place, so I can't hardcode the xpath of elements. What I want is:
I want to (print) extract entire table data and compare with actual.
So when I ask for "Name" as key it should give cell value infront of it as value of key.
What I tried:
I was able to get text of tr tags elements keeping td fixed. But for another user when some row is missing it fails or gives wrong value.
for (int i = 2; i < 58; i++) {
String actor_name = new WebDriverWait(driver, 30).until(ExpectedConditions
.elementToBeClickable(By.xpath(first_part+i+part_two))).getText();
System.out.print("\n"+"S.no. "+(i-1)+" "+actor_name);
try {
driver.findElement(By.xpath(first_part+i+part_two)).click();
new WebDriverWait(driver, 30).until(ExpectedConditions
.elementToBeClickable(By.partialLinkText("bio"))).click();
//driver.findElement(By.partialLinkText("bio")).click();
} catch (Exception e) {
// TODO: handle exception
System.out.println("Not a link");
}
Thread.sleep(5000);
System.out.print(" "+driver.findElement(By.xpath("//*[#id='overviewTable']/tbody/tr[3]/td[2]")).getText());
driver.get("http://www.imdb.com/title/tt2310332/fullcredits?ref_=tt_cl_sm#cast");
}
Above code works fine for top 3 actors on this page but fails for 4th because that doesn't have one row missing on bio page.
On the bio page there two columns in the table one has attribute other has its value. I want to make a collection with key value pair with key as attribute (value from left column) and its value as value from right column. So that I get the freedom of fetching the values by mentioning the attribute value.
I am using JAVA to write scripts.
Can you try out with following code and provide me with any concerns if you have any...
driver.get("http://www.imdb.com/title/tt2310332/fullcredits?ref_=tt_cl_sm#cast");
String height = "";
String actorName = "";
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
List<WebElement> lstUrls = driver.findElements(By
.xpath("//span[#itemprop='name']/..")); // all a tags
List<String> urls = new ArrayList<>();
for (WebElement webElement : lstUrls) {
urls.add(webElement.getAttribute("href")); // saving all hrefs attached in each a tag
}
Map<String, String> actorHeightData = new HashMap<String, String>();
for (String string : urls) {
driver.get(string);
actorName = driver.findElement(
By.xpath(".//*[#id='overview-top']/h1/span")).getText(); // Getting actor's name
driver.findElement(By.xpath("//a[text()='Biography']")).click(); // Clicking Biography
try {
height = driver.findElement(
By.xpath("//td[.='Height']/following-sibling::td"))
.getText(); // Getting height
} catch (NoSuchElementException nsee) {
height = ""; // If height not found
}
actorHeightData.put(actorName, height); // Adding to map
}
You can create class PersonData with all nullable fields you need. But with not null getters.
for example
calss PersonData{
private String name;
public getName(){
if(name == null)
return "";
return name;
}
}
and store all persons in a List.
In you page you will ask person for field and always have something in table's cell.