mdasberg / ng-apimock

Node plugin that provides the ability to use scenario based api mocking: for local development for protractor testing
MIT License
99 stars 26 forks source link

Show set-up instructions on README for an angular-cli project #10

Closed builtbyjay closed 7 years ago

builtbyjay commented 7 years ago

Unfortunately I can't figure out how to set this up within my angular-cli project, would you be able to provide some example code as to how to do this please?

wswebcreation commented 7 years ago

Hi @builtbyjay ,

What is your setup? That would make it easier to help you.

builtbyjay commented 7 years ago

Sorry I should've included that in the original post. I am using the latest version of angular-cli (1.0.0-rc.0 - build and compilation tasks handled by webpack) and angular 2.4.

It's a completely new and empty project initialised with angular-cli :)

wswebcreation commented 7 years ago

I need to dive into that, but is there a way you can hook on to the server process. I see angular-cli uses express.

mdasberg commented 7 years ago

@builtbyjay I have added ANGULAR_CLI.md which should contain all the information you need.

If you still have questions, don't hesitate to ask.

builtbyjay commented 7 years ago

Guys, thank you so much for a) the angular-cli documentation and b) this awesome awesome project! It is exactly what my team is looking for for our mocked e2e and behavioural tests. Would you mind if I wrote a blog article in the (hopefully not too distant) future about how we're using it in our Angular workflow?

wswebcreation commented 7 years ago

@builtbyjay

Tnx, and feel free.

builtbyjay commented 7 years ago

Sorry to reopen the issue, I'm unable to get ngApimock to work with my protractor tests. I have added:

global.ngApimock = require('./.tmp/ngApimock/protractor.mock.js');

to the onPrepare block of my protractor.conf.js file and when I run my e2e tests, I get the following error:

- Failed: Trying to load mock modules on an Angular v2+ app is not yet supported.

What am I doing wrong?

Angular 2.4.0 Angular-cli 1.0.0-rc.2 Protractor 5.1.0

mdasberg commented 7 years ago

can you add

useAllAngular2AppRoots: true

to your protractor conf.

That should fix your problem

builtbyjay commented 7 years ago

That's that problem fixed, but now I'm getting the following error:

[10:56:14] E/launcher - Error: TSError: ⨯ Unable to compile TypeScript
e2e/app.e2e-spec.ts (12,5): Cannot find name 'ngApimock'. (2304)

Seems I can't access the global.ngApimock declared in my onPrepare.

wswebcreation commented 7 years ago

@builtbyjay

Can you give an example of your app.e2e-spec.ts file?

Did you also declared it like this declare const ngApimock: any; ?

builtbyjay commented 7 years ago

Sure. protractor.conf.js looks like this:

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

const { SpecReporter } = require('jasmine-spec-reporter');

exports.config = {
  useAllAngular2AppRoots: true,
  allScriptsTimeout: 11000,
  specs: [
    './e2e/**/*.e2e-spec.ts'
  ],
  capabilities: {
    'browserName': 'chrome'
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  framework: 'jasmine',
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000,
    print: function() {}
  },
  beforeLaunch: function() {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
  },
  onPrepare() {
    global.ngApimock = require('./.tmp/ngApimock/protractor.mock.js');
    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
  }
};

And app.e2e-spec.ts looks like this:

import { TestPage } from './app.po';

describe('App', () => {
  let page: TestPage;

  beforeEach(() => {
    page = new TestPage();
  });

  it('should display one instalment', () => {
    ngApimock.selectScenario('api/get-instalments', 'single');
    page.navigateTo();
    expect(page.getInstalments().count()).toEqual(1);
  });

  it('should display three instalments', () => {
    ngApimock.selectScenario('api/get-instalments', 'three');
    page.navigateTo();
    expect(page.getInstalments().count()).toEqual(3);
  });
});
builtbyjay commented 7 years ago

Ok, so I've figured out how to pass ngApimock into the e2e file. I've changed the onPrepare block of protractor.conf.js to add ngApimock to the global browser object:

  onPrepare() {
    browser.ngApimock = require('./.tmp/ngApimock/protractor.mock.js');
    jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
  }

And I can access that within my e2e test as follows:

import { TestPage } from './app.po';
import { browser } from 'protractor';

describe('App', () => {
  let page: TestPage;

  beforeEach(() => {
    page = new TestPage();
  });

  it('should display one instalment', () => {
    browser['ngApimock'].selectScenario('api/get-instalments', 'single');
    page.navigateTo();
    expect(page.getInstalments().count()).toEqual(1);
  });

  it('should display three instalments', () => {
    browser['ngApimock'].selectScenario('api/get-instalments', 'three');
    page.navigateTo();
    expect(page.getInstalments().count()).toEqual(3);
  });
});

This isn't working unfortunately, the browser fires up but the tests hang and the page is never loaded.

wswebcreation commented 7 years ago

Did you declare the global ngApimock in your e2e file?

builtbyjay commented 7 years ago

No I don't think I have..

builtbyjay commented 7 years ago

Hey guys, I think I've solved my issue. When running my e2e tests, my angular-cli app is served on port 49154, proxied to the ngApimock server running on port 3000.

However, in the generated .tmp/ngApimock/protractor.mock.js, the _execute() requests are being sent to http://localhost:49154/ngapimock/mocks rather than to http://localhost:3000/ngapimock/mocks, resulting in timeouts.

Manually setting the baseUrl to use the same port as the ngApimock server fixes the issue.

    var ngapimockid = require('uuid').v4(),
        request = require('sync-request'),
        // baseUrl = require('url-join')(browser.baseUrl, 'ngapimock');
        baseUrl = 'http://localhost:3000/ngapimock';

I hope my explanation makes sense!

wswebcreation commented 7 years ago

Tnx for the response.

I'm closing the issue for now. If you have more questions feel free to open a new issue

allanbond commented 7 years ago

@builtbyjay

I had the same problem with the port and found that I needed to add another entry to my proxy.config.json.

I added my app's endpoints AND the ngmockapi endpoints. This way, both sets of endpoints will be sent to the ngmockapi server (at port 3000).

{
 "/myapi/*": {
   "target": "http://localhost:3000",
   "secure": false,
   "logLevel": "debug"
 },
 "/ngapimock/*": {
   "target": "http://localhost:3000",
   "secure": false,
   "logLevel": "debug"
 }
}
builtbyjay commented 7 years ago

@allanbond That is a very nice fix, thanks!