JavaでのSelenium WebDriverの使用。新しいタブを開いてそこで操作を行い、前のタブ(親)に戻る機能を自動化しようとしています。スイッチハンドルを使用しましたが、機能しません。そして、2つのタブが同じウィンドウハンドルを持っているため、タブを切り替えることができないため、奇妙なことです。
ただし、別のFirefoxウィンドウで試しているときは動作しますが、タブでは動作しません。
タブを切り替える方法を教えてください。 OR私の場合、ウィンドウハンドルは両方のタブと同じなので、ウィンドウハンドルを使用せずにタブを切り替えるにはどうすればよいですか。
(同じウィンドウで異なるタブを開いても、ウィンドウハンドルは同じままであることに気付きました)
psdbComponent.clickDocumentLink();
ArrayList<String> tabs2 = new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(tabs2.get(1));
driver.close();
driver.switchTo().window(tabs2.get(0));
このコードは完璧に機能しました。やってみて。新しいタブで何かをする前に、常にドライバーを新しいタブに切り替える必要があります。
これは、新しいタブを開いてフォーカスを変更し、タブを閉じて古いタブまたは元のタブにフォーカスを戻すための簡単なソリューションです。
@Test
public void testTabs() {
driver.get("https://business.Twitter.com/start-advertising");
assertStartAdvertising();
// considering that there is only one tab opened in that point.
String oldTab = driver.getWindowHandle();
driver.findElement(By.linkText("Twitter Advertising Blog")).click();
ArrayList<String> newTab = new ArrayList<String>(driver.getWindowHandles());
newTab.remove(oldTab);
// change focus to new tab
driver.switchTo().window(newTab.get(0));
assertAdvertisingBlog();
// Do what you want here, you are in the new tab
driver.close();
// change focus back to old tab
driver.switchTo().window(oldTab);
assertStartAdvertising();
// Do what you want here, you are in the old tab
}
private void assertStartAdvertising() {
assertEquals("Start Advertising | Twitter for Business", driver.getTitle());
}
private void assertAdvertisingBlog() {
assertEquals("Twitter Advertising", driver.getTitle());
}
Webドライバーがさまざまなウィンドウを処理する方法と、さまざまなタブを処理する方法に違いがあります。
ケース1:
複数のウィンドウがある場合、次のコードが役立ちます。
//Get the current window handle
String windowHandle = driver.getWindowHandle();
//Get the list of window handles
ArrayList tabs = new ArrayList (driver.getWindowHandles());
System.out.println(tabs.size());
//Use the list of window handles to switch between windows
driver.switchTo().window(tabs.get(0));
//Switch back to original window
driver.switchTo().window(mainWindowHandle);
ケース2:
同じウィンドウに複数のタブがある場合、ウィンドウハンドルは1つだけです。したがって、ウィンドウハンドルを切り替えると、コントロールは同じタブに保持されます。
この場合、Ctrl +\t(Ctrl + Tab)を使用してタブを切り替えるのがより便利です。
//Open a new tab using Ctrl + t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"t");
//Switch between tabs using Ctrl + \t
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL +"\t");
詳細なサンプルコードは次の場所にあります。
http://design-interviews.blogspot.com/2014/11/switching-between-tabs-in-same-browser-window.html
回避策
Assumption:Webページ上で何かをクリックすると、新しいタブが開きます。
以下のロジックを使用して、2番目のタブに切り替えます。
new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD2).build().perform();
同じ方法で、最初のタブに再び切り替えることができます。
new Actions(driver).sendKeys(driver.findElement(By.tagName("html")), Keys.CONTROL).sendKeys(driver.findElement(By.tagName("html")),Keys.NUMPAD1).build().perform();
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL, Keys.RETURN);
WebElement e = driver.findElement(By
.xpath("html/body/header/div/div[1]/nav/a"));
e.sendKeys(selectLinkOpeninNewTab);//to open the link in a current page in to the browsers new tab
e.sendKeys(Keys.CONTROL + "\t");//to move focus to next tab in same browser
try {
Thread.sleep(8000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//to wait some time in that tab
e.sendKeys(Keys.CONTROL + "\t");//to switch the focus to old tab again
お役に立てば幸いです。
最初に行う必要があるのは、新しいタブを開いてハンドル名を保存することです。キーはオートメーションサーバーで常に使用できるとは限らないため、keys(ctrl + t)ではなくjavascriptを使用して行うことをお勧めします。例:
public static String openNewTab(String url) {
executeJavaScript("window.parent = window.open('parent');");
ArrayList<String> tabs = new ArrayList<String>(bot.driver.getWindowHandles());
String handleName = tabs.get(1);
bot.driver.switchTo().window(handleName);
System.setProperty("current.window.handle", handleName);
bot.driver.get(url);
return handleName;
}
次に行う必要があるのは、タブを切り替えることです。スイッチウィンドウハンドルのみで行うと、作業するタブが常にフォーカスされているとは限らず、Seleniumが時々失敗するため、常に機能するとは限りません。私が言ったように、キーを使用することは少し問題があり、javascriptはタブの切り替えを実際にサポートしていないので、タブを切り替えるためにアラートを使用し、魅力のように機能しました:
public static void switchTab(int tabNumber, String handleName) {
driver.switchTo().window(handleName);
System.setProperty("current.window.handle", handleName);
if (tabNumber==1)
executeJavaScript("alert(\"alert\");");
else
executeJavaScript("parent.alert(\"alert\");");
bot.wait(1000);
driver.switchTo().alert().accept();
}
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL,Keys.SHIFT,Keys.TAB);
この方法は、複数のウィンドウを切り替えるのに役立ちます。この方法の制限的な問題は、必要なウィンドウに達するまで何度もしか使用できないことです。それが役に立てば幸い。
JavaでWebDriverとしてfirefox 47.0.1を使用するSelenium 2.53.1では、開いたタブの数に関係なく、「driver.getWindowHandles()」は1つのハンドルのみを返すため、タブを切り替えることはできませんでした。
Chrome 51.0の使用を開始すると、すべてのハンドルを取得できました。次のコードは、複数のドライバーと各ドライバー内の複数のタブにアクセスする方法を示しています。
// INITIALIZE TWO DRIVERS (THESE REPRESENT SEPARATE CHROME WINDOWS)
driver1 = new ChromeDriver();
driver2 = new ChromeDriver();
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver1.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs1 = new ArrayList<String> (driver1.getWindowHandles());
// REPEAT FOR THE SECOND DRIVER (SECOND CHROME BROWSER WINDOW)
// LOOP TO OPEN AS MANY TABS AS YOU WISH
for(int i = 0; i < TAB_NUMBER; i++) {
driver2.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
// SLEEP FOR SPLIT SECOND TO ALLOW DRIVER TIME TO OPEN TAB
Thread.sleep(100);
// STORE TAB HANDLES IN ARRAY LIST FOR EASY ACCESS
ArrayList tabs2 = new ArrayList<String> (driver1.getWindowHandles());
// NOW PERFORM DESIRED TASKS WITH FIRST BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
driver1.switchTo().window(tabs1.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
// PERFORM DESIRED TASKS WITH SECOND BROWSER IN ANY TAB
for(int ii = 0; ii <= TAB_NUMBER; ii++) {
drvier2.switchTo().window(tabs2.get(ii));
// LOGIC FOR THAT DRIVER'S CURRENT TAB
}
複数のブラウザウィンドウで複数のタブを操作する方法の良いアイデアが得られれば幸いです。
私のために働いた簡単な答え:
for (String handle1 : driver1.getWindowHandles()) {
System.out.println(handle1);
driver1.switchTo().window(handle1);
}
driver.window_handles
が順番になっていないため、より良い解決策はこれです。
最初に、ショートカット
Control + X
を使用して最初のタブに切り替え、ブラウザウィンドウの 'x'番目のタブに切り替えます。
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "1");
# goes to 1st tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "4");
# goes to 4th tab if its exists or goes to last tab.
パブリッククラスTabBrowserDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("Main Started");
System.setProperty("webdriver.gecko.driver", "driver//geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.irctc.co.in/eticketing/userSignUp.jsf");
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.findElement(By.xpath("//a[text()='Flights']")).click();
waitForLoad(driver);
Set<String> ids = driver.getWindowHandles();
Iterator<String> iterator = ids.iterator();
String parentID = iterator.next();
System.out.println("Parent WIn id " + parentID);
String childID = iterator.next();
System.out.println("child win id " + childID);
driver.switchTo().window(childID);
List<WebElement> hyperlinks = driver.findElements(By.xpath("//a"));
System.out.println("Total links in tabbed browser " + hyperlinks.size());
Thread.sleep(3000);
// driver.close();
driver.switchTo().window(parentID);
List<WebElement> hyperlinksOfParent = driver.findElements(By.xpath("//a"));
System.out.println("Total links " + hyperlinksOfParent.size());
}
public static void waitForLoad(WebDriver driver) {
ExpectedCondition<Boolean> pageLoadCondition = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(pageLoadCondition);
}
下記を参照してください:
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.get("https://www.irctc.co.in/");
String oldTab = driver.getWindowHandle();
//For opening window in New Tab
String selectLinkOpeninNewTab = Keys.chord(Keys.CONTROL,Keys.RETURN);
driver.findElement(By.linkText("Hotels & Lounge")).sendKeys(selectLinkOpeninNewTab);
// Perform Ctrl + Tab to focus on new Tab window
new Actions(driver).sendKeys(Keys.chord(Keys.CONTROL, Keys.TAB)).perform();
// Switch driver control to focused tab window
driver.switchTo().window(oldTab);
driver.findElement(By.id("textfield")).sendKeys("bangalore");
これが役立つことを願っています!
選択された答えの欠点は、webDriver.getWindowHandles()
の順序を不必要に想定していることです。 getWindowHandles()
メソッドはSet
を返しますが、これは順序を保証しません。
次のコードを使用してタブを変更しましたが、タブは順序付けを想定していません。
String currentTabHandle = driver.getWindowHandle();
String newTabHandle = driver.getWindowHandles()
.stream()
.filter(handle -> !handle.equals(currentTabHandle ))
.findFirst()
.get();
driver.switchTo().window(newTabHandle);
これは、MacOS for FirefoxおよびChromeで機能します。
// opens the default browser tab with the first webpage
driver.get("the url 1");
thread.sleep(2000);
// opens the second tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND + "t");
driver.get("the url 2");
Thread.sleep(2000);
// comes back to the first tab
driver.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND, Keys.SHIFT, "{");
最近問題が発生し、リンクが新しいタブで開かれましたが、Seleniumは最初のタブに焦点を合わせていました。
Chromedriverを使用していますが、タブに注目する唯一の方法はswitch_to_window()
を使用することでした。
Pythonコードは次のとおりです。
driver.switch_to_window(driver.window_handles[-1])
したがって、ヒントは必要なウィンドウハンドルの名前を見つけることです。
driver.window_handles
親ウィンドウのハンドルを取得します。
String parentHandle = driverObj.getWindowHandle();
public String switchTab(String parentHandle){
String currentHandle ="";
Set<String> win = ts.getDriver().getWindowHandles();
Iterator<String> it = win.iterator();
if(win.size() > 1){
while(it.hasNext()){
String handle = it.next();
if (!handle.equalsIgnoreCase(parentHandle)){
ts.getDriver().switchTo().window(handle);
currentHandle = handle;
}
}
}
else{
System.out.println("Unable to switch");
}
return currentHandle;
}
これは非常に簡単なプロセスです。2つのタブがあり、client.window(callback)
を使用して現在のタブを閉じる必要があると仮定します。切り替えコマンドは「最初に使用可能なタブに切り替えます」。その後、client.switchTab
を使用してタブを簡単に切り替えることができます。
ブラウザでタブを切り替える方法の簡単な例(ウィンドウが1つの場合):
// open the first tab
driver.get("https://www.google.com");
Thread.sleep(2000);
// open the second tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "t");
driver.get("https://www.google.com");
Thread.sleep(2000);
// switch to the previous tab
driver.findElement(By.cssSelector("body")).sendKeys(Keys.CONTROL + "" + Keys.SHIFT + "" + Keys.TAB);
Thread.sleep(2000);
タブ間の切り替えを確認するためにタイムアウトを設定するためだけにThread.sleep(2000)
と書いています。
Ctrl + Tabキーを使用して次のタブに切り替え、Ctrl + Shift + Tabキーを使用して前のタブに切り替えることができます。
protected void switchTabsUsingPartOfUrl(String platform) {
String currentHandle = null;
try {
final Set<String> handles = driver.getWindowHandles();
if (handles.size() > 1) {
currentHandle = driver.getWindowHandle();
}
if (currentHandle != null) {
for (final String handle : handles) {
driver.switchTo().window(handle);
if (currentUrl().contains(platform) && !currentHandle.equals(handle)) {
break;
}
}
} else {
for (final String handle : handles) {
driver.switchTo().window(handle);
if (currentUrl().contains(platform)) {
break;
}
}
}
} catch (Exception e) {
System.out.println("Switching tabs failed");
}
}
このメソッドを呼び出して、切り替え先のタブのurlのサブストリングをパラメーターに渡します