I am trying to use isDisplay() method in my selenium script.
While I am using this method I have found this method returns false every time.
Is there any other way to use this method or alternative of this method?
Scroll_UP is done successfully. But If element is display, Scroll_UP is not terminate.And I need return value also.
Thanks in advance.
code logic which I write
public static boolean scroll_Up_Until_FindWebe(WebElement dragEle, WebElement ele, int scrollPoint)
{
int numberOfPixelsToDragTheScrollbarUp = -10;
for (int i = scrollPoint; i > 10; i = i +numberOfPixelsToDragTheScrollbarUp)
{
if (ele.isDisplayed()) //if the tag options is displayed
{
Log4J.logp.info("Ending scroll_Up_Until_FindWebe - Element is found");
return true;
}
dragger.moveToElement(dragEle).clickAndHold().moveByOffset(0,numberOfPixelsToDragTheScrollbarUp).release().build().perform();
}
Thread.sleep(500);
return scroll_Up_Until_FindWebe(dragEle, ele, 30);
}
Related
In my webpage, I have a refresh button and one Text Field,
when i landed to that page, Initially that Text Field value would be processing (In backend there is a functionality which is processing, Inorder to inform the user, textfield value is processing in UI), and after functionality is done, that Text Field would be completed
Now coming to the question,
We will get to know the updated value of Text Field only when we click on the refresh button,
Is there a way to make a WebElement to be waited until that Text field has value as completed? We also need to click on that particular refresh button periodically to check that text field value became completed or not
I've found a method called textToBePresentInElement in ExpectedConditions, But using this, we cannot refresh button periodically,
Any other solution selenium webdriver is providing?
It's possible to implement a custom Expected condition:
import org.openqa.selenium.support.ui.ExpectedCondition
public static ExpectedCondition<Boolean> textToBePresentForElementWithRefreshByClick(By originalElement, Strint expectedText, By refreshElement) {
return new ExpectedCondition<Boolean>() {
private boolean hasText = false;
private String currentText = "";
#Override
public Boolean apply(WebDriver driver) {
currentText = driver.findElement(originalElement).getText();
hasText = currentText == expectedText;
if(!hasText) {
driver.findElement(refreshElement).click();
// Optionally some sleep might be added here, like Thread.sleep(1000);
}
return hasText;
}
#Override
public String toString() {
return String.format("element \"%s\" should have text \"%s\", found text: \"%s\"", originalElement.toString(), expectedText, currentText);
}
};
}
Usage:
By originalElement = ...;
By refreshElement = ...;
new WebDriverWait(driver, Duration.ofSeconds(10)).until(
textToBePresentForElementWithRefreshByClick(originalElement, "completed", refreshElement)
)
You need to write a custom method to wait for sometime then to perform click operation. You can see below sample code,
Code:
Create a re-usable method and write down the logic inside the method for click operation and element value check on given explicit interval times.
public static void clickUntilStatusIsChanged(By element1, By element2, String expectedStatus, int timeOutSeconds) {
WebDriverWait wait = new WebDriverWait(driver, 5);
/* The purpose of this loop is to wait for maximum of 50 seconds */
for (int i = 0; i < timeOutSeconds / 10; i++) {
if (wait.until(ExpectedConditions.textToBePresentInElementLocated(element2, expectedStatus))) {
break;
} else {
/* Waits for 10 seconds and performs click operation */
waitForTime(timeOutSeconds / 5);
driver.findElement(element1).click();
}
}
}
public static void waitForTime(int interval) {
int waitTillSeconds = interval;
long waitTillTime = Instant.now().getEpochSecond() + waitTillSeconds;
while (Instant.now().getEpochSecond() < waitTillTime) {
// Do nothing...
}
}
Pass the parameters to the re-usable method:
clickUntilStatusIsChanged(By.xpath("Element#1"), By.xpath("Element#2"), "completed", 50);
I need to test a dynamic Web Element using Selenium that will change its value after some time(back-end dependent). So, I built a boolean method that returns true if the web element has the value I need and false if that value is never retrieved. I want to check for value change at some intervals (thus, the Thread.sleep between page refreshes). My code always returns true, what am I doing wrong?
public boolean checkStatus() throws InterruptedException {
for(int i=0; i<2;) {
if (!serviceStatus.serviceElement().equals("LIVE")) {
Thread.sleep(5000);
theBrowser.navigate().refresh();
i++;
}else{
return true;
}
}
return false;
}
The method is used in the main test on the following assert:
Ensure.that(checkStatus()).isTrue();
I presume serviceElement() is the Webelement,you have to get the text for the element using getText() method and compare with the string you desire("LIVE") in this scenario.You seems to be comparing an Webelement with String here. Below should work if i understood the requirement correctly.
public boolean checkStatus() throws InterruptedException {
boolean isMatching = false;
for(int i=0; i<2;) {
if (!serviceStatus.serviceElement().getText().equals("LIVE")) {
Thread.sleep(5000);
theBrowser.navigate().refresh();
i++;
isMatching = false;
break;
}else{
isMatching = true;
}
}
return isMatching;
}
I have WebElement which I have to convert into Testobject in katalon using groovy script.
For Example
List<WebElement> WEs = WebUI.executeJavaScript("return document.querySelector('#email').parentElement", [])
Now I want to convert WEs[0] to TestObject which Katalon accepts.
Please let me know if you have an idea about this.
There is no direct way to convert WebElements to TestObjects. According to this forum question, you could create a function to get the xpath of the web element
protected String getXPathFromElement(RemoteWebElement element) {
String elementDescription = element.toString();
return elementDescription.substring(elementDescription.lastIndexOf("-> xpath: ") + 10, elementDescription.lastIndexOf("]"));
}
and then create a new test object with the given xpath:
protected TestObject fromElement(RemoteWebElement element) {
TestObject testObject = new TestObject();
testObject.addProperty("xpath", ConditionType.EQUALS, getXPathFromElement(element));
return testObject;
}
NOTE:
For other way around (Test Object -> WebElement), use
WebUiCommonHelper.findWebElement(test-object, timeout)
WebUI.convertWebElementToTestObject()
To create Test Object from any WebElement, I have developed the function as below
public static String WebElementXPath(WebElement element) {
if (element.tagName.toUpperCase() == 'HTML') return '/html';
if (element.tagName.toUpperCase() == 'BODY') return '/html/body';
// calculate position among siblings
int position = 0;
// Gets all siblings of that element.
List<WebElement> siblings = WebUI.executeJavaScript("return arguments[0].parentNode.childNodes", [element])
WebElement innerSibs
//List<WebElement> siblings = element.parentNode.childNodes;
WebElement sibling
def type,response
for(int i=0;i<siblings.size();i++){
type = WebUI.executeJavaScript("return arguments[0].nodeType", [siblings[i]])
if (type == null){
continue;
}
if(type!=1){
continue;
}
sibling = siblings[i];
// Check Siblink with our element if match then recursively call for its parent element.
if (sibling == element) {
innerSibs = WebUI.executeJavaScript("return arguments[0].parentElement", Arrays.asList(sibling))
if(innerSibs==null){
return ""
}
response = functions.WebElementXPath(innerSibs)
return response+'/'+element.tagName+'['+(position+1)+']';
}
// if it is a siblink & element-node then only increments position.
type = WebUI.executeJavaScript("return arguments[0].nodeType", [sibling])
if (type == 1 && sibling.tagName == element.tagName) position++;
}
}
And then I have created function to get test object as below as suggested by Mate Mrše
public static TestObject getTestObjectFromWebElement(WebElement element) {
TestObject object = new TestObject()
object.addProperty("xpath", ConditionType.CONTAINS, functions.WebElementXPath(element))
return object
}
Note : "Framework" folder had been created by us as inside the Keyword folder and then We had created the "functions" keyword
I hope this might help other developers.
Is it possible to find out if one WebElement comes before another one in the html code?
More general, is it possible to sort a collection of WebElement objects according to their order in the html code? (note: sorting a lot of elements is not actually my intention)
/*
<html>
<body>
<div>
<div>first</div>
</div>
<div>second</div>
</body>
</html>
*/
public int compare(WebElement a, WebElement b) {
return -1; // if a=first, b=second
return 0; // I'm not really interested in corner cases
return 1; // if a=second, b=first
}
In XPath you have the preceding:: and following:: axes, but in my case I already have the WebElement objects and I want to determine their relative order.
I have not tested this and I'm coding it on-the-fly:
public WebElement firstInList(WebElement a, WebElement b) {
WebElement found = null;
List<WebElement> all = driver.findElements(By.xpath("//*");
for (WebElement test : all) {
if (test.equals(a)) {
found = a;
break;
} else if (test.equals(b)) {
found = b;
break;
}
}
return found;
}
To make it using two differents IWebElements will be a pain - is hard and will take so much time to proccess the information to discovery the html nodes and know where each one is in -> and finaly says who is the first and who is the second one.
My sugestion is using two selectors: cssSelector or Xpath. Both of they are able to mix more than one selecting condition inside itself, and when you try to return a list of IWebElements using findElements, it will return based on html order. It means that, the fiers html node will be the first element in the list.
An example (in c#, sorry, i don't know java)
public bool IsATheFirstElement(string aXPathSelector, string bXPathSelector)
{
// Creates a xpath to find both elements: A and B
var generalXPath = aXPathSelector + " | " + bXPathSelector;
// Get a list of elements containing A and B, in HTML order
var ab = _driver.FindElements(By.XPath(generalXPath));
// Get the A element
var a = _driver.FindElement(By.XPath(aXPathSelector));
// Returns a bool value that checks if a is the first element or not
return ab.First() == a;
}
This solution is rather "brute force".
It looks for all the elements after a and sees if b is in there.
public int compare(WebElement a, WebElement b) {
if(a.equals(b)){
return 0;
}
List<WebElement> afterA = a.findElements(By.xpath("descendant::* | following::*"));
if(afterA.contains(b)) {
return -1;
} else {
return 1;
}
}
I need help with this scenario where I need to find a string from a pagination table wherein each page contains 50 items. My code below works fine, only problem is that when it cannot find the data my while loop sometimes keep running indefinitely and does not fail but sometimes it does! What can I do so that it will always return an error after reaching a number of loops?
public int inboxLocateLoan(String expName, String name) throws Throwable {
//Locate Loan element in SharePoint table
report.setFailedResult("Loan element is not found");
int loanRow;
try {
boolean loansearch = true;
while (loansearch) {
List < WebElement > rowElem = getWebElements(getAEDriver(), "xpath", sRow);
for (int i = 1; i <= rowElem.size(); i++) {
String actualLoanName = driver.findElement(By.xpath("//*[#id='onetidDoclibViewTbl0']/tbody[2]/tr[" + i + "]/td[3]")).getText();
// String actualLoanNumber = driver.findElement(By.xpath("//*[#id='onetidDoclibViewTbl0']/tbody[2]/tr["+i+"]/td[5]")).getText();
loanRow = i;
if (actualLoanName.equals(expName)) {
loansearch = false;
return loanRow;
}
if (actualLoanName.equals(name)) {
click(getAEDriver(), "xpath", "//*[#class='ms-pivotControl-surfacedOpt-selected']", "Refresh");
loansearch = true;
} else {
if (i == 50) {
click(getAEDriver(), "xpath", "//*[#id='pagingWPQ2next']/a", "Next Page");
} else {
loansearch = true;
}
}
}
}
}
Initialize the romElem outside the for, and then use it to toggle your flag. If you reached your max rowElemen and you didn't find what you were looking for, it is safe then to assume that the value will be false.
Also, what is the purpose of the while? you could remove it completely, it is usually a bad idea to mix a while and a for. I don´t see the point in doing so in this case.