Search code examples
htmlgoogle-chromeseleniumspockgeb

Interacting with <dialog> with Geb/Selenium (only with Chrome)


All my Geb/Spock tests were running perfectly on Firefox and then I tried with Chrome (v59) and it keep hanging when an alert or confirm pop up is raised.

With Firefox I was using withAlert{} or withConfirm{} to handle those but it doesn't work with Chrome.

So I did some digging into views and I found out that dialog were managed by this widget. So I created accessors to <dialog> in my page object but Chrome is still unable to interact with it (no way to detect that the pop up is displayed nor closing it). I tried several things such as using displayed or waiting for the text to be shown but nothing worked.

I am not used to jQuery so maybe I am missing something here?

Here is a sample of the code I must interact with:

<dialog class="qq-alert-dialog-selector">
    <div class="qq-dialog-message-selector"></div>

    <div class="qq-dialog-buttons">
        <button type="button" class="qq-cancel-button-selector">Close</button>
    </div>
</dialog>

And this is how I try to access to it (in my page object):

alertPopUp {$("dialog", class:"qq-alert-dialog-selector")}
alertCloseButton {alertPopUp.children("div.qq-dialog-buttons").children("button")}

And finally how I would like to test the pop up:

when: "Trying to upload ..."
uploadFileButton = incorrect.absolutePath

then: "An alerting pop up occurs"
waitFor{alertPopUp.displayed}


when: "Closing the pop up"
alertCloseButton.click(SubmitAClaim)

then: "Number of uploaded files should not change"
uploadedElements.size() == initialUploadedFiles

Can anyone help? I guess it may have something to do with chrome's focus (I mean if it is currently on the pop up or on the page behind.

EDIT:

After all, it seems that the problem is not linked with jQuery (good thing I guess). We can verify the dialog box is open thanks to open attribute in <dialog>. I have done something like this:

when: "Trying to upload ..."
uploadFileButton = incorrect.absolutePath

then: "A alerting pop up occurs"
waitFor {alertPopUp.getAttribute("open") == "true"}

But I still cannot interact with the dialog box: when I try to click on alertCloseButton it raise an ElementNotVisibleException. So it has something to do with browser focus, I guess. I tried:

  • withWindow{} or driver.switchTo().window() but the only window available is the main one.
  • withFrame() but I get a NoSuchFrameException
  • driver.switchTo().alert() but it raise a NoAlertRaisedException

So I wonder if someone know how Chrome considers <dialog> tag (alert, confirm, ...) ?

Note: According to caniuse.com, Chrome is the only browser compatible with <dialog> for now.


Solution

  • Finally I managed to find a way to handle this issue. I took a look into google demo for <dialog> use and I used the js object provided by Geb to execute the js example from Google. This finally gives this:

    when: "Trying to upload ..."
    uploadFileButton = incorrect.absolutePath
    
    then: "A alerting pop up occurs"
    waitFor {alertPopUp.getAttribute("open") == "true"}
    
    
    when: "Closing the pop up"
    report "After upload"
    js.exec """var dialog = document.querySelector(".qq-alert-dialog-selector");
        dialog.close();
        return true;
    """
    
    then: "Number of uploaded files should not change"
    uploadedElements.size() == initialUploadedFiles
    

    This is really brute force and I don't like it as it relies a lot on back end, how dialogs are set up etc... But it works. I really hope Geb/Selenium will provide something easier to use (as <dialog>is W3C it will become usual on all browsers).