Friday, August 12, 2016

It's Official - I Can Develop ASP.NET MVC Web Applications

Recently, I finally decided to go down and take the 70-486 Developing ASP.NET MVC Web Applications exam which is the second of three exams required to become a Microsoft Certified Software Developer (MCSD).

This exam was actually easier (for me, at least) than the 70-483 Programming in C# exam. If you have worked on an MVC project for 2+ years, this should be a piece of cake.

Tips:
  1. Carefully read each question
    For questions which were fill-in-the-blanks, often the answer would be obvious without needing to read the question (can answer purely based on syntax). However, there were cases where an answer to a given question would be revealed in sample code for another question.
  2. First Chance Exceptions
    I think this was the only topic I really did not have much experience with. Make sure you know what First Chance Exceptions are and how they work!
  3. Configuration File Security
    Make sure you understand how to secure parts of your configuration file (like connection strings).

Overall

If you have a few years experience working with MVC, this test will be a no-brainer. I was able to finish the exam in 45 minutes and for many of the questions, the answer was trivially obvious (based on syntax) or something that you really should know. I felt the breadth of topics was waaaay smaller than for the Programming in C# exam so studying was fairly easy. In this case, I am fairly confident that even without studying, I would have passed this exam with no problems.

Being the second of three exams, passing did not increase my standing as far as Certification Titles. With the first exam, I became an MCP. This exam, I remain an MCP. With the next exam (70-487 Developing Microsoft Azure and Web Services) I will achieve the Microsoft Certified Software Developer (MCSD) Title.

Happy Coding!

Friday, July 8, 2016

Knockout + Kendo UI Date Picker - Open To Specific Date without Selecting

Don't you just love working with 3rd party vendor controls? In this post, I want to look at how you can open a Kendo UI Date Picker to a specific date, without selecting the date.

The Problem

Let's say you are using Knockout with Kendo UI and the Knockout-Kendo bindings. Your view model has two properties, one for start date and one for end date.

class DateRange {
    start: KnockoutObservable;
    end: KnockoutObservable;  // end date is optional

    constructor(start?: Date, end?: Date){
        this.start = ko.observable(start);
        this.end = ko.observable(end);
    }
}


When the user selects a start date in the future (more specifically, a start date that requires calendar paging), then we want the end date calendar to open to the same date, but not select the end date because the end date is optional.

The following code does not work correctly. It seems that setting the value of the DateView does not set the value of the observable property bound to the calendar and you cannot re-select the selected date. Consider the following steps:
  1. Select Start Date of July 10th, 2016
  2. Open End Date Calendar; notice that July 10th is selected, but the DateRange.end observable is not set
  3. Attempt to select July 10th for end date; nothing happens

// DOES NOT WORK
<input class="form-control" data-bind="kendoDatePicker: { value: start, min: new Date() }" placeholder="Start Date* (mm/dd/yyyy)" />
<input class="form-control" data-bind="kendoDatePicker: { 
    value: end,
    min: new Date(),
    open: function(e){
        if(start() && !end()) {
            e.sender.dateView.value(start());
        }
    }
}" placeholder="End Date* (mm/dd/yyyy)" />


By setting the value to the desired date and back to null, the date becomes focused, but not selected. This allows re-selection of that date.

// WORKS - null out value again; it keeps focus but is not selected
<input class="form-control" data-bind="kendoDatePicker: { value: start, min: new Date() }" placeholder="Start Date* (mm/dd/yyyy)" />
<input class="form-control" data-bind="kendoDatePicker: {
    value: end,
    min: new Date(),
    open: function(e){
        if(start() && !end()) { 
            e.sender.dateView.value(start());
            e.sender.dateView.value(null);
        }
    }
}" placeholder="End Date* (mm/dd/yyyy)" />

Tuesday, June 14, 2016

Knockout Placeholder Select Binding

So, for whatever reason, the select tag does not support the placeholder attribute. If it did, I'm assuming that's what the Knockout binding for optionsCaption would end up setting. I tried a few approaches to get a placeholder effect from the select box and have a decent working example. Of course, as is true with most coding questions, I started with a quick search of stack overflow. I took the example that worked the best for my scenario and turned it into a knockout binding.
At first, I thought I should extend the existing select binding, however, I soon realized there is no select binding; it just uses value, options, optionsText, ... to accomplish its task. So, I looked into adjusting the optionsCaption binding, and saw that it is just part of the options binding and I followed suit.

ko.bindingHandlers.placeHolderSelect = {
    after: ['options', 'value', 'optionsCaption'],
    init: function (elem, value, allBindings, viewModel, bindingContext) {
        var options = ko.utils.unwrapObservable(value());

        if (allBindings['has']('optionsCaption')) {
            var caption = $(elem).find('option[value=""]');

            if (options === 'required') {
                caption.prop('hidden', 'hidden');
                caption.prop('disabled', 'disabled');
            }

            var emptyClass = 'empty';
            $(elem).change(function() {
                if (!$(elem).val()) {
                    $(elem).addClass(emptyClass);
                } else {
                    $(elem).removeClass(emptyClass);
                }
            });
            $(elem).change();
        }
    }
}

To use this binding, simply add placeHolderSelect and set the value to either 'required' if the selection should not allow the caption to be re-selected or any other value if the caption should allow re-selection.

    <!-- Cannot re-select caption -->
    <select data-bind="options: myOptions, optionsCaption: 'Caption Text', placeHolderSelect: 'required'"></select>

    <!-- Can re-select caption -->
    <select data-bind="options: myOptions, optionsCaption: 'Caption Text', placeHolderSelect: false"></select>
Enjoy!

Monday, June 6, 2016

Decomposing Page Objects

This month has been heavily dedicated to defining a more robust approach to the page object pattern, which I have been calling Page Modeling. Page Modeling is not going away, however, in a recent 'twitter war' with Marcel de Vries, I was forced to really think about what the classic Page Objects pattern brings to the table that Page Modeling is 'missing' and to be able to highlight where Page Modeling fits into the picture.

This post is dedicated to decomposing the page object pattern into three distinct layers of abstraction. I believe that Page Objects have too many responsibilities and this leads to confusion / ambiguity on how to build the Page Object as well as having a need for multiple changes to the Page Object when only simple changes are made to the UI. Of course I will explain further about what this exactly means.

To start, I would like to identify three distinct aspect of the Page Object pattern which I feel should be decoupled.
  1. Page Modeling
    Finding UI elements on screen and exposing the behaviors and observations of those UI elements
  2. Orchestration
    Given the UI capabilities, what are the interesting things we can do
  3. Scenarios
    Given an orchestration, implements scenarios based on real user use of the application
I realized that page modeling alone does not provide all of the utility of page objects, but the additional utility can easily be added. Now, I will cover each aspect and how they can be assembled to implement the page object pattern in a far more robust and maintainable manner. The additional utility, however, doesn't really have a standard abstraction and would be custom to your application. This is because the higher level abstractions depend on the business concerns around how to use the application and are not representing the UI.

Page Modeling

I have covered Page Modeling in depth in previous blogs as well as CodedUI Examples website so I'll just summarize it here. Martin Fowler indicates that
The basic rule of thumb for a page object is that it should allow a software client to do anything and see anything that a human can. It should also provide an interface that's easy to program to and hides the underlying widgetry in the window.
At some point, you actually do need to interrogate that widgetry to test UI state and that the controls are behaving properly (formatting phone numbers, providing money with $, etc). This point is what makes the traditional page object pattern unmanageable as I will try to highlight below. Page Modeling hides the implementation of the widgetry so that the client doesn't care if they are using a TextBox, TextArea, MyCustomTextControl, etc... Page Modeling exposes the observations and behaviors of a UI element. So what are observations and behaviors you ask?

Behaviors

Behaviors are what the user can do with the UI. For instance, setting the value of a TextBox or Clicking a button. The result of a behavior is typically a Page Model representing the next most-likely thing with which the user will interact. This allows for a fluent syntax where the result of an action returns the next thing to work with.

Page Modeling


interface ILoginPage : IPageModel
{
    // instead, expose the components that allow a login to happen
    IReadWriteValuePageModel<string, ILoginPage> Username {get;}
    IReadWriteValuePageModel<string, ILoginPage> Password {get;}
    ISelectionablePageModel<ILoginPage> RememberMe {get;}
    IClickablePageModel<IAccountSettings> Login {get;}
}

interface IAccountSettings : IPageModel
{
    IReadWriteValuePageModel<string, ILoginPage> FirstName {get;}
    IClickablePageModel<IAccountSettings> Save {get;}
}

public void LoginAndSetFirstName()
{
    ILoginPage loginPage = new LoginPage(browserWindow);// get a reference to the login page

    Assert.IsFalse(loginPage.Login.IsActionable()); // IsActionable <=> enabled and visible
    
    Assert.IsTrue(loginPage.UserName.SetText("MyUserName") // set the username which returns reference to the login page
                           .Password.SetText("MyPassword") // set the password which returns reference to the login page
                           .Login.IsActionable());

    IAccountSettings accountSettings = loginPage.Login.Click(); // click login which returns a reference to account settings page

    // from here, I could do more, but the above logic would probably be refactored out into a Scenario
    // IAccountSettings accountSettings = new LoginScenario(loginPage).LoginStandardUser();

    Assert.IsFalse(loginPage.IsRendered());
    Assert.IsTrue(accountSettings.IsRendered());

    string myName = "MyName";
    accountSettings.FirstName.SetText(myName) // set first name returns reference to account settings page
                   .Save().Click() // click save which returns a reference to account settings page
                   .FirstName.Value; // get the current value in the first name field after the page refreshes from the POST request

    Assert.IsTrue(myName.Equals(myName));
}

This fluent syntax is highly expressive of what the user is doing. In Page Objects, you would have a ton of methods like Is{control}{state}(). In Page Modeling, you have one property for each UI element {control} with methods like Is{state}(). Consider the difference below.

Page Objects


class LoginPage : Page
{
    AccountSettings Login(string username, string password);
    bool IsLoginButtonActionable();
}

class AccountSettings : Page
{
    // I can create one method for each property
    // AccountSettings UpdateFirstNameAndSave(string firstName); // oh boy... do not go this route!

    // or use optional parameters for what I want to set
    // which means every time fields are added or removed, this method has to change
    // and the logic inside is kinda crappy if(!String.IsNullOrWhitespace(firstName)) {/*set first name*/} ...
    AccountSettings SetUserInfoAndSave(string firstName = null, string lastName = null, DateTime? birthDate = null);

    // what about reading?  either need a class/struct to hold all the values
    AccountInfo GetUserInfo();

    // or one for each; again, no clear answer
    string GetFirstName();
}

public void LoginAndSetFirstName()
{
    var loginPage = new LoginPage(browserWindow);
    Assert.IsFalse(loginPage.IsLoginButtonActionable());

    // If I login, I can't assert anything about the button, so let me go update my class...
    loginPage.Login("myUser", "myPass");
}

// updating LoginPage
class LoginPage : Page
{
    AccountSettings Login(string username, string password);
    bool IsLoginButtonActionable();
    LoginPage SetUsernameAndPassword(string username, string password);
}

// updating Test
public void LoginAndSetFirstName()
{
    var loginPage = new LoginPage(browserWindow);
    Assert.IsFalse(loginPage.IsLoginButtonActionable());

    loginPage.SetUsernameAndPassword("myUser", "myPass");
    Assert.IsTrue(loginPage.IsLoginButtonActionable());

    // now, I want to login, but I only need click the login button
    // there is no way to do that, I have to either do a .Login call
    // to (again) set the username and password, or update my class!
}

// updating LoginPage
class LoginPage : Page
{
    AccountSettings Login(string username, string password); // no enforcement that this calls SetUsernameAndPassword which may have special logic for setting
    bool IsLoginButtonActionable();
    LoginPage SetUsernameAndPassword(string username, string password);
    AccountSettings ClickLogin(); // assuming only use this method in conjunction with SetUsernameAndPassword method
}

// updating Test
public void LoginAndSetFirstName()
{
    var loginPage = new LoginPage(browserWindow);
    Assert.IsFalse(loginPage.IsLoginButtonActionable());

    loginPage.SetUsernameAndPassword("myUser", "myPass");
    Assert.IsTrue(loginPage.IsLoginButtonActionable());

    var name = "myName";
    IAccountSettings accountSettings = loginPage.ClickLogin();
    accountSettings.SetUserInfoAndSave(firstName: myName);
    Assert.IsTrue(name.Equals(GetFirstName()));
    Assert.IsTrue(name.Equals(GetUserInfo().FirstName));
}

Not only are there a bunch of methods, but there are overlapping concerns and an ambiguous development strategy. There are two ways to login now. Login() and SetUsernameAndPassword() followed by ClickLogin(). Along the way, multiple methods were added just to test something about the UI. In Page Modeling, there is no ambiguity. Simply, there is a property per UI element that exposes what it can do and what about it can be observed.

Observations

Observations are what the user can observe about your UI. For instance, what is the current value of the text box, is the element visible, does it exist on the screen, is it enabled, ... Observations should not have side affects and should not require an action from the user whenever possible. Sometimes this is unavoidable and the observation becomes more similar to a behavior. However, as long as the side affect or user action doesn't require manipulation of state outside of the UI elements control, it is typically safe. An example of this would be that the value of a TextBox is obscured until you click the eyeball in the textbox. An observation that read the text by first clicking the eyeball if needed, and then resetting the state to obscured would be OK. There should be a way to tell if the state of the box is obscured or plain for rigorous testing.

Orchestration

Orchestrations is simply defining meaningful strings of actions against a page model and exposing only the dependencies of that string of actions to the client to call. Using the above case of a login page, an orchestration method may be the Login(string username, string password) method. The orchestration simply takes a reference to whatever page model it orchestrates and uses the exposed observations and behaviors to create a meaningful set of actions.

interface ILoginActions
{
   IAccountSettings Login(string username, string password);
}

public class LoginActions : ILoginActions
{
    public readonly ILoginPage loginPage;
    public LoginActions(ILoginPage loginPage)
    {
       this.loginPage = loginPage;
    }

    public IAccountSettings Login(string username, string password)
    {
       // the orchestrator does not typically need to make assertions,
       // and can assume that there are tests for Login actions
       return
       this.loginPage
           .Username.SetValue(username)
           .Password.SetValue(password)
           .Login.Click();
    }
}

// using the orchestration in a test
public void LoginAndSetFirstName()
{
    var loginPage = new LoginPage(browserWindow);

    // do not care how to actually login
    IAccountSettings accountSettings = new LoginActions(loginPage).Login("myUsername", "myPassword");

    // perform the interesting work of setting name and asserting
    accountSettings.FirstName.SetValue("myName").Save.Click();
    Assert.IsTrue("myName".Equals(accountSettings.FirstName.Value));
}

// could even create extension methods
public static class LoginActionExtensions
{
    public static IAccountSettings Login(this ILoginPage loginPage, string username, string password)
    {
        return new LoginActions(loginPage).Login(username, password);
    }
}

// using the extension in the test seems more natural
public void LoginAndSetFirstName()
{
    // no need to new up some orchestrator class, just get the page and use the extension
    IAccountSettings accountSettings = new LoginPage(browserWindow).Login("username", "password");

    // perform the interesting work of setting name and asserting
    accountSettings.FirstName.SetValue("myName").Save.Click();
    Assert.IsTrue("myName".Equals(accountSettings.FirstName.Value));
}

Using the orchestration classes, tests which are dependent on some previous page model (eg, must first login to get to desired page), can use the orchestration class to not worry about how to perform the given action while knowing that the details are thoroughly tested elsewhere. Commonly used orchestrations would typically become scenarios, which are described next.

Scenarios

Scenarios are even higher level abstractions than orchestrations and they perform a real world user use of the application. Consider you have three types of users: Basic, Premium, and Administrator. Each type would have different login credentials and those credentials could change or even the way login is performed could change, but the Scenario shields tests from these issues. Methods of a Scenario should typically not require any dependencies exposed to the client.

interface ILoginScenarios
{
    IAccountSettings LoginBasicUser();
    IAccountSettings LoginPremiumUser();
    IAdminDashboard LoginAdminUser(); // notice, we're going somewhere else after login; this would be annoying to handle in a test
}

public class LoginScenarios : ILoginScenarios
{
    public readonly ILoginActions loginActions;
    protected readonly BrowserWindow window;

    public LoginScenarios(ILoginPage loginPage, BrowserWindow window) : this(new LoginActions(loginPage), window) { }

    public LoginScenarios(ILoginActions loginActions, BrowserWindow window)
    {
        this.loginActions = loginActions;
        this.window = window;
    }

    public IAccountSettings LoginBasicUser()
    {
       return this.loginActions.Login("basicUsername", "basicPassword");
    }

    public IAccountSettings LoginPremiumUser()
    {
       return this.loginActions.Login("premiumUsername", "premiumPassword");
    }

    public IAdminDashboard LoginAdminUser()
    {
       // don't return as it's not the right model
       this.loginActions.Login("adminUsername", "adminPassword");
       return new AdminDashboard(this.window);
    }
}

// and possibly extensions here as well
public static class LoginScenarioExtensions
{
     public static IAccountSettings LoginBasicUser(this ILoginPage loginPage)
     {
        return new LoginScenarios(loginPage).LoginBasicUser();
     }

     public static IAdminDashboard LoginAdminUser(this ILoginPage loginPage)
     {
        return new LoginScenarios(loginPage).LoginAdminUser();
     }
}



Of course, the downside with extension method approach is that the extension method class cannot implement the interface it reflects, but you could do something more elegant. Let's combine the power of all three layers into a single Facade.

public LoginFacade : ILoginPage, ILoginActions, ILoginScenarios
{
    public readonly ILoginScenarios LoginScenarios;
    public ILoginActions LoginActions => this.LoginScenarios.LoginActions;
    public ILoginPage LoginPage => this.LoginActions.LoginPage;
    protected readonly BrowserWindow window;

    public LoginFacade(ILoginPage loginPage, BrowserWindow window) : this(new LoginActions(loginPage), window) { }
    public LoginFacade(ILoginActions loginActions, BrowserWindow window) : this(new LoginScenarios(loginActions), window) { }
    public LoginFacade(ILoginScenarios loginScenarios, BrowserWindow window)
    {
       this.LoginScenarios = loginScenarios;
       this.window = window;
    }

    // delegate all actions
    IReadWriteValuePageModel<string, ILoginPage> Username => this.LoginPage.Username;
    IReadWriteValuePageModel<string, ILoginPage> Password => this.LoginPage.Password;

    public IAccountSettings Login(string username, string password)
    {
        return this.LoginActions.Login(username, password);
    }

    public IAdminDashboard LoginAdminUser()
    {
        return this.LoginScenarios.LoginAdminUser();
    }
}



And we have come full circle. There is now a master object that can do all three layers which the client can manipulate. Each layer is exposed so that tests can test the granular widgetry if needed or simply use an orchestration or scenario to navigate past the already tested workflows of the application.

Hopefully I've convinced you that decoupling the Page Object pattern is worth the effort and reduces ambiguity while increasing consistency of the testing strategy.

Sunday, June 5, 2016

Change Image Source on Hover using Knockout JS

I found this js fiddle for how to do it using jQuery so I converted it to use a Knockout binding.  Surprisingly, the first page of google didn't have any KO binding to do it.

ko.bindingHandlers.hoverImage = {
  init: function(element, valueAccessor) {
    var options = ko.utils.unwrapObservable(valueAccessor());
    $(element).bind('mouseover', function(event) {
      var $this = $(this);
      if (!$this.data('original-image')) {
          $this.data('original-image', $this.attr('src'));
      }
      $this.attr('src', options);
    })
    .bind('mouseout', function(event) {
       var $this = $(this);
       $this.attr('src', $this.data('original-image'));
    });
  }
};
To use it,
<img src="initialImageSrc.jpg" data-bind="hoverImage: 'hoverImageSrc.jpg'>

Saturday, June 4, 2016

Proper Page Modeling - In depth

In a previous article, I tried to explain why the page object pattern that I have seen described is simply lacking from what it could be.

Let's start with the good things about page objects.

1.  They are an abstraction of what the page should do
2.  They provide an implementation agnostic approach to testing (don't care if wpf, html, etc)
3.  They allow for more easily readable, and therefore more maintainable, code
4.  They provide a easy to understand navigation pattern where the result of actions are the next thing to work with

Ok, great.  How is this accomplished.  Let's look at an example in depth and compare what I've seen as 'traditional' page objects and compare to my approach to page modeling.

Let's take two pages into account.  Login page and Account Settings page.




When you login successfully, you'll go to the account settings page.

In code, your traditional page objects may look something like this.

class LoginPage : Page
{
    /// Logs in using the credentials supplied
    AccountSettings Login(string username, string password, bool rememberMe);
    RegisterPage ClickRegisterLink();
    ForgotPasswordPage ClickForgotPassword();
    AccountSettings LoginWithTwitter(string twittername, string twitterpass);
    AccountSettings LoginWithFacebook(string facebookname, string facebookpass);
}

I think this much we can agree upon.  Now, where it starts to fall apart for me.  Here is a quote from uncle bob martin.

There are differences of opinion on whether page objects should include assertions themselves, or just provide data for test scripts to do the assertions. Advocates of including assertions in page objects say that this helps avoid duplication of assertions in test scripts, makes it easier to provide better error messages, and supports a more TellDontAsk style API. Advocates of assertion-free page objects say that including assertions mixes the responsibilities of providing access to page data with assertion logic, and leads to a bloated page object.
I favor having no assertions in page objects. I think you can avoid duplication by providing assertion libraries for common assertions - which can also make it easier to provide good diagnostics. 

I agree with no assertions in page objects.  He makes an aside that I also agree with:
One form of assertions is fine even for people like me who generally favor a no-assertion style. These assertions are those that check the invariants of a page or the application at this point, rather than specific things that a test is probing. 
So, I know that there are more things about this page like, is the login button enabled when no username or password is present.  Here are two ways I can extend this class:

class LoginPage : Page
{
    bool IsValid();
}

In this case, how do I know what is not valid so I can fix it?  Also, what does the logic look like for this method?

public bool IsValid()
{
    if(String.IsNullOrEmpty(username.Text) || String.IsNullOrEmpty(password.Text))
    {
        if(loginButton.Enabled)
        {return false;}
    }
    else
    {
        if(!loginButton.Enabled){ return false; }
    }

    // .. maybe more tests for other requirements?
    // what about this?
    // these are requirements for the page that these elements are visible
    if(!IsRegisterLinkVisible()) { return false; }
    if (!IsForgotPasswordLinkVisible()) { return false; }

    // and that they work?
    var registerHref = GetRegisterHref();
     using(var client = new HttpClient())
     {
         var result = await client.GetAsync(registerHref);
          if(!result.IsSuccessful) { return false; }
     }
    return true;
}

Or, I could just throw an exception so I can include detail about what is wrong:

class LoginPage : Page
{
    void ThrowIfNotValid();
}

but this is not good either.  I can't just ask the page if it's valid with out a try block.

So, I can expose all of the things I'm expecting?

class LoginPage : Page
{
    bool IsLoginButtonProperlyEnabledOrDisabled();
}

and then maybe a master IsValid that calls these and possibly throws an exception.

Now, say that the button is not supposed to be disabled, but it is supposed to be 'inactive', but still clickable to trigger form validation.

Ok, so I have to either update this method to

class LoginPage : Page
{
    bool IsLoginButtonPropertlyInactiveOrActive();
}

which is crazy.  Or, I can not rename the method and change the logic so that it doesn't really match.

Another approach to this would be just add methods for each thing you want to test.  Great,

class LoginPage : Page
{
    bool IsLoginButtonEnabled();
    LoginPage SetUsernameAndPassword(string user, string pass); // don't login, just set
}

but when requirement changes to inactive,

class LoginPage : Page
{
    bool IsLoginButtonActive();
}

So, requirements change again.  The password is only visible when a username with 6 or more characters is present.  Great, more methods.

class LoginPage : Page
{
    bool IsPasswordVisible();
    LoginPage SetUsername(string user);
}

To me, this is clearly a violation of open / close principal.  Especially since this is highly predictable.  UI elements have a natural set of consistent things you may want to do with them.  Testing UI elements for visibility, click-ability, enabled-ness, ... are extremely natural concerns and should be consistently available for all UI elements.

We'll look at crafting tests after the comparison with my approach to page modeling.

In my approach to page modeling, I strive for consistency of expression of the UI elements that create the control.  In my approach, the model looks like this:

// because of this inheritance, the login page is also testable for isvisible, exists, ...
interface ILoginPage : IPageModel
{
    // this type of method doesn't even belong here.  it belongs at some other level of abstraction
    // what a 'Login' action means is not any concern of this control
    //AccountSettings Login(string username, string password, bool rememberMe);

    // instead, expose the components that allow a login to happen
    IReadWriteValuePageModel<string, ILoginPage> Username {get;}
    IReadWriteValuePageModel<string, ILoginPage> Password {get;}
    ISelectionablePageModel<ILoginPage> RememberMe {get;}
    IClickablePageModel<IAccountSettings> Login {get;}

    // expose an object that supports click, and all native ui tests (is visible, enabled, ...)
    IClickablePageModel<IRegisterPage> Register {get;}
    IClickablePageModel<IForgotPasswordPage> ForgotPassword {get;}
    IClickablePageModel<ITwitterLoginPage> Twitter {get;set;}
    IClickablePageModel<IFacebookLoginPage> Facebook {get;set;}
}

Another interesting this happens here.  What happens if the facebook login button is on multiple pages.  The LoginWithFacebook(string facebookname, string facebookpass) logic has to be duplicated to all the pages that use it or some helper class is created to share logic.  Again, this belongs at a different level of abstraction for the testing.

To enable these scenarios, you could do something like:

class LoginPageUserActions
{
    protected ILoginPage LoginPage{get;}

    public LoginPageUserActions(ILoginPage loginPage)
    {
         this.LoginPage = loginPage;
    }

    public AccountSettings Login(string username, string password, bool rememberMe)
    {
         // even here, just assume that login works, no need for assertions
         // there should be tests to verify that login works
        return  this.LoginPage
                         .Username.SetText(username)
                        .Password.SetText(password)
                        .RememberMe.SetSelected(rememberMe)
                        .Login.Click();
    }
}

Now, lets compare how you write the tests for the above business requirements and implement the changes in both approaches.

Business Requirements:

1.  Main Login Control
-> Username, Password, and Remember Me all present and enabled
-> Login button visible, but disabled until username and password are set

2.  External Login Control
-> Facebook and Twitter links are present and enabled always

3.  Register Link
-> Present and enabled always

4.  Forgot password
-> Present and enabled always

5.  Upon successful login, the user lands on account settings page.

So the start of the test class would look like this:

public class LoginPageTests()
{
         protected BrowserWindow window;

         [TestInitialize]
         public void GivenLoginPage()
         {
              this.window = BrowserWindow.Launch("loginpageurl");
         }
}

I like to follow the Given, When, Then type of syntax where the Given is my test initialize as the arrange, the When and Then are part of the TestMethod as the act and assert.

To add the first business requirement for the main login control, we run into the first issue that I mentioned.  I could have an IsValid method that captures all this logic, or maybe an IsMainLoginControlValid method that only tests that part of the control.  Seems wrong for the model to do the testing; I would have thought the test class decides what IsValid means*. (* full disclosure, I violate this run on very rare occasion)

So maybe the test looks like:

public void ThenUsernamePasswordAndRememberMeVisibleAndEnabled()
{
    Assert.IsTrue(new LoginPage(this.window).IsValid());
}

Granted, it's short and sweet, it doesn't really tell me much.  And the next test would look the same:

public void ThenTheLoginButtonIsNotEnabled()
{
    Assert.IsTrue(new LoginPage(this.window).IsValid());
}

And finally some actual work:

public void WhenUsernameAndPasswordEntered_ThenLoginButtonIsEnabled()
{
    var loginPage = new LoginPage(this.window);
    Assert.IsTrue(loginPage.IsValid());
    loginPage.SetUsernameAndPassword("user", "pass");
    Assert.IsTrue(loginPage.IsValid()); 
}

Aside from the method name, I really have no idea what this would be testing for :)

Ok, so ditch the is valid approach and expose the methods of interest:

public void ThenUsernamePasswordAndRememberMeVisibleAndEnabled()
{
    var loginPage = new LoginPage(this.window);

    // add all these methods to the class first ~_~
    Assert.IsTrue(loginPage.IsUsernameVisible() && 
    loginPage.IsUsernameEnabled() &&
    loginPage.IsPasswordVisible() &&
    loginPage.IsPasswordEnabled());

    // maybe more simply, add these instead and hope you don't need to test them separately
    Assert.IsTrue(loginPage.IsUsernameVisibleAndEnabled() && loginPage.IsPasswordVisibleAndEnabled()); // still not great :/
}

public void ThenTheLoginButtonIsNotEnabled()
{
    Assert.IsFalse(loginPage.IsLoginButtonEnabled());
}

public void WhenUsernameAndPasswordEntered_ThenLoginButtonIsEnabled()
{
    loginPage.SetUsernameAndPassword("user", "pass");
   Assert.IsTrue(loginPage.IsLoginButtonEnabled());
}

To implement the next requirements, I would do the same thing = add tons of methods for testing the UI state, which are business requirements.  I'll skip 2, 3, and 4 for this reason.  You can imagine what that looks like.

The last requirement would involve the next page's model.  Presently, there is no way to test if the page is actually the page displayed to the user.  So maybe that should be in the isvalid method.  Or maybe it should be an IsPageVisible() method on the page object.

public void WhenValidCredentials_ThenAccountSettingsIsShown()
{
    var loginPage = new LoginPage(this.window);
    var accountPage = loginPage.Login("user", "pass");
    
    Assert.IsTrue(accountPage.IsPageVisible());
    Assert.IsFalse(loginPage.IsPageShown()); // there is no enforcement on consistency and someone named it differently...
}

Ok, so now the requirement changes.  

1.  Login button is not supposed to be disabled, it is supposed to be inactive and validation error is shown, if any, when clicked.
2.  Password is only visible if username with 6 or more characters is present.

In the case of IsValid, we'd go into the method and change the logic to reflect this, shuffle some test names around and add one test method:

// method name change
public void ThenUsernameAndRememberMeVisibleAndEnabledPasswordHidden()
{
    // body doesn't change as it doesn't really express much 
    Assert.IsTrue(new LoginPage(this.window).IsValid());
}

// method name change
public void ThenTheLoginButtonIsInactive()
{
    Assert.IsTrue(new LoginPage(this.window).IsValid());
}

public void WhenUsernameWithSixOrMoreCharacters_ThenPasswordIsShown()
{
     var loginPage = new LoginPage(this.window);
    Assert.IsTrue(loginPage.IsValid());
    loginPage.SetUsername("username");
    
     // still not an overly expressive test :/
    Assert.IsTrue(loginPage.IsValid()); 
}

In the case of exposing tons of methods for everything, you would change the IsEnabled methods to IsActive for the login button.  Not much different from the previous.

Using page models, lets do the same exercise.  Firstly, because of this approach, there is no ambiguity as to what methods to add to your UI.  Simply, you expose whatever UI elements are present and that is enough for the test to drive (or some middle, orchestration abstraction).

public void ThenUsernamePasswordAndRememberMeVisibleAndEnabled()
{
    var loginPage = new LoginPage(this.window);
     // more expressive about what is valid means for a given set of inputs (in this case, no inputs)
    Assert.IsTrue(loginPage.Username.IsActionable() && loginPage.Password.IsActionable() && loginPage.RememberMe.IsActionable());
}

public void ThenLoginButtonIsDisabled()
{
    Assert.IsTrue(new LoginPage(this.window).Login.IsNotEnabled())
}

public void WhenUsernameAndPasswordEntered_ThenLoginButtonIsEnabled()
{
    Assert.IsTrue(loginPage.Username.SetText("user")
                                        .Password.SetText("pass")
                                        .Login.IsEnabled())
}

public void WhenValidCredentials_ThenAccountSettingsIsShown()
{
    var loginPage = new LoginPage(this.window);
    // this method chain to login can be shared easily (see below)
    var accountPage = loginPage.UserName.SetText("user").Password.SetText("pass").Login.Click();
    
    Assert.IsTrue(accountPage.IsVisible());
    Assert.IsFalse(loginPage.IsVisible()); // enforcement on consistency
}

Notice, when writing these tests, I did not need to add anything to my model.  Also, there is room for a shared set of actions that are higher level that setting values and clicking things.  

public void WhenValidCredentials_ThenAccountSettingsIsShown()
{
    var loginPage = new LoginPage(this.window);
    var loginActions = new LoginPageActions(loginPage);
    var accountPage = loginActions.Login("username", "pass");
    
    Assert.IsTrue(accountPage.IsVisible());
    Assert.IsFalse(loginPage.IsVisible()); // enforcement on consistency
}

The underlying point I'm trying to make here is that you may want to very rigorously test the login page details in the login page tests, and then assume that login works in the shared code which does not need to be rigorous in assertions about page state.  This is probably my biggest gripe with page object pattern that I've seen explained.  It is not the page object's concern to know all these things.  It only stores values that may or may not be read and exposes hooks to click on things or other user actions.

So, to make the same requirement changes, nothing changes in the model.  Only the test for that requirement changes.

public void ThenUsernameAndRememberMeVisibleAndEnabledPasswordHidden()
{
     var loginPage = new LoginPage(this.window);
     // more expressive about what is valid means for a given set of inputs (in this case, no inputs)
    Assert.IsTrue(loginPage.Username.IsActionable() && loginPage.Password.IsNotRendered() && loginPage.RememberMe.IsActionable());
}

// method name change
public void ThenTheLoginButtonIsInactive()
{
    Assert.IsTrue(new LoginPage(this.window).Login.IsNotActive());
}

public void WhenUsernameWithSixOrMoreCharacters_ThenPasswordIsShown()
{
     var loginPage = new LoginPage(this.window);
     loginPage.Username.SetText("abc");
     Assert.IsTrue(loginPage.Password.IsNotRendered());
     loingPage.Username.SetText("userna");
     Assert.IsTrue(loginPage.Password.IsRendered());
}

Another point that falls out of this example is that in the traditional page objects approach, I had a Login(string username, string password, bool rememberMe) method for setting all three inputs and clicking login.  I had to add another method to only set username and password so I can test the login button visibility.  Then I had to add one to set only user name to test password visibility when requirement changed.

In this case, nothing had to be changed.  You can expect to want to test input boxes for visibility and to set and read text from them.

Now, we add in the requirement for the validation messages to be shown when login is clicked, but username or password not set.

In the traditional approach, we have to add a method for clicking the button (since we're not doing a login, but trying anyway; maybe the Login method allows empty string as input, or maybe it throws; so implementation details are bleeding out if I assume something about it).  Or a method to explicitly clear username or password and click ClickLoginWithoutUsernamePassword();

class LoginPage : Page
{
    // notice this return type is ambiguous.  If i click after SetUsernameAndPassword,
   // I would actually go to AccountSettingsPage, but I'm adding to satisfy test requirement
   // of click to fail
    LoginPage ClickLoginButton();
    AccountSettings ClickLoginButton2();

    LoginPage ClickLoginWithoutUsernamePassword(); // not ambiguous

    bool IsValidationMessageShown(); // maybe IsCorrectValidationMessageShown()?
     string GetValidationMessageText();
    // or worse
    bool IsExpectedValidationMessage(string message);
}

Notice, I have to add two methods for validation message:  Is it shown (not consistent naming) and what is the value of the text shown.  If I want to know more about the message, more methods!

Using page modeling, you get the login button click for free and just need to add a property for the validation message.

public ILoginPage : IPageModel
{
    IValuedPageModel<string, ILoginPage> ValidationMessage {get;}
}

and the tests for both:

// Using is valid is still not interesting
public void WhenNoUsernameAndLoginClicked_ThenValidationMessageShown()
{
    Assert.IsTrue(loginPage.IsValid());
    loginPage.Setusername("User");
    var page = loginPage.ClickLoginButton();

    Assert.IsTrue(loginPage.IsValid());
}

public void WhenNoUsernameAndLoginClicked_ThenValidationMessageShown()
{
      Assert.IsFalse(loginPage.IsValdationMessageShown());
      loginPage.SetUsername("username").ClickLoginButton();
      Assert.IsTrue(loginPage.IsValidationMessageShown());
       Assert.IsTrue(loginPage.GetValidationMessage().Equals(expectedMessage));
}

Again, very inconsistent methods and requirement to constantly add stuff to the page model.  With page modeling:

public void WhenNoUsernameAndLoginClicked_ThenValidationMessageShown()
{
      Assert.IsFalse(loginPage.ValidationMessage.IsRendered());
      loginPage.SetUsername("username").Login.Click();
      Assert.IsTrue(loginPage.ValidationMessage.IsRendered());
       Assert.IsTrue(loginPage.ValidationMessage.Text.Equals(expectedMessage));
}

Edit: Added examples for changing login method to require a pin

So, I was challenged that this approach is not maintainable considering the example of login changing to require a pin instead of a password.

I will show how page modeling is less affected by this change than page objects in this case.

Regardless, this is a large change.  In the case of page objects, I would update my login page as:

class LoginPage : Page
{
    // AccountSettings Login(string username, string password, bool rememberMe);
    AccountSettings Login(string username, int pin, bool rememberMe);

// all the IsPinVisible, IsPinEnabled methods have to replace the password ones
// and any orchestration method that uses password
    // bool IsPasswordVisible();
   bool IsPinVisible();

    // bool IsPasswordEnabled();
    bool IsPinEnabled();

   // there is nothing like this in page modeling to update since it belongs in a test
   // SetUsernameAndPin(string username, int pin);
}

This change requires EVERY test that logs in to change.  There is no avoiding this as the password type changed from string to int so at a minimum you'll have to make that change.

This is also true for the page modeling abstraction, but in a different way.  The orchestration layer is affected, and the tests for the login page it self are affected.

class LoginPageUserActions
{
    protected ILoginPage LoginPage{get;}

    public LoginPageUserActions(ILoginPage loginPage)
    {
         this.LoginPage = loginPage;
    }

    public AccountSettings Login(string username, int pin, bool rememberMe)
    {
         // even here, just assume that login works, no need for assertions
         // there should be tests to verify that login works
        return  this.LoginPage
                         .Username.SetText(username)
                        .Pin.SetValue(pin)
                        .RememberMe.SetSelected(rememberMe)
                        .Login.Click();
    }

    // there is no need for an orchestration method like SetUsernameAndPassword
    // it doesn't help anything and is added to page object purely to provide functionality for testing
}

This is exactly the same change that was required by page object.  However, the model for the page changes only by updating it's properties (do not need to change methods around at all since they have the same abstraction over the input).  This reflects much more accurately the real change.  The page added a pin and removed a password.

interface ILoginPage : IPageModel
{
     // password changes to pin
    // IValuable<string, ILoginPage> Password {get;}
    IReadWriteValuePageModel<int, ILoginPage> Pin{get;}
}

The only places that use the Pin directly are the tests for the login page itself.  Everything else uses the LoginPageUserActions orchestration wrapper.

To show what this would look like, lets continue on to the AccountSettings tests.

public class AccountSettingsTests
{
    BrowserWindow window;
    IAccountSettings accountSettings;

    [TestInitialize]
    public void GivenAccountSettingsPage()
    {
          this.window = BrowserWindow.Launch("loginpageurl");

          // before change to use pin
          //new LoginPageUserActions(new LoginPage(this.window)).Login("user", "password");

          // after the change to use pin
          this.accountSettings = new LoginPageUserActions(new LoginPage(this.window)).Login("user", 1234);
    }

    public void WhenChangeFirstNameAndSave_ThenFirstNameIsUpdated()
     {
            this.accountSettings.FirstName.SetText("New Value").Save.Click();
            this.window.Refresh();
            Assert.IsTrue(this.accountSettings.FirstName.Value.Equals("New Value"));
     }
}

Even if I have 1,000 tests in account settings, the only change was in Initialize().  Further, that change is required for page objects as well.

Now, the changes required to page objects are actually more because of the change required for all the methods.  Page Models had exactly one change and that was to remove old property and add new one.  Page objects has to replace all old methods with new ones.

In the page modeling approach, you have extensive tests for a given page and other pages use an orchestration class.  To me, this is far more maintainable than updating tons of methods.  Also, the Pin property is exactly the same as the Password property except that its .SetValue() method takes an int instead of a string.  Testing for visibility, enabled, etc... are all exactly the same and would not change in tests (aside from property name).  You could probably just do a refactor -> rename, change the type, and update the methods that use it to put an int when setting the text.  All other usage would be identical.


Friday, June 3, 2016

Proper Page Modeling (aka Page Objects)

It is making me crazy to see how many people are talking about Page Objects in what seems to be the least robust way possible.  I will try to keep it civil, but here are several examples of what I consider a terrible way to model your UI for testing:

http://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern
http://fluentbytes.com/maintainable-test-automation-for-winforms-using-codedui/ (this one makes me particularly sad as it's Marcel and he's kinda the name for testing in this space ~_~)
https://www.youtube.com/watch?list=PL6tu16kXT9PoUbSYNcLrMG8ox6UBbbsCv&v=UUxSUsUVg-U

In all of these cases, the page objects have methods like .SetUserName("MyUserName"), .ClickLoginLink(), .LoginUser(string username, string password).

How terribly inconsistent and un-maintainable.  What if the user name input is not shown by default and there is a button that shows the user name box.  I'll have to add methods for .IsUserNameBoxVisible(), .ClickButtonToShowUserNameBox().  Wowzer.  As a tester who did not write the page object, I have no consistent expectation of what the page object can do or what the controls on the page can do or what I can assert about them.

Instead, the page object, which I'll now refer to as a Page Model, should expose the UserName input as a property which has methods for .IsVisible(), .Click(), .IsEnabled(), .SetText(string text).  Now, instead of .SetUserName("MyUserName"), it would be .UserName.SetText("MyUserName").  At a glance you may say, so what?  However, having the .UserName property gives me (for free) all of the common actions I may take.  For instance,

interface ILoginPage : IPageModel
{
    IReadWriteValuePageModel<string, ILoginPage> UserName {get;}
    IValuablePageModel<string, ILoginPage> Password {get;}
    IClickablePageModel<ILoginPage> ShowLogin {get;}
    IClickablePageModel<IAccountPage> Login{get;}
}

// page starts with username hidden
Assert.IsTrue(UserName.IsHidden());

// click show login button
ShowLogin.Click();

// assert that the user name is now visible
Assert.IsTrue(UserName.IsVisible());

// assert that the login button is disabled (no username / password entered)
Assert.IsTrue(Login.IsNotActionable());

// enter user name
UserName.SetText("MyUserName");

// assert login button is still disabled (no password)
Assert.IsTrue(Login.IsNotActionable());

// enter a password
Password.SetText("MyPassword");

// the login button should be enabled
Assert.IsTrue(Login.IsActionable());

Login.Click();

compared to

interface ILoginPage
{
    ILoginPage SetUserName(string userName);
    bool IsUserNameVisible();
    ILoginPage SetPassword(string password);
    ILoginPage ClickShowUsernameButton();
    bool IsLoginButtonEnabled();
    IAccountPage ClickLoginButton();
}

If I want to check if the password is visible, then I have to add it as a method.  If I want to check that the show username button disappears after clicking, I have to add a method.  This violates the Open / Close principal and in general is annoying.

It is the responsibility of the tests themselves to create these higher level concepts like

public void LoginUser(string username, string password)
{
    if(ShowLogin.IsVisible())
    {
         ShowLogin.Click();
    }

    UserName.SetText(username).Password.SetText(password).Login.Click();
}

Then, this can be reused in a test:

[TestMethod]
public void GivenLogin_WhenSaveFirstNameInProfile_ThenNameIsLoadedBack()
{
    var accountPage = LoginUser("someUser", "somePass");
    Assert.IsTrue(accountPage.IsVisible());

    string myName = "Myname";
    account.FirstName.SetText(myName).Save.Click();
    Logoff();

    accountPage = LoginUser("someUser", "somePass");
    Assert.IsTrue(myName.Equals(accountPage.FirstName.Value));
}

Wednesday, April 20, 2016

Scrollable Windows 10 Universal JavaScript App

As I'm working more and more on Windows 10 Universal JavaScript Application development, I just can not help but wonder how more people are not on this platform.  With all those web developers out there, you'd think it would be an easy win.

One thing that I found extremely hard to find information about is how to create vertically scrollable areas that are full window height (or full minus some other content area).

At any rate, searching for how to make a UWP app scrollable if the body content exceeds the window height returns barely anything relevant and mostly related to the XAML side of things.  The best answer I could find was to set an explicit height on the element and set the overflow-y: scroll.  This does not work if your screen size changes so I decided to dig in a little bit.

Here are a few different approaches you could take...

Body Fixed Height

You can apply styling to the body element via css to assign a fixed height and set the overflow-y to scroll.

body {
    height: 500px;
    overflow-y: scroll;
}
This will give you a 500px tall, scrollable body.  This is very unlikely to be what you want as you probably want the height to be the window height.

Body Dynamic Height

Since the height of the body should be the height of the window, you'll need to execute some javascript to get this to work.  The page height is not known until the page is rendered.  Even then, the window could be resized, etc.  Here is how to deal with those concerns.

body {
    overflow-y: scroll;
}

function setBodyToWindowHeight() {
    $('body').height($(window).innerHeight());
}

$(function(){ 
    setBodyToWindowHeight(); 
    window.resize(setBodyToWindowHeight); 
});
This will set the body to window height on document ready and whenever the window is resized.

Element Dynamic Height

There may be cases where you do not want the entire body to scroll, but instead some region in the page.  Maybe there is a static header and footer and the middle section needs to scroll.  In this case, you can do something similar if the header and footer do not change after page load.

body {
    overflow-y: scroll;
}

function setElementToRemainingWindowHeight(selector, usedHeight) {
    $(selector).height($(window).innerHeight() - usedHeight);
}

function calculateUsedHeight() {
    return $('.header').innerHeight() + $('footer').innerHeight();
}

$(function(){
    setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
    window.resize(function() {
        setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
    });
});
This will find the used height by finding the inner height of the header and footer and subtracting from the window height.

Element Dynamic Height with Dynamic Layout

There may be a case where the element's height depends on what other content happens to be present and visible on the page.  For instance, maybe the header has a slider that pushes the body and footer down.  In the previous example, the footer would be pushed off the page and you would not be able to scroll to it.

This starts to get a little messy since we have to register callbacks with everything that can change the page.  Assume it's some knockout observable like isInfoExpanded that tells us when the information panel is open.

body {
    overflow-y: scroll;
}

function setElementToRemainingWindowHeight(selector, usedHeight) {
    $(selector).height($(window).innerHeight() - usedHeight);
}

function calculateUsedHeight() {
    return $('.header').innerHeight() + $('footer').innerHeight() + $('#infoPanel').innerHeight();
}

$(function(){
    setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
    window.resize(function() {
        setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
    });

    // this is what I would like to do, but it has a problem...
    // when calculating the used height, the info panel's height is 0 when newVal = true
    // because it has not rendered yet, only the observable value has updated
    // and it is not obvious how to wait until afterRender or throttle a subscribe call
    //isInfoExpanded.subscribe(function(newVal) {
    //    setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
    //});

    // instead, gotta be dirty and use a computed
    // further, since we don't actually need to use the value returned by the computed, but need to still
    // access it for updates, more dirty code can be used :)
    ko.computed(function() { isInfoExpanded() || !isInfoExpanded() &&
        setElementToRemainingWindowHeight('#scrollingRegion', calculateUsedHeight());
    }).extend({throttle: 100}); // this allows time for the rendering
});

This will update the scrolling region's height based on the available height of the window, considering whether the info panel is showing.

Dynamic Elements with Dynamic Height and Dynamic Layout

Phew, so in the previous case, we have an element in the page that will always exist that is having its height manipulated.  What happens if the element whose height is dynamic does not exist in the page when the layout changes.

Consider a button in the layout panel that creates a div whose height should be the available window height.  The above example will not work without having another subscription that somehow is fired when the new div is created and it waits until the div is rendered to set the height, ...

Instead, lets just alter the css rules for the page to accommodate any element popping into the page.

<div data-bind="visible: observableValue">Info Panel</div>
<div data-bind="if: observableValue">
    <div class="scrollableContent">True observable scrolling area</div>
</div>
<div data-bind="ifnot: observableValue">
  <div class="scrollableContent">False observable scrolling area</div>
<div>

In the above markup, the divs with class scrollableContent are only in the page when the condition is true so we cannot target them via jQuery to set the height without the complications mentioned earlier.

Instead, we'll simply alter the rule for scrollableContent to be the desired height.


export class ScrollableContentHelper {
    getCSSRule(ruleName:string, deleteFlag?:string) {
        for (var i = 0; i < document.styleSheets.length; i++) {
            var styleSheet : any = document.styleSheets[i];
            var ii = 0;
            do { // For each rule in stylesheet
                if (styleSheet.rules[ii] && styleSheet.rules[ii].selectorText == ruleName) {
                    return styleSheet.rules[ii]; // return the style object.
                }
                ii++;
            } while (styleSheet.rules[ii]) // end While loop
        } // end For loop
        return false; // we found NOTHING!
    }

    giveSelectorRemainingHeight(ruleName, usedHeightCalculation: () => number) {
        this.getCSSRule(ruleName).style.height = ($(window).innerHeight() - usedHeightCalculation()) + "px";
    }
}


Here is a TypeScript class that can help manage this process.  The giveSelectorRemainingHeight function takes a callback that is run to calculate the used height before setting the element height.

Then, in your default.js file (or whatever is powering your page), instead of using jQuery to set the height of elements by a selector, we'll modify the css rules to do the same thing.


args.setPromise(WinJS.UI.processAll().then(function () { 
    window['applicationViewModel'] = new ApplicationViewModel(); 
    var scrollHelper = new scrollableHelper.ScrollableContentHelper(); 
    ko.computed(() => window['applicationViewModel'].observableValue() &&
                         scrollHelper.giveSelectorRemainingHeight(".scrollContent",
                                                                  () => $("div.header").innerHeight() +  $('footer').innerHeight() + 225))
      .extend({throttle: 100}); 
}));


With this, when the observable value changes, instead of finding the elements and adjusting their height, the css rule is changed to set the height of that selector globally (so that elements that appear after the code is run are still affected).

So it would seem this is not really a UWP concern as much as how to use javascript to dynamically set the height of elements in the page.  By default, web pages viewed in a browser are scrollable when the content exceeds the browser window's height.  In a UWP app, however, no scrolling is provided automatically when the body content exceeds the window's height.  This was the confusing part of me and hopefully this code helps the other developer that is actually creating a UWP application using javascript...

Monday, April 4, 2016

Windows 10 Universal JS + Typescript = Broken in 2015 Update 2

I have been working on a windows universal 10 javascript application and everything was going great.  All my familiar tools were working perfectly and very little change needed to get things working the same way I usually develop.

I needed to re-pave my laptop and tried using a boxstarter script (more on this in another post).  Just about everything was going well, but when I opened the previously working project, it no longer had support for typescript.  Everything that was included with TypeScriptCompile tags were not included in the project and it would only run one time before erroring out saying that it was unable to find the produced js files.

After hours of wondering if my install failed, I was finally able to find an issue submitted on github.  Using Azure Virtual Machines, I was able to identify that the problem was actually related to Visual Studio 2015 Update 2 (see my comments on the issue with included pictures).  TypeScript seemed to work fine in other projects, but just not universal javascript apps.

There seems to be no one else on the internet with this problem, however.  It was insanely difficult to find even this issue, which frankly had very little information inside.  It makes me wonder if people are just not writing universal JS apps or if they are just no using typescript (which is crazy to me).

So far the universal javascript app experience has been quite amazing and very familiar to typical web development.  Hopefully people will begin writing these apps more and support for them improves.

Wednesday, March 30, 2016

Windows 10 Universal JavaScript Debugging TypeScript

Overall, still loving the new Windows 10 Universal Platform JavaScript apps.  Feels just like building for the web.  The one big difference I'm noticing now is that debugging is actually easier in web pages.  How is this possible?

In the browser, when things go wrong, you hit F12 and you're off to the races.  Right click, inspect anything on the page, execute scripts in the console, hover over scripts (including TypeScript) and see the property value, etc.  All good stuff, especially the fact that I can debug my typescript files.  I do not need to work with the generated javascript and figure out what that was in the typescript.

In universal apps, it's closer to traditional development with visual studio where you can set breakpoints and view watch window or locals.  I will say that breakpoints work better in studio than in the browser generally as you can more easily set breakpoints on inline lambda functions that I have not figured out how to do in the browser.

Eg,

this.controller.fetchData().then((result) => [breakpoint] this.storeResult(result));

Breaking into the lambda as written here is difficult in the browser, I would normally have to convert the statement to:

this.controller.fetchData().then((result) => {
    [breakpoint] return this.storeResult(result);
});

so that the function body has a line number which to set the break.

However, the horrible downside to the windows universal stuff is that in the debugger, if you are working on typescript, it will tell you everything is undefined.  Why?  Because of JavaScript's scoping for the this keyword.  In the generated code, you'll find _this is the reference you'll need to work with the object in the console.

Also, I cannot find anyway to 'inspect' the output in the simulator so that finding elements in the page to modify is definitely more difficult.  You do get all the nice features of being able to edit style sheets or markup, but when you modify TypeScript files, it doesn't actually use the modifications!  This can be terribly confusing as the debugger will walk the script with the change, but just not use the modified code.  This may not be true if you directly modify the javascript (haven't tried), but you definitely have to restart the app for type script changes to take hold; which honestly is OK since the TS is compiled during the build, however, it should not give the appearance of being modified and running the modified code.  Simply disallow it or give some grayed out indicator that the code is not actually being used.

Hopefully the 'this' scoping will be fixed soon and a way to inspect would make the development experience better than web development.

Thursday, March 24, 2016

Windows 10 Universal JS with Application Insights

Man oh man oh man.  So much confusion around what is possible with Windows 10 Universal JS apps.  If you google around for what you can and cannot do or how to do things, you'll likely find references to Windows Phone 8 vs 8.1 and silver light and all kinds of stuff so I'm trying to track down what actually works and the proper way of including things in these new projects.

There are even articles that say you cannot do certain things in JS applications or that they are different than the XAML versions, but often no reference is even given to the JS applications.  Store Apps only have XAML references and often JavaScript is referred to as 'JavaScript Web Pages' which is even more confusing.

As of this article's writing, however, the following seems to be true about application insights with regards to Windows 10 Universal JavaScript Apps.

Yes, you can absolutely use Application Insights!

But how?

Normally, when creating a project, you'll have an option to automatically add application insights to your project.  However, this is not the case with Universal JavaScript Applications.  You simply get a blank slate with nothing really provided for you.

You will need to get a special version of the AI library, which can be found here on github.  There is also a minified version available in this repo.

Include this in your js folder, and add it to whatever page/s you want to track by adding a script reference in your HEAD section.

Go to the azure portal and create a new Application Insights Developer Service or locate the instrumentation key for an existing instance.

Then, in your app start code, initialize a new AppInsights object with your instrumentation key and specify the enpointUrl as 'http://dc.services.visualstudio.com/v2/track'.

// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
 "use strict";

 var app = WinJS.Application;
 var activation = Windows.ApplicationModel.Activation;

 window.appInsights = window.appInsights || new Microsoft.ApplicationInsights.AppInsights({ instrumentationKey: '', endpointUrl: 'http://dc.services.visualstudio.com/v2/track' });
 window.appInsights.trackPageView();

 app.onactivated = function (args) {
  if (args.detail.kind === activation.ActivationKind.launch) {
   if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
    // TODO: This application has been newly launched. Initialize your application here.
   } else {
    // TODO: This application was suspended and then terminated.
    // To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
   }
   args.setPromise(WinJS.UI.processAll().then(function () {
    // for debugging, keep global reference
    window.applicationViewModel = new ApplicationViewModel();
       ko.applyBindings(window.applicationViewModel);
   }));
  }
 };

 app.oncheckpoint = function (args) {
  // TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
  // You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
  // If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
 };

 app.start();
})();

That's all there is to it!  You can now view page requests, dependencies, ... in the portal.  It seems that the Visual Studio integration does not work with this approach (at least not with the simulator) so you will not receive notifications or trace data in studio while running in the simulator.

Monday, March 21, 2016

Windows 10 Universal JS + Typescript

While investigating the Windows 10 universal javascript application story, I have been trying to use all the good things that I normally use when developing web applications.  As such, I would like to use TypeScript to help generate valid, working javascript.  Using Typescript is no problem for universal applications as the files are compiled into javascript and available at runtime.

The not-so-obvious part, however, is that by default, no Windows 10 Universal specific definitions are included or available for use by newly created projects.  When working with Web Applications and Windows Universal 10 JS applications, lib.d.ts is available when writing TypeScript files so that things like window.localStorage are available.

When working with universal apps, however, we do not want to use window.localStorage, but instead Windows.Storage.ApplicationData.current.localStorage should be used.  By default, however, this is not available to typescript files.  You must install the definition from nuget or elsewhere.

PM> Install-Package winjs.typescript.definitelytyped
PM> Install-Package winrt.typescript.definitelytyped

These packages will provide definitions for storage and other native APIs that can be called from javascript.

Hopefully this will save someone else hours of searching! :)

Thursday, March 17, 2016

Windows Universal 10 JavaScript App + Knockout.js

I finally decided to see what the universal app stuff is all about, and was ready to finally tackle XAML when, to my surprise, I found that you can write your app using JavaScript and HTML.  No thanks to the template being buried out of the way.  I figured it would have been an option once I picked Universal App just like when you create a Web App you can select WebApi, MVC, Web Forms, how accounts will be handled, ...  Thank god for channel 9.

Even though I found that I *could* do a JavaScript universal app, I figured it would be some really limited subset or quirky, but so far, it's been pretty much an outstanding process.  I was unsure what would and wouldn't work, so I decided to just throw everything I wanted into the project and see what worked.  So far, everything has worked!

In preparation for the project, I googled around about including Knockout.js into a Windows Universal 10 JS App and did not find my information.  In fact, the information that I did find turned out to not work.

I was able to use the package manager to install all of the following:

PM> Install-Package Knockoutjs
PM> Install-Package knockout.TypeScript.DefinitelyTyped
PM> Install-Package fontawesome
PM> Install-Package jquery
PM> Install-Package jquery.typescript.definitelytyped

Honestly, I feel dirty including jquery as I really only ever use the ajax and promises parts of it and should probably learn a better way of dealing with those concerns.  More on that another day.

In default.html, include knockout before the default.js file so that it is in scope when default.js runs.  Modify default.js to include a call to ko.applyBindings.

default.js:
    // For an introduction to the Blank template, see the following documentation:
    // http://go.microsoft.com/fwlink/?LinkId=232509
    (function () {
 "use strict";

 var app = WinJS.Application;
 var activation = Windows.ApplicationModel.Activation;

 app.onactivated = function (args) {
  if (args.detail.kind === activation.ActivationKind.launch) {
   if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
    // TODO: This application has been newly launched. Initialize your application here.
   } else {
    // TODO: This application was suspended and then terminated.
    // To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
   }

   args.setPromise(WinJS.UI.processAll().then(function () {
       ko.applyBindings(new ApplicationViewModel());
   }));

  }
 };

 app.oncheckpoint = function (args) {
  // TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
  // You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
  // If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
 };

 app.start();
})();



In this example I have a new ApplicationViewModel that is being created and bound.  The script file containing the view model also needs to be included on the default.html page.

It's just that simple.

So far, the only things that's really different about this compared to MVC is there is not a routing engine and razor (that I've come across at least).  Just simple page using relational links as you might do in a simple website.

At any rate, I highly encourage anyone that is a web developer to take a look at the Windows Universal 10 JS Apps.

Thursday, February 18, 2016

IEnumerable missing from platform 5.4 class lib

I was converting some code to use the new project templates for .net platform 5.4.  I love how it is setup for sharing by default by producing nuget packages.  I'll have to setup a private nuget server for my sharing code and I'll be sure to write about that when I get there.

Interestingly, the first couple projects I created had no minimal problems and I was able to produce nuget packages quite easily.  Yay.

This time around, however, I was refactoring out some models and interfaces for my web application and I ran in an interesting error...

The type 'IEnumerable<>' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

So, I'm thinking it must be some other error in the project, surely IEnumerable is in there somewhere, right?  WRONG!

Googling around found minimal information that was complete so I figured I'd put together the pieces.  This post got me in the right direction.

 Before:

 "frameworks": {
    "net451": {
      "dependencies": {
        "System.ComponentModel.Annotations": "4.0.0"
      }
    },
    "dotnet5.4": {
      "dependencies": {
        "Microsoft.CSharp": "4.0.1-beta-23516",
        "System.Collections": "4.0.11-beta-23516",
        "System.ComponentModel.Annotations": "4.0.11-beta-23516",
        "System.Linq": "4.0.1-beta-23516",
        "System.Runtime": "4.0.21-beta-23516",
        "System.Threading": "4.0.11-beta-23516"
      }
    }
  }

After:

  "frameworks": {
    "net451": {
      "dependencies": {
        "System.ComponentModel.Annotations": "4.0.0"
      },
      "frameworkAssemblies": {
        "System.Runtime": "4.0.10.0"
      }
    },
    "dotnet5.4": {
      "dependencies": {
        "Microsoft.CSharp": "4.0.1-beta-23516",
        "System.Collections": "4.0.11-beta-23516",
        "System.ComponentModel.Annotations": "4.0.11-beta-23516",
        "System.Linq": "4.0.1-beta-23516",
        "System.Runtime": "4.0.21-beta-23516",
        "System.Threading": "4.0.11-beta-23516"
      }
    }
  }

Saturday, February 13, 2016

Creating a Derived Knockout Binding

public class Person
{
    [DataType(DataType.Date)]
    [Column(TypeName = "Date")]
    public DateTime DateOfBirth {get;set;}
}
When returning a Person object from a WebAPI, the JSON looks like:
{
  DateOfBirth: "1990-01-01T00:00:00"
}
When trying to bind this to a date input type using Knockout.js
  <input data-bind="value: DateOfBirth" type="date" />
you will notice that the rendering of the control is the one used when the value is not set and is not initialized properly.

I figured I could update the view model that does the fetching to replace all date string before loading model types or create a binding that handled the possibility of this date format.

I decided to try the latter and create a binding that works similar to the value binding except that it first checks the format of the date input string and updates it to one that works with the date input type.
ko.bindingHandlers.dateValue = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (/^\d\d\d\d-\d\d-\d\d(T\d\d:\d\d:\d\dZ?)?/.test(valueAccessor()())) {
            valueAccessor()((valueAccessor()() || "").substr(0, 10));
        }

        ko.bindingHandlers.value.init(element, valueAccessor, allBindings, viewModel, bindingContext);
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.bindingHandlers.value.update(element, valueAccessor, allBindings, viewModel, bindingContext);
    }
}
In the above example, I assume that the binding will be applied to date input types and that the model property is an observable containing the date.  In the init function, I simply get the value from the value accessor and test it's format.  If it matches, I convert to the format required by date input types by simply taking a sub string.   Then I call the value binding's init function, passing along all the parameters.  In the update, I simply call the value binding's update function, passing along all the parameters.

In the knockout documentation, they describe a way to register a preprocessor function on existing bindings, but this method effectively creates a derived binding, similar to how a derived class would be created.  This could also be considered a wrapper around the existing value binding.

This was simpler than I thought it would be!

Tuesday, February 2, 2016

Typing data returned from a WebAPI

I'm a huge fan of where modern web development is headed.  My current technology stack is ASP.NET MVC 5 & WebAPI 2 using ASP.NET Identity to provide social integration.  On the client, I really like Knockout.js because it handles just model binding.  Currently, I also use jQuery for it's promises and ajax, but I think there is probably a better (more light-weight) solution for just that and I will be looking to replace it.

While I have been interviewing, I have noticed that Angular often comes up while talking about ASP.NET MVC and that drives me crazy, crazy.  Firstly, if you are going Angular, why are you using ASP.NET MVC with IIS?  I like having ASP.NET handling my routing, security, data validations, ... and let knockout handle just the model binding on the front end.  If you are using Angular just for model binding, I would image you are pulling in way more than needed.  Similar to my using jQuery for just the ajax / promises :)

With that out of the way, I can focus on the real task at hand....

How to handle data returned from a WebAPI

Ok, so that's a broad topic.  Let's narrow it down to a few categories:

Display Only Data

This type of data is only used to display something to the user.  They are not going to manipulate this data.

In this case, I have seen examples of folks generating interfaces for the data and using that where needed.  An example would look like:

C#
public class MyListItem
  {
    public int Id { get; set; }
    public string Title { get; set; }
  }
TypeScript
 interface IMyListItem {
    Id: number;
    Title: string;
  }
However, I prefer to use types instead.
 type MyListItemInfo = {
    Id: number;
    Title: string;
  };
This seems to be a more appropriate indication of the expectation of the data.

If I were to call some ApiController method that returned a list of these, it may look something like this:


[HttpGet]
[Route("")]
public async Task<MyListItem[]> GetItems()
{
        return await this.Request.GetOwinContext().Get<ApplicationDbContext>().Items.ToArrayAsync();
}

//[{Id:1, Title:"Red Hat"}]
GetItems() : JQueryPromise<MyListItem[]> {
    return $.getJSON("http://mysite.com/api/items/");
}

At this point, my javascript code has to hope for the best.  It is being handed JSON from some external source which may not be under our control.  Indicating that it is some type which the designated shape better defines the data.  If we were to return it as an interface, that may indicate that we have ensured the created javascript code actually implements the interface.

The following would be an appropriate use of interfaces:

class MyListItem implements IMyListItem {
 Id: number;
 Title: string;
 // prefer to accept the type when loaded from external
 constructor(initial?:IMyListItem/*MyListItemInfo*/){
   this.Id = initial && initial.Id;
   this.Title = initial && initial.Title; 
 } 
}; 

class ItemManagementViewModel{ 
 private urlBase: string; 
 constructor(urlBase: string){ 
   this.urlBase = urlBase; 
 } 

 // actually implements IMyListItem
 GetItems() : JQueryPromise<IMyListItem[]>{
   return $.getJSON(this.urlBase)
           .then(result => $.map(result, r => new MyListItem(r)));
 }
}


Read / Write Data

This type of data is meant to be downloaded and presented to the user for possible manipulation. In this case, I'd like to have a editable version of the object.

class MyListItemEdit {
    // cannot edit Id; it's an identifier for what we have just edited
    Id: number;
    Title: KnockoutObservable<string>;
    constructor(initial?: MyListItemInfo){
        this.Id = initial && initial.Id;
        this.Title = ko.observable(initial && initial.Title);
    }
}


[HttpPost]

[Route("save")]
public async Task<int> SaveItem([FromBody]MyListItem toSave) {
  var item = await 
  this.Request
      .GetOwinContext()
      .Get<ApplicationDbContext>()
      .Items
      .FirstOrDefaultAsync(x => x.Id == toSave.Id);
   if( null == item ){ throw new ArgumentException(); }
   item.Title = toSave.Title;
   return await this.Request
      .GetOwinContext()
      .Get<ApplicationDbContext>().SaveChangesAsync();
}

// notice that we have to project into the edit type
// this is why I prefer the edit type to take a type
// and not an interface
GetItemsForEdit() : JQueryPromise<MyListItemEdit[]>{
   return $.getJSON(this.urlBase)
           .then(result => $.map(result, r => new MyListItemEdit(r)));
 }

SaveItem(toSave: MyListItemEdit) : JQueryPromise<number>{
   return $.ajax({
      url: this.urlBase + 'save',
      method: 'POST',
      contentType: 'application/json',
      dataType: 'json',
      data: JSON.stringify(ko.toJS(toSave))
   });
 }



To this end, I was about to create a tool to generate these typescript files from C# types, but I stumbled across this article regarding generating these files using TypeLite.  I like that it was built on top of T4 templates and will be giving this a shot.  I am going to try an manipulate the template to generate types instead of interfaces and to create edit types that take the type as constructor argument.