merge two WebElements list - java

cannot print values from the merged lists as it is throwing me null!
List<WebElement> DateTime2 = driver.findElements(By.xpath(""));
driver.findElement(By.xpath("")).click();
List<WebElement> DateTime3 = driver.findElements(By.xpath(""));
List<WebElement> DateTime = new ArrayList<>(DateTime2);
DateTime.addAll(DateTime3);
Thread.sleep(2000);
System.out.println("This is for testing the list " +
DateTime.get(2).getText());
System.out.println("This is for testing the list " +
DateTime.get(30).getText());
i expect output to be printed date and time

Here's an example of some code I use (though I changed it a bit for this example. This is usually a part of a class that extends another.)
int sanitycount= 0;
int ec_Timeout = 10; //seconds to wait for list...
public void RunAction(WebDriver driver, String in_xpath)
{
try
{
wait = new WebDriverWait(driver, ec_Timeout);
List<WebElement> found_elements = new ArrayList<>();
found_elements = wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(in_xpath)));
if (!found_elements.isEmpty())
{
// store this array, return an array from function
// or loop through array and add items to more global array..
}
}
catch (Exception e)
{
if (e.getClass().getCanonicalName().equals("org.openqa.selenium.StaleElementReferenceException"))
{
//need to do it again, not finished loading
System.out.println("*****************Stale caught-redoing");
sanitycount++;
if (sanitycount<ec_Timeout * 2)
{
RunAction(driver, in_xpath);
}
System.out.println (e.toString());
}
else
{
System.out.println (e.toString());
}
}
}
RunAction(your_driver, your_xpath);
//set sanitycount back to zero if you run again...

Related

If the element is not available on a web page how to retry upto 3 times before failing in selenium

I am implementing a wrapper method for a retry mechanism for finding WebElements on a web page, my requirement is If the element is not available , retry upto 3 times before failing how do i implement this method, below is my code is it correct ?
public static WebElement findElementWithRetry(WebDriver driver, By by, int retryCount){
WebElement element = null;
try {
wait = new WebDriverWait(driver, 30);
element = wait.until(ExpectedConditions.visibilityOfElementLocated(by));
} catch (Exception e) {
//TODO: handle exception
for(int i=0; i<retryCount; i++){
element = driver.findElement(by);
if(element.isDisplayed())
return element;
}
}
return element;
}
How about this:
for(int i = 1; i <= retryCount; i++) {
try {
WebElement element = new WebDriverWait(driver, 30).until(ExpectedConditions.visibilityOfElementLocated(by));
if (element.isDisplayed()) {
return element
}
}
catch(TimeOutException e) {
// ignore
}
}
throw new ValueError(String.format("Element %s not found after %s retries", by, retryCount));

How can you use a passed value from one class to another in a for loop?

So I have a user field that they can type in 1-10 for number of players:
playersFld.setTextFormatter(new TextFormatter<String>(playersValidator));
custartBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, actionEvent4 -> {
Integer playersNum = Integer.valueOf(playersFld.getText());
if (!playersNum.equals("")) {
System.out.println("Got the values");
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/score_page.fxml"));
root = loader.load();
ScorePageCtrl scorePageCtrl = loader.getController();
scorePageCtrl.displayDate(strDate);
scorePageCtrl.recievePlayers(playersNum);
stage = (Stage) ((Node) actionEvent4.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("missing value(s)");
}
});
I pass that to the next page's controller in this method:
public int recievePlayers(int plrNum){
System.out.println("Players: " + plrNum);
return plrNum;
}
The sout let's me know I'm getting the correct number, but I can't seem to pass the returned value to a for array
AtomicInteger tabs = new AtomicInteger(2);
for (int i = 2; i <= recievePlayers(); i++) {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
}
I've tried the method name, the integer name, making int p; and then attaching it to the return, but nothing seems to work.
EDIT:
So I've tried changing things and I can get it to work but for some reason it only fires every other time, which is less than ideal.
I changed:
public static int plrNum;
public int receivePlayers(int players) {
System.out.println("Players: " + players);
//Used to make sure I get the number datesSP.setText(String.valueOf(players));
return this.plrNum = players;
}
And use this to instantiate so I can put it in the for loop:
int n = plrNum;
But there has to be a better way.
EDIT: So I've updated my gist to reflect the current code that is working, but for some reason it only works every other time.
https://gist.github.com/Spider-Ian/3d5c777171d7ad632e9b71943fcf950c
Your method takes a parameter, but you are calling it without. Change it to
public int recievePlayers() {
and it should work.
Bonus tip! Change it to
public int receivePlayers() {
to make it easier to use.
For example, this way can work also.
public class Player {
public int num;
public int recievePlayers(int plrNum){
System.out.println("Players: " + plrNum);
return this.num = plrNum;
}
}
public static void main(String[] args) {
Player player = new Player();
player.recievePlayers(3);
int n = player.num;
AtomicInteger tabs = new AtomicInteger(2);
for (int i = 2; i <= n; i++) {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
}
}
Okay apparently there is a very strict course of events that happen in a controller. It loads FXML items, it initializes and then it looks for other methods and fun things to play with. So, the way to make sure that the tabs get the data first, I can call them ahead of time with the previous controller.
threeThirBtn.addEventHandler(MouseEvent.MOUSE_CLICKED, actionEvent1 -> {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/score_page.fxml"));
root = loader.load();
ScorePageCtrl scorePageCtrl = loader.getController();
scorePageCtrl.displayDate(strDate);
scorePageCtrl.displayEvent("3 x 30");
scorePageCtrl.receivePlayers(3);
scorePageCtrl.receivePlays(3);
scorePageCtrl.receiveRounds(30);
//**Here is where I told the method to get the returned value before initialization**
scorePageCtrl.addTabs();
scorePageCtrl.addRows();
stage = (Stage) ((Node) actionEvent1.getSource()).getScene().getWindow();
scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
//TODO: Set the row and column numbers to thirty rows and three columns
System.out.println("3 x 30 button clicked");
});
I did have to move the AtomicInteger out of the initialize and into its own method.
public void addTabs() {
int plr = plrNum;
AtomicInteger tabs = new AtomicInteger(2);
for (int i = 2; i <= plr; i++) {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
}
addPlayerBtn.setOnAction(event -> {
if (tabs.get() <= 10) {
tabPaneSP.getTabs().add(new Tab("Player" + tabs.getAndIncrement()));
tabPaneSP.getSelectionModel().selectLast();
} else {
System.out.println("No more homies");
}
});
}
The only think I'm still not happy with is the amount of hoops to get a get value to return as an useable integer.

what is the difference two functions while and expected condition

I have two functions for actualy lookng for element that appear after sometime (something around 7 sec) so I tried to do it with expected conditions - visibility / presence of element with time duration of 10 sec and I got error that the element is not appear eventhough I saw it in other hand I did function :
public SafeModeScreen validateSafeModeScreen(){
boolean flag = false;
while(!flag) {
try {
System.out.println("The name is :" +driver.findElement(safeModeScreen).getAttribute("name"));
System.out.println("The screen height is :" + driver.findElement(safeModeScreen).getSize().getHeight());
System.out.println("The screen width is :" + driver.findElement(safeModeScreen).getSize().getWidth());
flag = true;
}
catch (Exception e){
}
}
Assert.assertTrue(flag, "Safe mode screen didn't appear");
return this;
}
the other function is:
public void waitForElementToBeVisible(By element, int delay) {
wait = new WebDriverWait(driver, delay);
wait.until(ExpectedConditions.visibilityOfElementLocated(element));
wait = new WebDriverWait(driver, 30);
}
and that worked, what is the difference between them that the while worked?
Thank you

How to change a specific parameters of the specific elements in an array-list based on another elements parameters

I am new to java but have been playing with array-lists and am now stuck.
I have an array list created off a class called Car with three parameters one of which is called times moved.
ArrayList:
private ArrayList<Car> list = new ArrayList<Car>() ;
Car class
public Car ( String licenseNum, String carStatus , int timesMoved)
{
licensePlate = licenseNum ;
status = carStatus ;
moved = timesMoved;
}
I am reading input of a file that is supposed to be like a garage and says if a car is "Arriving" or "Departing"
I am trying to write a code using an if statement that says if the status is "Departing" then the current element gets deleted the all elements in front of it add one to their "times moved parameter"
The part I am stuck on is the one where, based on the element getting deleted, all the elements in front of it in the array list add one to their "times moved" parameter.
Would anyone give me some advice on how it would be possible to do that?
I came up with this but it does not seem to work
public void carDepart()
{
for ( int i = 0 ; i < list.size() ; i++ )
{
Car current = list.get( i ) ; // get next car
if (current.getStatus().equals("DEPART"))
{
int pos = list.indexOf(i);
for ( int j = 0 ; pos < j ; j++)
{
current.setTimesMoved(1 + current.getTimesMoved());
}
list.remove(i);
}
break;
}
}
Second method
public void moveCarInGarage()
{
for ( int i = 0 ; i < list.size() ; i++ )
{
Car current = list.get( i ) ; // get next car
if (current.getStatus().equals("ARRIVE"))
{
currentCars++;
if (currentCars <= 10)
{
System.out.println("Car with license plate" +
current.getLicenseNum() + " has been moved into the garage");
}
else
{
System.out.println("The garage is full at this " +
"time so come back later");
}
}
else
{
currentCars--;
System.out.println("Car with license plate" +
current.getLicenseNum() + " is departing and has been moved "
+ current.getTimesMoved() + " times" );
}
}
}
Here is an example of what you can do. In it, I assume you are using getters and setters. You can also call the attributes directly assuming you've set the access modifiers in a way that allows you to do so.
All I did was create a new method called incrementTimesMoved() that iterates through your ArrayList and increments all the "moved" attributes in it's elements until it gets to the one with a given index. It removes this, and stops running.
public class MCVE {
public static void main(String[] args) {
// IMO list isn't very descriptive, so I changed it to carList.
ArrayList<Car> carList = new ArrayList<>();
// Add a bunch of values to carList here.
for(int i = 0; i < carList.size(); i++) {
if(carList.get(i).getStatus().equals("Departing")) {
incrementTimesMoved(i, carList);
return; // stops the method
}
}
}
// only static because I am calling in the main() function
private static void incrementTimesMoved(int index, ArrayList<Car> carList) {
for(int i = 0; i < carList.size(); i++) {
if(i == index) {
carList.remove(index);
return;
}
carList.get(i).setMoved(carList.get(i).getMoved() += 1);
}
}
}

Changing values of static class variables in a nested loop

I'm having an issue with changing the values of a class variable within nested loops - I can't figure out why. I'm guessing it's because the variable is static. But it's a static method and because it's used for listing a User in a system from a file, it has to be static (I'm calling it from main method to read file to TreeMaps). Is it not possible to rewrite a static class variable from within a method? If it's possible - what the heck am I doing wrong?
public class Loan{
protected int noOfLoans;
protected int noOfReturns;
protected User user=new User();
protected static Book book= new Book();
protected Map <Integer, Book> currentLoans=new TreeMap <Integer, Book>();
protected Map <Integer, Book> returned=new TreeMap <Integer, Book>();
protected static Map<Integer, Loan> loanList=new TreeMap<Integer, Loan>();
public static void main(String[] args){
readLoans();
}
public static void readLoans(){
loanList.clear();
BufferedReader reader = null;
try {
reader=new BufferedReader(new FileReader("loans.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = null;
try {
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
while (line!=null) {
String[] splitOut=line.split("-");
String[] loan_User=splitOut[0].split(",");
String[] loan_CurrentLoans=splitOut[2].split(",");
String[] loan_Returned=splitOut[4].split(",");
Loan loan = new Loan();
loan.user.setFirstName(loan_User[0]);
loan.user.setSurname(loan_User[1]);
loan.user.setPersonalID(loan_User[2]);
for (int i = 1; i <= Integer.parseInt(splitOut[1]); i++) {
book.setName(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)]);
book.setAuthorFirstname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+1]);
book.setAuthorSurname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+2]);
book.setISBN(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+3]);
loan.currentLoans.put(i, book);
}
for (int i = 1; i <= Integer.parseInt(splitOut[3]); i++) {
book.setName(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)]);
book.setAuthorFirstname(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+1]);
book.setAuthorSurname(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+2]);
book.setISBN(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+3]);
loan.returned.put(i, book);
}
loan.setNoOfLoans(Integer.parseInt(splitOut[1]));
loan.setNoOfReturns(Integer.parseInt(splitOut[3]));
loanList.put(loanList.size()+1, loan);
try {
line=reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Here's an input line for reference:
John,Doe,8012311213-2-a book,Author,Authorson,1234567890123,another book,Author,Authorson,2345678901234-1-a returned book,Author,Authorson,3456789012345
What I'm hoping to get when printing above line:
Current Loans:
1. a book by Author Authorson (1234567890123)
2. another book by Author Authorson (2345678901234)
Returned Loans:
1. a returned book by Author Authorson (3456789012345)
What I'm currently getting:
Current Loans:
1. a book by Author Authorson (1234567890123)
2. a book by Author Authorson (1234567890123)
Returned Loans:
1. a book by Author Authorson (1234567890123)
And
readLoans();
System.out.println(loanList.get(2).currentLoans.get(1).toString());
System.out.println(loanList.get(2).currentLoans.get(2).toString());
returns
a returned book by Author Authorson (3456789012345)
a returned book by Author Authorson (3456789012345)
Which leads me to believe I actually cannot make instances of my static Book object, but have to make it non-static and try to create instances of the object within the method. If so - how do I do that?
From here, it's hard to understand how you can understand as much as you do, and yet be so confused, at the same time. I don't mean that to be insulting - just to say that I'm not at all sure I understand where you are.
Create instances by using new. So in your two loops, where you keep overwriting the one static book, instead you need a local variable that you assign a new book to and then set the fields on.
The problem isn't that your Book is static, the problem is more simply that it's the same object every time you change it during the loop. This does happen because you've declared it as a static field but you are on the wrong track thinking the way you are about it.
Let's simplify the problem and instead of a Book, use this to illustrate:
class AnObject {
int aValue;
}
And instead of IO, just loop some times and add it to a list:
class PersistenceOfChangesDemo {
static List<AnObject> theList = new ArrayList<AnObject>();
public static void main(String[] args) {
AnObject theObject = new AnObject();
for(int i = 1; i <= 3; i++) {
/* reassign the object's value */
theObject.aValue = i;
/* adds the same object each time */
theList.add(theObject);
}
/* theList is now of size 3
* but all its elements refer to the same object (theObject) */
for(AnObject anObject : theList) {
/* prints '3' every time
* because that was the last value assigned */
System.out.println(anObject.aValue);
/* prints 'true' every time */
System.out.println(anObject == theObject);
}
}
}
The solution is that you need to create a new object each time you want a new one:
class PersistenceOfChangesDemo {
static List<AnObject> theList = new ArrayList<AnObject>();
public static void main(String[] args) {
for(int i = 1; i <= 3; i++) {
/* make a new object each time */
AnObject anObject = new AnObject();
anObject.aValue = i;
theList.add(anObject);
}
/* theList now has references to 3 different objects */
for(AnObject anObject : theList) {
/* prints 1, 2, 3 */
System.out.println(anObject.aValue);
}
}
}
Per your comment, make sure you are creating the new instance for each time you put it in to the map:
for (int i = 1; i <= Integer.parseInt(splitOut[1]); i++) {
Book newBook = new Book();
newBook.setName(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)]);
newBook.setAuthorFirstname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+1]);
newBook.setAuthorSurname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+2]);
newBook.setISBN(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+3]);
loan.currentLoans.put(i, newBook);
}
it's just Reference problem. All three are referring to same object static book so represent the same details which are inserted last.
The change is only create new object of Book() instead of using same object for different detail.
try below code
Loan loan = new Loan();
loan.user.setFirstName(loan_User[0]);
loan.user.setSurname(loan_User[1]);
loan.user.setPersonalID(loan_User[2]);
for (int i = 1; i <= Integer.parseInt(splitOut[1]); i++) {
book = new Book(); // added this line
book.setName(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)]);
book.setAuthorFirstname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+1]);
book.setAuthorSurname(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+2]);
book.setISBN(loan_CurrentLoans[((Integer.parseInt
(splitOut[1])-1)*4)+3]);
loan.currentLoans.put(i, book);
}
for (int i = 1; i <= Integer.parseInt(splitOut[3]); i++) {
book = new Book(); // added this line
book.setName(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)]);
book.setAuthorFirstname(loan_Returned[((Integer.parseInt
(splitOut[3])-1)*4)+1]);
How I solved it;
public static void readLoans(){
// Reads the bookList and userList.
readBooks();
readUsers();
// Creates a new BufferedReader and tries to read "loans.txt"
BufferedReader reader = null;
try {
reader=new BufferedReader(new FileReader("loans.txt"));
}
// Catches exception if "books.txt" does not exist.
catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = null;
// tries to read the first line and interpret it as a String.
try {
line = reader.readLine();
}
// Catches IOexception if any is thrown when trying to read line.
catch (IOException e) {
e.printStackTrace();
}
// Loop as long as "line" is not empty, i.e. as long as a Loan is read.
while (line!=null) {
// split the String "line" at every RegEx "-"
String[] splitOut=line.split("-");
// Create a String from the first index of the first split.
String user = splitOut[0];
/* Split the second and third index of the first split and create
* new Stringarrays from them.*/
String[] loans = splitOut[1].split(",");
String[] returns = splitOut[2].split(",");
User aUser = new User();
/* Find the user in the userList whose personal ID matches the
* String "user" that we created. This is the user that we want to
* create (a) loan/s and/or (a) returned loan/s for.*/
for (int i = 1; i < userList.size()+1; i++) {
if (userList.get(i).getPersonalID().equals(user)) {
/*Set the variables for the User.*/
aUser.setFirstname(userList.get(i).getFirstname());
aUser.setSurname(userList.get(i).getSurname());
aUser.setPersonalID(userList.get(i).getPersonalID());
aUser.setTelephone(userList.get(i).getTelephone());
aUser.setLoans(userList.get(i).getLoans());
aUser.setReturns(userList.get(i).getReturns());
// Create an ArrayList for Loans and Returns for every user
ArrayList<Loan> listOfloans = new ArrayList<Loan>();
ArrayList<Loan> listOfreturns = new ArrayList<Loan>();
// if the new user has any loans...
for (int j = 0; j < aUser.getLoans(); j++) {
for (int k = 1; k < bookList.size()+1; k++) {
/* ... find the "Book" object with the
* corresponding ISBN...*/
if (bookList.get(k).getIsbn().equals(loans[j*3])) {
// ...then create a new loan object for each...
Loan loan = new Loan();
// ...and set the variables of each loan...
loan.setTitle(bookList.get(k).getTitle());
loan.setAuthor_firstname(bookList.get(k).
getAuthor_firstname());
loan.setAuthor_surname(bookList.get(k).
getAuthor_surname());
try {
loan.setIsbn(bookList.get(k).getIsbn());
} catch (Exception e) {
e.printStackTrace();
}
loan.setMaxLoan(bookList.get(k).getMaxLoan());
loan.setOnLoan(bookList.get(k).getOnLoan());
loan.setAvailable(bookList.get(k).
getAvailable());
loan.setSignature(loans[j*3+1]);
loan.setTimestamp(loans[j*3+2]);
/* ...then add each one to the "listOfloans"
* ArrayList.*/
listOfloans.add(loan);
}
}
}
/* if the "listOfloans" ArrayList is not empty,
* add the loan to loanList with User as Key.*/
if (!listOfloans.isEmpty()) {
loanList.put(aUser, listOfloans);
}
// if the new user has any returned loans...
for (int j = 0; j < aUser.getReturns(); j++) {
for (int k = 1; k < bookList.size()+1; k++) {
/* ... find the "Book" object with the
* corresponding ISBN...*/
if(bookList.get(k).getIsbn().equals(returns[j*4])){
// ...then create a new loan object for each...
Loan loan = new Loan();
// ...and set the variables of each loan...
loan.setTitle(bookList.get(k).getTitle());
loan.setAuthor_firstname(bookList.get(k).
getAuthor_firstname());
loan.setAuthor_surname(bookList.get(k).
getAuthor_surname());
try {
loan.setIsbn(bookList.get(k).getIsbn());
} catch (Exception e) {
e.printStackTrace();
}
loan.setMaxLoan(bookList.get(k).getMaxLoan());
loan.setOnLoan(bookList.get(k).getOnLoan());
loan.setAvailable(bookList.get(k)
.getAvailable());
loan.setSignature(returns[j*4+1]);
loan.setTimestamp(returns[j*4+2]);
loan.setReturndate(returns[j*4+3]);
/* ...then add each one to the "listOfreturns"
* ArrayList.*/
listOfreturns.add(loan);
}
}
}
/* if the "listOfreturns" ArrayList is not empty,
* add the returned loan to returnList with User as Key.*/
if (!listOfreturns.isEmpty()) {
returnList.put(aUser, listOfreturns);
}
}
}
// tries to read the next line and interpret it as a String.
try {
line=reader.readLine();
}
// Catches IOexception if any is thrown when trying to read line.
catch (IOException e) {
e.printStackTrace();
}
}
// try to close the BufferedReader.
try {
reader.close();
}
// Catches IOexception if any is thrown when trying to close.
catch (IOException e) {
e.printStackTrace();
}
}
It was a problem with the instancing of the Book object and with objects and methods being static. I had to rewrite a few of the methods behind the scenes that were major problems. Thanks for all the help! =)

Categories

Resources