Search code examples
javascriptnode.jscookiessingle-sign-onwebdriver-io

Webdriver.IO Dealing with Single Sign On cookies


I'm creating some node.js webdriverio tests. When I connect to any of my sites, there's a check for the presence of a ssosession cookie (among others) to confirm user has access to the page. If it's not there, the browser immediately redirects to our login page. I need to capture the resulting cookies from a successful login and use them to load the pages I want to test.

In curl, I do that like this:

curl -H"Content-type: application/json" --user-agent "MyTestAgent" --cookie-jar cookiefile -o - --data-ascii "{\"user_id\": \"username\", \"user_secret\": \"password\"}" -X POST https://loginpage.net

Then:

curl -H"Content-type: application/json" --user-agent "MyTestAgent" --cookie cookiefile - --cookie-jar cookiefile -o - https://testpage.net

Currently in my code, when I hit the url of the page I intend to test it immediately redirects to the login page, I enter the login credentials and it logs in successfully. I then dump the cookies out to console and they're not updated. The ssosession stuff isn't there (yet?). If I console.log the ssosession alone, it's null. If I console.log all the cookies, they're the same as if I just grabbed the cookies from the login page without signing in. None of the SSO stuff is present.

describe('testpage.net page', function () {
    it('should login', function () {
        browser.url('https://testpage.net');
        //this immediately redirects to https://loginpage.net
        browser.setValue('#userid','noone@nowhere.net');
        browser.setValue('#passwd','S3cr3tP4ssw0rd');
        browser.submitForm('#login');
        console.log(browser.getCookie('ssosession'));
        //returns null
        console.log(browser.getCookie());
        //returns cookies that existed prior to login success
    });
});

I need a means to grab the post login success cookies, store them locally equivalent to curls cookiejar and use them in subsequent tests. I've been beating my head up against a wall trying to figure out how this is done. This is an internal site that has very dated authentication method, but I need to write test automation for it's gui. Once over this particular hurdle, it should be easy to do that. Suggestions greatly appreciated!


Solution

  • I had the same problem and found a workaround solution.

    let's say we have two domains: sso.example.com and application.example.com

    After successful login, I open a new popup window with a url of the SSO, and grab the cookies from this popup, and store them to a file. when the test script starts I am just injecting the cookies and everything works perfect :-)

      // login just ended, you are at "application.example.com/sessioned-url"
      // ...
      // post login code, save cookies to file
      await saveCookies(browser);
      //open popup with sso.example.com (any url of this subdomain is OK even favicon or 404 becasue the cookies will be available)
      await browser.newWindow("https://sso.example.com", {
        windowName: "WebdriverIO window",
        windowFeature: "width=1,height=1,resizable,scrollbars=yes,status=1",
      });
      const handles = await browser.getWindowHandles();
      //move to the new window the SSO url
      await browser.switchToWindow(handles[1]);
      // save the SSO cookies (make sure to add the cookies to a file, NOT override it)
      await saveCookies(browser);
    
      //close popup and go back to "application.example.com/sessioned-url" window...
      await browser.closeWindow();
      await browser.switchToWindow(handles[0]);
    

    when starting a new session:

      // inject cookies of both domains
      await injectCookies(browser);
    
      // main window, will goto url without forcing login
      await browser.url("application.example.com/sessioned-url");
    

    hope it will help anyone in the long future :-)