Visible but overlaid - java

I am making a script using selenium and at one step it shows loading icon in center of webpage.The loading icon appears after 1st line is executed
test.driver.findElement(By.id("oaapprove")).click();
test.driver.findElement(By.xpath("//*[text()='DATA EXPLORER']")).click();
The 2nd element is still there in DOM but its not clickable so i get error as not clickable
i tried this:
Boolean isPresent=test.driver.findElements(By.xpath("//div[#class='spinner-container']")).size() > 0;
if(isPresent)
{
System.out.println("Target element found");
}
while(test.driver.findElements(By.xpath("//div[#class='spinner-container']")).size() > 0)
{
try {
System.out.println("inside");
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(!(test.driver.findElements(By.xpath("//div[#class='spinner-container']")).size() > 0))
{
System.out.println("Target element not found");
}
It is printing "inside" till the loading icon is visible but but after icon disappears it does not print "inside" but it waits for 7-8 secs and then executes next statements.
What is the cause of waiting?
Can u please tell how to i solve this.

try actions class if it's showing using fluentwait that element is clickable:
WebElement yourElement = test.driver.findElement(By.xpath("//*[text()='DATA EXPLORER']"));
Actions act = new Actions(test.driver);
act.moveToElement(yourElement).click().build().perform();

I got the solution and i used stalenessOf
new WebDriverWait(driver, 10).until(ExpectedConditions.stalenessOf(findElement(By.xpath("element_path"))));

Related

Nested iframe in Stripe 3DS - unable to attach to them using Selenium/Serenity

I'm having trouble with locating the buttons in this Stripe 3DS sandbox which appear to be 3 iframes down into the page. The layout is in the attached image.
I have tried the following:
The below results in a message that the frame cannot be found
OnStage.theActorInTheSpotlight().attemptsTo(Switch.toFrame("__privateStripeFrame8499"));
OnStage.theActorInTheSpotlight().attemptsTo(Switch.toFrame("__stripeJSChallengeFrame"));
OnStage.theActorInTheSpotlight().attemptsTo(Switch.toFrame("acsFrame"));
The below results in null pointer exceptions (even with this at the top of the file)
#Managed
WebDriver driver;
driver.switchTo().frame(driver.findElement(By.xpath("/html/body/div[1]/iframe")));
driver.switchTo().frame(driver.findElement(By.xpath("//*[#id=\"challengeFrame\"]")));
driver.switchTo().frame(driver.findElement(By.xpath("/html/body/div/iframe")));
This variant results in a casting error
OnStage.theActorInTheSpotlight().attemptsTo(Switch.toFrame((WebElement) StripePaymentDetailsPage.STRIPE_IFRAME));
OnStage.theActorInTheSpotlight().attemptsTo(Switch.toFrame((WebElement)StripePaymentDetailsPage.STRIPE_CHALLENGE_IFRAME));
OnStage.theActorInTheSpotlight().attemptsTo(Switch.toFrame((WebElement)StripePaymentDetailsPage.STRIPE_FULLSCREEN_FRAME));
I found a solution to this after a few hours at it, my first discovery was that the iframes have dynamic names - I used debugging code like this to dig down
List<WebElement> frameList = driver.findElements(By.tagName("iframe"));
System.out.println("Num Frames: " + frameList.size());
for (WebElement element : frameList) {
String frameName = element.getAttribute("name");
System.out.println("Frame Name is " + frameName);
}
In the end I found the cancel button on a different layer to the buttons but to interact with the buttons themselves I did this:
private void completeOrFail3dsAuthentication(String action) throws InterruptedException {
Thread.sleep(5000);
WebDriver driver = BrowseTheWeb.as(OnStage.theActorInTheSpotlight()).getDriver();
// try switching to a frame
driver.switchTo().frame(0); // cancel button
Thread.sleep(500);
driver.switchTo().frame(0); // sub frame
Thread.sleep(500);
driver.switchTo().frame(0); // frame with Complete or Fail Authentication
if(action.equalsIgnoreCase("fail")) {
BaseTasks.waitAndClick(OnStage.theActorInTheSpotlight(), StripePaymentDetailsPage.THREE_D_S_FAIL_AUTH_BUTTON);
} else {
BaseTasks.waitAndClick(OnStage.theActorInTheSpotlight(), StripePaymentDetailsPage.THREE_D_S_COMPLETE_AUTH_BUTTON);
}
Thread.sleep(500);
//switch back to original frame
driver.switchTo().parentFrame();
Thread.sleep(500);
driver.switchTo().parentFrame();
Thread.sleep(500);
driver.switchTo().parentFrame();
}

Selenium check if a window is currently open

So I have a selenium webdriver logging me into a website and from there I click a button which opens a second window. I use this code below to switch to the new window
String winParent = driver.getWindowHandle();
for (String winHandle : driver.getWindowHandles()) {
driver.switchTo().window(winHandle);
}
Now on that second window I run some automation . Once complete I would press the save button and this would close the current window. If the window doesn't close it means I have some errors on the page and I need to loop back and fix it.
driver.findElement(By.id("btnSave")).click();
if (isAlive(driver) == false) {
//break and exit
System.out.println("cic" + name);
finalString = finalString + "cic: " + name;
break;
}
public Boolean isAlive(WebDriver driver) {
try {
driver.getCurrentUrl();//or driver.getTitle();
return true;
} catch (Exception ex) {
return false;
}
}
The The program works as expected when it catches the errors and the window doesn't close. But as soon as everything is clear and the window closes it enters the if statement above and displays this error.
Unable to receive message from renderer.
I believe that I'm not checking if the window has been closed correctly.
edit: after some debugging it seems like once the window closes the program can't really tell what to do next. http://i.imgur.com/l8nsPPr.png
I suggest using windowHandle for this.
You are saving initial window in String winParent = driver.getWindowHandle();
Then you switch to the second window, which will have different handle.
When you need to check if the second window is still open, just use:
private boolean isNewWindowOpened(WebDriver driver, String parentWindowHandle) {
try {
return !driver.getWindowHandle().equals(parentWindowHandle);
} catch (Exception ex) {
driver.switchTo(parentWindowHandle);
return false;
}
I came across the same situation, I've got a solution for you, check window count after clicking on "Save" button. Ideally, there will be one window if you have provided all the correct data and if not then there are two windows.
driver.findElement(By.id("btnSave")).click();
if (driver.getWindowHandled().size() >= 2) {
// make required changes
// again click on save button
} else {
//break and exit
System.out.println("cic" + name);
finalString = finalString + "cic: " + name;
break;
}
}

(StaleElementException:Selenium) How do I handle this?

This is my first time first day working on selenium and I have no hands on experience on Web Technologies in depth either.
Working around, I have been facing StaleElementException while i try to access a particular object on the DOM.
Following Method handles all the task:
private void extract(WebDriver driver) {
try {
List<WebElement> rows = driver.findElements(By.xpath("//*[#id='gvSearchResults']/tbody/tr"));
for (WebElement row : rows) {
WebElement columns = row.findElement(By.xpath("./td[1]/a"));
if (assertAndVerifyElement(By.xpath("//*[#id='gvSearchResults']/tbody/tr/td[1]/a"))) {
columns.click();
}
List<WebElement> elements = driver
.findElements(By.xpath("//*[#id='ctl00_MainContent_pnlDetailsInd']/table/tbody/tr"));
for (WebElement element : elements) {
WebElement values = element.findElement(By.xpath("./td[1]"));
System.out.print(values.getText() + " ");
WebElement values2 = element.findElement(By.xpath("./td[2]"));
System.out.println(values2.getText());
}
if(assertAndVerifyElement(By.xpath("//*[#id='ctl00_MainContent_btnBack']")))
driver.findElement(By.xpath("//*[#id='ctl00_MainContent_btnBack']")).click();
}
} catch (Exception e) {
e.printStackTrace();
}
}
The Assertion logic goes here:
public boolean assertAndVerifyElement(By element) throws InterruptedException {
boolean isPresent = false;
for (int i = 0; i < 5; i++) {
try {
if (driver.findElement(element) != null) {
isPresent = true;
break;
}
} catch (Exception e) {
// System.out.println(e.getLocalizedMessage());
Thread.sleep(1000);
}
}
Assert.assertTrue("\"" + element + "\" is not present.", isPresent);
return isPresent;
}
I have tried few solutions asking me to use wait until expected conditions, but none of them worked.
Also, It would be appreciated if you point out any bad design practices I might be using in the above sample.
I can give you the idea to overcome staleness.
Generally we will be getting the Stale Exception if the element attributes or something is changed after initiating the webelement. For example, in some cases if user tries to click on the same element on the same page but after page refresh, gets staleelement exception.
To overcome this, we can create the fresh webelement in case if the page is changed or refreshed. Below code can give you some idea.
Example:
webElement element = driver.findElement(by.xpath("//*[#id='StackOverflow']"));
element.click();
//page is refreshed
element.click();//This will obviously throw stale exception
To overcome this, we can store the xpath in some string and use it create a fresh webelement as we go.
String xpath = "//*[#id='StackOverflow']";
driver.findElement(by.xpath(xpath)).click();
//page has been refreshed. Now create a new element and work on it
driver.findElement(by.xpath(xpath)).click(); //This works
Another example:
for(int i = 0; i<5; i++)
{
String value = driver.findElement(by.xpath("//.....["+i+"]")).getText);
System.out.println(value);
}
Hope this helps you. Thanks
The StaleElementException occurs when the webelement in question is changed on the dom and the initial reference to that webelement is lost.
You can search for the webelement again
try this
try:
element = self.find_element_by_class('')
element.click()
except StaleElementReferenceException:
element = self.find_element_by_class('')
element.click()

Wait until text is not present in textbox selenium

Below is the scenario I am trying to automate:
1) Some text is already present in Textbox.
2) Click on Radio button.
3) Processing popup is displayed for few seconds. After popup disappears the textbox
becomes blank
4) After textbox is blank then I have to enter different value in text box.
Please help me, how to wait till textbox value is blank.
I am automating with IE driver.
Thanks In advance
I would try:
int timeout = 10; // depends on your needs
WebDriverWait myWait= new WebDriverWait(driver,timeout);
myWait.until(ExpectedCondition.textToBePresentInElementValue(By locator, String text))
-- with empty string passed as text argument
You can try something like this :-
public void waitUntilTextNotToBeInWebElement(WebElement element, String textValue) {
int timer = 0;
final int pollInterval = 500;
while (timer < MAX_TIME*1000) {
if (element.getText().equalsIgnoreCase(textValue)) {
sleep(500);
timer += pollInterval;
} else {
return;
}
}
throw new TimeoutException("Maximum time exceeded.");
}
Hi there is two possible way through which you can do this
1.Use Expected condition
// after you have clicked on radio button and it does some processing
WebDriverWait wait = new WebDriverWait(driver,30);
wait.until(ExpectedConditions.invisibilityOfElementWithText(locator, "your text"));
// now perform your operation
use if else
// get the text of input box like below
String myInitialText = driver.findElement(By.xpath("")).getAttribute("value");
// click on radio button
// now apply the logic
if(myInitialText == null){
System.out.println("Input box is blank");
// perform next operation
}else{
Thread.sleep(5000);
}
// now fill the input box
Below code worked for me.
WebElement element=driver.findElement(By.id("ctl00_cphClaimFlow_tabcontainerClaimFlow_tabFulfillment_Shipping_ctl33_txtStreeAddress1"));
String myInitialText=element.getAttribute("value");
//click on radio btn
driver.findElement(By.id("ctl00_cphClaimFlow_tabcontainerClaimFlow_tabFulfillment_Shipping_ctl33_radNewAddress")).click();
logger.info("New Address radio button clicked");
System.out.println("1 "+myInitialText);
while(!myInitialText.equals("")){
try {
Thread.sleep(5000);
logger.info("Thread is sleeping");
//System.out.println("2 "+myInitialText);
myInitialText=driver.findElement(By.id("ctl00_cphClaimFlow_tabcontainerClaimFlow_tabFulfillment_Shipping_ctl33_txtStreeAddress1")).getAttribute("value");
//System.out.println("3 "+myInitialText);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
driver.findElement(By.id("ctl00_cphClaimFlow_tabcontainerClaimFlow_tabFulfillment_Shipping_ctl33_txtStreeAddress1")).sendKeys(td.getAddressLine1().get(0));
logger.info("Address Line1 entered");

How to make click on the Update Button in the shopping Cart Page - Url="http://live.guru99.com/"

Even though x-path picking the element , and i tried with java executor, but at the time of code run , it is only able to click on update button for the first element in the cart . Below is the Code :
Here once after placing 3 products in the cart i have added there text boxes into a list :
I have attached the image :
Url="http://live.guru99.com/"
List<WebElement> li2 =driver.findElements(By.xpath(".//td[#class='product-
cart-actions']/input"));
for(int j=0;j<li2.size();j++)
{
if(j==0)
{
li2.get(j).clear();
li2.get(j).sendKeys("4");
driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update']")).click();
li2 =driver.findElements(By.xpath(".//td[#class='product-cart-actions']/input"));
}
else if(j==1)
{
li2.get(j).clear();
li2.get(j).sendKeys("2");
//wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']")));
//driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']")).isDisplayed();
WebElement element = driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']"));
try {
if (element.isEnabled() && element.isDisplayed()) {
System.out.println("Clicking on element with using java script click");
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
} else {
System.out.println("Unable to click on element");
}
} catch (StaleElementReferenceException e) {
System.out.println("Element is not attached to the page document "+ e.getStackTrace());
} catch (NoSuchElementException e) {
System.out.println("Element was not found in DOM "+ e.getStackTrace());
} catch (Exception e) {
System.out.println("Unable to click on element "+ e.getStackTrace());
}
// if (element.isDisplayed()) {
// element.click();
//}
li2 =driver.findElements(By.xpath(".//td[#class='product-cart-actions']/input"));
}
else
{
li2.get(j).clear();
li2.get(j).sendKeys("3");
WebElement element1 = driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update']"));
if (element1.isDisplayed()) {
element1.click();
}
}
This is the culprit:-
WebElement element = driver.findElement(By.xpath(".//td[#class='product-cart-actions']/button[#title='Update' and #type='submit']"));
So when you have multiple elements with same locators, WebDriver clicks on the first and moves ahead. So if you want to click the 2nd or 3rd element you can modify your xpath something like:-
.//td[#class='product-cart-actions']/button[#title='Update' and #type='submit'][2] -- For 2nd Element
OR
.//td[#class='product-cart-actions']/button[#title='Update' and #type='submit'][3] -- For 3rd element.
But it won't be a nice approach there may be multiple in future and you won't go around adding the index for each and every element.
Best approach would be to identify the update button with reference to the product name which is unique in your case.

Categories