Подтвердить что ты не робот

WebDriver открывает новую вкладку

Я прорвал сеть и API WebDriver. Я не вижу способ открыть новые вкладки с помощью WebDriver/Selenium2.0.

Кто-нибудь может подтвердить, что я прав?

Спасибо, Крис. P.S: Текущая альтернатива, которую я вижу, - либо загружать разные URL-адреса в одном окне, либо открывать новые окна.

4b9b3361

Ответ 1

Существует абсолютно кросс-браузерный способ сделать это с помощью 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 выше. Я оставлю это как упражнение для вас, чтобы понять.

Ответ 2

API Selenium WebDriver в настоящее время не поддерживает управление вкладками в браузере.

Ответ 3

        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);

Ответ 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);

Он откроет новую вкладку, на которой вы сможете выполнять свои действия на новой вкладке.

Ответ 5

Хотя API для открытия новой вкладки отсутствует, вы можете просто создать новый экземпляр WebDriver, называя его чем-то немного отличающимся и передавая URL-адрес, который вы хотите на новой вкладке. После того, как вы сделали все, что вам нужно сделать, закройте эту вкладку и сделайте новый драйвер NULL, чтобы он не мешал исходному экземпляру Webdriver. Если вам нужно открыть обе вкладки, убедитесь, что вы ссылаетесь на соответствующий экземпляр WebDriver. Используется для автоматизации Sitecore CMS и работает.

Ответ 6

Мы не можем создавать новые вкладки TAB или handle с помощью веб-драйвера/selenium 2.0

Вместо этого вы можете открыть новое окно.

Ответ 7

Спасибо за отличную идею @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

Привет, @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"""

Он отлично работает для меня. Я открыт для вопросов...

Ответ 9

Сделайте это

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

или Last() и т.д.

PS нет гарантии, что WindowHandles находятся в порядке, отображаемом в вашем браузере, поэтому я бы посоветовал вам сохранить некоторую историю текущих окон до того, как вы выполните команду, которая заставила открыть новую вкладку. Затем вы можете сравнить сохраненные ручки окна с текущим набором и переключиться на новый в списке, из которых должен быть только один.

Ответ 10

Я тоже должен сказать, что я тоже это пробовал, и хотя он, похоже, работает с некоторыми привязками (Java, насколько Джонатан говорит, и рубин тоже, видимо), с другими, это не так: selenium python bindings сообщает только один дескриптор на окно, даже если содержит несколько вкладок

Ответ 11

Я бы предпочел открыть новое окно. Есть ли разница в открытии нового окна и открытии новой вкладки с точки зрения автоматизированного решения?

вы можете изменить свойство target anchors и после нажатия целевой страницы откроется в новом окне.

Затем используйте driver.switchTo() для перехода в новое окно. Используйте его, чтобы решить проблему.

Ответ 12

IJavaScriptExecutor - очень полезный класс, который может манипулировать HTML DOM во время выполнения через JavaScript, ниже приведен пример кода о том, как открыть новую вкладку браузера в Selenium через IJavaScriptExecutor:

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 нет методов, которые позволят вам открыть новую вкладку, приведенный выше код будет динамически создавать элемент привязки и направляет его на открытие новой вкладки.

Ответ 13

Вы можете попробовать таким образом, так как в новом webdriver есть action_chain. Я использую Python, поэтому, пожалуйста, игнорируйте грамматику:

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

Ответ 14

Вместо открытия новой вкладки вы можете открыть новое окно, используя код ниже.

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

Ответ 15

Для 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')

Ответ 16

package automationexamples;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.openqa.selenium.WebDriver;

/**
 *
 * @author Nadir
 */

  public class NavigateExample {

  private WebDriver driver;
  public static final int OPEN_IN_NEW_TAB=1;

  NavigateExample(WebDriver driver){
  if(driver!=null)
  this.driver = driver;
  else System.out.println("Driver is NULL (Not initialized)");
  }
  public void navigateUrls(String[] URLS)
  {
  for(String URL:URLS) showURL(URL);
  }

  private void showURL(String URL)
  {
  driver.get(URL);
  }

  void navigateUrls(String[] URLS, int OPTION) {
  for(int i=0;i<URLS.length;i++) 
  {
  if(i>0)showURL(URLS[i],OPTION);
  else showURL(URLS[i]);
  } 
  }

  private void showURL(String URL, int OPTION) {

  if(OPTION==OPEN_IN_NEW_TAB)
  {
  createTAB();
  switchToNewTAB();
  }

  showURL(URL);


  }



  private void createTAB() {
  try {
  Robot r = new Robot();
  r.keyPress(KeyEvent.VK_CONTROL);
  r.keyPress(KeyEvent.VK_T);
  r.keyRelease(KeyEvent.VK_CONTROL);
  r.keyRelease(KeyEvent.VK_T); 

  } catch (AWTException ex) {
  Logger.getLogger(NavigateExample.class.getName()).log(Level.SEVERE, null, ex);
  }
  }

  private void switchToNewTAB() {
  Set set=driver.getWindowHandles();
  for(Iterator<String> it=set.iterator();it.hasNext();) 
  if(it.hasNext()) driver.switchTo().window(it.next());
  }
}

Ответ 17

Java Robot можно использовать для отправки Ctrl + t (или Cmd + t, если MAC OS X) следующим образом:

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 в качестве браузера может быть разветвлен здесь.

Ответ 18

@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 content.
  driver.switchTo().defaultContent();  
 } 

мы можем использовать события клавиатуры и легко автоматизировать открытие и переключение между несколькими вкладками. Этот пример ссылается на ЗДЕСЬ