I am trying to find an element by its full path (wholeElement) and by first finding the higher level element and then finding the lower level element within that element (modularElement). Here is my code:
WebElement modularElement = appDriver.findElement(By.xpath("//UIATableCell[2]")).findElement(By.xpath("//UIAStaticText[4]"));
WebElement wholeElement = appDriver.findElement(By.xpath("//UIATableCell[2]/UIAStaticText[4]"));
Logger.LogMessage("modularElement attribute1: " + modularElement.getLocation(), Priority.High);
Logger.LogMessage("wholeElement attribute1: " + wholeElement.getLocation(), Priority.High);
The really strange issue I am experiencing is the two elements (modular and whole) are different elements and not the same one (shown by the different locations printed in the code above). Can anyone explain why this is the case?
Thanks.
UPDATE:
I have also tried using .// but that is providing the same issue still:
WebElement modularElement = appDriver.findElement(By.xpath("//UIATableCell[2]")).findElement(By.xpath(".//UIAStaticText[4]"));
They are not the same.
appDriver.findElement(By.xpath("//UIATableCell[2]")).findElement(By.xpath("//UIAStaticText[4]"));
Here, you are searching for //UIAStaticText[4] anywhere, at any level in the entire DOM tree:
When using xpath be aware that webdriver follows standard conventions:
a search prefixed with "//" will search the entire document, not just
the children of this current node. Use ".//" to limit your search to
the children of this WebElement.
While //UIATableCell[2]/UIAStaticText[4] would search among the direct children of //UIATableCell[2] only.
I would do it like so instead:
By locator = new ByChained(By.xpath("//UIATableCell[2]"),By.xpath(".//UIAStaticText[4]"));
WebElement modularElement = appDriver.findElement(locator);
Or perhaps this:
public WebElement getCellTextElement(int cell, String varText) {
By locator = new ByChained(By.xpath("//UIATableCell[" + cell + "]"),
By.xpath(".//UIAStaticText[contains(text(),'" + varText + "')]"));
WebElement modularElement = appDriver.findElement(locator);
return modularElement;
}
Related
I have to verify a record from the search list. How can I do it effectively and in a reusable way? I search a keyword that returns 100s of records and then verify my expected search keyword is displayed in the search list.
Here is my code
public void Test_assert_equals() throws IOException, InterruptedException
{
System.out.println("Verify Testcase UploadDocument");
JavascriptExecutor js = (JavascriptExecutor)driver;
driver.findElement(By.name("usernameName")).sendKeys(new CharSequence[]{"dothicamtu#fecredit.com.vn"});
driver.findElement(By.name("passwordName")).sendKeys(new CharSequence[]{"Abc#123456"});
driver.findElement(By.xpath("//*[#id=\"login-form\"]/mat-spinner-button/button/span[1]")).click();
driver.findElement(By.xpath("//*[#id=\"fuseSidebar\"]/navbar/navbar-vertical-style-1/div[2]/div[3]/fuse-navigation/div/fuse-nav-vertical-group[1]/div[2]/fuse-nav-vertical-collapsable[1]/a")).click();
driver.findElement(By.xpath("//*[#id=\"fuseSidebar\"]/navbar/navbar-vertical-style-1/div[2]/div[3]/fuse-navigation/div/fuse-nav-vertical-group[1]/div[2]/fuse-nav-vertical-collapsable[1]/div/fuse-nav-vertical-item/a")).click();
Thread.sleep(2000); //w8 list all data
//Search
driver.findElement(By.xpath("//*[#id=\"isaleleadl2\"]/div[2]/div[1]/div[2]/fuse-search-bar/div/div/label/button/span[1]")).click();
//Search data Vu Manh Hai
driver.findElement(By.xpath("//*[#id=\"fuse-search-bar-input\"]")).sendKeys(new CharSequence[]{"Vũ Mạnh Hải"});
driver.findElement(By.xpath("//*[#id=\"fuse-search-bar-input\"]")).sendKeys(Keys.ENTER);
//String result= driver.findElement(By.xpath("//*[#id=\"isaleleadl2\"]/div[2]")).getText();
//Assert.assertEquals("Vũ Mạnh Hải", result);
Thread.sleep(1000);
}
enter image description here
I have using this logic check but got an errors in "assertEquals"
enter image description here
i need to verify "Vũ Mạnh Hải" is displayed in the search list
enter image description here
If there is no reference to the expected number of results containing the 'keyword', but if I know that there should be at least 1 result; then I would do the following:
Instead of using findElement I would get a list of elements by using findElements and check whether the size of the list is larger than 0.
It would look similar to the following:
List<WebElement> result = driver.findElements(By.xpath("//div[#col-
id='issueName'][contains(text(),’Vu Manh Hai’)]"));
Assert.assertTrue(result.size()>0);
Of course this is based on assumption that the keyword results in at least 1 search result. If you could get the number of the search results from a database query or so that would be much more accurate.
There are 2 drop-down lists. Each has a similar meaning, for example, "Jorge". Lists in different modules. When I need to fill in, for example, a list that is lower in the tree, then the first match is taken along the XPath path, on an undisclosed list.
Not lists, but values in drop-down lists!
There are 2 drop-down lists. Each has a similar meaning, for example, "Jorge". Lists in different modules. When I need to fill in, for example, a list that is lower in the tree, then the first match is taken along the XPath path, on an undisclosed list.
Not lists, but values in drop-down lists!
I wanted to implement it in Java this way:
Example:
if (findElement(By.xpath("(//example//example)")).isDisplayed()) {
findElement(By.xpath("(//example//example)")).click();
}
But in this case, the element is not displayed.
How to implement a search of all values similar to the XPath path in order to get the one that is displayed?
I tried to do something like this: (//example//example)1 (//example//example)[2] (//example//example)[3]
In my case, we have that 1 - the element does not exist [2] - exists, but is not displayed (isDisplayed = false) [3] - exists, is displayed (isDisplayed = true)
iterating through the values in the loop for [n] cannot be implemented, because, for example, the value 1 is not.
Described as difficult as possible :D. Excuse me.
If someone understands my nonsense, please help me. How to implement my requirement?
enter image description here
UPD:
The problem was solved (for me) by substituting the first value into the expression ()"{1}" immediately.
Now I'm interested in why I get an exception after the first iteration:
Method threw 'org.openqa.selenium.ElementNotInteractableException' exception.
Code:
int number = 1;
String option = "(//ul[contains(#style, 'display: block')]//li//span[contains(text(),'" + valueField + "') or strong[contains(text(),'" + valueField.toUpperCase() + "')]])";
findElement(By.xpath(option+"["+number+"]"));
String[] words = valueField.split(" ");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < words.length; i++) {
builder.append(words[i]);
setFieldByLabel(nameModule, nameLabel, builder.toString());
fastWaitLoading();
for (int y = 0; y < 10; y++) {
if (findElement(By.xpath(option+"["+number+"]")).isDisplayed()) {
new Actions(browser.getWebDriver())
.moveToElement(findElement(option))
.click()
.build()
.perform();
break;
}
number++;
}
}
So I am trying to fully understand your question, and I don't. What I would recommend for a situation like this is, iterate through all elements by creating a list with: findElements(By.xpath ... )
This way you will get a list of webelements and you can iterate through them. Then apply a foreach, assert if element is displayed (it exists as it has been found with findElements) and you should be able to interact with it.
Yeah, everything is in a prominent place)
Missed it
new actions(browser.getWebDriver()) .moveToElement(findElement(**option**)) .click() .build() .perform(); break;
Here
new actions(browser.getWebDriver())
.moveToElement(findElement(**option + "[" + number+"]"**))
.click()
.build()
.perform();
break;
I am iterating through elements on the website with XPath of each element.
//*[#id="app"]/div[1]/main/div[2]/section/div/section/div[4]/div[1]/div[X]
X values: from 1 to n. Where X is an ordinal number of the element.
xpath.getText() give me the name and price of current item.
I want to download the image also. Class name for the image isn't unique. It same for every element: "shop-card__image-block".
How to access"shop-card__image-block" for every element? I want to take the link to the image and download it with the name and price.
See the images.
First image
Second image
Use element.findElement(By by) or element.findElements(By by) to get child element(s). See https://www.tutorialspoint.com/locating-child-nodes-of-webelements-in-selenium.
Code :
WebDriverWait wait = new WebDriverWait(driver, 30);
int divSize = driver.findElements(By.xpath("//*[#id='app']/div[1]/main/div[2]/section/div/section/div[4]/div[1]/div")).size();
for (int i = 1; i<= divSize; i++) {
WebElement parentDiv = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='app']/div[1]/main/div[2]/section/div/section/div[4]/div[1]/div['"+i+"']")));
WebElement image = parentDiv.findElement(By.xpath(".//descendant::div[contains(#class,'shop-card__image-block')]"));
// now image is a web element, you can perform a click on it like image.click(); or any other operation.
}
now image is a web element, you can perform a click on it like image.click(); or any other operation.
trust this helps.
I am trying to implement some code using Selenium Webdriver using Java.
Basically, I have a website with a text box. Once user enter the first letter, based on that a value will be displayed(using AJAX). I need to select the particular value, which i mentioned in send keys .
WebElement fromCity = driver.findElement(By.id("pickUpLocation"));
fromCity.sendKeys("A Ma Temple / 媽閣");
Thread.sleep(2000);
WebElement ajaxContainer1 = driver.findElement(By.className("txt-box ng-touched ng-dirty ng-valid"));
WebElement ajaxHolder1 = ajaxContainer1.findElement(By.tagName("ul"));
List<WebElement> ajaxValues1 = ajaxHolder1.findElements(By.tagName("li"));
for (WebElement value1 : ajaxValues1) {
if (value1.getText().equals("A Ma Temple ")) {
((WebElement)ajaxValues1).click();
break;
}
}
After you send keys.your Ajax value should be retrieved in a box related to you keyword search.You need to get the complete box.and fetch each one as you have done in for loop .get the text and compare it with your expected text and click where this condition is true.
What is that line for before thread.sleep()
I think u can try selecting through index. It should be like this
List<WebElement> ajaxValues1 = ajaxHolder1.findElements(By.tagName("li"));
Select dropdown= new Select(ajaxValues1);
dropdown.selectByIndex(0);
dropdown.selectByIndex(1);
dropdown.selectByIndex(2);
0 represents the first element in the dropdown. Based on index number of that element, feed the corresponding number in selectByIndex(0)
Let me know if this helps. Thanks
#AndroidFindBy (uiAutomator = "new UiSelector().className(\"android.support.v7.widget.RecyclerView\").childSelector(new UiSelector().className(\"android.widget.RelativeLayout\"))")
public List<MobileElement> listOfElements;
System.out.print(listOfElements.size());
This returns 1.
So there is an element "android.support.v7.widget.RecyclerView" which contains 9 elements "android.widget.RelativeLayout". Those I want to get a list of, but I get only 1 element with the aforementioned locator. What am I doing wrong here?
If I add .index() at the end of locator, then it will give me an element according to specified index number, but I need a list of all child elements.
And does appium support all UiSelector commands? Because some of them do not seem to be working (like classNameMatches where you can type a regex, or fromParent, scrollable, ...)
you can use parent , child class strategy as below,
WebElement l1 = driver.findElementByClassName("android.support.v7.widget.RecyclerView\");
//All elements in big container L1
List<WebElement> l2 = l1.findElements(By.className("android.widget.RelativeLayout\));
System.out.println("size of L2= " + l2.size());
for(int i = 0 ; i<l2.size();i++){
System.out.println("\n Index is : " + i + "Content-desc is : " + l2.get(i).getAttribute("name"));
}
Modify the loop as per your needs