39

Is there a way to physically close a tab via Protractor or WebDriver?

I ask because while I know how to switch tabs programmatically, but it does not bring the active tab to the foreground. I can't always tell what is going on in my E2E tests that run on SauceLabs because when I view the screen casts it is showing the tab that I navigated away from, not the active one.

Am I going about this incorrectly?

it('should do something in the previous tab', function(done) {
    browser.getAllWindowHandles().then(function (handles) {
        browser.switchTo().window(handles[0]);
        // do something
        expect(something).toEqual(thisThing);
        done();
    });
});
Community
  • 1
  • 1
Aaron
  • 2,177
  • 3
  • 27
  • 33

11 Answers11

84

You can try the following:

  1. Switch to the new opened tab.
  2. Close the current windows (in this case, the new tab).
  3. Switch back to the first window.

    browser.getAllWindowHandles().then(function (handles) {
    browser.driver.switchTo().window(handles[1]);
    browser.driver.close();
    browser.driver.switchTo().window(handles[0]);
    });
    
iliketocode
  • 6,978
  • 5
  • 46
  • 60
Sakshi Singla
  • 2,402
  • 1
  • 16
  • 33
  • `close()` closed the tab for me when I opened an image. However, not sure still! – Sakshi Singla Apr 08 '15 at 05:38
  • @Aaron good to know, is it working for both firefox and chrome? Thanks. – alecxe Apr 09 '15 at 18:22
  • great solution for handling multiple browser windows. Not documented on Protractor's API page (at least not that we could find today -http://www.protractortest.org/#/api?view=ProtractorBrowser ). – bob.mazzo Nov 10 '16 at 22:41
  • 1
    C# version var tabs = driver.WindowHandles; if (tabs.Count > 1) { driver.SwitchTo().Window(tabs[1]); driver.Close(); driver.SwitchTo().Window(tabs[0]); } – Mark Rowe Dec 18 '17 at 19:08
  • @MarkRowe: Is this a tested and working code? If yes, then I can edit my answer to include the C# version – Sakshi Singla Dec 19 '17 at 06:27
  • Here, I'm able to close a new tab which was opened form another tab. But when I come back to old tab, a dialog is opened there and I am not able to click on buttons of that. – Anshul Tyagi Feb 07 '18 at 07:43
  • Did you switch to that dialog to perform some actions? – Sakshi Singla Feb 08 '18 at 07:47
18

First of all, selenium does not provide a reliable cross-browser API to work with browser tabs. A common approach to open or close a tab (although not quite reliable) is to invoke browser shortcuts for Chrome:

  • open tab: CTRL/COMMAND + T
  • close tab: CTRL/COMMAND + W

In protractor, find the body element and "send keys" to it:

var body = element(by.tagName("body"));
body.sendKeys(protractor.Key.chord(protractor.Key.CONTROL, "t"))
body.sendKeys(protractor.Key.chord(protractor.Key.CONTROL, "w"))

Or, using browser.actions():

browser.actions().keyDown(protractor.Key.CONTROL).sendKeys('t').perform();
browser.actions().keyDown(protractor.Key.CONTROL).sendKeys('w').perform();

Also, to open a new tab, there is an interesting hack (introduced here), which basically injects a new a element into the page and invokes click mouse event:

function openNewTab (url) {
    return browser.driver.executeScript(function(url) {(
        function(a, url){
            document.body.appendChild(a);
            a.setAttribute('href', url);
            a.dispatchEvent((function(e){
                e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, true, false, false, false, 0, null);
                return e;
            }(document.createEvent('MouseEvents'))))
        }(document.createElement('a'), url)
    );
    }, url)
};

There is also window.close() function, but it would not close the tab if it was not opened via window.open() (reference). In other words, if this is a tab you manually open, then you can use window.open() -> window.close() approach with the help of browser.executeScript().

alecxe
  • 441,113
  • 110
  • 1,021
  • 1,148
  • using `window.open()` do you know how to open a reference to an existing tab that was previously opened using `window.open()`? I have a chrome extension running in the 2nd tab to capture HTTP headers and I can't figure out how to how to get back to that tab to check them when something breaks. – luker02 Jan 15 '16 at 22:06
5

C# Version of Sakshi's answer:

   var tabs = driver.WindowHandles;
   if (tabs.Count > 1)
   {
       driver.SwitchTo().Window(tabs[1]);
       driver.Close();
       driver.SwitchTo().Window(tabs[0]);
   }
Mark Rowe
  • 831
  • 9
  • 7
4

Close all tabs except first one and switch to first tab:

var tabs = driver.WindowHandles; // 

foreach (var tab in tabs)
{
     // "tab" is a string like "CDwindow-6E793DA3E15E2AB5D6AE36A05344C68"
     if (tabs[0] != tab) 
     {                                    
         driver.SwitchTo().Window(tab); 
         driver.Close();
     }
}

driver.SwitchTab(tabs[0]); // Switch to first tab
driver.SwitchTo().DefaultContent(); // Switch to default frame

Pay attention to last two lines, they are need to avoid such errors like OpenQA.Selenium.NoSuchWindowException: no such window: target window already closed from unknown error: web view not found

Oleg Neumyvakin
  • 8,899
  • 3
  • 52
  • 57
1

You can use driver.close and then switch to active tab driver.SwitchTo().Window(m_driver.WindowHandles.First()); or any another available tab

v_vitalik
  • 11
  • 3
0

As Sakshi Singla answered, browser.driver.close() is worked for me ,Please see the sample spec.js for a Protractor Jasmine.

describe('Window handle', function() {  
      //Each single it function is a test script
      it('Navigae to the site', function() {
        browser.driver.ignoreSynchronization = true;
        browser.waitForAngularEnabled(false);     
        browser.driver.get('http://demo.automationtesting.in/Windows.html');    

      });

      it('handle the new window', function() {
          //This will open a new popup
            element(by.buttonText('click')).click();
          var winHandles=browser.getAllWindowHandles();
          winHandles.then(function(handles) 
          {
              var parentWindow=handles[0];
              var popUpWindow=handles[1];
              browser.switchTo().window(popUpWindow);
//verify title in the new window
              expect(browser.getTitle()).toEqual('Sakinalium | Home');
              element(by.linkText('Contact')).click();
//To close the popup
               browser.driver.close();
             //verify title in the parent window
              browser.switchTo().window(parentWindow);
              expect(browser.getTitle()).toEqual('Frames & windows');             
              element(by.linkText('Open Seperate Multiple Windows')).click();
              browser.sleep(7500);
          })
          });


})
GameO7er
  • 1,838
  • 1
  • 16
  • 31
Sameera De Silva
  • 1,178
  • 15
  • 27
0

if use keyboard library with selenium its very simple for switch on tab and close or etc :

first install keyboard library :

pip install keyboard

second use keyboard for close tab in code for example :

    def change_tab_my_func(self, number):
        driver.switch_to.window(driver.window_handles[number])

    change_tab_my_func(0)   #your tab index    
    keyboard.send('ctrl+w')  
mamal
  • 1,279
  • 13
  • 11
0

You can do

await browser.executeScript('window.close()');

just don't forget to switch to the working tab

let tabs = await browser.getAllWindowHandles();
await browser.switchTo().window(tabs[0]);
Sergey Pleshakov
  • 6,574
  • 2
  • 12
  • 33
0

Since we don't know for sure, which tab is the newly opened one; if you know that the URL of your desired tab contains some unique part, you can do something like this in C#:

string uniqueURL = "your unique text in URL of the tab you want to keep";
var windowHandles = driver.WindowHandles;
if(windowHandles.Count > 1)
{
       foreach(var tab in windowHandles)
       {
              driver.SwitchTo().Window(tab);
              if(!driver.Url.Contains(uniqueURL))
              {
                    driver.Close();
              }
       }

       driver.SwitchTo().Window(driver.WindowHandles.First());
}
0

This code works fine for selenium with Java

ArrayList<String> switchTabs= new ArrayList<String> (driver.getWindowHandles());
driver.switchTo().window(switchTabs.get(1));
driver.close();
driver.switchTo().window(switchTabs.get(0));

Note: close the tabs based on your requirement

David Buck
  • 3,594
  • 33
  • 29
  • 34
Ambitious
  • 21
  • 1
-1

I am using the command below to close the current tab after opening the link in new tab

Instance.Driver2.SwitchTo().Window(Instance.Driver2.WindowHandles[1]).Close();

Then, you can switch to the last tab by issue the command:

Instance.Driver2.SwitchTo().Window(Instance.Driver2.WindowHandles[0]);
philant
  • 33,077
  • 11
  • 67
  • 110