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

前端 未结 2 1912
感情败类
感情败类 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: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 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();
    

提交回复
热议问题