0

I am trying to create an integration test for retrieving a OneNote page. And when trying to use the LiveSDK 5.6 LiveAuthClient, my compiler is not even seeing any method named LiveAuthClient.LoginAsync(strin[]) which is mentioned in multiple answers (e.g. 1) on here as well as the MSDN :|

        var authClient = new LiveAuthClient(OneNoteApiConfig.ClientID);

        var result = await authClient.InitializeAsync(OneNoteApiConfig.Scopes);

        if (result.Status != LiveConnectSessionStatus.Connected)
        {
            result = await authClient.LoginAsync(Scopes); // method does not exist
        }

Any ideas?

I'm sure I am missing something obvious

There does seem to be a method called GetLoginUrl()?

Am i referencing the wrong LiveSDK?

I installed the LiveSDK 5.6 NuGet package, and the project is a .NET 4.5 Class Library project

Community
  • 1
  • 1
Michal Ciechan
  • 13,492
  • 11
  • 76
  • 118

2 Answers2

3

I managed to get it to work, but had to use the GetLoginUrl(), than use Selenium to login to window live using a test account and approve the permission request, which then gets redirected with a code in the query string(..?code=xx.xxx) which i use to call the AuthClient.ExchangeAuthCodeAsync with, and get a Session which includes an AccessToken + RefreshToken, for all other tests I can use that refresh token :-) as it's valid for a year.

    [Test]
    public async void TryAuthoriseWithMsLiveLibrary()
    {
        var authClient = new LiveAuthClient(OneNoteApiConfig.ClientID);

        var result = await authClient.InitializeAsync(OneNoteApiConfig.Scopes);

        var getLoginUrl = authClient.GetLoginUrl(OneNoteApiConfig.Scopes);
        Console.WriteLine("\r\nGetLoginUrl = " + getLoginUrl);

        // New selenium Driver
        _driver = new FirefoxDriver();

        //Set wait to 2 seconds by defualt
        _driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(2));

        // Go to the url provided by auth client
        _driver.Navigate().GoToUrl(getLoginUrl);

        // Try find the accept button, if automatically directed to the "Grant Permission page", otherwise try find the Login/Passwd and login first
        try
        {
            _driver.FindElementById("idBtn_Accept");
        }
        catch (NoSuchElementException)
        {
            var un = _driver.FindElementByName("login"); // Login TextBox
            var pw = _driver.FindElementByName("passwd"); // Password TextBox
            var signIn = _driver.FindElementByName("SI"); // Sign-In Button

            un.SendKeys(OneNoteTestConfig.WindowsLiveUsername);
            pw.SendKeys(OneNoteTestConfig.WindowsLivePassword);
            signIn.Submit();
        }
        // Find a click the idBtn_Accept, if not found straight away, will implictly wait 2 seconds as set baove
        var button = _driver.FindElementById("idBtn_Accept");
        button.Click();

        // Try wait until the client is successfully redirected to the url with the code
        try
        {
            var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(5));
            wait.Until(d => d.Url.StartsWith("https://login.live.com/oauth20_desktop.srf"));
            //example https://login.live.com/oauth20_desktop.srf?code=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&lc=1033
        }
        catch (WebDriverTimeoutException)
        {
            Console.WriteLine(_driver.Url);
            throw;
        }

        Console.WriteLine("\r\nUrl = " + _driver.Url);

        // Retrieve code from query string (?code=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&...)
        var code = MsLiveAuthHelper.GetSessionCodeFromRedirectedUrl(_driver.Url);

        code.Should().NotBeNull();
        Console.WriteLine("\r\ncode = " + code);

        // Try get open a session using retrieved code.
        // From my uynderstanding you can only do this once with the code, as it expired after
        // and need to use the refresh token from this point, or re-request a code using above procedure
        var session = await authClient.ExchangeAuthCodeAsync(code);

        session.Should().NotBeNull();
        session.AccessToken.Should().NotBeNullOrWhiteSpace();

        Console.WriteLine("\r\nLiveConnectSession.AccessToken = " + session.AccessToken);
        Console.WriteLine("\r\nLiveConnectSession.AuthenticationToken = " + session.AuthenticationToken);
        Console.WriteLine("\r\nLiveConnectSession.Expires = " + session.Expires);
        Console.WriteLine("\r\nLiveConnectSession.RefreshToken = " + session.RefreshToken);
    }

For my other tests, res.RefreshToken and have a TestRefreshTokenHandler : IRefreshTokenHandler which i save it in:

public class TestRefreshTokenHandler : IRefreshTokenHandler
{
    public Task SaveRefreshTokenAsync(RefreshTokenInfo tokenInfo)
    {
        return Task.Factory.StartNew(() =>
        {
            Console.WriteLine("------------------------");

            Console.WriteLine("\r\nUserID = " + tokenInfo.UserId);
            Console.WriteLine("\r\nRefresh Token = " + tokenInfo.RefreshToken);

            Console.WriteLine("\r\n------------------------");
        });
    }

    public Task<RefreshTokenInfo> RetrieveRefreshTokenAsync()
    {
        Console.WriteLine("RetrieveRefreshTokenAsync()");
        return Task.FromResult(new RefreshTokenInfo(OneNoteTestConfig.OneNoteRefreshToken));
    }
}

And finally in other tests:

    [Test]
    public async void GetNewTokenByRefresh()
    {
        var authClient = new LiveAuthClient(OneNoteApiConfig.ClientID, new TestRefreshTokenHandler());
        var res = (await authClient.InitializeAsync(OneNoteApiConfig.Scopes)).Session;

        Console.WriteLine("\r\nLiveConnectSession.AccessToken = " + res.AccessToken);
        Console.WriteLine("\r\nLiveConnectSession.AuthenticationToken = " + res.AuthenticationToken);
        Console.WriteLine("\r\nLiveConnectSession.Expires = " + res.Expires);
        Console.WriteLine("\r\nLiveConnectSession.RefreshToken = " + res.RefreshToken);
        res.AuthenticationToken.Should().NotBeNullOrWhiteSpace();
    }

Hope this helps someone!

Michal Ciechan
  • 13,492
  • 11
  • 76
  • 118
1

I don't think the login workflow is supported from a desktop app with the Live SDK, only from a Windows Store app. You'll probably have to drop down to the REST APIs for an automated test.

GarethJ
  • 6,496
  • 32
  • 42
  • Doing further investigation, and a little bit of trial + error + luck, i managed to get it to work, but had to use the GetLoginUrl(), than use Selenium to login to window live using a test account and approve the permission request, which then gets redirected with a code in the query string(..?code=xx.xxx) which i use to call the AuthClient.ExchangeAuthCodeAsync with, and get a Session which includes an AccessToken + RefreshToken, for all other tests i can use that refresh token :-) as it's valid for a year. See my answer which i'm about to post. – Michal Ciechan Jan 07 '15 at 00:04