如何使用Selenium WebDriver处理登录弹出窗口?

42

如何使用Selenium Webdriver处理登录弹出窗口? 我在此处附上示例屏幕。 如何在此登录弹出/警报窗口中输入用户名和密码?

谢谢和问候, 请输入图片描述


2
你在使用WebDriver时用的是什么语言?Java?C#?还是其他的? - Ripon Al Wasim
这个回答解决了你的问题吗?Selenium FileUpload accept() is not clicking button - dank8
17个回答

45

使用在URL请求中发送用户名和密码的方法:

http://username:password@the-site.com
所以为了更清晰明确。用户名是username,密码是password,其余部分是您测试网站的常规URL。 对我而言没有需要任何调整即可工作。
示例Java代码:
public static final String TEST_ENVIRONMENT = "the-site.com";
private WebDriver driver;

public void login(String uname, String pwd){
  String URL = "http://" + uname + ":" + pwd + "@" + TEST_ENVIRONMENT;
  driver.get(URL);
}

@Test
public void testLogin(){
   driver = new FirefoxDriver();
   login("Pavel", "UltraSecretPassword");
   //Assert...
}

2
我认为这个解决方案对我来说不起作用。因为在使用用户名和密码登录产品后,我的URL看起来像是“http://localhost:4040/lgserver/admin/operations/overview/index.jsp”。所以这个解决方案可能行不通。 - shiva oleti
1
先试一下。URL将是http://username:password@localhost:4040/lgserver/admin/operations/overview/ - Pavel Janicek
2
但我想通过传递用户名和密码值并单击“确定”按钮来处理弹出窗口。您能否提供使用WebDriver处理弹出窗口的示例代码? - shiva oleti
1
在这种情况下,您将需要使用AutoIt或其他软件。但是通过URL将用户名和密码传递给应用程序基本上是相同的。 - Pavel Janicek
我的用户名中有''字符。我们如何处理这种情况? - Sagar Varule
显示剩余2条评论

8

这应该适用于Windows Server 2012和IE。

var alert = driver.SwitchTo().Alert();

alert.SetAuthenticationCredentials("username", "password");

alert.Accept();

5

在 WebDriver 3.0 中(目前仍处于Beta阶段), 这非常简单。

Alert alert = driver.switchTo().alert() ;
alert.authenticateUsing(new UserAndPassword(_user_name,_password));
driver.switchTo().defaultContent() ; 

希望这能有所帮助。

4

现在在2020年,Selenium 4支持使用基本认证和摘要认证进行身份验证。它使用CDP,目前仅支持基于Chromium的浏览器。

例如:

Java示例:

    Webdriver driver = new ChromeDriver();
    
    ((HasAuthentication) driver).register(UsernameAndPassword.of("username", "pass"));

    driver.get("http://sitewithauth");
    
 

注意:在Alpha-7版本中存在一个bug,它会将用户名发送给用户和密码。需要等待下一个Selenium版本的发布,因为修复程序已经在主干中可用。https://github.com/SeleniumHQ/selenium/commit/4917444886ba16a033a81a2a9676c9267c472894


Beta-1已发布,它运行良好! - SiKing

3

解决方案:使用Thread和Robot进行Windows活动目录身份验证

我使用Java Thread和Robot与Selenium webdriver自动化我们网站的Windows活动目录身份验证过程。这个逻辑在Firefox和Chrome中运行良好,但在IE中不起作用。

由于某种原因,当弹出身份验证窗口时,IE会杀死webdriver,而Chrome和Firefox则会防止web driver被杀死。我没有尝试其他浏览器,如Safari。

//...
//Note: this logic works in Chrome and Firefox. It did not work in IE and I did not try Safari.
//...

//import relevant packages here

public class TestDemo {

    static WebDriver driver;

    public static void main(String[] args) {

        //setup web driver
        System.setProperty("webdriver.chrome.driver", "path to your chromedriver.exe");
        driver = new ChromeDriver();

        //create new thread for interaction with windows authentication window
        (new Thread(new LoginWindow())).start();                

        //open your url. this will prompt you for windows authentication
        driver.get("your url");

        //add test scripts below ...
        driver.findElement(By.linkText("Home")).click();    
        //.....
        //.....
    }

    //inner class for Login thread    
    public class LoginWindow implements Runnable {

        @Override
        public void run() {
            try {
                login();
            } catch (Exception ex) {
                System.out.println("Error in Login Thread: " + ex.getMessage());
            }
        }

        public void login() throws Exception {

            //wait - increase this wait period if required
            Thread.sleep(5000);

            //create robot for keyboard operations
            Robot rb = new Robot();

            //Enter user name by ctrl-v
            StringSelection username = new StringSelection("username");
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(username, null);            
            rb.keyPress(KeyEvent.VK_CONTROL);
            rb.keyPress(KeyEvent.VK_V);
            rb.keyRelease(KeyEvent.VK_V);
            rb.keyRelease(KeyEvent.VK_CONTROL);

            //tab to password entry field
            rb.keyPress(KeyEvent.VK_TAB);
            rb.keyRelease(KeyEvent.VK_TAB);
            Thread.sleep(2000);

            //Enter password by ctrl-v
            StringSelection pwd = new StringSelection("password");
            Toolkit.getDefaultToolkit().getSystemClipboard().setContents(pwd, null);
            rb.keyPress(KeyEvent.VK_CONTROL);
            rb.keyPress(KeyEvent.VK_V);
            rb.keyRelease(KeyEvent.VK_V);
            rb.keyRelease(KeyEvent.VK_CONTROL);

            //press enter
            rb.keyPress(KeyEvent.VK_ENTER);
            rb.keyRelease(KeyEvent.VK_ENTER);

            //wait
            Thread.sleep(5000);
        }                        
    }      
}

不是很好的解决方案,因为它假定活动窗口本身就是浏览器。 - ameen

3
处理身份验证弹出窗口最简单的方法是在 URL 中输入凭据。例如,我有类似以下的凭据:用户名:admin密码:admin
WebDriver driver = new ChromeDriver();
driver.get("https://admin:admin@your website url");

这太完美了! - Anthony

3
这是一个基于Python的Selenium解决方案,通过查看源代码(在这里)后,我发现以下三个步骤很有用。
obj = driver.switch_to.alert
obj.send_keys(keysToSend="username\ue004password")
obj.accept()

这里是制表符的值,可以在源代码的Keys类中找到。

我猜在JAVA中也可以使用相同的方法,但不确定。


1

我的使用情况是:

  1. 导航到Web应用程序。
  2. Web应用程序检测到我未登录,并重定向到单点登录(SSO)站点 - 不同的服务器!
  3. SSO站点(可能在Jenkins上)检测到我未登录到AD,并显示一个登录弹出窗口。
  4. 输入凭据后,将被重定向回Web应用程序。

我使用的是Selenium 3的较新版本,但是使用driver.switchTo().alert();无法检测到登录弹出窗口,结果会出现NoAlertPresentException

仅在URL中提供username:password不能从步骤1传播到步骤2。

我的解决方法:

import org.apache.http.client.utils.URIBuilder;

driver.get(...webapp_location...);
wait.until(ExpectedConditions.urlContains(...sso_server...));

URIBuilder uri = null;
try {
    uri = new URIBuilder(driver.getCurrentUrl());
} catch (URISyntaxException ex) {
    ex.printStackTrace();
}
uri.setUserInfo(username, password);
driver.navigate().to(uri.toString());

0

弹出窗口的类型在webdriver警报中定义:https://www.selenium.dev/documentation/webdriver/browser/alerts/

这里还有另一种类型 - 认证弹出窗口 - 例如由Weblogic生成,Selenium无法看到。

由于是HTTPS,用户/密码不能直接放在URL中。

解决方案是创建一个浏览器扩展程序:打包或未打包。

以下是未打包的代码和打包过程:https://qatestautomation.com/2019/11/11/handle-authentication-popup-in-chrome-with-selenium-webdriver-using-java/

在manifest.json中,将“https://ReplaceYourCompanyUrl”替换为“<all_urls>”。 未打包的程序可以直接在Selenium中使用:

#python:
co=webdriver.ChromeOptions()
co.add_argument("load-extension=ExtensionFolder")

<all_urls> 是一个匹配模式

请求的流程在https://developer.chrome.com/docs/extensions/reference/webRequest/中。


0

只需切换到警报窗口,使用authenticateUsing设置用户名和密码,然后返回到父窗口即可。

Alert Windowalert = driver.switchTo().alert() ;
Windowalert.authenticateUsing(new UserAndPassword(_user_name,_password));
driver.switchTo().defaultContent() ; 

1
更新:从selenium 3.8.0开始,Alert.authenticate已被删除。 - neonidian
1
无法处理这种类型的窗口,它不是HTML弹出窗口(框架或模态对话框),而是像JS中的alert函数一样的桌面窗口。 - ameen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接