【问题标题】:How to switch to window authentication popup and enter credentials? [duplicate]如何切换到窗口身份验证弹出窗口并输入凭据? [复制]
【发布时间】:2019-06-17 07:49:30
【问题描述】:

打开应用程序 URL 后,用户被重定向到有登录按钮的登录页面。

driver.get("abc.com")

现在当用户点击登录按钮时,在同一个窗口中的 URL 会更改为 xyz.com 并显示身份验证弹出窗口,用于登录目的,类似于下图所示。

要在身份验证窗口中输入用户名和密码,我尝试了以下代码

shell = win32com.client.Dispatch("WScript.Shell")
shell.Sendkeys("username")
time.sleep(1)
shell.Sendkeys("{TAB}")
time.sleep(1)
shell.Sendkeys("password") 
time.sleep(1)
shell.Sendkeys("{ENTER}")
time.sleep(1)

没有用。然后我尝试使用上面的代码直接打开Windows身份验证弹出窗口(通过单击登录按钮后复制URL),它起作用了

driver.get("xyz.com")//instead of abc.com my application URL

我有点困惑。如果我打开我的应用程序 URL abc.com,单击登录按钮,使用 autoit,它没有输入凭据。但是,如果我直接发送窗口身份验证 URL xyz.com 而不是应用 URL abc.com 并使用 autoit,它就可以工作。

谁能建议我在这里缺少什么?我还尝试在单击登录按钮后切换窗口,思考它的新 URL,然后使用 autoit 命令,但它仍然无法正常工作。

driver.switch_to_window(driver.window_handles[1])

对此有任何想法吗?

注意:我注意到点击登录按钮,windows 正在无限加载,并且光标在 windows 身份验证弹出窗口的用户名文本字段上处于活动状态。此外,一旦出现 Windows 身份验证窗口,selenium 命令和 autoit 命令都不起作用。

【问题讨论】:

  • @DebanjanB 我的情况不同。当我打开应用程序说 abc.com 时,它没有显示身份验证弹出窗口。现在,当用户单击登录按钮时,会出现 Windows 身份验证弹出窗口,并且 URL 会更改为 xyz.com。这就是使用第一个 url 传递用户名和密码不起作用的原因。知道如何解决吗?
  • 尝试打开url,点击登录按钮后会显示该url以及凭据。
  • 你的意思是说我应该使用两次 driver.get() 函数?首先是应用程序,然后是单击登录按钮后的第二个?

标签: java python selenium


【解决方案1】:

该对话框被 selenium 视为警报。在 C# 中,为 Firefox 测试输入凭据的代码如下所示:

// Inputs id with permissions into the Windows Authentication box
var alert = driver.SwitchTo().Alert();
alert.SendKeys( @"username" + Keys.Tab + 
                @"password" + Keys.Tab);
alert.Accept();

第一行告诉驱动程序检查打开的警报(对话框)。

第二行将用户名和密码发送到警报

然后第三行发送这些凭据,假设它们有效,测试将继续。

假设您使用 Firefox 进行测试,则无需使用额外的框架来处理此身份验证框。

【讨论】:

    【解决方案2】:

    看起来您只需要使用基本身份验证凭据打开 URL。 你可以先试试这个吗?

    driver.get('http://username:password@abc.com')
    

    如果你仍然收到弹出窗口,试试这个

    driver.get('http://username:password@xyz.com') #assuming this is the site that handles authentication
    driver.get('abc.com')
    

    它应该停止弹出窗口

    【讨论】:

    • 试过了。它没有输入凭据,虽然光标在用户名上闪烁但没有输入文本
    【解决方案3】:

    你可以自动化keyboard:

    import keyboard
    keyboard.write("username")
    keyboard.press_and_release("tab")
    keyboard.write("password")
    keyboard.press_and_release("enter")
    

    这是一个使用selenium 加载登录页面,然后使用keyboard 输入登录凭据的示例:

    from selenium.webdriver import Firefox
    import keyboard
    
    driver = Firefox()
    driver.get('https://somelink')
    
    keyboard.press_and_release('tab')
    keyboard.press_and_release('shift + tab')
    keyboard.write('user', delay=1)
    keyboard.press_and_release('tab')
    keyboard.write('pass', delay=1)
    keyboard.press_and_release('enter')
    

    注意:keyboard 在 Linux 上可能需要 root 权限。

    【讨论】:

      【解决方案4】:

      您需要切换到警报,这与窗口不同。出现警报后,切换警报句柄,然后使用.authenticate 方法为其提供用户名和密码

      alert = driver.switch_to.alert
      alert.authenticate(username, password)
      

      您可能需要等待 EC.alert_is_present 预期条件以确保警报存在。

      【讨论】:

        【解决方案5】:

        试试这个(page_title 是弹出窗口的标题,假设你在 Windows 机器上):

        from win32com.client import Dispatch
        autoit = Dispatch("AutoItX3.Control")
        
        def _window_movement_windows(page_title):
                autoit.WinSetOnTop(page_title, "", 1)
                autoit.WinActivate(page_title, "")
                autoit.WinWaitActive(page_title)
        

        可以在此处找到如何使用 python 设置 AutoIt 的示例:Calling AutoIt Functions in Python

        【讨论】:

        • 它不工作,标题是应用程序的 url 很长并且不断变化
        • 那么你有没有像_window_movement_windows(Authentication Required)这样调用函数?
        • 是的,试过了..不工作..像往常一样光标在用户名字段上继续闪烁,但没有输入文本
        • shell 对象还是autoit 对象(发送密钥)?你也试过autoit.Send("my_username")吗?
        【解决方案6】:

        使用 Firefox,可以通过在请求时自动提供凭据来避免身份验证弹出窗口。

        它需要在浏览器级别注入和运行一些代码来检测身份验证尝试并设置凭据。

        这是一个工作示例:

        from selenium import webdriver
        from selenium.webdriver.remote.webdriver import WebDriver
        
        
        def add_credentials_moz(driver, target, username, password):
            driver.execute("SET_CONTEXT", {"context": "chrome"})        
            driver.execute_script("""
                let [target, username, password] = [...arguments];
                let WebRequest = Cu.import('resource://gre/modules/WebRequest.jsm', {});
                WebRequest.onAuthRequired.addListener(function listener(){
                  WebRequest.onAuthRequired.removeListener(listener);
                  return Promise.resolve({authCredentials: {username: username, password: password}});
                }, {urls: new MatchPatternSet([target])}, ['blocking']);
                """, target, username, password)        
            driver.execute("SET_CONTEXT", {"context": "content"})
        
        WebDriver.add_credentials_moz = add_credentials_moz
        
        
        
        driver = webdriver.Firefox()
        driver.add_credentials_moz("https://httpbin.org/*", username="user", password="passwd")
        
        driver.get("https://httpbin.org/")
        
        driver.find_element_by_css_selector("[href='/basic-auth/user/passwd']")\
              .click()
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-25
          • 2020-08-28
          • 1970-01-01
          • 2019-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多