WebDriver打开新标签

时间:2011-06-21 07:47:02

标签: java automated-tests webdriver selenium-webdriver

我浏览了网页和WebDriver API。我没有看到使用WebDriver / Selenium2.0打开新标签的方法。

有人可以确认我是否正确吗?

谢谢, 克里斯。 P.S:我看到的当前替代方案是在同一窗口中加载不同的URL或打开新窗口。

17 个答案:

答案 0 :(得分:35)

使用webdriver完全有一种跨浏览器的方式,那些说你不能太懒的人。首先,您需要使用WebDriver将标记注入并锚定到打开所需选项卡的页面中。这是我的工作方式(注意:驱动程序是WebDriver实例):

/**
 * Executes a script on an element
 * @note Really should only be used when the web driver is sucking at exposing
 * functionality natively
 * @param script The script to execute
 * @param element The target of the script, referenced as arguments[0]
 */
public void trigger(String script, WebElement element) {
    ((JavascriptExecutor)driver).executeScript(script, element);
}

/** Executes a script
 * @note Really should only be used when the web driver is sucking at exposing
 * functionality natively
 * @param script The script to execute
 */
public Object trigger(String script) {
    return ((JavascriptExecutor)driver).executeScript(script);
}

/**
 * Opens a new tab for the given URL
 * @param url The URL to 
 * @throws JavaScriptException If unable to open tab
 */
public void openTab(String url) {
    String script = "var d=document,a=d.createElement('a');a.target='_blank';a.href='%s';a.innerHTML='.';d.body.appendChild(a);return a";
    Object element = trigger(String.format(script, url));
    if (element instanceof WebElement) {
        WebElement anchor = (WebElement) element; anchor.click();
        trigger("var a=arguments[0];a.parentNode.removeChild(a);", anchor);
    } else {
        throw new JavaScriptException(element, "Unable to open tab", 1);
    }       
}

接下来,您需要告诉webdriver将其当前窗口句柄切换到新选项卡。我是这样做的:

/**
 * Switches to the non-current window
 */
public void switchWindow() throws NoSuchWindowException, NoSuchWindowException {
    Set<String> handles = driver.getWindowHandles();
    String current = driver.getWindowHandle();
    handles.remove(current);
    String newTab = handles.iterator().next();
    locator.window(newTab);
}

完成此操作后,您可以使用相同的WebDriver实例与新页面上下文中的元素进行交互。完成该选项卡后,您始终可以使用与上面的switchWindow函数类似的机制返回到默认窗口上下文。我会把它作为练习让你弄明白。

答案 1 :(得分:30)

Selenium WebDriver API目前不支持在浏览器中管理选项卡。

答案 2 :(得分:8)

        var windowHandles = webDriver.WindowHandles;
        var script = string.Format("window.open('{0}', '_blank');", url);
        scriptExecutor.ExecuteScript(script);
        var newWindowHandles = webDriver.WindowHandles;
        var openedWindowHandle = newWindowHandles.Except(windowHandles).Single();
        webDriver.SwitchTo().Window(openedWindowHandle);

答案 3 :(得分:4)

我遇到了同样的问题并找到了答案。试一试。

Robot r = new Robot(); 
r.keyPress(KeyEvent.VK_CONTROL); 
r.keyPress(KeyEvent.VK_T); 
r.keyRelease(KeyEvent.VK_CONTROL); 
r.keyRelease(KeyEvent.VK_T);

它将打开一个新标签,您可以在新标签中执行操作。

答案 4 :(得分:1)

@Test
 public void openTab() {
  //Open tab 2 using CTRL + t keys.
  driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");


 //Open URL In 2nd tab.
  driver.get("http://www.qaautomated.com/p/contact.html");

  //Call switchToTab() method to switch to 1st tab
  switchToTab(); 
}

public void switchToTab() {
  //Switching between tabs using CTRL + tab keys.
  driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");
  //Switch to current selected tab's content.
  driver.switchTo().defaultContent();  
 } 

我们可以使用键盘事件,并可以非常轻松地在多个标签之间自动打开和切换。此示例来自HERE

答案 5 :(得分:1)

这样做

_webDriver.SwitchTo().Window(_webDriver.WindowHandles.Where(x => x != _webDriver.CurrentWindowHandle).First());

或者Last()等。

PS无法保证WindowHandles符合浏览器显示的顺序,因此,我建议您在执行命令之前保留当前窗口的历史记录,这会导致打开新选项卡。然后,您可以将存储的窗口句柄与当前集合进行比较,并切换到列表中的新窗口句柄,其中应该只有一个。

答案 6 :(得分:1)

嘿@Paul和谁曾经有问题在python中打开第二个标签。这是解决方案

我不确定这是否是webdriver中的错误,或者因为它与mutlitab不兼容,但它肯定是错误的,我将展示如何解决它。

<强>问题:  我看到不止一个问题。

第一个问题必须在打开第二个标签时执行此操作,您只能看到一个句柄而不是两个句柄。

第二期,这就是我的解决方案的用武之地。看起来尽管句柄值仍然存储在驱动程序中,但窗口仍然失去了与它的同步。

以下是解决第二个问题的解决方案:

elem = browser.find_element_by_xpath("/html/body/div[2]/div[4]/div/a") #href link
time.sleep(2) 
elem.send_keys(Keys.CONTROL + Keys.RETURN + "2") #Will open a second tab

#solution for the 2nd issue is here    
for handle in browser.window_handles:
        print "Handle is:" + str(handle) #only one handle number
        browser.switch_to_window(handle)

time.sleep(3)

#Switch the frame over. Even if you have switched it before you need to do it again
browser.switch_to_frame("Frame") 


"""now this is how you handle closing the tab and working again with the original tab"""

#again switch window over
elem.send_keys(Keys.CONTROL + "w")
for handle in browser.window_handles:
    print "HandleAgain is:" + str(handle) #same handle number as before
    browser.switch_to_window(handle)

#again switch frame over if you are working with one
browser.switch_to_frame("Frame") 

time.sleep(3)
#doing a second round/tab
elem = browser.find_element_by_xpath("/html/body/div[2]/div[4]/div/a") #href link
time.sleep(2) 
elem.send_keys(Keys.CONTROL + Keys.RETURN + "2") #open a 2nd tab again

"""Got it? find the handle, switch over the window then switch the frame"""

这对我来说非常合适。我对问题持开放态度......

答案 7 :(得分:1)

感谢@Jonathan Azoff的好主意!

以下是我在Ruby中的表现:

def open_new_window(url)
  a = @driver.execute_script("var d=document,a=d.createElement('a');a.target='_blank';a.href=arguments[0];a.innerHTML='.';d.body.appendChild(a);return a", url)
  a.click
  @driver.switch_to.window(@driver.window_handles.last)
end

答案 8 :(得分:1)

我们无法使用web driver / selenium 2.0

创建新的TAB或处理选项卡

您可以改为打开一个新窗口。

答案 9 :(得分:1)

虽然没有用于打开新选项卡的API,但您可以创建一个新的WebDriver实例,将其称为略有不同的实例,并在新选项卡中传递所需的URL。完成所有操作后,关闭该选项卡并使新驱动程序为NULL,以便它不会干扰Webdriver的原始实例。如果您需要打开两个选项卡,请确保引用适当的WebDriver实例。用于Sitecore CMS自动化,它可以工作。

答案 10 :(得分:0)

IJavaScriptExecutor是非常有用的类,可以通过JavaScript在运行时操作HTML DOM,下面是如何通过IJavaScriptExecutor在Selenium中打开新的浏览器选项卡的示例代码:

IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
                object linkObj = js.ExecuteScript("var link = document.createElement('a');link.target='_blank';link.href='http://www.gmail.com';link.innerHTML='Click Me';document.getElementById('social').appendChild(link);return link");
                /*IWebElement link = (IWebElement)linkObj;
                link.Click();*/
                browser.Click("//*[@id='social']/a[3]");

为了给出一个见解,Selenium中没有允许你打开新标签的方法,上面的代码会动态创建一个锚元素并指示它打开一个新的标签。

答案 11 :(得分:0)

我更喜欢打开一个新窗口。打开新窗口与从自动解决方案角度打开新标签真的不一样吗?

您可以修改锚点目标属性,点击后,目标页面将在新窗口中打开。

然后使用driver.switchTo()切换到新窗口。用它来解决你的问题

答案 12 :(得分:0)

我必须说我也尝试了这一点,虽然它似乎可以使用一些绑定(Java,就Jonathan而言,显然也是ruby),与其他绑定不同:selenium python绑定报告每个窗口只有一个句柄,即使包含多个标签

答案 13 :(得分:0)

您可以尝试这种方式,因为新的webdriver中有action_chain。 我正在使用Python,所以请忽略语法:

act = ActionChains(driver)
act.key_down(Keys.CONTROL)
act.click(link).perform()
act.key_up(Keys.CONTROL)

答案 14 :(得分:0)

对于MAC OS

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://google.com")
body = driver.find_element_by_tag_name("body")
body.send_keys(Keys.COMMAND + 't')

答案 15 :(得分:0)

Java Robot可用于发送Ctrl + t(如果MAC OS X,则为Cmd + t),如下所示:

int vkControl = IS_OS_MAC ? KeyEvent.VK_META : KeyEvent.VK_CONTROL;
Robot robot = new Robot();
robot.keyPress(vkControl);
robot.keyPress(KeyEvent.VK_T);
robot.keyRelease(vkControl);
robot.keyRelease(KeyEvent.VK_T);

使用Chrome作为浏览器的完整运行示例可以分叉here

答案 16 :(得分:-1)

您可以使用以下代码打开新窗口,而不是打开新标签页。

for(String childTab : driver.getWindowHandles())
    {
        driver.switchTo().window(childTab);
    }