Sponsored By Kids In Touch

E2E Testing Angular Apps with Cypress.io

UPDATE : Gleb Bahmutov, from the Cypress team, was kind enough to put together a blog post explaining how to solve my issue.

I have to admit that I've rarely done unit testing or end to end testing with any of the Ionic framework apps I've developed. I've tried several times and have simply found it too hard to get rolling. It was almost as if I needed to know a brand new language.

Last week, I discovered the E2E testing library called Cypress. Right away, I could tell I was going to like it. After watching the simple Writing Your First Test video, I was ready to test the login page of a major enterpris app I work on. Within minutes, I had my first working test. Since then, I've been reading documentation and learning how to do most routine testing.

Howevever, one thing I have not figured out how to do involves actually talking to the Angular services and methods that I need to access. For example, I don't want to use the UI to login to the app before each and every test script. The Cypress documentation talks about how to actually do this with a non-Angular app like:

cy.request({  
  method: 'POST',
  url: '/login',
  body: {
    username: 'xxxx',
    password: 'yyyy'
  }
})

Unfortunately, I can't do something quite to simple in the app I'm working on. My login process does all kinds of things like encrypting the user object before POSTing. So, I really need to just call a method on my Auth service, but I can't figure out a way to do this in Cypress.

I've tried something like this:

describe('The Home Page', function() {

  var Auth;

  it('successfully loads the home page', function() {

    cy.visit('/');

    Auth = angular.element(document.querySelector('body')).injector().get('Auth');

    Auth.login({
      "userid": "xxxxx",
      "password": "xxxxx",
      "language": "en"
    }).then(response => {
      console.log('Response = ', response);
      cy.visit('/#/app/tabs/store-overview');
    });

  });
})

Due to the way Cypress enqueus all tests, the code above tries to access Angular before my default page is even visited. So, I get an error like this:

Next, I tried to do this:

describe('The Home Page', function() {

  var Auth;

  it('successfully loads', function() {
    cy.visit('/');

    cy.url()
        .should('include', '/#/login')
        .then(() => {
          setTimeout(() => {
            console.log('Getting auth!');
            Auth = angular.element(document.querySelector('body')).injector().get('Auth');
            console.log('Auth = ', auth);

            Auth.login({
              "userid": "xxxxx",
              "password": "xxxxx",
              "language": "en"
            }).then(response => {
              console.log('Response = ', response);
            })

          })
        });

      cy.visit('/#/app/tabs/store-overview');

  });
})

This throws no failures, but doesn't really do anything. The Getting Auth gets called, but for some reason, the console after getting Auth does not get called.

So, now I'm stuck and looking for ideas. Does anyone have a suggestion on how to interact with my services and controllers when needed?