I have submit button, which is only one on the page, and it\'s in form.
html part:
The method object.submit()
is there for submitting the form to the server. It has another advantage, in case if you're not able to locate the "submit" button then you can take any object of the form and trigger submit() function.
It seems in searchButton.submit();
searchButton is an element of the form and the submit action on it triggers submission of form on server.
Now, why searchButton.click();
not working here could have following reasons.
searchButton
element.Suggestion: Evaluate following code and check it returns more than one element. If it does then you're clicking on the wrong instance.
List<WebElements> e = driver.findElements(By.xpath("//button[@type='submit']"));
Also try,
driver.findElement(By.xpath(".//button[@class='btn btn__primary'][@type='submit']")).click()
http://docs.seleniumhq.org/docs/03_webdriver.jsp#user-input-filling-in-forms
submit()
submit() method is defined as :
void submit()
Throws:
NoSuchElementException - If the given element is not within a form
As per the JavaDocs when you invoke submit()
on an WebElement
, if this current element is a form, or an element within a form, then this will be submitted to the remote server. If this causes the current page to change, then this method will block until the new page is loaded.
click()
click() method is defined as :
void click()
Throws:
StaleElementReferenceException - If the element no longer exists as initially define
As per the JavaDocs when you invoke click()
on an WebElement
and if this causes a new page to load, you should discard all references to this element and any further operations performed on this element will throw a StaleElementReferenceException. Note that if click() is done by sending a native event (which is the default on most browsers/platforms) then the method will not wait for the next page to load and the caller should verify that themselves. There are some ExpectedConditions for an element to be clicked. The element must be visible and it must have a height
and width
greater then 0.
In your usecase, the target WebElement
//button[@type='submit']
is within a <form>
tag. You are able to successfully press it via submit()
as it blocks the method untill the new page is loaded completely as a result of submission on the previous page. Hence the following works :
WebElement searchButton = driver.findElement(By.xpath("//button[@type='submit']"));
searchButton.submit();
But when you try click()
method as below, click()
being a native event doesn't waits for the new page to load completely. Hence invoking click()
method fails.
WebElement button = driver.findElement(By.xpath("//button[@type='submit']"));
button.click();
Validating the button.isEnabled()
condition won't fetch us the required result if the element is clickable or not as isEnabled() validates Is the element currently enabled or not? This will generally return true for everything leaving out the disabled input elements
. But necessarily isEnabled()
wouldn't be validating if the WebElement
is visible, interactable and clickable or not.
As per the details provided, the solution to invoke click()
method would be to induce WebDriverWait
with ExpectedConditions
clause set to elementToBeClickable as below :
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@type='submit']"))).click();
As per the updated HTML
and your subsequent comment where you mentioned about Angular4
being used in your app, a much more effective way would be to construct the xpath
mocking the HTML DOM
as follows :
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("//form[@class='search-form ng-touched ng-dirty ng-valid']//button[@class='btn btn__primary' and @type='submit']"))).click();