问题
We developed a Chrome extension, and I want to test our extension with Selenium. I created a test, but the problem is that our extension opens a new tab when it's installed, and I think I get an exception from the other tab. Is it possible to switch to the active tab I'm testing? Or another option is to start with the extension disabled, then login to our website and only then enable the extension. Is it possible? Here is my code:
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()
The test fails with ElementNotVisibleException: Message: element not visible
, because in the new tab (opened by the extension) "Log In" is not visible (I think the new tab is opened only after the command self.driver.get(url='http://example.com/logout')
).
Update: I found out that the exception is not related to the extra tab, it's from our website. But I closed the extra tab with this code, according to @aberna's answer:
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])
After closing the extra tab, I can see my tab in the video.
回答1:
Some possible approaches:
1 - Switch between the tabs using the send_keys (CONTROL + TAB)
self.driver.find_element_by_tag_name('body').send_keys(Keys.CONTROL + Keys.TAB)
2 - Switch between the tabs using the using 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 - Another approach could make usage of the Selenium methods to check current window and move to another one:
You can use
driver.window_handles
to find a list of window handles and after try to switch using following methods.
- driver.switch_to.active_element
- driver.switch_to.default_content
- driver.switch_to.window
回答2:
This actually worked for me in 3.x:
driver.switch_to.window(driver.window_handles[1])
window handles are appended, so this selects the second tab in the list
to continue with first tab:
driver.switch_to.window(driver.window_handles[0])
回答3:
The accepted answer didn't work for me.
To open a new tab and have selenium switch to it, I used:
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 newer versions.
if you need to switch back to the main tab, use:
driver.switch_to_window(driver.window_handles[0])
Summary:
The window_handles
contains a list of the handles
of opened tabs
, use it as argument in switch_to_window()
to switch between tabs.
回答4:
Pressing ctrl+t or choosing window_handles[0]
assumes that you only have one tab open when you start.
If you have multiple tabs open then it could become unreliable.
This is what I do:
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)
This is something that would positively identify the new tab before switching to it and sets the active window to the desired new tab.
Just telling the browser to send ctrl+tab does not work because it doesn't tell the webdriver to actually switch to the new tab.
回答5:
Found a way using ahk library. Very easy for us non-programmers that need to solve this problem. used Python 3.7.3
Install ahk with. 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..
If you want a full script that shows a test with tinyURL shoot me an email gus1ibis@gmail.com
-----------
回答6:
Here is the full script.
Note: Remove the spaces in the two lines for tiny URL below. Stack Overflow does not allow the tiny link in here.
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)
来源:https://stackoverflow.com/questions/28715942/how-do-i-switch-to-the-active-tab-in-selenium