ボタンをクリックすると開く新しいブラウザウィンドウに切り替えるにはどうすればよいですか?


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()は、Setを返し、Setは順序付けを保証しないためです。最後の要素は必ずしも最後のウィンドウではありません。彼のコメントが多くの賛成を得ていることに私は驚いています。
シルバー

@silver:あなたが何について話しているのかわかりません。私のコードでは、WindowHandlesはReadOnlyCollection <string>を返します。これにより、最後のエントリが常に最後に開いたウィンドウであることを保証できます。私はそれをテストしました。これがC#で完全に機能するが、Javaで正しく実装されていない場合は、バグとして報告する必要があります。
Elmue 2017

@ElmueこれはJavaスレッドです。に関するLuke(Selenium開発者)の回答をお読みくださいgetWindowHandles()。これは、メソッド、特にJava Set <T>の既知の動作(バグではない)です。したがって、switchTo().window(handles[handles.length-1])Javaでは保証されません。AC#ソリューションが正しいと主張することはできません。
シルバー

5
@Elmue 3回目(そして最後)は、人々を誤解させる可能性のあるドキュメントと開発者によってサポートされているように、Javaに対するあなたの答えは誤りです。C#用だと言うところに答えを投稿してください。問題ありません。GitHub for Javaで問題カードを作成し、先に進みます。単にあなたの答えはスレッドでタグ付けされた言語には当てはまらず、人々はそうではないと考えるかもしれません。区別がつかない場合は、理解力が不足しています。
シルバー

3
@Elmueちなみに、driver.close()が両方のウィンドウを閉じると言うのも間違っています。電流を閉じるだけです。driver.quit()はすべてのインスタンスを強制終了します。誰かがすでにこれをあなたに指摘しているのを見ることができます。あなたのコメントは間違いでいっぱいです。良い一日を過ごしてください。
シルバー

12

コンテンツに追加するだけです...

メインウィンドウ(デフォルトウィンドウ)に戻ります。

使用する driver.switchTo().defaultContent();


11

このスクリプトは、あなたから切り替えることができます親ウィンドウ子ウィンドウの親ウィンドウへと戻って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()は新しいウィンドウで機能します。新しいタブの場合は、次のコードを使用して新しいタブを閉じます。driver.findElement(By.cssSelector( "body"))。sendKeys(Keys.CONTROL + "w");
リポンアルワシム2016

4

スーリヤ、2つの理由であなたのやり方はうまくいきません:

  1. テストの評価中にドライバーを閉じることはできません。アクティブな要素に切り替える前にフォーカスが失われるため、NoSuchWindowExceptionが発生します。
  2. ChromeDriverでテストを実行すると、ウィンドウは表示されませんが、アプリケーションをクリックするとタブが表示されます。以下のようSeleniumDriverタブを持って行動することはできません、ウィンドウ間のみswitchsを、それが新しいタブを開くこと、およびタイムアウトにクラッシュされたクリックでハングアップします。

1
ドライバのウィンドウハンドルを切り替えて、現在閉じているウィンドウを呼び出すため、実際にはdriver.close()の呼び出しを使用できます。複数のウィンドウを扱うときは、コードで定期的に使用しています。driver.Quit()は、テストを強制終了する呼び出しです。Chromedriverでは、getWindowHandles()を呼び出して、使用可能なウィンドウのリストを取得できます。Webテストでタブを使用する理由が思いつかない。
ベン

@Elmue元の質問では、クリックすると2番目のウィンドウが開き、複数のウィンドウハンドルが作成されると述べられていました。driver.close();を呼び出すことができます。現在フォーカスがあるウィンドウを閉じます。その後、選択した他のアクティブなウィンドウに切り替えることができます。driver.close()とdriver.quit()は同じ機能を共有していません。driver.quit()を呼び出すと、アクティブなドライバーインスタンスが強制終了されますが、closeは現在のウィンドウハンドルのみを強制終了します。また、ウェブサイトのJavaScriptが新しいウィンドウを作成するときにクリックが呼び出された後にタブを開くだけの呼び出しはまだ見ていません。
ベン

私は間違っていて、コメントを削除しました。あなたもあなたの答えを削除することができます。
Elmue 2015

3

IEのレジストリを変更します。

ie_x64_tabprocgrowth.png

  1. HKEY_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main
  2. 右クリック→新規→文字列値→値名:TabProcGrowth(存在しない場合は作成)
  3. TabProcGrowth(右クリック)→変更...→値データ:0

出典: Internet Explorer8-10でのSeleniumWebDriverウィンドウの切り替えの問題

私の場合、IEはレジストリの編集後に新しいウィンドウハンドルの検出を開始しました。

MSDNブログからの抜粋:

タブプロセスの増加: IEが新しいタブプロセスを作成する速度を設定します。

「Max-Number」アルゴリズム:これは、特定の必須整合性レベル(MIC)で、単一フレームプロセスの単一分離セッションに対して実行できるタブプロセスの最大数を指定します。相対値は次のとおりです。

  • TabProcGrowth = 0:タブとフレームは同じプロセス内で実行されます。フレームはMICレベル間で統合されていません。
  • TabProcGrowth = 1:特定のフレームプロセスのすべてのタブは、特定のMICレベルの単一のタブプロセスで実行されます。

出典: 新しいタブを開くと、Internet Explorer8.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チェックが含まれていますWebDriverWait以下のステートメントでサポートされているように、成功の可能性が高まるようです。

Luke Inman-Semerauからの引用:(Seleniumの開発者)

ブラウザが新しいウィンドウを確認するのに時間がかかる場合があり、ポップアップウィンドウが表示される前にswitchTo()ループに陥っている可能性があります。

getWindowHandles()によって返される最後のウィンドウが、最後に開かれたウィンドウであると自動的に想定します。それらは任意の順序で返されることが保証されていないため、必ずしもそうとは限りません。

ソース: IEでポップアップを処理できません、コントロールがポップアップウィンドウに転送されていません


関連記事:


2

あなたが使用することができます:

driver.SwitchTo().Window(WindowName);

WindowNameは、フォーカスを切り替えるウィンドウの名前を表す文字列です。元のウィンドウの名前を使用してこの関数を再度呼び出し、完了したら元のウィンドウに戻ります。


1
提案ありがとうございます、ウィンドウ名マスクを設定する方法はありますか?「WinName *」のように、ここで*-任意の記号。
Volodymyr Prysiazhniuk 2012年

1
私は暗黙的に10秒ですが、2秒で例外NoSuchWindowExceptionが発生します。
Volodymyr Prysiazhniuk 2012年

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

新しいタブへの切り替えに失敗していますが、目的の新しいタブをクリックします。どうして?
ポール2014年

このコードによってテストが非常に遅くなる理由はありますか?このコードの後、newwinでアクションを実行するのに約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では、すぐには何も起こらず、すぐには発生しません)。また、要素をクリックする前にウィンドウが1つだけであると想定していますが、常にそうであるとは限りません。また、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.