Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HtmlUnitDriver alert handling doesn't handle confirms or prompts #14

Closed
barrypitman opened this issue May 27, 2016 · 18 comments
Closed
Assignees
Labels
Milestone

Comments

@barrypitman
Copy link

I logged an issue here: SeleniumHQ/selenium#1373 but since HtmlUnitDriver has moved to the new repository, I was advised to re-log the issue. It has been verified by 2 others. Copied below for convenience:

The new alert handling functionality in HtmlUnitDriver (driver.switchTo().alert()) only handles alert boxes, not other modal dialogs such as confirm and prompt. Other drivers handle confirm, alert and prompt. The test case below illustrates this.

I know that I can install a confirmHandler for the HtmlUnit WebClient, but that requires modifying the underlying driver and messages are difficult to retrieve.

import org.junit.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;

/**
 * Handling of javascript popups is implemented inconsistently for HtmlUnitDriver, since v2.47.0
 *
 * @author barry
 * @since 2015/12/13
 */
public class AlertTest {

    @Test
    public void testAlerts() throws Exception {
        testAlertsWithDriver(new ChromeDriver());
        testAlertsWithDriver(new FirefoxDriver());
        testAlertsWithDriver(new HtmlUnitDriver(true)); // test fails for HtmlUnitDriver
    }

    private void testAlertsWithDriver(WebDriver driver) {
        driver.get("https://www.google.com");
        JavascriptExecutor executor = (JavascriptExecutor) driver;

        // alerts are implemented
        String alertMessage = "error!";
        executor.executeScript("alert('" + alertMessage + "')");
        assertThat(driver.switchTo().alert().getText(), equalTo(alertMessage));
        driver.switchTo().alert().accept(); // dismiss the alert

        // but confirm messages aren't
        String confirmMessage = "are you sure?";
        executor.executeScript("confirm('" + confirmMessage + "')");

        // "NoAlertPresentException: No alert was present" thrown for HtmlUnitDriver only
        assertThat(driver.switchTo().alert().getText(), equalTo(confirmMessage));

        driver.switchTo().alert().accept(); // dismiss the confirm

        driver.quit();
    }
} 
@asashour
Copy link
Contributor

confirm() and prompt() need interaction with the client code, and this can only be achieved when the client and server run separately. This is not the case with HtmlUnitDriver currently, and this is the most important feature to be implemented.

I am starting a branch for making HtmlUnitDriver a Remote one, any contribution is more than welcome.

@trumpetx
Copy link

Here's how I got around it:

    @Before
    public void setup( )
    {
        String driver = System.getProperty("webtest.driver", DEFAULT_WEBDRIVER);
        switch (driver)
        {
            case "firefox":
                webDriver = new org.openqa.selenium.firefox.FirefoxDriver( );
                break;
            case "htmlunit":
            default :
                webDriver = new org.openqa.selenium.htmlunit.HtmlUnitDriver(BrowserVersion.INTERNET_EXPLORER_11, true)
                {
                    @Override
                    protected WebClient modifyWebClient(WebClient webClient)
                    {
                        org.apache.commons.logging.LogFactory.getFactory( ).setAttribute("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.NoOpLog");
                        java.util.logging.Logger.getLogger("com.gargoylesoftware").setLevel(java.util.logging.Level.OFF);
                        java.util.logging.Logger.getLogger("org.apache.commons.httpclient").setLevel(java.util.logging.Level.OFF);
                        AbstractWebTest.this.htmlUnitWebClient = webClient;
                        return webClient;
                    }
                };
        }
    }
    protected void clickLinkAndHandleConfirm(By by,
                                             final boolean acceptConfirm)
            throws IOException
    {
        // Bug in HtmlUnitWebDriver - confirm dialogs do not work
        if (htmlUnitWebClient != null)
        {
            htmlUnitWebClient.setConfirmHandler(new ConfirmHandler( )
            {
                @Override
                public boolean handleConfirm(Page page,
                                             String message)
                {
                    return acceptConfirm;
                }
            });
            clickLink(by);
            htmlUnitWebClient.setConfirmHandler(null);
        }
        else
        {
            clickLink(by);
            Alert alert = waitUntil(ExpectedConditions.alertIsPresent( ));
            if (acceptConfirm)
            {
                alert.accept( );
            }
            else
            {
                alert.dismiss( );
            }
        }
    }

@asashour asashour self-assigned this Feb 22, 2017
@asashour asashour added the bug label Feb 22, 2017
@asashour
Copy link
Contributor

In remote branch, all cases of AlertsTest now pass, please give it a try, and provide feedback.

The plan is to test the remote branch against HtmlUnit test suite, and when it passes, it will be merged in master

@asashour asashour added this to the 2.26 milestone Feb 23, 2017
@stiemannkj1
Copy link

For those stuck on HtmlUnitDriver 2.25 and below, a potential workaround is to disable alerts via JavaScript:

JavascriptExecutor javascriptExecutor = (JavascriptExecutor) webDriver;
javascriptExecutor.executeScript("window.alert = function(message){ console.log(message); };" +
    "window.confirm = function(message){ console.log(message); return true; };");

For more info, see my StackOverflow answer.

@sangeethmani
Copy link

Do we have the functionality to driver.switchTo().window(ChildWindow) available in the HtmlUnit driver? Is it possible to get the branch for the same if available?

@asashour
Copy link
Contributor

@sangeethmani: for different question, please create a new issue.

Yes, the method is available, use latest version, and provide more details if you encounter an issue.

@barrypitman
Copy link
Author

@asashour Just checking in - has the remote branch been merged into master? I'm struggling to find a release that I can use which addresses this issue. The latest available release is 2.27. Should I rather build my own version from the master branch? Thanks

@sangeethmani
Copy link

I cannot find the version 2.27 in the maven repository. Why arn't the latest versions available in the maven repos?

@sangeethmani
Copy link

sangeethmani commented Oct 18, 2017

sorry has the artifact id changed from selenium-htmlunit-driver->htmlunit-driver.. so that's the difference between the 2.52 and the 2.27 version?

https://github.com/SeleniumHQ/htmlunit-driver

@asashour
Copy link
Contributor

The remote branch was merged, but the removed for performance reasons, however the master supports the same function, without the intermediate server.

The latest release is

 <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>htmlunit-driver</artifactId>
    <version>2.27</version>
</dependency>

And there is 2.28-snapshot in here

@barrypitman
Copy link
Author

I tried just tried the AlertTest (at the top of this issue) using the latest snapshot (htmlunit-driver-2.28-20171004.075130-9), but its still failing with the same error message, 'NoAlertPresentException: No alert was present'

@asashour
Copy link
Contributor

I had a local error, ClassNotFoundException due to the jetty upgrade of HtmlUnit, now it is fixed and a new snapshot is now deployed.

Our reference is the build server, and it was green, please check your environment.

@barrypitman
Copy link
Author

barrypitman commented Oct 19, 2017

@asashour are you able to get the AlertTest to pass? I've tried with the latest snapshots and still failing, not sure if its because I don't have the right artifacts or not. Thanks!

@asashour
Copy link
Contributor

Yes, all the AlertsTest pass locally. Make a new project with only HtmlUnitDriver project, or check if you have conflicting dependencies.

@barrypitman
Copy link
Author

I'm attaching a simple maven project which uses htmlunit-driver v. 2.28-SNAPSHOT. I've added https://oss.sonatype.org/content/repositories/snapshots as a repository, its pulling down htmlunit-driver-2.28-20171019.070134-10.jar but when I run the AlertTest, it still fails with "No alert was present"
htmlunit-alerts.zip

@asashour
Copy link
Contributor

There is an error, which needs investigations at HtmlUnit side, please read this

Caused by: net.sourceforge.htmlunit.corejs.javascript.EcmaError: TypeError: Cannot read property "Kf" from undefined
(https://www.google.de/xjs/_/js/k=xjs.s.de.b7c4UjVSNxc.O/m=sx,c,sb,cdos,cr,elog,hsm,jsa,r,d,csi/am=wCLS4wUPQP4_BELqCmGBbGAy0A/rt=j/d=1/t=zcms/rs=ACT90oHaBoshtx_DEpWvv2n0SW6kAJwrpw#767)
	at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:4130)
	at net.sourceforge.htmlunit.corejs.javascript.ScriptRuntime.constructError(ScriptRuntime.java:4108)

@barrypitman
Copy link
Author

Hi @asashour, I think that error might be related to the javascript executed by the www.google.com page that is loaded during the test that I provided previously.

To eliminate that as the cause, I modified the test to run using locally generated content only. I still get the test failing with the same error message:

/**
 * Handling of javascript popups is implemented inconsistently for HtmlUnitDriver, since v2.47.0
 *
 * @author barry
 * @since 2015/12/13
 */
public class AlertTest {

    @Test
    public void testAlerts() throws Exception {
//        testAlertsWithDriver(new ChromeDriver());
//        testAlertsWithDriver(new FirefoxDriver());
        testAlertsWithDriver(new HtmlUnitDriver(true)); // test fails for HtmlUnitDriver
    }

    private void testAlertsWithDriver(WebDriver driver) throws IOException {
        File tempFile = File.createTempFile("fragment", ".html");
        tempFile.deleteOnExit();
        String htmlTemplate = "<html><body><script type='text/javascript'>%s</script></body></html>";

        // alerts are implemented
        String alertMessage = "error!";
        FileUtils.writeStringToFile(tempFile, String.format(htmlTemplate, "alert('" + alertMessage + "');"), Charset.defaultCharset());
        driver.get(tempFile.toURI().toURL().toString());
        assertThat(driver.switchTo().alert().getText(), equalTo(alertMessage));
        driver.switchTo().alert().accept(); // dismiss the alert

        // but confirm messages aren't
        String confirmMessage = "are you sure?";
        FileUtils.writeStringToFile(tempFile, String.format(htmlTemplate, "confirm('" + confirmMessage + "')"), Charset.defaultCharset());
        driver.get(tempFile.toURI().toURL().toString());

        // "NoAlertPresentException: No alert was present" thrown for HtmlUnitDriver only
        assertThat(driver.switchTo().alert().getText(), equalTo(confirmMessage));
        driver.switchTo().alert().accept(); // dismiss the confirm

        driver.quit();
    }
}

I do notice this warning message on the console: WARNING: window.confirm("are you sure?") no confirm handler installed, simulating the OK button. However, even if I do install a ConfirmHandler on the WebClient, I don't see how I'd prevent web driver API from throwing a NoAlertPresentException

@asashour
Copy link
Contributor

Thanks for reporting, confirm() was missing. Now it is fixed, and a new snapshot is available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants