There is no frame but still there is an error element is not found - selenium

Below is my code, the line =>
driver.findElement(By.xpath("//*[#id=\"quote_password\"]")).sendKeys("password"); throws exception that element is not found
#Test
public void mytest()
{
System.setProperty("webdriver.chrome.driver","Drivers/chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("http://billing.scriptinglogic.net/index.php/sessions/login");
driver.findElement(By.xpath("//*[#id='email']")).sendKeys("email");
driver.findElement(By.xpath("//*[#id='password']")).sendKeys("password");
driver.findElement(By.xpath("/html/body/div/div/form/input")).click();
driver.findElement(By.xpath("//*[text()='Quotes']")).click();
driver.findElement(By.xpath("//*[text()='Create Quote']")).click();
driver.findElement(By.xpath("//*[#id=\"quote_password\"]")).sendKeys("password");
}

Quick and dirty solution:
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
driver.get("http://billing.scriptinglogic.net/index.php/sessions/login");
driver.findElement(By.id("email")).sendKeys("<EMAIL>");
driver.findElement(By.id("password")).sendKeys("<PASSWORD>");
driver.findElement(By.name("btn_login")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[text()='Quotes']"))).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".create-quote"))).click();
wait.until(ExpectedConditions.elementToBeClickable(By.id("quote_password"))).sendKeys("password");
Updated based on the credentials supplied in the comment below. I've tweaked the selectors to use ID, name and class where applicable. There is no need to use complex XPath locators when they aren't needed.
The explicit waits are required based on the way the site is working and I've added JeffC's suggestion of using an elementToBeClickable expected condition for the input element (I don't think it's really required in this instance though since the site doesn't seem to ever disable the input field, so a visibilityOfElementLocated expected condition is just as good really).
This solution is working for me in Chrome and Firefox in standard mode and Firefox in headless mode. It's not working in headless mode in Chrome because the screen size is smaller and when the screen width goes below 1000px the header changes and the text "Quotes" is never displayed. Below 767px the header is completely removed and you get a side menu. This means that the flow of the script needs to change slightly based on resolution.
I would suggest asking your developer to add an ID to the menu items, it will make it easier to locate them and use the site in its various states. The quick and dirty solution to this problem is ensure the browser is a certain size while the test runs, you can do this by setting the size in the first line of your script:
driver.manage().window().setSize(new Dimension(1024, 768));
When you do this it passes in Firefox and Chrome in standard and headless mode.
Note: The lines with an explicit wait that result in an element being clicked are anchor elements so there is no point waiting for the element to be clickable as the condition is always going to return true.

Related

How to resolve org.openqa.selenium.WebDriverException?

I am writing an automated test and want to report bugs, if occur, directly in the repo at GitHub. The step which fails in my program is the Submit new issue button from GitHub Issue Tracker.
Here is the code:
WebElement sendIssue = driver.findElement(By.xpath("/html/body/div[5]/div/div/div[2]/div[1]/div/form/div[2]/div[1]/div/div/div[3]/button"));
sendIssue.click();
And the exception:
org.openqa.selenium.WebDriverException: Element is not clickable at
point (883, 547.7999877929688). Other element would receive the click:
div class="modal-backdrop"></div
The following command also does not work:
((JavascriptExecutor) driver).executeScript("arguments[0].click();", sendIssue);
How can I make it clickable? Is there any other way by which I can resolve this issue?
This is happening because when selenium is trying to click ,the desired element is not clickable.
You have to make sure that the Xpath provided by you is absolutely right.If you are sure about the Xpath then try the following
replace
WebElement sendIssue = driver.findElement(By.xpath("/html/body/div[5]/div/div/div[2]/div[1]/div/form/div[2]/div[1]/div/div/div[3]/button"));
sendIssue.click();
with
WebElement sendIssue =(WebElement)new WebDriverWait(DRIVER,10).until(ExpectedConditions.elementToBeClickable(By.xpath("/html/body/div[5]/div/div/div[2]/div[1]/div/form/div[2]/div[1]/div/div/div[3]/button")));
sendIssue.click();
If that doesn't work ,You will get an Timeout exception, In that case try incaresing the timeout amount from 10 to 20.
If it still doesn't work please post a screenshot of the HTML.
You need to write something in the issue title and description to make the issue clickable are you sure you are not making that mistake of clicking the button without writing anything in those places I am adding screenshot for your convenience.
Selenium Webdriver introduced in a previous version (v2.48) a new behavior that prevent clicks on elements that may be overlapped for something else (a fixed header or footer - for example) or may not be at your viewport (visible area of the webpage within the browser window).
You can see the debate here.
To solve this you will need to scroll (up or down) to the element you're trying to click.
One approach would be something like this post:
Page scroll up or down in Selenium WebDriver (Selenium 2) using java
Another, and maybe more reasonable, way to create a issue on Github, would be using their API. Maybe it would be good to check out!
Github API - Issues
Gook luck.
This worked for me. Instead of HTML browser this would be useful if we perform intended Web Browser
// Init chromedriver
String chromeDriverPath = "/Path/To/Chromedriver" ;
System.setProperty("webdriver.chrome.driver", chromeDriverPath);
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1200","--ignore-certificate-errors");
WebDriver driver = new ChromeDriver(options);

What to do when waiting for an element is not enough?

I am writing selenium test scripts using the industry standard of webdriver waits before interacting with elements, but I still frequently find my tests are failing, and it seems to be due to a race condition.
Here's the example I have been running into lately:
Go to the product catalog page
Apply a filter
Wait for the filter to be applied
Click the save button on the product which loads after the filter is applied
Step number 4 only works if I place a Thread.Sleep() in front of the step - using webdriverwait is not enough. I'm guessing this is because the webdriverwait only waits until the element is attached to the DOM, even though the relevant JavaScript click event has not been added to the element.
How do you get around this issue? Is there an industry standard for dealing with this race condition?
EDIT This was resolved by upgrading to the latest version firefox. Thanks everyone!
As we discovered in comments, updating Firefox to the latest version did the trick.
The code looks really good to me and makes total sense.
What I would try is to move to the element before making a click:
Actions builder = new Actions(WebDriver);
IWebElement saveButton = wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector(".button-wishlist")));
Actions hoverClick = builder.MoveToElement(saveButton).Click();
hoverClick.Build().Perform();
As we've discovered in comments, the issue is related to the size of the window (the test passed without a Thread.sleep() if the browser window is maximized). This makes me think that if you scroll to the element before making a click it could be enough to make it work:
IWebElement saveButton = wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector(".button-wishlist")));
((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", saveButton);
Actions hoverClick = builder.MoveToElement(saveButton).Click();
hoverClick.Build().Perform();
Take a look at this SO post for custom wait method. Sounds like element presence is not enough of a check in your case because the button may be present at all times in the DOM. What you need is something along the lines of ExpectedConditions.elementToBeClickable().
I am not familiar with the C# API but it looks like there is no built in method to do the same thing as in Java. So you could write a custom wait function that will have checks according to your needs.

Selenium evaluates DOM or Visible elements

I would like to understand how Selenium evaluates the page.
I have set of test to check elements on the page. Written with Nunit, Selenium and PhantomJS as Driver.
Page.Visit();
Page.FindElement(By.Id("testid").Text.Should().NotBeNull(); // PASS
Page.FindElement(By.Id("testid").Text.Should().NotBeEmpty(); // does NOT PASS
The test DOES NOT pass if the browser size is set to be very small:
driver.Manage().Window.Size = new Size(10,10);
Based on this test, it is confusing how PhantomJS evaluates the page. I always thought that it checks the DOM but seems like for element TEXT it evaluates based on visibility!
Although this surprised me too when I first discovered it, Selenium will only find elements visible in the viewport of the browser. For this reason, you will want to ensure at the start of your tests that your browser viewport is large enough to accommodate the content of your application.
Typically this can be done by maximizing the browser window. If you are using Windows, triggering the F11 key via Selenium should work.

How to make xpath work with Selenium when filepicker.io is loaded

After implementing filepicker.io, some of our Selenium regression tests have started failing. The failures (intermittent, but more often than not in some circumstances) are that clicks are ignored on WebElements found via XPath queries. e.g.
driver.findElement(By.xpath("//a[text()='Demo data']")).click();
Adding a Sleep(2000) between findElement() and click() generally resolves the problem. (I say generally because Sleep(1000) was mostly enough, until it wasn't, so I made it Sleep(2000)...)
Checking element.isDisplayed() has not helped. The problem disappears if we stop including the filepicker.io JavaScript file.
Is it something to do with filepicker.io introducing an IFRAME? We have also noticed that JQuery's document.ready() seems to be now invoked twice.
As usual with this kind of problems, you are trying to find an element that is not yet available on the page due to AJAX request still downloading/processing it. You need to wait for the element to appear on the page.
There are three ways to do this:
Using sleep(). This is the discouraged way. You should not use hardcoded sleeps, because you'll either wait too long (making the tests unnecessarily slow) or too short (failing the test).
Use Implicit wait. That will always wait for an element if it's not found.
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
Use explicit wait. That enables you to wait explicitly for one element to (dis)appear / become available / whatever.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Demo data")));
We now run this code first after opening any page that includes filepicker.js:
while (FindElementsMaybeNone(By.cssSelector("#filepicker_comm_iframe")).size() == 0)
Sleep(50);
while (driver.switchTo().frame("filepicker_comm_iframe") == null)
Sleep(50);
driver.switchTo().defaultContent();
We guess that filepicker's dynamic IFRAME insertion is discombobulating Firefox or Selenium. I'm not marking this as the answer because I don't really know why it works.

Alternative of visibility of element located in selenium 2.0 that checks the presence of an element on the DOM?

I have a problem in my framework that instead of using static sleeps I try to wait for a visibility of an element. The thing is that visibilty of element checks the presence of an element on the DOM, that will return true but in my system the page is not fully loaded yet. What happens is that as soon as I get true when checking the visibility of element I set values. These values get reset when the actual page get fully loaded.
My question is what can I use instead of static sleeps to wait for the actual page (not only the DOM) to get fully loaded as visibility of element is not working for me?
P.S. I'm using Selenium webdriver with python 2.7
/Adam
The expected_conditions.visibility_of_element_located(locator) method will check for both - the presence of the element in the DOM, and its visibility (element is displayed with height and width greater than zero).
Ideally, the driver.get(url) method should automatically wait for the full page to be loaded before moving on to the next line. However, this might not behave as expected, in case, the web application being tested uses ajax calls/actions (as although the page has loaded but the ajax actions are still in progress). In such scenario, we can use something like below to wait for stability before performing action(s) on the desired webelements.
# create the firefox driver
driver = webdriver.Firefox()
# navigate to the app url
driver.get('http://www.google.com')
# keep a watch on jQuery 'active' attribute
WebDriverWait(driver, 10).until(lambda s: s.execute_script("return jQuery.active == 0"))
# page should be stable enough now, and we can perform desired actions
elem = WebDriverWait(driver, 10).until(expected_conditions.visibility_of_element_located((By.ID, 'id')))
elem.send_keys('some text')
Hope this helps..
Try ExpectedConditions.elementToBeClickable.
See: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html#elementToBeClickable-org.openqa.selenium.By-