버튼을 클릭하면 열리는 새 브라우저 창으로 전환하는 방법은 무엇입니까?


86

버튼을 클릭하면 검색 결과와 함께 새 브라우저 창이 열립니다.

새로 열린 브라우저 창에 연결하고 초점을 맞추는 방법이 있습니까?

그리고 그것으로 작업 한 다음 원래 (첫 번째) 창으로 돌아갑니다.


자동으로 전환 할 수 있습니다. 고급 사용법은 여기에서 확인하세요. testautomationguru.com/…
vins

답변:


117

아래와 같이 창을 전환 할 수 있습니다.

// 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
수락 된 솔루션이 Chrome에서는 일관되게 작동하지만 IE에서는 작동하지 않음을 확인할 수 있습니다. 새 창 핸들은 IE에서 인식되지 않습니다. @Elmue는 getWindowHandles()세트를 반환 하고 세트는 주문을 보장하지 않기 때문에 올바르지 않습니다 . 마지막 요소가 항상 마지막 창이되는 것은 아닙니다. 그의 댓글이 많은 찬성표를 얻은 것에 놀랐습니다.
은색

@silver : 무슨 말을하는지 모르겠네요. 내 코드에서 WindowHandles는 마지막 항목이 항상 가장 최근에 열린 창임을 보장 할 수있는 ReadOnlyCollection <string>을 반환합니다. 나는 그것을 테스트했다. 이것이 C #에서 완벽하게 작동하지만 Java에서 잘못 구현 된 경우 버그로보고해야합니다.
Elmue

@Elmue 이것은 Java 스레드입니다. 에 관한 Luke의 (Selenium 개발자) 응답을 읽어보십시오 getWindowHandles(). 이는 특히 Java Set <T> 메서드와 알려진 동작 (버그가 아님)입니다. 따라서 switchTo().window(handles[handles.length-1])Java에서는 보장되지 않습니다. AC # 솔루션이 정확하다고 주장 할 수 없습니다.
은색

5
@Elmue 세 번째 (그리고 마지막) 시간 동안, 당신의 대답은 사람들을 MISLEAD 할 수있는 문서 및 개발자가 지원하는 Java에 대해 거짓 입니다. C #에 대한 답변을 게시하십시오. 문제 없습니다. Java 용 GitHub에서 문제 카드를 올리십시오. 단순히 귀하의 답변은 스레드의 TAGGED 언어에 적용되지 않으며 사람들은 다르게 생각할 수 있습니다. 구별 할 수 없다면 이해력이 부족한 것입니다.
은색

3
@Elmue 그런데 driver.close ()가 두 창을 모두 닫는다는 것도 틀 렸습니다. 전류 만 닫습니다. driver.quit ()는 모든 인스턴스를 종료합니다. 누군가 이미 당신에게 이것을 지적한 것을 볼 수 있습니다. 귀하의 의견은 실수로 가득 차 있습니다. 좋은 하루 되세요.
은색

12

내용에 추가하기 위해 ...

기본 창 (기본 창)으로 돌아갑니다.

사용하다 driver.switchTo().defaultContent();


11

이 스크립트는 부모 창 에서 자식 창으로 전환 하고 다시 부모 창 으로 전환하는 데 도움이됩니다.

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 ()는 새 창에서 작동합니다. 새 탭인 경우 코드를 사용하여 새 탭을 닫습니다. driver.findElement (By.cssSelector ( "body")). sendKeys (Keys.CONTROL + "w");
Ripon Al Wasim

4

Surya, 당신의 방식은 두 가지 이유로 작동하지 않습니다.

  1. 활성 요소로 전환하기 전에 포커스가 풀리므로 테스트 평가 중에 드라이버를 닫을 수 없으며 NoSuchWindowException이 발생합니다.
  2. ChromeDriver에서 테스트를 실행하면 창이 표시되지 않고 애플리케이션에서 탭을 클릭합니다. 으로 SeleniumDriver가 탭으로 작동 할 수 없습니다 만이 새 탭이 개방되고있는 클릭에 달려, 창 사이를 switchs 및 시간 제한에 충돌합니다.

1
드라이버의 창 핸들을 전환하고 현재 닫을 창을 호출하기 때문에 실제로 driver.close () 호출을 사용할 수 있습니다. 여러 창을 다룰 때 내 코드에서 정기적으로 사용합니다. driver.Quit ()는 테스트를 종료 할 호출입니다. Chromedriver에서 여전히 getWindowHandles ()를 호출하여 사용 가능한 창 목록을 가져올 수 있습니다. 웹 테스트에서 탭을 사용하는 이유를 생각할 수 없습니다.
Ben

@Elmue 원래 질문은 클릭 한 번으로 여러 창 핸들을 만드는 두 번째 창이 열립니다. 나는 driver.close (); 호출을 할 수있다. 현재 포커스가있는 창을 닫습니다. 그런 다음 내가 선택한 다른 활성 창으로 전환 할 수 있습니다. driver.close () 및 driver.quit ()는 동일한 기능을 공유하지 않습니다. driver.quit ()에 대한 호출은 활성 드라이버 인스턴스를 종료하는 반면 close는 현재 창 핸들 만 종료합니다. 또한 웹 사이트의 javascript가 새 창을 만들 때 클릭이 호출 된 후에 만 ​​탭을 여는 호출을 아직 보지 못했습니다.
Ben

내가 틀렸고 내 댓글을 삭제했습니다. 답변을 삭제할 수도 있습니다.
Elmue

3

IE의 레지스트리 수정 :

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. 마우스 오른쪽 버튼 클릭 → 새로 만들기 → 문자열 값 → 값 이름 : TabProcGrowth (존재하지 않는 경우 생성)
  3. TabProcGrowth (오른쪽 클릭) → 수정 ... → 값 데이터 : 0

출처 : Internet Explorer 8-10에서 Selenium WebDriver 창 전환 문제

필자의 경우 IE는 레지스트리 편집 후 새 창 핸들을 감지하기 시작했습니다.

MSDN 블로그에서 발췌 :

탭 프로세스 증가 : IE가 새 탭 프로세스를 생성하는 속도를 설정합니다.

"Max-Number"알고리즘 : 특정 MIC (필수 무결성 수준)에서 단일 프레임 프로세스에 대한 단일 격리 세션에 대해 실행될 수있는 최대 탭 프로세스 수를 지정합니다. 상대 값은 다음과 같습니다.

  • TabProcGrowth = 0 : 탭과 프레임이 동일한 프로세스 내에서 실행됩니다. 프레임은 MIC 수준에서 통합되지 않습니다.
  • TabProcGrowth = 1 : 주어진 프레임 프로세스에 대한 모든 탭은 주어진 MIC 레벨에 대해 단일 탭 프로세스에서 실행됩니다.

출처 : 새 탭을 열면 Internet Explorer 8.0에서 새 프로세스가 시작될 수 있습니다.


인터넷 옵션:

  • 보안 → 모든 영역 (인터넷, 로컬 인트라넷, 신뢰할 수있는 사이트, 제한된 사이트)에 대해 보호 모드 활성화 선택 해제
  • 고급 → 보안 → 강화 된 보호 모드 활성화 선택 해제

암호:

브라우저 : IE11 x64 (줌 : 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);

위의 코드에는 Set<T>Java에서 보장 된 순서가 없으므로 부모 창으로 전환하지 않는지 확인하는 if-check가 포함되어 있습니다. WebDriverWait아래 진술에서 뒷받침하는 성공 가능성을 높이는 것으로 보입니다.

Luke Inman-Semerau 인용 : (Selenium 개발자)

브라우저가 새 창을 확인하는 데 시간이 걸릴 수 있으며 팝업 창이 나타나기 전에 switchTo () 루프에 빠질 수 있습니다.

getWindowHandles ()에 의해 반환 된 마지막 창이 마지막으로 열린 창이 자동으로 가정합니다. 어떤 순서로든 반품이 보장되지 않으므로 반드시 사실은 아닙니다.

Source : Unable to handle a popup in IE, control is not transfer to popup window


관련 게시물:


2

다음을 사용할 수 있습니다.

driver.SwitchTo().Window(WindowName);

여기서 WindowName은 포커스를 전환 할 창의 이름을 나타내는 문자열입니다. 작업을 마치면 원래 창의 이름으로이 함수를 다시 호출하여 다시 돌아옵니다.


1
제안 해주셔서 감사합니다. 방법은 없나요, 어떻게 창 이름 마스크를 설정할 수 있습니까? "WinName *"과 같이 *-모든 기호.
볼로디미르 Prysiazhniuk

1
내 암시 적으로 10 초이지만 2 초 안에 NoSuchWindowException 예외가 발생합니다.
Volodymyr Prysiazhniuk

2

반복기와 while 루프를 사용하여 다양한 창 핸들을 저장 한 다음 앞뒤로 전환합니다.

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

새 탭으로 전환하지 못하지만 원하는 새 탭을 클릭합니다. 왜?
paul

이 코드로 인해 테스트가 매우 느려지는 이유가 있습니까? 이 코드 이후에 새로운 작업을 수행하는 데 약 10 분이 소요되는 것 같습니다
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

따라서 이러한 솔루션의 많은 문제는 창이 즉시 표시된다고 가정한다는 것입니다 (즉시 발생하는 것은 없으며 IE에서는 즉시 발생하는 것이 훨씬 적습니다). 또한 요소를 클릭하기 전에 하나의 창이 있다고 가정합니다. 항상 그런 것은 아닙니다. 또한 IE는 예측 가능한 순서로 창 핸들을 반환하지 않습니다. 그래서 나는 다음을 할 것입니다.

 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

브라우저가 두 개 이상인 경우 (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);
  }

}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.