Làm thế nào để chuyển sang cửa sổ trình duyệt mới, sẽ mở ra sau khi nhấp vào nút?


86

Tôi có tình huống, khi nhấp vào nút sẽ mở ra cửa sổ trình duyệt mới với kết quả tìm kiếm.

Có cách nào để kết nối và tập trung vào cửa sổ trình duyệt mới mở không?

Và làm việc với nó, sau đó quay lại cửa sổ ban đầu (đầu tiên).


Chúng tôi có thể làm công tắc tự động - kiểm tra vào đây để việc sử dụng tiên tiến - testautomationguru.com/...
VIN

Câu trả lời:


117

Bạn có thể chuyển đổi giữa các cửa sổ như sau:

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

3
Tôi có thể xác nhận rằng giải pháp được chấp nhận hoạt động nhất quán trong Chrome nhưng không hoạt động trong IE. Tay cầm cửa sổ mới không được nhận dạng trong IE. @Elmue không chính xác vì getWindowHandles()trả về một Bộ và một Bộ không đảm bảo đặt hàng . Phần tử cuối cùng không phải lúc nào cũng là cửa sổ cuối cùng. Tôi rất ngạc nhiên khi bình luận của anh ấy nhận được rất nhiều lượt ủng hộ.
bạc,

@silver: Tôi không biết bạn đang nói gì. Trong mã của tôi, WindowHandles trả về một <string> ReadOnlyCollection mà tôi có thể đảm bảo rằng mục nhập cuối cùng luôn là cửa sổ được mở mới nhất. Tôi đã thử nghiệm điều đó. Nếu điều này hoạt động hoàn hảo trong C #, nhưng được triển khai sai trong Java, bạn nên báo cáo đó là lỗi.
Elmue

@Elmue Đây là một chuỗi Java. Vui lòng đọc phản hồi của Luke (nhà phát triển Selenium) về getWindowHandles(). Đó là một hành vi đã biết (không phải lỗi) của phương thức và Bộ Java <T> nói riêng. Do đó, switchTo().window(handles[handles.length-1])không được đảm bảo trong Java. Không thể xác nhận giải pháp AC # là đúng.
bạc

5
@Elmue Lần thứ 3 (và cuối cùng), câu trả lời của bạn là sai đối với Java vì được hỗ trợ bởi các tài liệu và nhà phát triển có thể MISLEAD mọi người. Đăng một câu trả lời mà bạn nói rằng đó là cho C #, không vấn đề gì. Tăng thẻ vấn đề trong GitHub cho Java, hãy tiếp tục. Đơn giản là câu trả lời của bạn không áp dụng cho ngôn ngữ ĐƯỢC GỬI trong chuỗi và mọi người có thể nghĩ khác. Nếu bạn không thể phân biệt được thì khả năng hiểu của bạn còn thiếu.
bạc

3
@Elmue Nhân tiện, bạn cũng sai khi nói driver.close () đóng cả hai cửa sổ. Nó chỉ đóng hiện tại. driver.quit () giết tất cả các phiên bản. Tôi có thể thấy ai đó đã chỉ ra điều này cho bạn. Nhận xét của bạn đầy sai lầm. Chúc bạn ngày mới tốt lành.
bạc

12

Chỉ để thêm vào nội dung ...

Để quay lại cửa sổ chính (cửa sổ mặc định).

sử dụng driver.switchTo().defaultContent();


11

Tập lệnh này giúp bạn chuyển từ cửa sổ Cha sang cửa sổ Con và quay lại cntrl thành cửa sổ Cha

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 () sẽ hoạt động cho cửa sổ mới. Nếu đó là Tab mới thì hãy sử dụng mã để đóng tab mới: driver.findElement (By.cssSelector ("body")). SendKeys (Keys.CONTROL + "w");
Ripon Al Wasim

4

Surya, cách của bạn sẽ không hiệu quả, bởi vì hai lý do:

  1. bạn không thể đóng trình điều khiển trong quá trình đánh giá thử nghiệm vì nó sẽ mất tiêu điểm , trước khi chuyển sang phần tử hoạt động và bạn sẽ nhận được NoSuchWindowException.
  2. nếu kiểm tra được chạy trên ChromeDriver, bạn sẽ không nhận được một cửa sổ, mà là tab khi nhấp vào ứng dụng của bạn. Vì SeleniumDriver không thể hoạt động với các tab , chỉ chuyển đổi giữa các cửa sổ, nó bị treo khi nhấp vào nơi tab mới đang mở và bị treo khi hết thời gian chờ.

1
Bạn thực sự có thể sử dụng lệnh gọi driver.close () vì bạn đang chuyển đổi các chốt điều khiển cửa sổ trên trình điều khiển và yêu cầu đóng cửa sổ bạn hiện đang bật. Tôi sử dụng nó thường xuyên trong mã của mình khi xử lý nhiều cửa sổ. driver.Quit () là lệnh gọi sẽ kết thúc quá trình kiểm tra. Trong Chromedriver, bạn vẫn có thể gọi getWindowHandles () để lấy danh sách các cửa sổ khả dụng của mình. Tôi không nghĩ ra lý do để sử dụng tab trong thử nghiệm web.
Ben

@Elmue Câu hỏi ban đầu cho biết rằng một cú nhấp chuột sẽ mở ra cửa sổ thứ hai tạo ra nhiều cửa sổ điều khiển. Tôi có thể thực hiện cuộc gọi driver.close (); và đóng cửa sổ của tôi hiện có tiêu điểm. Sau đó, tôi có thể chuyển sang bất kỳ cửa sổ đang hoạt động nào khác mà tôi chọn. driver.close () và driver.quit () không có cùng chức năng. Một lệnh gọi cho driver.quit () sẽ giết thể hiện trình điều khiển đang hoạt động trong khi việc đóng chỉ giết tay cầm cửa sổ hiện tại. Ngoài ra, tôi vẫn chưa thấy lệnh gọi nào chỉ mở một tab sau khi nhấp chuột được gọi khi javascript trên trang web tạo một cửa sổ mới.
Ben

Tôi đã sai và đã xóa bình luận của mình. Bạn cũng có thể xóa câu trả lời của mình.
Elmue

3

Sửa đổi sổ đăng ký cho IE:

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. Nhấp chuột phải → Mới → Giá trị chuỗi → Tên giá trị: TabProcGrowth (tạo nếu không tồn tại)
  3. TabProcGrowth (nhấp chuột phải) → Sửa đổi ... → Dữ liệu giá trị: 0

Nguồn: Sự cố chuyển đổi cửa sổ Selenium WebDriver trong Internet Explorer 8-10

Đối với trường hợp của tôi, IE bắt đầu phát hiện các xử lý cửa sổ mới sau khi chỉnh sửa sổ đăng ký.

Lấy từ Blog MSDN:

Tăng trưởng quy trình tab: Đặt tốc độ IE tạo quy trình Tab mới.

Thuật toán "Max-Number": Thuật toán này chỉ định số lượng quy trình tab tối đa có thể được thực thi cho một phiên cách ly duy nhất cho một quy trình khung đơn ở mức toàn vẹn bắt buộc cụ thể (MIC). Giá trị tương đối là:

  • TabProcGrowth = 0: các tab và khung chạy trong cùng một quá trình; khung không được thống nhất giữa các mức MIC.
  • TabProcGrowth = 1: tất cả các tab cho một quy trình khung nhất định chạy trong một quy trình tab duy nhất cho một mức MIC nhất định.

Nguồn: Mở Tab mới có thể khởi chạy Quy trình mới với Internet Explorer 8.0


Tùy chọn Internet:

  • Bảo mật → Bỏ chọn Bật Chế độ Bảo vệ cho tất cả các khu vực (Internet, Mạng nội bộ cục bộ, Trang web đáng tin cậy, Trang web bị hạn chế)
  • Nâng cao → Bảo mật → Bỏ chọn Bật Chế độ bảo vệ nâng cao

Mã:

Trình duyệt: IE11 x64 (Thu phóng: 100%)
Hệ điều hành: 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);

Đoạn mã trên bao gồm một dấu kiểm để đảm bảo rằng bạn không chuyển sang cửa sổ mẹ vì Set<T>không có thứ tự đảm bảo nào trong Java . WebDriverWaitdường như để tăng cơ hội thành công như được hỗ trợ bởi tuyên bố dưới đây.

Trích dẫn từ Luke Inman-Semerau : (Nhà phát triển cho Selenium)

Trình duyệt có thể mất thời gian để xác nhận cửa sổ mới và bạn có thể rơi vào vòng lặp switchTo () trước khi cửa sổ bật lên xuất hiện.

Bạn tự động giả định rằng cửa sổ cuối cùng do getWindowHandles () trả về sẽ là cửa sổ cuối cùng được mở. Điều đó không nhất thiết đúng, vì chúng không được đảm bảo sẽ được trả lại theo bất kỳ thứ tự nào.

Nguồn: Không thể xử lý cửa sổ bật lên trong IE, điều khiển không chuyển sang cửa sổ bật lên


Bài viết liên quan:


2

Bạn đã có thể sử dụng:

driver.SwitchTo().Window(WindowName);

Trong đó WindowName là một chuỗi đại diện cho tên của cửa sổ bạn muốn chuyển tiêu điểm sang. Gọi lại chức năng này với tên của cửa sổ ban đầu để quay lại khi bạn hoàn tất.


1
cảm ơn bạn đã gợi ý, có cách nào, làm thế nào tôi có thể đặt mặt nạ tên cửa sổ? Như "WinName *", trong đó * - bất kỳ ký hiệu nào.
Volodymyr Prysiazhniuk

1
Ngầm của tôi là 10 giây, nhưng trong 2 giây, nó mang lại cho tôi ngoại lệ NoSuchWindowException.
Volodymyr Prysiazhniuk

2

Tôi sử dụng trình vòng lặp và vòng lặp while để lưu trữ các chốt cửa sổ khác nhau và sau đó chuyển đổi qua lại.

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

Nó không thể chuyển sang tab mới, tuy nhiên nó thực hiện các nhấp chuột vào tab mới mong muốn. Tại sao?
paul

có lý do gì mã này có thể làm cho quá trình kiểm tra trở nên rất chậm không? Dường như sau khi bit này mã sẽ mất khoảng 10 phút để thực hiện bất kỳ hành động trong 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);
            }

0

Vì vậy, vấn đề với nhiều giải pháp này là bạn đang giả định rằng cửa sổ xuất hiện ngay lập tức (không có gì xảy ra ngay lập tức và mọi thứ xảy ra ngay lập tức ít hơn đáng kể trong IE). Ngoài ra, bạn đang giả định rằng sẽ chỉ có một cửa sổ trước khi nhấp vào phần tử, điều này không phải lúc nào cũng vậy. Ngoài ra IE sẽ không trả về các chốt cửa sổ theo thứ tự có thể đoán trước được. Vì vậy, tôi sẽ làm như sau.

 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

Nếu bạn có nhiều hơn thì một trình duyệt (sử dụng 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);
  }

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.