Skip to content

Integrating pact mock service with Grunt and Protractor

Michel Boudreau edited this page Jan 9, 2015 · 1 revision

If you're like us and use Grunt to build your front-end resources, this is a definite need if you want to automatically spin up pact-mock-service before your end to end tests starts (in our case, using protractor)

##Dependencies## You will need to install:

npm install grunt-shell-spawn@^0.3.1 grunt-wait grunt-mkdir grunt-contrib-connect protractor grunt-protractor-runner --save-dev

##Gruntfile.js## Make sure to add the load tasks for the dependencies:

grunt.loadNpmTasks('grunt-shell-spawn');
grunt.loadNpmTasks('grunt-wait');
grunt.loadNpmTasks('grunt-mkdir');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-protractor-runner');

###Grunt taskConfig###

####Shell task for the pact-mock-service command: ####

shell: {
  options: {
      stdout: true,
      stderr: true,
      failOnError: true
  },
  pact: {
    command: 'pact-mock-service -p 9700', 
    options: {
      async: true
    }
  }
}

Make sure to specify the port you are using with the pact-mock-service, otherwise it will pick an open port at random.

The async option will allow the pact service to spin up alongside the rest of the grunt script.

Wait Task

We add a small delay since our pact might take a little while to spin up and we don't want protractor to run beforehand.

wait: {
  options: {
    delay: 1000
  },
  pact: {
  }
}

Mkdir Task - create tmp directory for pact and chrome

mkdir: {
    tmp: {
    options: {
	create: ['.tmp/chrome', '.tmp/pacts']
        }
    }
}

Pact will write its files in the .tmp directory after the tests are complete. We're also setting up chrome in it's own sandbox, hence the extra folder.

It's also worth adding the .tmp directory to the clean of your project as well if you have grunt-contrib-clean installed.

clean: [
  '<%= build_dir %>',
  '<%= release_dir %>',
  '<%= package_dir %>',
  '<%= mkdir.tmp.options.create %>' /*.tmp cleanup */
]

Connect Task

connect: {
	options: {
		protocol: 'http', 
	},
	test: {
		options: {
			port: 8181,
			base: '<%= build_dir %>'
		}
	}
}

Protractor Task

protractor: {
	options: {
		configFile: "protractor.config.js",
		keepAlive: true,
		args: {
			verbose: true,
			specs: '<%= app_files.jse2e %>',
			baseUrl: '<%= connect.options.protocol %>://localhost:<%= connect.test.options.port %>/<%= pkg.name %>/'
		}
	},
	all: {
	}
}

Protractor Config

exports.config = {
    noColor: false,
    rootElement: 'html',
    directConnect:true,
    chromeDriver: 'node_modules/chromedriver/lib/chromedriver/chromedriver',
    capabilities: {
	    browserName:'chrome',
	    chromeOptions: {
		    args: ['disable-web-security', 'user-data-dir=./.tmp/chrome']
	    }
    },
    jasmineNodeOpts: {
	    onComplete: null,
	    isVerbose: true,
	    showColors: true,
	    includeStackTrace: true
    }
};

####Adding the pact-mock-service tasks to your grunt task####

grunt.registerTask('test:e2e', ['connect:test', 'shell:pact', 'wait:pact', 'protractor', 'shell:pact:kill']);

In this example, connect:test will be run, spinning up a light web server to run the e2e tests on. Grunt will then spin up the pact service and wait for a second to get that setup. Then protractor will run, conducting its e2e testing.

Finally, the pact-mock-service will be killed after protractor is done.