Selenium chrome webDriver - get focus on the latest open new tab java - java

I have problem while trying to get focus on the latest new tab i'v opened with selenium web driver.
in some mysterious way, when i try to change between 2 tabs it works,
but when i'm trying to do this with 4 tabs it always get focus on the 3rd tab.
here is the code of the function that gets WebDriver element:
ArrayList tabs = new ArrayList(driver.getWindowHandles());
System.out.println(tabs);
System.out.println(tabs.get(tabs.size() -1));
driver.switchTo().window((String) tabs.get(tabs.size() - 1));
and here is the out put when i'm printing the tabs:
[CDwindow-(43C81B1D7B7C666BFBFB339971ADEE0F), CDwindow-(CDD5D45D021E698DD005BC2AD6201714), CDwindow-(33FB208B51A8DD5F7DB947C7B0BAB9DD), CDwindow-(4B50A8C4074BEDB41152003DED37FB32)]
CDwindow-(4B50A8C4074BEDB41152003DED37FB32)
as you can see the first row is the all the ArrayList.
and the second row is only the last tab that i want to get focus on.
am i missing something here??

I fail to see the issue.
tabs holds a list of handles (which may or may not be in the order you see them in the browser).
tabs.size() is returning 4 (4 tabs). so tabs.get(tabs.size() - 1)) is tabs.get(4 -1 ) or tabs.get(3).
Since java is 0-indexed, tabs.get(3) is the last tab. And looking at the output above is correct; CDwindow-(4B50A8C4074BEDB41152003DED37FB32).
Where is it going to the third tab; CDwindow-(33FB208B51A8DD5F7DB947C7B0BAB9DD)?
I find it easier to keep track of if you Map the windows to a name:
public static Map<String, String> tabs = new HashMap<String, String>();
With the first String being your own descriptor like "Admin", or "Facebook" and the second String is the WindowHandle. You will need to add the windows one by one to keep track of them.
tabs.put(handleName, handle);
But when you want to switch you can use:
driver.switchTo().window(tabs.get("Admin"));
And eliminate all confusion.

So, after a little bit of debugging - i just wrote an if statement the will stop on the page i want.
Set<String> handles = driver.getWindowHandles();
String currentHandle = driver.getWindowHandle();
for (String handle : handles) {
if (!handle.equals(currentHandle)) {
driver.switchTo().window(handle);
if(whatImLookingFor)
break;
}
}
the problem is solved for me, but i think it worth to try to understand this for future needs...

Related

Selenium throws StaleElementReferenceException

Testing CEF-based one-page application and have some problems. So, my application can generate an output file in many different configurations that are available to choose from dependent on each other dropdown lists.
Trying to generate files for all possible options by simulating the appropriate clicking: display list select the first possible option -> the same with list2 -> the same with list3 again -> go forward -> export file -> go back to the beginning.
for (WebElement material : materialList) {
displayMaterialList.click();
material.click();
for (WebElement size : sizeList) {
displaySizeList.click();
size.click();
for (WebElement thickness : thicknessList) {
displayThicknessList.click();
thickness.click();
//Exporting file:
nextStepButton.click()
nextStepButton.click();
exportFileButton.click();
copyPasteText("filename" + "_" + currentDataTime);
previousStepButton.click();;
}
}
}
These loops work fine without exporting file fragment embedded in the deepest loop, used them to display combinations of all possible options. But when I added file naming and exporting fragment tests project threw out
StaleElementReferenceException just after generated file, at the start of the second iteration. I think it can't find thickness.click(); but don't know why.
according to Exception Doc Selenium
Common Causes
A stale element reference exception is thrown in one of two cases, the first being more common than the second:
The element has been deleted entirely.
The element is no longer attached to the DOM.
Please check that, and if can't see the html tha you are trying to test in pretty difficult give a appropiate answer.

Unable to Navigate to URL with Selenium Gecko WebDriver

I have this funny bug happening to me today. I've been using Selenium for years already and never had an issue navigating to URL (via driver.navigate().to(url)) however today I'm attempting to navigate to a specific URL and I find that after executing the program several times it sometimes just stays on the original page without navigating to new page.
The funny thing is that this only happens about 50% of the time and it only happens when navigating to a specific URL at a specific part of the program (in other parts of program I have no issue navigating to this url).
Is it possible that some element on the current page is preventing driver.navigate().to(url) from executing?
I've looked at this and this question but both seem to have issues with navigating altogether. In my case, it sometimes works and sometimes doesn't (even when the exact same url is being used).
Also I'm not getting any specific errors (so I don't have much more info to post). The program just moves on as if the statement didn't exist.
I'll be happy to provide additional details if necessary.
Code:
shoppingCartURL.navToShoppingCart(driver);
String[] XPath = { "//*[contains (#value,'Delete')]" };
List<WebElement> elementList = webElementX.getElementListByXPath(driver, XPath);
System.out.println("Deleting " + elementList.size() + " element(s) from shopping cart");
for (int elementListCounter = 0; elementListCounter < elementList.size(); elementListCounter++) {
WebElement singleElement = elementList.get(elementListCounter);
try {
singleElement.click();
} catch (Exception e) {
System.out.println("Exception occurred (StaleElementReferenceException)");
}
}
if (conditionX == false) {
productPage.navToProductPage(driver, product); // this method is not always executed, program continues to execute productPage.performActionOnPage(driver); without navigating to 'product page'
productPage.performActionOnPage(driver);
}
public void navToProductPage(WebDriver driver, String product)
{
String URL = "https://www.example.com/product/" + product;
System.out.println("Navigating to " + URL); // always prints the correct url (but still doesn't always navigate to url as mentioned in question)
driver.navigate().to(URL);
}
Update:
I noticed ref=cart-ajax-error in redirect url (after deleting items from cart). Apparently, the site is using AJAX to refresh page after deleting items from cart. Might this conflict with my attempt to navigate to another page? In other words, perhaps Selenium is getting two different messages at the same time.. refresh page and navigate to new page.. so it remains on the current page?
If this is true, what can be done to resolve this issue?
Thanks!
When it sometimes happens and sometimes not it's nearly always a matter of timing.
Add an explicit wait to your code after navigating to the URL:
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.urlToBe(URL));

Selenium sends incomplete text

I'm having a problem with Selenium when it comes to use .sendKeys(text). During the automation process, sometimes selenium is sending incomplete strings to the browser, which causes to create incorrect searchs.
i.e. I want to type "MY DROP", and it will type "Y DROP", or "ROP".
It does not always type the same way, so sometimes 2 letters might be missing, and sometimes the whole word is missing.
This only happens to dropdowns, where I have a specific method that handles the dropdown selection, as we are using angular I can't use the selenium select dropdown method.
I already tried to set Thread.Sleeps and waits on the dropdown selection but nothing seems to work, currently this is what I use to select a value:
public void select(String item) {
waitTillClicable();
WebElement element = getElement();
openDropDown(element);
element.sendKeys(item);
waitResultLoad();
selectResult(element);
}
This code was working perfectly until the last week. I'm thinking it has something to deal with the new Chrome version 45, as before it was not happening. I also tried to use different chromedriver versions, and running on a Linux machine, but nothing seems to have an effect.
Right now I created a workaround where I keep verifying if the string was typed correctly, and re-typing it until it is correct, but this makes the execution time increased, which I wanted to avoid.
Why are you using .sendKeys() to select a value in a SELECT? Use the provided methods for a Select: .selectByIndex(int), .selectByValue(String), or .selectByVisibleText(String). Some examples...
Select test = new Select(driver.findElement(By.id("dropdown")));
test.selectByIndex(1);
test.selectByValue("myValue");
test.selectByVisibleText("VisibleText");
See if the happens on Firefox driver or IE driver
The other thing is the method signature is
public void sendKeys(CharSequence... value)
can you try to send it like this sendKeys( "MY","DROP"); instad and see the result
Hope this may help.
Alan Mehio
London, UK

Write java loop with selenium webdriver

I am automating UI flow using Webdriver and Java. Need help in the following:
Clicking a link, verifying the title, clicking browser back button - these steps are repeated for number of links in the content. I am using page object design and all the objects are in different class. My code is:
objectBase.clickLink1();
titleVeri(pageTitle1);
driver.navigate().back();
objectBase.clickLink2();
titleVeri(pageTitle2);
driver.navigate().back();
objectBase is the name of the object where I kept all my page objects. clickLink1 and clickLink2 are methods on page objects class which does clicking on links. titleVeri is utility method for verifying the title.
What I need is construct this inside loop as I have more this.
you could use a map for this, make a method clickLink(key) in objectBase
then do something like
Map<String,String> myMap = new TreeMap();
myMap.put("1",pageTitle1);
myMap.put("2",pageTitle2);
for(Map.Entry<String,String> entry : myMap.entrySet()){
objectBase.clickLink(entry.getKey());
titleVeri(entry.getValue());
driver.navigate().back();
}
What you are describing is not strictly possible. The reason is that you cannot have a pointer to a function.
However, you said that you are using the Page objects pattern. Rather than using the clickLink1() function, do you have a function that returns link1()? That way you could use a Map (like BevynQ said).
Map<WebElement, String> linksAndTitles = new HashMap();
linksAndTitles.put(page.getHomePageLink(), "Home");
linksAndTitles.put(page.getUserPageLink(), "Contact Details");
...and so on for each of the different links...
for (WebElement link: linksAndTitles.keySet()){
link.click();
titleVeri(linksAndTitles.get(link));
driver.navigate().back();
}
As a side note...if one of those links is the Logout link...that has to be tested seperatly.
Furthermore...I really don't recommend this test...it's likely just a waste of time. On each of your pages, in your isLoaded() function, you should test the title. That way, whenever you call page.get(), the title will be automatically tested, and it isn't part of your test.

Limit to the number switch/if options?

Small disclaimer I am new to Java and this is my first real programme i am trying to write.
I am currently writing a programme with 3 class's. The first is a GUI with a JComboBox, 4 JButtons and 20 JTextFields.
The second takes information from the JComboBox box and uses it to give labels to the 4 JButtons using a set of if statements.
The third populates the JTextFields when one of the the JButtons is clicked depending on the button clicked and the choice in the JComboBox using a set of switch statements.
The first 2 class's work fine and the third works fine until i enter x amount of switches and then i start to get an error.
A small example of my code for the third class is
switch (hiddenText) {
case "Abecean Longfin":
if (command.equals("Weakness to Frost")){
gui.r1.setText("Elves Ear");
gui.r2.setText("Fire Salts");
gui.r3.setText("Ice Wraith Teeth");
gui.r4.setText("White Cap");
gui.r5.setText("");
gui.r6.setText("");
gui.r7.setText("");
gui.r8.setText("");
gui.r9.setText("");
gui.r10.setText("");
gui.r11.setText("");
gui.r12.setText("");
gui.r13.setText("");
gui.r14.setText("");
gui.r15.setText("");
gui.r16.setText("");
gui.r17.setText("");
gui.r18.setText("");
gui.r19.setText("");
gui.r20.setText("");
}
if (command.equals("Fortify Sneak")){
gui.r1.setText("Beehive Husk");
gui.r2.setText("Frost Mirriam");
gui.r3.setText("Hawk Feathers");
gui.r4.setText("Human Flesh");
gui.r5.setText("Powdered Mammoth Tusk");
gui.r6.setText("Purple Mountain Flower");
gui.r7.setText("");
gui.r8.setText("");
gui.r9.setText("");
gui.r10.setText("");
gui.r11.setText("");
gui.r12.setText("");
gui.r13.setText("");
gui.r14.setText("");
gui.r15.setText("");
gui.r16.setText("");
gui.r17.setText("");
gui.r18.setText("");
gui.r19.setText("");
gui.r20.setText("");
}
if (command.equals("Weakness to Poison")){
gui.r1.setText("Bleeding Crown");
gui.r2.setText("Chaurus Eggs");
gui.r3.setText("Deathbell");
gui.r4.setText("Giant Lichen");
gui.r5.setText("Pine Thrush Egg");
gui.r6.setText("Sabre Cat Tooth");
gui.r7.setText("Small Antlers");
gui.r8.setText("");
gui.r9.setText("");
gui.r10.setText("");
gui.r11.setText("");
gui.r12.setText("");
gui.r13.setText("");
gui.r14.setText("");
gui.r15.setText("");
gui.r16.setText("");
gui.r17.setText("");
gui.r18.setText("");
gui.r19.setText("");
gui.r20.setText("");
}
if (command.equals("Fortify Restoration")){
gui.r1.setText("Cyrodilic Spadetail");
gui.r2.setText("Salt Pile");
gui.r3.setText("Small Antlers");
gui.r4.setText("Small Pearl");
gui.r5.setText("");
gui.r6.setText("");
gui.r7.setText("");
gui.r8.setText("");
gui.r9.setText("");
gui.r10.setText("");
gui.r11.setText("");
gui.r12.setText("");
gui.r13.setText("");
gui.r14.setText("");
gui.r15.setText("");
gui.r16.setText("");
gui.r17.setText("");
gui.r18.setText("");
gui.r19.setText("");
gui.r20.setText("");
}
break;
There are a total of 92 cases, each with 4 if statements and the programme works fine until i get to 57 cases and 2 if statements then i get an error symbol in the class tab title in IDE (using NetBeans) but not within the code itself.
When i compile and run the code i get an error box appearing saying "One or more projects compiled with errors" but if i choose to run anyway the programme will run fine as far as i have seen.
I have tried writing the code in various ways.e.g. originally using if statements and originally having class 2 and 3 as the same class and i always get this error at reaching x amount of choices.
In previous versions i would sometimes get the error symbol appear in the class tab title in the IDE and not within the code as usual but when trying to run the programme it wouldn 't run at all and gave some classpath error which i can't seem to reproduce now so can't post the exact code.
From the testing i have done.e.g. removing different sections of code it appears that it happens when x amount of choices are added.i.e. i can add the 52nd case and 3rd if statement and the error appears but if i remove a previous if statement so there are 52 cases and 2 if statements still then everything if fine.
From experimenting it would seem there is a limit to the amount of switches/if statements i can use although from looking around i could in theory have an infinite amount?
So my question is, is there a limit to the amount of switches/if statements i can use or is there something else going on which is causing an error when i enter x number of switches/if statements?
you need to separate your data from your code. stick all that data in a combination of maps and lists and use some simple, common code to update the gui elements.
// setup data code
List<String> elements = Arrays.asList("Elves Ear", "Fire Salts", ...);
Map<String,List<String>> elementMap;
elementMap.put("Weakness to Frost");
// setup ui code
List<String> elements = elementMap.get(command);
initUI(elements);
public void initUI(List<String> elements) {
gui.r1.setText(elements.get(0));
// ...
}
note, you could keep all your text fields in a List, and then the update code is:
public void initUI(List<String> elements) {
for(int i = 0; i< textFields.size(); ++i) {
textFields.get(i).setText(elements.get(i));
}
}
in general, if you find yourself writing a lot of repetitive code, you are probably doing it wrong.
also, as #thatidiotguy pointed out in the comments, as you advance, you could move the data out of code like my example and into some sort of separate config file.

Categories

Resources