web-dev-qa-db-fra.com

WebDriver ouvre un nouvel onglet

J'ai parcouru le Web et l'API WebDriver. Je ne vois pas comment ouvrir de nouveaux onglets avec WebDriver/Selenium2.0. 

Quelqu'un peut-il s'il vous plaît confirmer si j'ai raison?

Merci ...

24
ChrisOdney

Il existe un moyen totalement inter-navigateur de faire cela en utilisant webdriver, ceux qui disent que vous ne pouvez pas être trop paresseux. Tout d'abord, vous devez utiliser WebDriver pour injecter et ancrer une balise dans la page qui ouvre l'onglet souhaité. Voici comment je le fais (note: le pilote est une instance de 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);
    }       
}

Ensuite, vous devez demander à Webdriver de basculer son handle de fenêtre actuel sur le nouvel onglet. Voici comment je fais ça:

/**
 * 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);
}

Une fois cette opération terminée, vous pouvez ensuite interagir avec des éléments du nouveau contexte de page à l'aide de la même instance WebDriver. Une fois que vous avez terminé avec cet onglet, vous pouvez toujours revenir au contexte de fenêtre par défaut en utilisant un mécanisme similaire à la fonction switchWindow ci-dessus. Je vais laisser cela comme un exercice pour vous de comprendre.

35
Jonathan Azoff

L'API Selenium WebDriver ne prend pas en charge la gestion des onglets dans le navigateur.

30
JimEvans
        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);
8
user2283070

J'ai eu le même problème et j'ai trouvé une réponse. Essayer.

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

Il va ouvrir un nouvel onglet, vous pouvez effectuer vos actions dans le nouvel onglet.

4
deactivate

Faire ceci

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

ou Last () etc.

PS il n’ya aucune garantie que les WindowHandles soient dans l’ordre affiché sur votre navigateur, par conséquent, je vous conseillerais de conserver un historique des fenêtres actuelles avant de lancer la commande qui a provoqué l’ouverture d’un nouvel onglet. Ensuite, vous pouvez comparer vos poignées de fenêtre stockées avec le jeu actuel et basculer vers le nouveau dans la liste, dont il ne devrait y en avoir qu’un.

1
kernowcode
@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();  
 } 

nous pouvons utiliser les événements de clavier et automatiser l’ouverture et la commutation entre plusieurs onglets très facilement. Cet exemple est référencé de ICI

1
anuja jain

Merci pour la bonne idée @ Jonathan Azoff!

Voici comment je l'ai fait dans 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
1
bbbco

Hey @Paul et qui n'a jamais eu de problème pour ouvrir un deuxième onglet en python. Voici la solution

Je ne suis pas sûr qu'il s'agisse d'un bogue dans le WebDriver ou s'il n'est pas encore compatible avec mutlitab, mais il ne fait aucun mal à le gérer et je vais vous montrer comment le corriger.

Problème: Eh bien, je vois plus d’un problème. 

Premier problème doit le faire lorsque vous ouvrez un deuxième onglet, vous ne pouvez voir qu’un seul descripteur au lieu de deux. 

2ème problème et voici où ma solution entre en jeu. Il semble que bien que la valeur du descripteur soit toujours stockée dans le pilote, la fenêtre a perdu sa synchronisation avec raison.

Voici la solution en réglant le 2ème problème:

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"""

Cela fonctionne parfaitement pour moi. Je suis ouvert aux questions ...

1
Khaled Nakawa

Bien qu’il n’existe aucune API permettant d’ouvrir un nouvel onglet, vous pouvez simplement créer une nouvelle instance de WebDriver, l’appelant quelque chose de légèrement différent et transmettant l’URL souhaitée dans le nouvel onglet. Une fois tout ce que vous avez à faire, fermez cet onglet et indiquez NULL pour le nouveau pilote afin qu’il n’interfère pas avec l’instance originale de Webdriver. Si vous avez besoin d'ouvrir les deux onglets, assurez-vous de vous référer à l'instance appropriée de WebDriver. Utilisé pour l’automatisation du système de gestion de contenu Sitecore et cela a fonctionné.

1
Ola Ajibode

Il est impossible de créer de nouveaux onglets ou de gérer des onglets à l'aide du pilote Web/Selenium 2.0.

Vous pouvez ouvrir une nouvelle fenêtre à la place.

1
Mayur Shah

IJavaScriptExecutor est une classe très utile qui peut manipuler HTML DOM lors de l'exécution via JavaScript. Voici un exemple de code indiquant comment ouvrir un nouvel onglet de navigateur dans Selenium via 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]");

Juste pour donner un aperçu, il n'y a pas de méthodes dans Selenium qui vous permettraient d'ouvrir un nouvel onglet, le code ci-dessus créerait dynamiquement un élément d'ancrage et le dirigerait pour ouvrir un nouvel onglet.

0
Anand

Vous pouvez essayer de cette façon, car il y a action_chain dans le nouveau WebDriver . J'utilise Python, donc ignorez la grammaire:

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

Je préférerais ouvrir une nouvelle fenêtre. Existe-t-il une différence entre ouvrir une nouvelle fenêtre et ouvrir un nouvel onglet du point de vue d'une solution automatisée?

vous pouvez modifier la propriété cible des ancres et, une fois cliqué, la page cible s'ouvrira dans une nouvelle fenêtre.

Utilisez ensuite driver.switchTo() pour passer à la nouvelle fenêtre. Utilisez-le pour résoudre votre problème

0
Shrikant Khadilkar

Pour 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')
0

Java Robot peut être utilisé pour envoyer Ctrl + t (ou Cmd + t si MAC OS X) comme suit:

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

Un exemple complet d'utilisation de Chrome en tant que navigateur peut être créé ici .

0
Boni García

Je dois dire que j’ai aussi essayé cela, et bien que cela fonctionne apparemment avec certaines liaisons (Java, autant que Jonathan le dit, et Ruby aussi, apparemment), avec d’autres: les liaisons Selenium python ne signalent qu’une poignée par fenêtre, contenant plusieurs onglets

0
Pa_