Selenium: submit() works fine, but click() does not

前端 未结 2 1882
感情败类
感情败类 2020-12-12 04:21

I have submit button, which is only one on the page, and it\'s in form.

html part:

相关标签:
2条回答
  • 2020-12-12 05:03

    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.

    1. The button is visible but not enabled.
    2. Driver is finding the 2 instances of 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

    0 讨论(0)
  • 2020-12-12 05:14

    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.


    Your Usecase :

    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();
    

    Your Code Trials :

    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.


    Solution :

    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();
    

    Update :

    Best Practice :

    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();
    
    0 讨论(0)
提交回复
热议问题