如何切换到 Selenium 中的活动选项卡?

Posted

技术标签:

【中文标题】如何切换到 Selenium 中的活动选项卡?【英文标题】:How do I switch to the active tab in Selenium? 【发布时间】:2015-04-27 06:21:52 【问题描述】:

我们开发了一个 Chrome 扩展程序,我想用 Selenium 测试我们的扩展程序。我创建了一个测试,但问题是我们的扩展程序在安装时会打开一个新选项卡,我想我从另一个选项卡中得到了一个例外。是否可以切换到我正在测试的活动选项卡?或者另一种选择是先禁用扩展程序,然后登录我们的网站,然后才启用扩展程序。可能吗?这是我的代码:

def login_to_webapp(self):
    self.driver.get(url='http://example.com/logout')
    self.driver.maximize_window()
    self.assertEqual(first="Web Editor", second=self.driver.title)
    action = webdriver.ActionChains(driver=self.driver)
    action.move_to_element(to_element=self.driver.find_element_by_xpath(xpath="//div[@id='header_floater']/div[@class='header_menu']/button[@class='btn_header signature_menu'][text()='My signature']"))
    action.perform()
    self.driver.find_element_by_xpath(xpath="//ul[@id='signature_menu_downlist'][@class='menu_downlist']/li[text()='Log In']").click()
    self.driver.find_element_by_xpath(xpath="//form[@id='atho-form']/div[@class='input']/input[@name='useremail']").send_keys("[email]")
    self.driver.find_element_by_xpath(xpath="//form[@id='atho-form']/div[@class='input']/input[@name='password']").send_keys("[password]")
    self.driver.find_element_by_xpath(xpath="//form[@id='atho-form']/button[@type='submit'][@class='atho-button signin_button'][text()='Sign in']").click()

ElementNotVisibleException: Message: element not visible 测试失败,因为在新标签页(由扩展程序打开)中“登录”不可见(我认为新标签页仅在命令 self.driver.get(url='http://example.com/logout') 之后打开)。

更新:我发现异常与额外标签无关,它来自我们的网站。但是根据@aberna 的回答,我用这段代码关闭了额外的标签:

def close_last_tab(self):
    if (len(self.driver.window_handles) == 2):
        self.driver.switch_to.window(window_name=self.driver.window_handles[-1])
        self.driver.close()
        self.driver.switch_to.window(window_name=self.driver.window_handles[0])

关闭额外标签后,我可以在视频中看到我的标签。

【问题讨论】:

【参考方案1】:

这实际上在 3.x 中对我有用:

driver.switch_to.window(driver.window_handles[1])

附加窗口句柄,因此选择列表中的第二个选项卡

继续第一个标签:

driver.switch_to.window(driver.window_handles[0])

【讨论】:

如果你知道你的测试网站应该在一个新标签中打开一个链接而不是其他任何东西,它看起来很hackish但效果很好。非常适合快速和肮脏。 @sdkks 对不起,我不明白你的意思。抱歉,如果我的评论愚蠢或冒犯,那不是故意的。我使用了这段代码,它工作正常。你能详细说明为什么它看起来很hackish吗? you 这个词我的意思不是“你,用户 sdkks”,而是“测试站点应该在一个新选项卡中打开链接”之外的另一个原因,例如,如果开发人员明确要求 webdriver 打开一个新标签。 不能再欣赏你了..你是男人。非常感谢!【参考方案2】:

一些可能的方法:

1 - 使用 send_keys (CONTROL + TAB) 在选项卡之间切换

self.driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + Keys.TAB)

2 - 使用 ActionsChains (CONTROL+TAB) 在选项卡之间切换

actions = ActionChains(self.driver)      
actions.key_down(Keys.CONTROL).key_down(Keys.TAB).key_up(Keys.TAB).key_up(Keys.CONTROL).perform()

3 - 另一种方法可以利用 Selenium 方法检查当前窗口并移动到另一个窗口:

你可以使用

driver.window_handles

查找窗口句柄列表并尝试使用以下方法进行切换。

- driver.switch_to.active_element      
- driver.switch_to.default_content
- driver.switch_to.window

例如,要切换到上次打开的标签页,您可以这样做:

driver.switch_to.window(driver.window_handles[-1])

【讨论】:

它不起作用,我认为它不会切换标签,因为在视频中 [app.crossbrowsertesting.com/public/id7ed71371078e09/selenium/…] 我看到活动标签是相同的。 @Uri 不太容易通过视频分析行为。我用另一种可能的方法更新了答案 @Uri 解决您的问题的方法是什么? 我认为如果第二个选项卡有文本输入并且 selenium 在那里输入文本,那么这种方法将不起作用 - 至少在我的情况下。 我在使用新标签时遇到了问题,这种方法节省了时间driver.switch_to_window(driver.window_handles[1])【参考方案3】:

接受的答案对我不起作用。 要打开一个新标签并让 selenium 切换到它,我使用了:

driver.execute_script('''window.open("https://some.site/", "_blank");''')
sleep(1) # you can also try without it, just playing safe
driver.switch_to.window(driver.window_handles[-1]) # last opened tab handle  
# driver.switch_to_window(driver.window_handles[-1]) # for older versions

如果您需要切换回主选项卡,请使用:

driver.switch_to.window(driver.window_handles[0])

总结:

window_handles 包含打开的tabshandles 列表,将其用作switch_to.window() 中的参数以在选项卡之间切换。

【讨论】:

请注意 switch_to_window() 已被弃用并由 switch_to.window() 取代 可能有用的补充 - 连续循环浏览所有打开的标签,使用import itertools, time; for tab in itertools.cycle(reversed(driver.window_handles)): driver.switch_to.window(tab); time.sleep(2) @winklerrr 答案更新为较新的switch_to.window(),tks!【参考方案4】:

ctrl+t 或选择 window_handles[0] 假定您在开始时只打开一个选项卡。

如果您打开了多个选项卡,那么它可能会变得不可靠。

这就是我的工作:

old_tabs=self.driver.window_handles
#Perform action that opens new window here
new_tabs=self.driver.window_handles
for tab in new_tabs:
     if tab in old tabs:
          pass
     else:
          new_tab=tab
driver.switch_to.window(new_tab)

这是在切换到新标签之前积极识别新标签并将活动窗口设置为所需的新标签的东西。

仅仅告诉浏览器发送 ctrl+tab 是行不通的,因为它并没有告诉 webdriver 实际切换到新选项卡。

【讨论】:

【参考方案5】:

如果你只想关闭活动标签并且需要保持浏览器窗口打开,你可以使用switch_to.window方法,它的输入参数为窗口句柄ID。以下示例展示了如何实现这种自动化:

from selenium import webdriver
import time

driver = webdriver.Firefox()
driver.get('https://www.google.com')

driver.execute_script("window.open('');")
time.sleep(5)

driver.switch_to.window(driver.window_handles[1])
driver.get("https://facebook.com")
time.sleep(5)

driver.close()
time.sleep(5)

driver.switch_to.window(driver.window_handles[0])
driver.get("https://www.yahoo.com")
time.sleep(5)

#driver.close()

【讨论】:

【参考方案6】:

来自用户“aberna”的提示对我有用:

首先我得到了一个标签列表:

  tab_list = driver.window_handles

然后我选择标签:

   driver.switch_to.window(test[1])

返回上一个标签:

    driver.switch_to.window(test[0])

【讨论】:

您的答案中的test 变量来自哪里?与接受的答案或一些最受好评的答案有何不同? test=tab_list 正如帖子中提到的,解决方案的想法已经在接受的答案中,第 3 项,我只是认为写下来可以帮助像我这样的用户,没有受过正规 IT 教育的菜鸟。直到现在我才意识到“Avaricious_vulture”也在之前的帖子中解释过......【参考方案7】:

这是完整的脚本。

注意:删除下面两行小 URL 的空格。 Stack Overflow 不允许这里有微小的链接。

import ahk
import win32clipboard
import traceback
import appJar
import requests
import sys
import urllib
import selenium
import getpass
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import socket
import time 
import urllib.request
from ahk import AHK, Hotkey, ActionChain # You want to play with AHK. 
from appJar import gui

try:                                                                                                                                                                         
    ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU64.exe")    

except:                                                                                                                                                                         
    ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU32.exe")    

finally:                                                                                                                                                                         
    pass 

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--start-maximized')
chrome_options.add_experimental_option("excludeSwitches", ['enable-automation']);
chromeDriver = webdriver.Chrome('C:\\new_software\\chromedriver.exe', chrome_options = chrome_options)

def  ahk_disabledevmodescript():
    try:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU64.exe")                                                                                                                                                                           
    except:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU32.exe")                                                                                                                                                                         
    finally:                                                                                                                                                                         
        pass   
    ahk_disabledevmodescriptt= [
    str('WinActivate,ahk_exe chrome.exe'),
    str('Send esc'),
    ]
    #Run-Script
    for snipet in  ahk_disabledevmodescriptt:
        ahk.run_script(snipet, blocking=True )
    return 

def launchtabsagain():

    chromeDriver.execute_script("window.open('https://developers.google.com/edu/python/introduction', 'tab2');")
    chromeDriver.execute_script("window.open('https://www.facebook.com/', 'tab3');")
    chromeDriver.execute_script("window.open('https://developer.mozilla.org/en-US/docs/Web/API/Window/open', 'tab4');")
    chromeDriver.execute_script("window.open('https://www.easyespanol.org/', 'tab5');")
    chromeDriver.execute_script("window.open('https://www.google.com/search?source=hp&ei=EPO2Xf3EMLPc9AO07b2gAw&q=programming+is+not+difficult&oq=programming+is+not+difficult&gs_l=psy-ab.3..0i22i30.3497.22282..22555...9.0..0.219.3981.21j16j1......0....1..gws-wiz.....6..0i362i308i154i357j0j0i131j0i10j33i22i29i30..10001%3A0%2C154.h1w5MmbFx7c&ved=0ahUKEwj9jIyzjb_lAhUzLn0KHbR2DzQQ4dUDCAg&uact=5', 'tab6');")
    chromeDriver.execute_script("window.open('https://www.google.com/search?source=hp&ei=NvO2XdCrIMHg9APduYzQDA&q=dinner+recipes&oq=&gs_l=psy-ab.1.0.0i362i308i154i357l6.0.0..3736...0.0..0.179.179.0j1......0......gws-wiz.....6....10001%3A0%2C154.gsoCDxw8cyU', 'tab7');")

    return  
chromeDriver.get('https://ebc.cybersource.com/ebc2/')
compoanionWindow = ahk.active_window

launchtabs = launchtabsagain()
disabledevexetmessage = ahk_disabledevmodescript()



def copyUrl(): 
    try:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU64.exe")                                                                                                                                                                           
    except:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU32.exe")                                                                                                                                                                         
    finally:                                                                                                             

        pass 
    snipet = str('WinActivate,ahk_exe chrome.exe')
    ahk.run_script(snipet, blocking=True )  
    compoanionWindow.activate() 
    ahk_TinyChromeCopyURLScript=[

        str('WinActivate,ahk_exe chrome.exe'),
        str('send ^l'),
        str('sleep 10'),
        str('send ^c'),
        str('BlockInput, MouseMoveoff'),
        str('clipwait'),
    ] 

    #Run-AHK Script
    if ahk:
        for snipet in  ahk_TinyChromeCopyURLScript:
            ahk.run_script(snipet, blocking=True )  
    win32clipboard.OpenClipboard()
    urlToShorten = win32clipboard.GetClipboardData()
    win32clipboard.CloseClipboard()   


    return(urlToShorten)


def tiny_url(url):
    try:

        apiurl = "https: // tinyurl. com / api - create. php? url= " #remove spaces here
        tinyp = requests.Session()
        tinyp.proxies = "https" : "https://USER:PASSWORD." + "@userproxy.visa.com:443", "http" : "http://USER:PASSWORD." + "@userproxy.visa.com:8080"
        tinyUrl = tinyp.get(apiurl+url).text
        returnedresponse = tinyp.get(apiurl+url)
        if returnedresponse.status_code == 200: 
            print('Success! response code =' + str(returnedresponse))
        else:
            print('Code returned = ' + str(returnedresponse))
            print('From IP Address =' +IPadd)


    except:
        apiurl = "https: // tinyurl. com / api - create. php? url= " #remove spaces here
        tinyp = requests.Session()
        tinyUrl = tinyp.get(apiurl+url).text
        returnedresponse = tinyp.get(apiurl+url)
        if returnedresponse.status_code == 200: 
            print('Success! response code =' + str(returnedresponse))
            print('From IP Address =' +IPadd)
        else:
            print('Code returned = ' + str(returnedresponse))

    return tinyUrl

def tinyUrlButton():

    longUrl = copyUrl()
    try:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU64.exe")                                                                                                                                                                           
    except:                                                                                                                                                                         
        ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU32.exe")                                                                                                                                                                         
    finally:                                                                                                                                                                         
        pass
    try:
        shortUrl = tiny_url(longUrl)
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardText(shortUrl)
        win32clipboard.CloseClipboard()
        if ahk:
            try:
                if str(shortUrl) == 'Error':
                    ahk.run_script("Msgbox,262144 ,Done.,"+ shortUrl + "`rPlease make sure there is a link to copy and that the page is fully loaded., 5.5" )
                else:
                    ahk.run_script("Msgbox,262144 ,Done.,"+ shortUrl + " is in your clipboard., 1.5" )
                # ahk.run_script("WinActivate, tinyUrl" )
            except:
                traceback.print_exc()
                print('error during ahk script')

                pass

    except:
        print('Error getting tinyURl')
        traceback.print_exc()

def closeChromeTabs(): 
        try: 
            try:                                                                                                                                                                          
                ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU64.exe")                                                                                                                                                                          
            except:                                                                                                                                                                          
                ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU32.exe")                                                                                                                                                                  
            finally:                                                                                                                                                                          
                    pass   
            compoanionWindow.activate()  
            ahk_CloseChromeOtherTabsScript = [ 

                str('WinActivate,ahk_exe chrome.exe'), 
                str('Mouseclick, Right, 30, 25,,1'), 
                str('Send UP 3 enter'), 
                str('BlockInput, MouseMoveOff'), 
                ] 
                #Run-Script 
            if ahk: 
                for snipet in  ahk_CloseChromeOtherTabsScript: 
                        ahk.run_script(snipet, blocking=True ) 
            return(True) 
        except: 
            traceback.print_exc() 
            print("Failed to run closeTabs function.") 
            ahk.run_script('Msgbox,262144,,Failed to run closeTabs function.,2') 
            return(False)         



        # create a GUI and testing this library.

window = gui("tinyUrl and close Tabs test ", "200x160")
window.setFont(9)
window.setBg("blue")
window.removeToolbar(hide=True)
window.addLabel("description", "Testing AHK Library.")
window.addLabel("title", "tinyURL")
window.setLabelBg("title", "blue")
window.setLabelFg("title", "white")
window.addButtons(["T"], tinyUrlButton)
window.addLabel("title1", "Close tabs")
window.setLabelBg("title1", "blue")
window.setLabelFg("title1", "white")
window.addButtons(["C"], closeChromeTabs)
window.addLabel("title2", "Launch tabs")
window.setLabelBg("title2", "blue")
window.setLabelFg("title2", "white")
window.addButtons(["L"], launchtabsagain)
window.go()

if window.exitFullscreen():
    chromeDriver.quit()


def closeTabs():
    try:
        try:                                                                                                                                                                         
            ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU64.exe")                                                                                                                                                                           
        except:                                                                                                                                                                         
            ahk = AHK(executable_path="C:\\Program Files\\AutoHotkey\\AutoHotkeyU32.exe")                                                                                                                                                                         
        finally:                                                                                                                                                                         
                pass   

        compoanionWindow.activate()     
        ahk_CloseChromeOtherTabsScript = [

            str('WinActivate,ahk_exe chrome.exe'),
            str('Mouseclick, Right, 30, 25,,1'),
            str('Send UP 3 enter'),
            str('BlockInput, MouseMoveOff'),
            ]
            #Run-Script
        if ahk:
            for snipet in  ahk_CloseChromeOtherTabsScript:
                    ahk.run_script(snipet, blocking=True )
        return(True)
    except:
        traceback.print_exc()
        print("Failed to run closeTabs function.")
        ahk.run_script('Msgbox,262144,Failed,Failed to run closeTabs function.,2')
        return(False)

【讨论】:

不完全确定为什么会收到负面评论。【参考方案8】:

找到了一种使用 ahk 库的方法。对于我们需要解决这个问题的非程序员来说非常容易。使用 Python 3.7.3

安装ahk。 pip install ahk

import ahk
from ahk import AHK
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ['enable-automation']); #to disable infobar about chrome controlled by automation. 
chrome_options.add_argument('--start-maximized') 
chromeDriver = webdriver.Chrome('C:\\new_software\\chromedriver.exe', chrome_options = options) #specify your chromedriver location

chromeDriver.get('https://www.autohotkey.com/')#launch a tab

#launch some other random tabs for testing. 
chromeDriver.execute_script("window.open('https://developers.google.com/edu/python/introduction', 'tab2');")

chromeDriver.execute_script("window.open('https://www.facebook.com/', 'tab3');")

chromeDriver.execute_script("window.open('https://developer.mozilla.org/en-US/docs/Web/API/Window/open', 'tab4');"`)
seleniumwindow = ahk.active_window #as soon as you open you Selenium session, get a handle of the window frame with AHK. 
seleniumwindow.activate() #will activate whatever tab you have active in the Selenium browser as AHK is activating the window frame 
#To activate specific tabs I would use chromeDriver.switchTo()
#chromeDriver.switch_to_window(chromeDriver.window_handles[-1]) This takes you to the last opened tab in Selenium and chromeDriver.switch_to_window(chromeDriver.window_handles[1])to the second tab, etc.. 

【讨论】:

以上是关于如何切换到 Selenium 中的活动选项卡?的主要内容,如果未能解决你的问题,请参考以下文章

使用关闭按钮切换引导选项卡

切换选项卡时,带有无头 chrome 的 Selenium 无法获取 url

使用 Selenium WebDriver 和 Java 切换选项卡

当用户切换选项卡时,如何允许 Easeljs Tickers 保持活动状态

如何使用 selenium 从空​​选项卡中获取 URL“about:blank”?

Selenium 开关选项卡