Working with selenium and InternetExplorer 11, I can navigate around this site.
I got a method that finds an input box on the page then inputs text. It works the first time, but when I go to another page it says that element does not exist and the page just refreshes randomly.
I a m just using a simple wait:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[contains(text(), 'Enter Name')]")));
WebElement nameField = driver.findElement(By.xpath("//*[contains(text(), 'Enter Name')]"));
It crashes and says the element can not be found during the wait.
I am not sure if this is just site specific or if I am doing something wrong.
If anyone has any idea I'd appreciate it :)
Here is the Answer to your Question:
As you mentioned when I go to another page the entire HTML DOM gets changed and now if you try to locate or use findElement() with a previously found id/name/css/xpath Selenium will fail to do that.
So when we are on a new page we have to search for the element again using the current id/name/css/xpath in-order to use click() or sendKeys() methods.
Let me know if this Answers your Question.
Related
I am working on a project in selenium, in which once it fills out a textbox, clicks next page, a captcha comes up. First you need to verify, then the captcha shows up. It is just a pop up box in the middle of the page and makes everything else unclickable with a white haze over the page behind it. Once the verification is clicked on I already have a method for solving the captcha.
The issue I am having is that with the methods I have tried, the webdriver cannot seem to find any trace of this button. I always get an no such element exception, when trying to use click(). I have tried wait.until(ExpectedConditions.elementToBeClickable(By.id("home_children_button"))).click();, wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("home_children_button")))).click(); , I have also tried putting a thread.sleep(Num) instead of using a wait, along with many other methods on google. Then when I did some research about href buttons, I found people recommend to use By.linkText. So I tried that with all the methods I tried before, and element still cannot be located. I couldn't find anything else on google, so I thought I would ask for help.
I have attatched the HTML Code I currently am looking at for the button, along with the link for the website. Unfortunately to encounter this page, you must make an account. This page normally comes up once I put the DOB in. Thank you for any clarification provided.
Verify
https://account.battle.net/creation/flow/creation-full
Code I have tried:
wait2.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("fc-iframe-wrap")));
wait2.until(ExpectedConditions.elementToBeClickable(By.id("home_children_button"))).click();
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("CaptchaFrame")));
wait2.until(ExpectedConditions.elementToBeClickable(By.id("home_children_button"))).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("home_children_button"))).click();
wait.until(ExpectedConditions.elementToBeClickable(By.id("home_children_button"))).click();,
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("home_children_button")))).click();
Thread.sleep(5000) //wait for it to pop up
driver.findElement(By.id("home_children_button"))).click();
Along with trying to use By.linkText.
Solution:
After being told it's an iframe, I looked closer at the HTML to see there was multiple iframes. So I waited to switch through them in order to click the button.
WebDriverWait wait2 = new WebDriverWait(driver, 20);
wait2.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("/html/body/div[4]/iframe")));
wait2.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("/html/body/div/div[1]/div/iframe")));
wait2.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("/html/body/div[1]/div[2]/div[1]/iframe")));
wait2.until(ExpectedConditions.elementToBeClickable(By.id("home_children_button"))).click();
As I suspected, it is in iframe, you need to switch the focus of your driver to interact with verify button :
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("CaptchaFrame")));
wait.until(ExpectedConditions.elementToBeClickable(By.id("home_children_button"))).click();
and once you are done with it, you may want to use defaultContent()
driver.switchTo().defaultContent();
This question already has answers here:
Element MyElement is not clickable at point (x, y)... Other element would receive the click
(5 answers)
Closed 3 years ago.
I do have a Select and I try to wait patiently for it to be available, but that won't do.
WebDriverWait wait = new WebDriverWait(getWebDriver(), 20);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("myxpath")));
Select select = new Select(element);
select.selectByVisibleText(text);
When I run the code on this particular Element I get an error message:
... is not clickable at point (1311,183) because another element <p class="ng-tns-c4-0"> obscures it
I suppose this is because the page has these annoying status messages showing on the upper right corner for some seconds and then fading away. Though they are far away from my dropdown, they still seem to obscure it.
The whole thing works if I add a 2 second explicit wait, but that somehow offends my sense of stile and I most likely would end up spreading them all over the tests and slow them down a lot.
Is there any generic way of waiting for an element not to be obscured? I mean a way without having to know which particular message pops in.
POSTSCRIPT:
Since I cannot add an answer on my own, I add this postscript. In the end I have settled for this solution:
protected void secureSelect(String text, Select select) {
try {
select.selectByVisibleText(text);
} catch(ElementClickInterceptedException e) {
Wait.seconds(2);
select.selectByVisibleText(text);
}
}
I know that these problems will occur all over the application with different messages of the same type. So in case of an error I just try once again and the let it fail if it goes wrong again.
To answer your last question, is there a generic way of waiting for an element to not be obscured? Outside of elementToBeClickable, not really. Web pages are dynamic and each one of them loads content differently so there's not exactly a catch-all for this. It is unfortunate that elementToBeClickable is encountering a ClickIntercepted error for your scenario, but there are a few workarounds.
You could try adding an additional wait to wait on invisibilityOfAllElements for the status messages that keep popping up, if these are what is getting in the way:
wait.until(ExpectedConditions.invisibilityOfAllElements(By.xpath("//p[contains(#class, 'ng-tns')]")));
This may encounter a timeout exception depending on the nature of displayed p elements compared with the rest of the page content. Another possible workaround would be leaving your code as it, and using Javascript to select elements from the Select instead:
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("myxpath")));
JavascriptExecutor js = (JavascriptExecutor)driver;
// expand the Select dropdown
js.executeScript("arguments[0].click();", element);
// wait for Select options menu to expand
WebElement optionToClick = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("xPathForDropdownOption")));
// select desired option
js.executeScript("arguments[0].click();", optionToClick);
The above code is a bit more 'explicit' in what we are waiting on -- specifically, the dropdown option value. Clicking both the Select dropdown and the dropdown option with Javascript are meant to be workarounds for the ClickIntercepted error.
I'm trying to click a button which is auto-focused by a script in the html.
I've tried both absolute path, relative path but no luck. pretty much anything I can think of. Attached is a screenshot which will display that the xpath is locating the element successfully on the web but when I use it in selenium, it can't find the element.
I've also tried waiting explicitly for 10 seconds for the element using a generic function. (Check the screenshot) This function is working for all other buttons that were called previously except for this one.
Something CAUGHT my eyes is that There's a method being called which auto-focuses the button. I might have to turn the focus to the entire window or the page in this case. I've also tried sending the enter key but still no luck.
Question_1: Does anyone have any solution?
Question_2: Does anyone know how to switch focus to the page?
Question_3: Or anything.
Any suggestion is highly appreciated.
Use Java Script click instead of click. Like this, Hope this will help.
WebElement element = driver.findElement(By.id("SubmitButtonId"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
To switch focus to parent window/default content window you should use switchTo() method on driver instance.
driver.switchTo().parentFrame();
OR
driver.switchTo().defaultContent();
You can use following two statements to know which element is currently focused.
driver.switchTo().activeElement();
driver.getPageSource();
If you try to click on input tag , your script will fail. try to find correct locator only. it will help or try submit() function as you said, this element is auto selected.
I thinks you need to bring element in to view before clicking on the same:
the code for that is:
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true)", webElement);
I would like for Selenium to navigate a menu via arrow keys--Starting with clicking the top menu item then pressing "DOWN", "DOWN", ...
The problem is that you have to always supply a specific element to send the "DOWN" to.
Is there any way to get the current element?
I tried:
by.xpath(".")
but it said that the expression was unrecognized or didn't return a proper object.
I expect I'm jsut missing some stupid trick.
In Selenium 2.0, if you are using WebDriver to drive the tests in the browser, you can use the WebDriver.TargetLocator class to get the element in focus, in a window/frame:
WebDriver driver = ... // initialize the driver
WebElement currentElement = driver.switchTo().activeElement();
If no element is in focus, the active element would turn out to be the body of the document being displayed, which might be the case when you launch a new page, for instance. When you invoke methods like click, sendKeys etc. you'll find the WebElement returned by the above invocation will always represent the element in focus.
This was tested using FirefoxDriver, and I would suspect that the same would be true of other drivers, except for the HtmlUnitDriver and similar drivers that do not use a full-fledged browser under the hood.
in python:
element = driver.switch_to.active_element
Don't know of a more straightforward way than accessing document.activeElement
How do I test which element has the focus in Selenium RC?
In Ruby/Capybara:
page.driver.browser.switch_to.active_element
Note that this returns a Selenium::WebDriver::Element not a Capybara::Node::Element.
I am searching for an element on a webpage by using its XPath. The XPath is correct and can find the element ONLY if I manually perform a click anywhere on the page first. If I do not do this before the statement runs it will not find the element.
I have tried many different attempts to allow focus on the page:
selenium.selectWindow(null);
selenium.fireEvent(xpath, "focus");
selenium.click(element on page);
selenium.mouseDown();
selenium.mouseUp();
After performing these functions the statement will still not find the element, but if I manually maximize the page and click anywhere on the page, then run the statement, the element is found. Can anyone help me out with this?
The statement I am using to find the element is:
selenium.isElementPresent("//div[#class='sample_class']");
Thanks!
Instead of using XPath, try using the CSS selector for that item.
Use selenium.isElementPresent("css=div.sample_class"); as your selector. Saucelabs have explained it quite well at http://saucelabs.com/blog/index.php/2009/10/selenium-tip-of-the-week-start-improving-your-locators/