Selenium method visibilityOf - Doesn't seem to be working? - java

When i used the listed method to see whether an element is visible on the page, I get an exception stating that its unable to locate an element using the specified locator.
Any ideas, has anyone faced this issue before or even have a better method?
public boolean isElementPresentByWebElement(WebElement element) {
Wait<WebDriver> fluentWait = new FluentWait<WebDriver>(driver).withTimeout(15, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
for (int i = 0; i < 2; i++) {
try {
fluentWait.until(ExpectedConditions.visibilityOf(element));
System.out.println("Element is visible: " + element.toString());
return true;
} catch (Exception e) {
System.out.println(
"Unable to locate the element: " + element.toString() + ", Exception: " + e.toString());
throw (e);
}
}
return false;
}

I think your code is overly complicated for what you are trying to do. There is a built in class, ExpectedConditions, that will do what you want. You are also looping over the wait which is unnecessary. I would suggest that you pass in a locator (By) instead of a WebElement. It will expand your ability to use this function because you won't have to find the element before using the function.
public boolean isElementPresentByLocator(By locator)
{
try
{
new WebDriverWait(driver, 15).until(ExpectedConditions.visibilityOfElementLocated(locator));
System.out.println("Element is visible: " + locator.toString());
return true;
}
catch (TimeoutException e)
{
System.out.println("Unable to locate the element: " + locator.toString() + ", Exception: " + e.toString());
return false;
}
}
The code below is more of a direct translation and simplification of your code.
public boolean isElementPresentByWebElement(WebElement element)
{
try
{
new WebDriverWait(driver, 15).until(ExpectedConditions.visibilityOf(element));
System.out.println("Element is visible: " + element.toString());
return true;
}
catch (TimeoutException e)
{
System.out.println("Unable to locate the element: " + element.toString() + ", Exception: " + e.toString());
return false;
}
}

Updated :
try using following :
int waitCounter = 0;
public static void WaitUntilVisible(WebDriver driver, WebElement element) throws InterruptedException, IOException {
try {
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOf(elementToBeClicked));
if (!elementToBeClicked.isDisplayed()) {
System.out.println("Element not visible yet. waiting some more for " + element);
if (waitCounter < 3) {
waitCounter++;
WaitUntilVisible(element);
}
waitCounter = 0;
}
} catch (Exception e)
{
System.out.println("Handling exception");
}
}

Related

Reactor 3 Emitter/Subscriber paralllel

i'm new in Reactive programming and have a lot of questions.
I think it is not a lack of examples or documentation it is just my understanding is wrong.
I'm trying to emulate slow subscriber;
Here is the code example
Flux.create(sink -> {
int i = 0;
while (true) {
try {
System.out.println("Sleep for " + MILLIS);
Thread.sleep(MILLIS);
int it = i++;
System.out.println("Back to work, iterator " + it);
sink.next(it);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).subscribeOn(Schedulers.elastic())
.subscribe(x -> {
try {
System.out.println("Value: " + x + ", Thread: " + Thread.currentThread().toString());
Thread.sleep(MILLIS + 4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
System out is
Sleep for 1000
Back to work, iterator 0
Value: 0, Thread: Thread[elastic-2,5,main]
Sleep for 1000
Back to work, iterator 1
Value: 1, Thread: Thread[elastic-2,5,main]
Sleep for 1000
Back to work, iterator 2
Value: 2, Thread: Thread[elastic-2,5,main]
I thought if subscriber is slow, i should see more threads due to Schedulers.elastic()
Also i tried to make publishOn() and it seems like i make it async, but still couldn't handle result in several threads.
Thanks for comments and answers.
If you want it to run in diferent threads you need to use .parallel() like this and the emit will be don in different thread
Flux.create(sink -> {
int i = 0;
while (true) {
try {
System.out.println("Sleep for " + MILLIS);
Thread.sleep(100);
int it = i++;
System.out.println("Back to work, iterator " + it);
sink.next("a");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
})
.parallel()
.runOn(Schedulers.elastic())
.subscribe(x -> {
try {
System.out.println("Value: " + x + ", Thread: " + Thread.currentThread().toString());
Thread.sleep(100 + 4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
})
;
}

StaleElementReferenceException while iterating over embedded links

On my webpage I have a list of links to sections, each section has links to details. I'm trying to go to each section, then verify all the links are not broken.
List<WebElement> sections = driver.findElements(By.xpath("//*[#id='sections']/li/a"));
System.out.println("sections: " + sections.size());
sections.forEach(selement -> {
selement.click();
List<WebElement> details = driver.findElements(By.xpath("//*[#id='details']/div/table/tbody/tr/td/table[1]/tbody/tr/td[2]/strong/a"));
System.out.println("details: " + details.size());
details.forEach(delement -> {
url = delement.getAttribute("href");
try {
huc = (HttpURLConnection) new URL(url).openConnection();
huc.setRequestMethod("HEAD");
huc.connect();
respCode = huc.getResponseCode();
if(respCode == 404) {
System.out.println(url + " link is broken");
} else if (respCode == 200) {
System.out.println(url + " link is ok");
} else {
System.out.println(url + " returned code " + respCode);
}
huc.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
driver.navigate().back();
});
The problem is I'm getting a StaleElementReferenceException after the first sections' details are checked. I'm guessing it's because after iterating over details and going back Selenium does not treat the rest of the sections list as current?
I could probably create a list of all the hrefs for sections and then iterate over that list navigating to specific section link and then checking for details' links. But maybe there is some other/simpler solution?
Yes, you are correct, after going back to the main page. list elements are changing and it will not refer same elements even though it is same.
You can not use for each for the first/outer iteration. You can change it as follows. Also. list elements should be re identified/searched after going back.
List<WebElement> sections = driver.findElements(By.xpath("//*[#id='sections']/li/a"));
System.out.println("sections: " + sections.size());
for(int i=0;i<sections.size();i++){
WebElement selement = sections.get(i);
selement.click();
List<WebElement> details = driver.findElements(By.xpath("//*[#id='details']/div/table/tbody/tr/td/table[1]/tbody/tr/td[2]/strong/a"));
System.out.println("details: " + details.size());
details.forEach(delement -> {
url = delement.getAttribute("href");
try {
huc = (HttpURLConnection) new URL(url).openConnection();
huc.setRequestMethod("HEAD");
huc.connect();
respCode = huc.getResponseCode();
if(respCode == 404) {
System.out.println(url + " link is broken");
} else if (respCode == 200) {
System.out.println(url + " link is ok");
} else {
System.out.println(url + " returned code " + respCode);
}
huc.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
});
driver.navigate().back();
sections = driver.findElements(By.xpath("//*[#id='sections']/li/a"));
}

Error removing user from ClientHandler

I have an error when a client closes the connection from the socket. What is supposed to happen is that the user closes their client, the server then receives this and should decrement the users who are connected which is stored in a relative integer value. However I receive an error relating to the for loop on the remove a user function.
public synchronized void removeUsers(Socket client,int clientUser)
{
int index=0;
for (ClientHandler newHandler:userList)
{
if(newHandler.getUserId() == clientUser)
{
try
{
client.close();
Thread.currentThread().isInterrupted();
userList.remove(index);
}
catch (IOException e)
{
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
index++;
}
}
Client handler run:
public void run()
{
String message;
message = input.nextLine(); //Note method!
getMessage(message);
System.out.println(message.substring(0, count+1)+"-"+message.substring(count+1));
while (!message.substring(0, count+1).equals("***CLOSE***"))
{
if(message.equals(user.getItemName(1)+"$status$")|| //checks for status of Ball
message.equals(user.getItemName(2)+"$status$"))
{
if (user.BidItem(user.getItemName(1)))
{
System.out.println("Top bid for " + //posts for server
message.substring(0, count+1) + " is: "
+ user.getTopBid(message.substring(0, count+1)));
output.println("Top bid for " + //posts for client
message.substring(0, count+1) + " is: "
+ user.getTopBid(message.substring(0, count+1))
+ " by User" +
user.getTopBidder(message.substring(0, count+1)));
}
else
{
System.out.println("-1");
output.println("-1");
}
}
else
{
if(user.BidItem(message.substring(count+2))) //same but now for Plate
{
if(user.isGrtrThanTopBid(message.substring(count+2),
Double.parseDouble(message.substring(0, count+1))))
{
user.setTopBid(message.substring(count+2),
Double.parseDouble(message.substring(0, count+1)), clientUser);
System.out.println("Bid Accepted for " + message.substring(count+2));
output.println("Bid Accepted for " + message.substring(count+2));
}
else
{
System.out.println("Low bid for " + message.substring(count+2));
output.println("Low bid for " + message.substring(count+2));
}
}
else
{
System.out.println("Late bid for " + message.substring(count+2));
output.println("Late bid for " + message.substring(count+2));
}
}
message = input.nextLine();
count = 0;
getMessage(message);
}
output.println(" messages received.");
System.out.println("\n* Closing connection... *");
user.removeUsers(client,clientUser);
}
The full error is here:
Exception in thread "Thread-2" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at Users.removeUsers(AuctionServer.java:211) //Relates to top of for loop
at ClientHandler.run(AuctionServer.java:435)
You can't remove objects from lists when you iterates on them.
Try this.
Instead use a queue.
Queue queue = new LinkedList<Client>();
int index=0;
for (ClientHandler newHandler:userList)
{
if(newHandler.getUserId() == clientUser)
{
try
{
client.close();
Thread.currentThread().isInterrupted();
queue.add(userList.get(index));
}
catch (IOException e)
{
System.out.println("Unable to disconnect!");
System.exit(1);
}
}
index++;
}
while(!queue.isEmpty()) {
userList.remove(queue.remove());
}

I want to know how to save the string ID and use the same to compare anywhere in any member function?

In Selenium we have a situation where we need to get the ID "MANTPLAP300920141426403767374" from an application and store it in a Object type Variable. We picked the ID using gettext() method.
We need to relogin into the application with an different user and use the ID that was saved earlier in a Object type variable in another method. We require to match the ID by doing a compare in each of the page in the approver application(some other method).
If the match is found we need to check the box and approve the record of that ID.
Flow:
STep 1: Login as an user 1 create record and save its ID.
2: Since its a string we Copy the ID into an Object variable.
3: logoff the application
4: Login with an diffrent user to approve the record
5: Search for the ID that was created by the first user in differnt pages if not found in the first page.
Issue is: We have one Java class where we are successfully storing the ID. After relogin into the application as a different user we are unaware how to call that object type variable and use it in that particular class.
In the debug mode we get NULL as the reference ID instead of saved ID "MANTPLAP300920141426403767374"
We want to know how to save the string ID and use the same to compare anywhere in any member function ?
CommonFunction Library.java
public static void getSourceRefId(String object,String data ) throws InterruptedException {
try{
{
ArrayList<String> NewTab = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(NewTab.get(1));
String SourceRefId=driver.findElement(By.id(OR.getProperty(object))).getText();
System.out.println("the value is "+ SourceRefId);
Log.info(" Required source ref is present in the applicaiton"+ object);
}
} catch (NoSuchElementException e){
Log.error("Not able to get the source ref id--- " + e.getMessage());
driver.close();
}
}
public static void searchSourceRefId(String object,String data ) throws InterruptedException{
try{
WindowsUtils.tryToKillByName("chromedriver.exe");
Thread.sleep(10000);
Log.info("Searching source ref id started");
WebDriver driver = null;
System.setProperty("webdriver.chrome.driver",System.getProperty("user.dir") + "\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://tpl.test.open.url.com/portal/login.do");
driver.findElement(By.name("j_username")).sendKeys("appoascgval1");
driver.findElement(By.name("j_password")).sendKeys("Password1");
driver.findElement(By.xpath("//input[#type='submit']")).click();
Thread.sleep(10000);
driver.findElement(By.xpath("//a[contains(text(),'Validation')]")).click();
Thread.sleep(30000);
//Getting the pages
List<WebElement> allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
System.out.println(allpages.size());
if(allpages.size()>0)
{
System.out.println("Pagination exists");
for(int i=0; i<=allpages.size(); i++)
{
//allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
List<WebElement> allrows = driver.findElements(By.xpath("//*[#id='content']/div[3]/table/tbody/tr"));
System.out.println("Total rows :" +allrows.size());
for(int row=1; row<=allrows.size(); row++)
{
System.out.println("Total rows :" +allrows.size());
allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
String validatorSoruceRefId = driver.findElement(By.xpath("//*[#id='content']/div[3]/table/tbody/tr["+row+"]/td[7]")).getText();
System.out.println(validatorSoruceRefId);
System.out.println("Row loop");
if(validatorSoruceRefId==Constants.SourceRefId){
// if(validatorSoruceRefId.contains("MANTPLAP300920141426403767374")){
System.out.println("is it found");
Log.info("Source id found" );
break;
}
else
{
System.out.println("Element doesn't exist");
// allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
}
}
System.out.println("I'm in page number" + i);
Thread.sleep(3000);
allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
allpages.get(i).click();
driver.manage().timeouts().pageLoadTimeout(50, TimeUnit.SECONDS);
//System.out.println(i);
}
}
else
{
System.out.println("Pagination doesn't exists");
}
}catch (IndexOutOfBoundsException e) {
}
}
}
Please help me to resolve this.
Store the first ID as a static variable and access it again (after logging in as a second user).
Try this code please:
static String SourceRefId;
public static String getSourceRefId(String object,String data ) throws InterruptedException {
try{
ArrayList<String> NewTab = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(NewTab.get(1));
SourceRefId=driver.findElement(By.id(OR.getProperty(object))).getText();
System.out.println("the value is "+ SourceRefId);
Log.info(" Required source ref is present in the applicaiton"+ object);
} catch (NoSuchElementException e){
Log.error("Not able to get the source ref id--- " + e.getMessage());
return SourceRefId;
}
}
public static void searchSourceRefId(String object,String data ) throws InterruptedException{
try{
WindowsUtils.tryToKillByName("chromedriver.exe");
Thread.sleep(10000);
//Log.info("Searching source ref id started");
WebDriver driver = null;
System.setProperty("webdriver.chrome.driver",System.getProperty("user.dir") + "\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://tpl.test.open.url.com/portal/login.do");
driver.findElement(By.name("j_username")).sendKeys("appoascgval1");
driver.findElement(By.name("j_password")).sendKeys("Password1");
driver.findElement(By.xpath("//input[#type='submit']")).click();
Thread.sleep(10000);
driver.findElement(By.xpath("//a[contains(text(),'Validation')]")).click();
Thread.sleep(30000);
//Getting the pages
List<WebElement> allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
System.out.println(allpages.size());
if(allpages.size()>0)
{
System.out.println("Pagination exists");
for(int i=0; i<=allpages.size(); i++)
{
//allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
List<WebElement> allrows = driver.findElements(By.xpath("//*[#id='content']/div[3]/table/tbody/tr"));
System.out.println("Total rows :" +allrows.size());
for(int row=1; row<=allrows.size(); row++)
{
System.out.println("Total rows :" +allrows.size());
allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
String validatorSoruceRefId = driver.findElement(By.xpath("//*[#id='content']/div[3]/table/tbody/tr["+row+"]/td[7]")).getText();
System.out.println(validatorSoruceRefId);
System.out.println("Row loop");
if(validatorSoruceRefId.equals(SourceRefId)){
// if(validatorSoruceRefId.contains("MANTPLAP300920141426403767374")){
System.out.println("is it found");
Log.info("Source id found" );
break;
}
else
{
System.out.println("Element doesn't exist");
// allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
}
}
System.out.println("I'm in page number" + i);
Thread.sleep(3000);
allpages = driver.findElements(By.xpath("//div[#class='content-table-pagination']//a"));
allpages.get(i).click();
driver.manage().timeouts().pageLoadTimeout(50, TimeUnit.SECONDS);
//System.out.println(i);
}
}
else
{
System.out.println("Pagination doesn't exists");
}
}catch (IndexOutOfBoundsException e) {
}
}
In the above code I have made the following changes:
Made SourceRefId as static
Changed the return type of method "getSourceRefId" to String so that it will return the "SourceRefId".
Lost the extra brackets inside try block of method "getSourceRefId".
Removed driver.close() from the method "getSourceRefId" and replaced it with the "return SourceRefId" that returns the value to be compared
And, finally changed the "if(validatorSoruceRefId==Constants.SourceRefId)" to "if(validatorSoruceRefId.equals(SourceRefId))" as Strings are compared here.
Hope this works out for you.

Selenium WebDriver By.xpath doesn't work all the time

Info :
I get fieldXpath from a config file, and it is "//input[#id='signin_password']"
HTML :
<li><input type="password" name="signin[password]" id="signin_password" /></li>
WORKS : (but not always)
Gets in the catch ...
public void doAction(WebDriver driver) throws TestException {
try {
WebElement el = driver.findElement(By.xpath(fieldXpath));
el.clear();
el.sendKeys(fieldValue);
} catch (Exception e) {
throw new TestException(this.getClass().getSimpleName() + ": problem while doing action : " + toString());
}
}
Does a solution that makes this code work with XPath?
I found the problem... : selenium WebDriver StaleElementReferenceException
*This may be caused because the page isn't loaded completely when the code starts or changes when the code is executed. You can either try to wait a little longer for the element or catch the StaleReferenceException and try again finding the div and the span.*
My code : (call these functions before each field)
/**
* Handle StaleElementReferenceException
* #param elementXpath
* #param timeToWaitInSec
*/
public void staleElementHandleByXpath(String elementXpath, int timeToWaitInSec) {
int count = 0;
while (count < 10) {
try {
WebElement slipperyElement = driver.findElement(By.xpath(elementXpath));
if (slipperyElement.isDisplayed()) {
slipperyElement.click(); // may throw StaleElementReferenceException
}
count = count + 10;
} catch (StaleElementReferenceException e) {
count = count + 1; // try again
} catch (ElementNotVisibleException e) {
count = count + 10; // get out
} catch (Exception e) {
count = count + 10; // get out
} finally {
// wait X sec before doing the action
driver.manage().timeouts().implicitlyWait(timeToWaitInSec, TimeUnit.SECONDS);
}
}
}
/**
* Wait till the document is really ready
* #param js
* #param timeToWaitInSec
*/
public void waiTillDocumentReadyStateComplete(JavascriptExecutor js, int timeToWaitInSec) {
Boolean ready = false;
int count = 0;
while (!ready && count < 10) {
ready = (Boolean) js.executeScript("return document.readyState == 'complete';");
// wait X sec before doing the action
driver.manage().timeouts().implicitlyWait(timeToWaitInSec, TimeUnit.SECONDS);
count = count + 1;
}
}
Use single ' quotes instead of ". So
String fieldXpath = "//input[#id='signin_password']";

Categories