44

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,367
  • 3
  • 25
  • 33

11 Answers11

90

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]);
    });
    
John Smith
  • 7,243
  • 6
  • 49
  • 61
Sakshi Singla
  • 2,462
  • 1
  • 18
  • 34
  • `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
19

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
  • 462,703
  • 120
  • 1,088
  • 1,195
  • 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
  • 919
  • 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
  • 9,706
  • 3
  • 58
  • 62
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
1

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,752
  • 35
  • 31
  • 35
Ambitious
  • 41
  • 1
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
  • 2,028
  • 1
  • 18
  • 33
Sameera De Silva
  • 1,722
  • 1
  • 22
  • 41
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,791
  • 20
  • 14
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
  • 7,964
  • 2
  • 17
  • 40
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());
}
-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
  • 34,748
  • 11
  • 69
  • 112