Bagaimana cara beralih ke jendela browser baru, yang terbuka setelah mengklik tombol?

86

Saya punya situasi, ketika mengklik tombol membuka jendela browser baru dengan hasil pencarian.

Apakah ada cara untuk menghubungkan dan fokus ke jendela browser yang baru dibuka?

Dan bekerja dengannya, lalu kembali ke jendela asli (pertama).

Volodymyr Prysiazhniuk
sumber
Kami dapat melakukan peralihan secara otomatis - periksa di sini untuk penggunaan lanjutan - testautomationguru.com/…
vins

Jawaban:

118

Anda dapat beralih antar jendela seperti di bawah ini:

// 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)
Surya
sumber
4
Saya dapat mengonfirmasi bahwa solusi yang diterima berfungsi secara konsisten di Chrome tetapi tidak di IE. Tuas jendela baru tidak dikenali di IE. @Elmue salah karena getWindowHandles()mengembalikan Set dan Set tidak menjamin pengurutan . Elemen terakhir tidak selalu merupakan jendela terakhir. Saya terkejut komentarnya mendapat banyak upvote.
perak
@ Perak: Saya tidak tahu apa yang Anda bicarakan. Dalam kode saya, WindowHandles mengembalikan <string> ReadOnlyCollection yang dapat saya jamin bahwa entri terakhir selalu merupakan jendela terbaru yang dibuka. Saya mengujinya. Jika ini bekerja dengan sempurna di C #, tetapi diterapkan secara salah di Java, Anda harus melaporkannya sebagai bug.
Elmue
1
@Elmue Ini adalah utas Java. Silakan baca tanggapan Luke (pengembang Selenium) tentang getWindowHandles(). Ini adalah perilaku yang diketahui (bukan bug) dari metode ini dan Java Set <T> pada khususnya. Oleh karena itu, switchTo().window(handles[handles.length-1])tidak dijamin di Jawa. Solusi AC # tidak dapat diklaim sebagai benar.
perak
6
@Elmue Untuk ketiga kalinya (dan terakhir), jawaban Anda salah untuk Java karena didukung oleh docs dan dev yang dapat MENYESATKAN orang. Posting jawaban yang Anda katakan untuk C #, tidak masalah. Angkat kartu masalah di GitHub untuk Java, lanjutkan. Jawaban Anda tidak dapat diterapkan untuk bahasa TAGGED di utas dan orang mungkin berpikir sebaliknya. Jika Anda tidak dapat membuat perbedaan, pemahaman Anda kurang.
perak
3
@Elmue Ngomong-ngomong, Anda juga salah mengatakan driver.close () menutup kedua jendela. Itu hanya menutup arus. driver.quit () membunuh semua instance. Saya dapat melihat seseorang telah menunjukkan hal ini kepada Anda. Komentar Anda penuh dengan kesalahan. Semoga harimu menyenangkan.
perak
12

Hanya untuk menambah konten ...

Untuk kembali ke jendela utama (jendela default).

menggunakan driver.switchTo().defaultContent();

Amarnath Rayudu
sumber
11

Script ini membantu Anda untuk beralih dari jendela Parent ke jendela Child dan kembali cntrl ke jendela Parent

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
          }
       }
Prashanth Sams
sumber
1
driver.close () akan berfungsi untuk jendela baru. Jika Tab baru, gunakan kode untuk menutup tab baru: driver.findElement (By.cssSelector ("body")). SendKeys (Keys.CONTROL + "w");
Ripon Al Wasim
4

Surya, caramu tidak akan berhasil, karena dua alasan:

  1. Anda tidak dapat menutup driver selama evaluasi pengujian karena akan kehilangan fokus , sebelum beralih ke elemen aktif, dan Anda akan mendapatkan NoSuchWindowException.
  2. jika tes dijalankan di ChromeDriver Anda `tidak akan mendapatkan jendela, tetapi tab saat diklik di aplikasi Anda. Karena SeleniumDriver tidak dapat bertindak dengan tab , hanya beralih di antara jendela, itu macet saat diklik di mana tab baru sedang dibuka, dan macet saat waktu tunggu.
Invy
sumber
1
Anda sebenarnya dapat menggunakan panggilan untuk driver.close () karena Anda mengalihkan pegangan jendela pada driver dan memanggil jendela yang saat ini Anda tutup. Saya menggunakannya secara teratur dalam kode saya saat menangani banyak jendela. driver.Quit () adalah panggilan yang akan menghentikan pengujian. Di Chromedriver, Anda masih dapat memanggil getWindowHandles () untuk mendapatkan daftar jendela yang tersedia. Saya tidak dapat memikirkan alasan untuk menggunakan tab dalam pengujian web.
Ben
@Elmue Pertanyaan asli menyatakan bahwa klik membuka jendela kedua dan membuat banyak pegangan jendela. Saya bisa melakukan panggilan driver.close (); dan tutup jendela saya yang saat ini fokus. Saya kemudian dapat beralih ke jendela aktif lain yang saya pilih. driver.close () dan driver.quit () tidak memiliki fungsi yang sama. Panggilan untuk driver.quit () akan mematikan instance driver yang aktif sedangkan close hanya membunuh pegangan jendela saat ini. Selain itu, saya belum melihat panggilan apa pun yang hanya membuka tab setelah klik dipanggil saat javascript di situs web membuat jendela baru.
Ben
Saya salah dan menghapus komentar saya. Anda juga dapat menghapus jawaban Anda.
Elmue
3

Ubah registri untuk IE:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. Klik kanan → Baru → Nilai String → Nama nilai: TabProcGrowth (buat jika tidak ada)
  3. TabProcGrowth (klik kanan) → Modify ... → Value data: 0

Sumber: Masalah peralihan jendela Selenium WebDriver di Internet Explorer 8-10

Untuk kasus saya, IE mulai mendeteksi jendela baru menangani setelah mengedit registri.

Diambil dari Blog MSDN:

Pertumbuhan Proses Tab: Menyetel tingkat di mana IE membuat proses Tab Baru.

Algoritme "Max-Number": Ini menentukan jumlah maksimum proses tab yang dapat dijalankan untuk sesi isolasi tunggal untuk proses bingkai tunggal pada tingkat integritas wajib tertentu (MIC). Nilai relatifnya adalah:

  • TabProcGrowth = 0: tab dan bingkai berjalan dalam proses yang sama; bingkai tidak disatukan di seluruh level MIC.
  • TabProcGrowth = 1: semua tab untuk proses bingkai tertentu berjalan dalam satu proses tab untuk level MIC tertentu.

Sumber: Membuka Tab Baru dapat meluncurkan Proses Baru dengan Internet Explorer 8.0


Pilihan internet:

  • Keamanan → Hapus centang Aktifkan Mode Terproteksi untuk semua zona (Internet, Intranet lokal, Situs terpercaya, Situs Terbatas)
  • Lanjutan → Keamanan → Hapus centang Aktifkan Mode Terlindungi yang Ditingkatkan

Kode:

Browser: IE11 x64 (Zoom: 100%)
OS: 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);

Kode di atas menyertakan if-check untuk memastikan Anda tidak beralih ke jendela induk karena Set<T>tidak ada jaminan pemesanan di Java . WebDriverWaittampaknya meningkatkan peluang sukses seperti yang didukung oleh pernyataan di bawah ini.

Dikutip dari Luke Inman-Semerau : (Pengembang untuk Selenium)

Browser mungkin memerlukan waktu untuk menerima jendela baru, dan Anda mungkin masuk ke loop switchTo () sebelum jendela popup muncul.

Anda secara otomatis berasumsi bahwa jendela terakhir yang dikembalikan oleh getWindowHandles () akan menjadi yang terakhir dibuka. Itu belum tentu benar, karena tidak dijamin akan dikembalikan dalam urutan apa pun.

Sumber: Tidak dapat menangani popup di IE, kontrol tidak mentransfer ke jendela popup


Posting terkait:

perak
sumber
2

Anda bisa menggunakan:

driver.SwitchTo().Window(WindowName);

Di mana WindowName adalah string yang mewakili nama jendela yang ingin Anda alihkan fokusnya. Panggil fungsi ini lagi dengan nama jendela asli untuk kembali ke fungsi ini setelah Anda selesai.

Breeze 91
sumber
1
terima kasih atas sarannya, adakah cara, bagaimana saya bisa mengatur window name mask? Seperti "WinName *", di mana * - simbol apa saja.
Volodymyr Prysiazhniuk
1
Saya secara implisit adalah 10 detik, tetapi dalam 2 detik itu memberi saya pengecualian NoSuchWindowException.
Volodymyr Prysiazhniuk
2

Saya menggunakan iterator dan while loop untuk menyimpan berbagai pegangan jendela dan kemudian beralih bolak-balik.

//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);
            }
StatusQuo
sumber
Itu gagal untuk beralih ke tab baru, namun itu melakukan klik pada tab baru yang diinginkan. Mengapa?
paul
adakah alasan kode ini dapat menyebabkan pengujian menjadi sangat lambat? Tampaknya setelah sedikit kode ini dibutuhkan sekitar 10 menit untuk melakukan tindakan apa pun di newwin
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);
            }
Ran Adler
sumber
0

Jadi masalah dengan banyak solusi ini adalah Anda mengasumsikan jendela muncul secara instan (tidak ada yang terjadi secara instan, dan hal-hal terjadi secara signifikan lebih sedikit di IE). Juga Anda berasumsi bahwa hanya akan ada satu jendela sebelum mengklik elemen, yang tidak selalu terjadi. Juga IE tidak akan mengembalikan pegangan jendela dalam urutan yang dapat diprediksi. Jadi saya akan melakukan hal berikut.

 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();
}
Dominic Giallombardo
sumber
-1

Jika Anda memiliki lebih dari satu browser (menggunakan java 8)

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

}
Ran Adler
sumber