Find element using explicit wait within another element - java

I have the following code:
List<MobileElement> messages = driver.findElements (By.id ("body_bubble")); //find all messages
MobileElement lastMessage = messages.get (messages.size () - 1); //get last message
// xpath query to check if the message is delivered
String xpathDeliveryStatus = ".//*[contains(#resource-id, 'delivered_indicator') or contains(#resource-id, 'read_indicator') or contains(#resource-id, 'sent_indicator')]";
MobileElement deliveryStatus = lastMessage.findElement (By.xpath (xpathDeliveryStatus));
I want to do the same except that I want to find the deliveryStatus variable using explicit wait.
So I want to find the deliveryStatus variable inside the lastMessage variable using wait.until (ExpectedConditions.visibilityOfElementLocated (By.locator))
How can I do this?
I don't want to do it using one immense Xpath. Besides, I don't even know how to find the last element with the id body_bubble using Xpath, as the number of these elements is not fixed and always changing.
P.S. For example, in Python we can define WebDriverWait with an element in the constructor instead of driver:
WebDriverWait(webelement, self.timeout)
Unfortunately, it does not work in Java.

Based on the Java documentation on ExpectedConditions, it looks like we can use presenceOfNestedElementLocatedBy to add explicit wait on the child element:
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement childElem = wait.until(
ExpectedConditions.presenceOfNestedElementLocatedBy(lastMessage, By.xpath(xpathDeliveryStatus)));

Related

How does looping through a list based on findElements work?

First one in list is easy since you can use find Element. I find the element and need to get information from preceding and following divs. For the "n" element in the list, what is the xPath syntax for moving/backwards to other associated divs?
I have tried various x path following syntax such as:
following-sibling::div
/following-sibling::div
./following-sibling::div
And many others. I just have not found the documentation for the correct syntax.
Preceding:
Select all nodes that come before the current node as shown in the below screen.
Following-sibling:
Select the following siblings of the context node. Siblings are at the same level of the current node as shown in the below screen. It will find the element after the current node.
Here you can find the correct syntax with examples.
You can also use drive.findElements(); method in order to find similar elements. It will return you the collection of elements which you can iterate to get the information.
This answer is entirely dependent on what HTML is displayed on the page you are trying to automate.
Without that context, I can only provide a generic answer, but here's how I would loop through a list of elements and grab information from preceding / following div's:
// locate the elements you want to iterate
List<WebElement> elements_to_iterate = driver.findElements(By.xpath(someLocatorHere))
// iterate the elements in a foreach loop
for (WebElement element : elements_to_iterate) {
// get preceding sibling
WebElement preceding_element = element.find_element_by_xpath("./preceding-sibling::div")
print(preceding_element.getText())
// get following sibling
WebElement following_element = element.find_element_by_xpath("./following-sibling::div")
print(following_element.getText())
}
As I mentioned, this is just a generic solution to give you an idea of how this would work. If you want some assistance with the locator strategy, posting your HTML would be helpful.
If you want to find multiple elements then please find below example for your reference. Based on your site you need to implement same kind of logic.
Please refer above screenshot where I am trying to get label of two highlighted button from google
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.get("https://www.google.com"); // URL in the browser
driver.manage().window().maximize(); // Maximize the browser
String expectedTooltip="Search";
List<WebElement> Listelements = driver.findElements(By.xpath("//div[#class='FPdoLc VlcLAe']//input"));
for (WebElement element: Listelements)
{
System.out.println("Element Text::"+element.getAttribute("aria-label"));
}
driver.close();
}
output:
Element Text::Google Search
Element Text::I'm Feeling Lucky
since the first one is easy; each elementList has a current-time and at least one picture
for (i=1; i < elementList.size(); i++) {
WebElement nextInList = elmentList(i);
WebElement getTime = nextInList.findElement(By.xpath("following::div[contains(#class, 'current-time')]"));
.
.
.
WebElement picture = nextInList.findElement(By.xpath("preceding::a[1]"));
.
}

Selenium, how to Copy a few words that are always different?

Im trying to copy automatically a Name out of the webbrowser but the Name changes so I don't know how to copy it.
I've tried to doublecklick it or to "ctrl + c" it but it didn't work.
WebDriver driver = new ChromeDriver();
driver.get("https://realnamecreator.alexjonas.de/?l=de#");
driver.findElement(By.linkText("[+] Filter-Optionen")).click();
driver.findElement(By.id("gender")).click();
new Select(driver.findElement(By.id("gender"))).selectByVisibleText("w");
driver.findElement(By.id("gender")).click();
driver.findElement(By.id("button")).click();
and after this I want to copy the name into my Program. So I would say
String text = driver...
First you need to retrieve the element, then call the getText method documented here:
driver.findElement(By.id("realname")).getText()
Hope that helps.
You should not use thread-sleep... use WebDriverWait:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("realname")));
Then use getText():
String text = driver.findElement(By.id("realname")).getText()
Hope this helps!
The link you have shared has the element with realname id before it generates and shows the name.
So waiting for visibility of the element with id realname would not give you the expected result.
You have to wait for the invisibility of the image that shows on the page load but doesn't show when the name is shown.
Try this,
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("#realname > a")));
String text = driver.findElement(By.id("realname")).getText();

Cannot find visible element

I need help in finding unique element to find these text. i don't know why my xpath is not working please check: image attached is the element for the text.
(new WebDriverWait(driver,10)).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//div[#class='"+viz+"']/h2[text()='"+reports+"']")));
wherein
String reports = Overdue Stock Analysis
String viz = dashlet-wrapper
error message is this :
Expected condition failed: waiting for visibility of all elements located by By.xpath:
//div[#class='dashlet-wrapper']/h2[text()='Overdue Stock Analysis']
(tried for 10 second(s) with 500 milliseconds interval)
You can the xpath I have mentioned in the expected condition for finding the element and
if there is only one element which is required to be fetched through the xpath, you should use visibilityOfElementLocated instead of the method visibilityOfAllElementsLocatedBy as visibilityOfAllElementsLocatedBy is used to check the visibility of a element list and not just a single element.
You can use visibilityOfElementLocated like:
(new WebDriverWait(driver,10)).until(ExpectedConditions. visibilityOfElementLocated(By.xpath("//div[#class='"+viz+"']//h2[#data-title='"+reports+"']")));

Appium find element by 2 parameters in Java

I use Appium with Java to automate tests for mobile application. I'm looking for a way to find element by 2 parameters. I.e. by accessibilityId and by xPath within this element. So really rough example to visualize what I mean
Element el = driver.findElementByAccessibilityId("name").isDisplayed();
Assert.assertTrue(el.findElement(By.xPath("//android.widget.TextView[#text='texty']")));
Is this correct way to do this? Is there a better way? Ideal would be one liner because it is easier to understand
isDisplayed() does not return MobileElement/WebElement it returns a Boolean so a valid way is something like mentioned below
WebElement el = driver.findElementByAccessibilityId("name");
if (e1.isDisplayed()){
WebElement e2 = el.findElement(By.XPath("//android.widget.TextView[#text='texty']"))
}
Assert.assertTrue(e2.isDisplayed());
You can chain any number of findElement e.g.
WebElement innerElement =
driver.findElement(By.AccessbilityID("someID"))
.findElement(By.xpath("someXpath"))
.findElement(By.cssSelector(".aValidCSSClass"));
If you use findElements you have to use it like this as it return List of WebElement or List of MobileElement
WebElement innerElement =
driver.findElements(By.AccessbilityID("someID"))
.get(2) //get 2nd element
.findElements(By.xpath("someXpath"))
.get(1) //get 1st element
.findElement(By.cssSelector(".aValidCSSClass"));

how to make #FindAll annotation stop looking for object once the right one is found?

OS: Windows 10
Selenium Version: 3.4
#FINDALL annotation is supposed to match at least one of the given criteria.
Here is the OR :
URL for WebPage : http://store.demoqa.com/
WebElement : -
#FINDALL ({
#findby(xpath = "//input[#name='s']"),
#findby(xpath = "//a[contains(.,'Magic Mouse')]")
})
public WebElement Header__txtSearch;
I am trying to verify element on page with multiple locators.
When I give 2 correct values of XPath, then the driver identifies it quickly on the webpage and returns normally. But when I give the first one as Correct and second one as Incorrect , then it still returns true that element is found but it waits for the object timeout that was provided while initializing the driver(implicit wait).
Isn't there a way where if it finds the first element then it immediately returns us as true instead of going to match the next locator, So that no more time is taken for the test execution to move forward.
How can it be stopped after finding the correct locater info ??
Or is there a workaround for this in which I can use multiple locators for one element so that driver return true as soon as it matches the one locator correctly?
did you try to combine selectors into one by "|"? like:
#findby(xpath = "//input[#name='s']|//a[contains(.,'Magic Mouse')]")
public WebElement Header__txtSearch;
You can use or in the to get the first matching locator.
#findby(xpath = "//input[#name='s'] or //a[contains(.,'Magic Mouse')]")
public WebElement Header__txtSearch;

Categories

Resources