Düğmeye tıkladıktan sonra açılan yeni tarayıcı penceresine nasıl geçilir?


Yanıtlar:


118

Aşağıdaki gibi pencereler arasında geçiş yapabilirsiniz:

// Store the current window handle
String winHandleBefore = driver.getWindowHandle();

// Perform the click operation that opens new window

// Switch to new window opened
for(String winHandle : driver.getWindowHandles()){
    driver.switchTo().window(winHandle);
}

// Perform the actions on new window

// Close the new window, if that window no more required
driver.close();

// Switch back to original browser (first window)
driver.switchTo().window(winHandleBefore);

// Continue with original browser (first window)

4
Kabul edilen çözümün tutarlı bir şekilde Chrome'da çalıştığını ancak IE'de çalışmadığını onaylayabilirim. Yeni pencere tutamacı IE'de tanınmıyor. @Elmue yanlıştır çünkü getWindowHandles()bir Set döndürür ve bir Set sıralamayı garanti etmez . Son öğe her zaman son pencere değildir. Yorumunun çok fazla olumlu oy almasına şaşırdım.
gümüş

@silver: Neden bahsettiğin hakkında hiçbir fikrim yok. Benim kodumda WindowHandles bir ReadOnlyCollection <string> döndürüyor ki bunun için son girdinin her zaman en son açılan pencere olduğunu garanti edebilirim. Bunu test ettim. Bu C # 'da mükemmel çalışıyorsa, ancak Java'da yanlış uygulanıyorsa, bunu bir hata olarak bildirmelisiniz.
Elmue

1
@Elmue Bu bir Java dizisidir. Luke'un (Selenyum geliştirici) okuyunuz tepkisini ilgili getWindowHandles(). Yöntemin ve özellikle Java Set <T> 'nin bilinen bir davranışıdır (hata değildir). Bu nedenle switchTo().window(handles[handles.length-1])Java'da garanti edilmez. AC # çözümünün doğru olduğu iddia edilemez.
gümüş

6
@Elmue Üçüncü (ve son) kez, cevabınız Java için yanlıştır , çünkü dokümanlar ve geliştiriciler tarafından YANLIŞ olabilir. C # için olduğunu söylediğiniz bir yanıt gönderin, sorun değil. Java için GitHub'da bir sorun kartı oluşturun, devam edin. Basitçe, cevabınız ileti dizisindeki ETİKETLİ dil için geçerli değildir ve insanlar aksini düşünebilir. Ayrımı yapamazsanız, anlayışınız eksiktir.
gümüş

3
@Elmue Bu arada, driver.close () işlevinin her iki pencereyi de kapattığını söylemekte yanılıyorsunuz. Sadece akımı kapatır. driver.quit () tüm örnekleri sonlandırır. Birinin bunu sana işaret ettiğini görebiliyorum. Yorumunuz hatalarla dolu. İyi günler.
gümüş

12

Sadece içeriğe eklemek için ...

Ana pencereye geri dönmek için (varsayılan pencere).

kullanım driver.switchTo().defaultContent();


11

Bu komut dosyası, bir arta geçiş için yardımcı Veli penceresine bir etmek Çocuk pencereye Veli penceresine ve arka CNTRL

String parentWindow = driver.getWindowHandle();
Set<String> handles =  driver.getWindowHandles();
   for(String windowHandle  : handles)
       {
       if(!windowHandle.equals(parentWindow))
          {
          driver.switchTo().window(windowHandle);
         <!--Perform your operation here for new window-->
         driver.close(); //closing child window
         driver.switchTo().window(parentWindow); //cntrl to parent window
          }
       }

1
driver.close () yeni pencere için çalışacaktır. Yeni bir Sekme ise yeni sekmeyi kapatmak için kodu kullanın: driver.findElement (By.cssSelector ("body")). SendKeys (Keys.CONTROL + "w");
Ripon Al Wasim

4

Surya, iki nedenden ötürü senin yolun işe yaramayacak:

  1. aktif öğeye geçmeden önce odağı kaybedeceği için testin değerlendirilmesi sırasında sürücüyü kapatamazsınız ve NoSuchWindowException alırsınız.
  2. ChromeDriver'da test çalıştırılıyorsa, bir pencere değil, uygulamanızda tıklama sekmesi göreceksiniz. As SeleniumDriver sekmeleri ile hareket edemez , sadece yeni sekme açma ediliyor tıklama asılı, pencereler arasında switchs ve zaman aşımı çöker.

1
Sürücüdeki pencere tutamaçlarını değiştirdiğiniz ve şu anda üzerinde bulunduğunuz pencereyi kapatmak için çağırdığınızdan, aslında driver.close () çağrısını kullanabilirsiniz. Birden çok pencereyle uğraşırken kodumda düzenli olarak kullanıyorum. driver.Quit () testi sonlandıracak çağrıdır. Chromedriver'da, kullanılabilir pencerelerin listesini almak için getWindowHandles () öğesini yine de arayabilirsiniz. Bir web testinde sekme kullanmak için bir neden düşünemiyorum.
Ben

@Elmue Asıl soru, bir tıklamanın çoklu pencere kolları oluşturan ikinci bir pencere açtığını belirtti. Driver.close () çağrısını yapabilirim; ve şu anda odaklanmış penceremi yakın tut. Daha sonra seçtiğim başka bir etkin pencereye geçebilirim. driver.close () ve driver.quit () aynı işlevselliği paylaşmaz. Driver.quit () için yapılan bir çağrı, aktif sürücü örneğini, close yalnızca geçerli pencere tutamacını öldürür. Ayrıca, web sitesindeki javascript yeni bir pencere oluşturduğunda, bir tıklama çağrıldıktan sonra yalnızca bir sekme açan herhangi bir aramayı henüz görmedim.
Ben

Hatalıydım ve yorumumu sildim. Cevabınızı da silebilirsiniz.
Elmue

3

IE için kayıt defterini değiştirin:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Yazılım \ Microsoft \ Internet Explorer \ Ana
  2. Sağ tıklayın → Yeni → Dize Değeri → Değer adı: TabProcGrowth (yoksa oluşturun)
  3. TabProcGrowth (sağ tıklama) → Değiştir ... → Değer verisi: 0

Kaynak: Selenium WebDriver windows anahtarlama sorunu Internet Explorer 8-10'da

Benim durumum için, IE kayıt defteri düzenlemesinden sonra yeni pencere tutamaçları algılamaya başladı.

MSDN Blogundan Alınmıştır:

Sekme İşlemi Büyümesi: IE'nin Yeni Sekme işlemlerini oluşturma hızını ayarlar.

"Maksimum Sayı" algoritması: Bu, belirli bir zorunlu bütünlük seviyesinde (MIC) tek bir çerçeve işlemi için tek bir izolasyon oturumu için yürütülebilecek maksimum sekme işlemi sayısını belirtir. Göreli değerler şunlardır:

  • TabProcGrowth = 0: sekmeler ve çerçeveler aynı işlem içinde çalışır; çerçeveler, MIC seviyelerinde birleştirilmez.
  • TabProcGrowth = 1: belirli bir çerçeve işleminin tüm sekmeleri, belirli bir MIC düzeyi için tek bir sekme işleminde çalışır.

Kaynak: Yeni Bir Sekme Açmak, Internet Explorer 8.0 ile Yeni İşlem Başlatabilir


İnternet Seçenekleri:

  • Güvenlik → Tüm bölgeler için Korumalı Modu Etkinleştir'in işaretini kaldırın (İnternet, Yerel intranet, Güvenilen siteler, Kısıtlanmış siteler)
  • Gelişmiş → Güvenlik → Seçimi Kaldır Gelişmiş Korumalı Modu Etkinleştir

Kod:

Tarayıcı: IE11 x64 (Yakınlaştırma:% 100)
İşletim Sistemi: Windows 7 x64
Selenium: 3.5.1
WebDriver: IEDriverServer x64 3.5.1

public static String openWindow(WebDriver driver, By by) throws IOException {
String parentHandle = driver.getWindowHandle(); // Save parent window
WebElement clickableElement = driver.findElement(by);
clickableElement.click(); // Open child window
WebDriverWait wait = new WebDriverWait(driver, 10); // Timeout in 10s
boolean isChildWindowOpen = wait.until(ExpectedConditions.numberOfWindowsToBe(2));
if (isChildWindowOpen) {
    Set<String> handles = driver.getWindowHandles();
    // Switch to child window
    for (String handle : handles) {
        driver.switchTo().window(handle);
        if (!parentHandle.equals(handle)) {
            break;
        }
    }
    driver.manage().window().maximize();
}
return parentHandle; // Returns parent window if need to switch back
}



/* How to use method */
String parentHandle = Selenium.openWindow(driver, by);

// Do things in child window
driver.close();

// Return to parent window
driver.switchTo().window(parentHandle);

Yukarıdaki kod, Set<T>Java'da garantili sıralama olmadığı için ana pencereye geçmediğinizden emin olmak için bir if-check içerir . WebDriverWaitAşağıdaki ifadeyle desteklendiği üzere başarı şansını artırdığı görülmektedir.

Alıntı sahibi Luke Inman-Semerau : (Selenyum için Geliştirici)

Tarayıcının yeni pencereyi kabul etmesi zaman alabilir ve açılır pencere görünmeden önce switchTo () döngünüze düşüyor olabilirsiniz.

GetWindowHandles () tarafından döndürülen son pencerenin açılan son pencere olacağını otomatik olarak varsayarsınız. Herhangi bir sırayla iade edilmeleri garanti edilmediğinden, bu mutlaka doğru değildir.

Kaynak: IE'de bir açılır pencere işlenemiyor, denetim açılır pencereye aktarılmıyor


İlgili Mesajlar:


2

Kullanabilirsin:

driver.SwitchTo().Window(WindowName);

Burada PencereAdı, odağı değiştirmek istediğiniz pencerenin adını temsil eden bir dizedir. İşiniz bittiğinde geri dönmek için bu işlevi orijinal pencerenin adıyla tekrar çağırın.


1
Öneriniz için teşekkür ederim, herhangi bir yol var mı, pencere adı maskesini nasıl ayarlayabilirim? "WinName *" gibi, burada * - herhangi bir sembol.
Volodymyr Prysiazhniuk

1
Benim örtük olarak 10 saniye, ancak 2 saniyede bana NoSuchWindowException istisnası veriyor.
Volodymyr Prysiazhniuk

2

Çeşitli pencere tutamaçlarını saklamak için yineleyici ve bir süre döngüsü kullanıyorum ve sonra ileri geri gidiyorum.

//Click your link
driver.findElement(By.xpath("xpath")).click();
//Get all the window handles in a set
Set <String> handles =driver.getWindowHandles();
Iterator<String> it = handles.iterator();
//iterate through your windows
while (it.hasNext()){
String parent = it.next();
String newwin = it.next();
driver.switchTo().window(newwin);
//perform actions on new window
driver.close();
driver.switchTo().window(parent);
            }

Yeni sekmelere geçemiyor, ancak istenen yeni sekmede tıklama yapıyor. Neden?
paul

Bu kodun testin çok yavaş olmasına neden olmasının bir nedeni var mı? Görünüşe göre bu kod parçasından sonra newwin'de herhangi bir eylemi gerçekleştirmek yaklaşık 10 dakika sürüyor
Hugo

0
 main you can do :

 String mainTab = page.goToNewTab ();
 //do what you want
 page.backToMainPage(mainTab);  

 What you need to have in order to use the main   

        private static Set<String> windows;

            //get all open windows 
            //return current window
            public String initWindows() {
                windows = new HashSet<String>();
                driver.getWindowHandles().stream().forEach(n ->   windows.add(n));
                return driver.getWindowHandle();
            }

            public String getNewWindow() {
                List<String> newWindow = driver.getWindowHandles().stream().filter(n -> windows.contains(n) == false)
                        .collect(Collectors.toList());
                logger.info(newWindow.get(0));
                return newWindow.get(0);
            }


            public String goToNewTab() {
                String startWindow = driver.initWindows();
                driver.findElement(By.cssSelector("XX")).click();
                String newWindow = driver.getNewWindow();
                driver.switchTo().window(newWindow);
                return startWindow;
            }

            public void backToMainPage(String startWindow) {
                driver.close();
                driver.switchTo().window(startWindow);
            }

0

Dolayısıyla, bu çözümlerin çoğuyla ilgili sorun, pencerenin anında göründüğünü varsaymanızdır (hiçbir şey anında olmaz ve işler IE'de önemli ölçüde daha az anında olur). Ayrıca, öğeye tıklamadan önce yalnızca bir pencere olacağını varsayarsınız, bu her zaman böyle değildir. Ayrıca IE, pencere tutamaçlarını tahmin edilebilir bir sırada döndürmez. Bu yüzden aşağıdakileri yapardım.

 public String clickAndSwitchWindow(WebElement elementToClick, Duration 
    timeToWaitForWindowToAppear) {
    Set<String> priorHandles = _driver.getWindowHandles();

    elementToClick.click();
    try {
        new WebDriverWait(_driver,
                timeToWaitForWindowToAppear.getSeconds()).until(
                d -> {
                    Set<String> newHandles = d.getWindowHandles();
                    if (newHandles.size() > priorHandles.size()) {
                        for (String newHandle : newHandles) {
                            if (!priorHandles.contains(newHandle)) {
                                d.switchTo().window(newHandle);
                                return true;
                            }
                        }
                        return false;
                    } else {
                        return false;
                    }

                });
    } catch (Exception e) {
        Logging.log_AndFail("Encountered error while switching to new window after clicking element " + elementToClick.toString()
                + " seeing error: \n" + e.getMessage());
    }

    return _driver.getWindowHandle();
}

-1

Birden fazla tarayıcınız varsa (java 8 kullanarak)

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class TestLink {

  private static Set<String> windows;

  public static void main(String[] args) {

    WebDriver driver = new FirefoxDriver();
    driver.get("file:///C:/Users/radler/Desktop/myLink.html");
    setWindows(driver);
    driver.findElement(By.xpath("//body/a")).click();
    // get new window
    String newWindow = getWindow(driver);
    driver.switchTo().window(newWindow);

    // Perform the actions on new window
    String text = driver.findElement(By.cssSelector(".active")).getText();
    System.out.println(text);

    driver.close();
    // Switch back
    driver.switchTo().window(windows.iterator().next());


    driver.findElement(By.xpath("//body/a")).click();

  }

  private static void setWindows(WebDriver driver) {
    windows = new HashSet<String>();
    driver.getWindowHandles().stream().forEach(n -> windows.add(n));
  }

  private static String getWindow(WebDriver driver) {
    List<String> newWindow = driver.getWindowHandles().stream()
        .filter(n -> windows.contains(n) == false).collect(Collectors.toList());
    System.out.println(newWindow.get(0));
    return newWindow.get(0);
  }

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.