Running webdriver-start and protractor-start using grunt and protractor is not starting as webdriver-start command doesn't let next process to start

StackOverflow https://stackoverflow.com/questions/23582435

Question

I am using Grunt to run protractor end to end test cases. I have following three tasks (I am using windows 7 machine)

  1. webdriver-stop
  2. webdriver-start
  3. protractor-start

I am trying to run these three tasks as mentioned above order. However problem is grunt stuck at #webdriver-start process and doesn't let #protractor-start process to run. Following is my grunt config. Please help.

/**
 * New node file
 */
module.exports = function(grunt){

    //globalConfig and paths which will used in the grunt script

    var config={

            srcFolderName: 'src',
            distFolderName: 'dist',
            appFileName: 'server.js',
            nodeModuleFolderName: 'node_modules',
                        testSourceFolderName: 'src-test',
                        testDestFolderName: 'Test',
            //change this command based on project requirement
            apiDocCommand:'apidoc -i src/server -o apidoc',
            npmInstallCommand: 'npm install --prefix ./dist/<%= pkg.name %>/node_modules',
                        protractorPath:'./node_modules/protractor'

    }

    //init
    grunt.initConfig({
        config:config,
        pkg: grunt.file.readJSON('package.json'),
        copy: {

            //copy all source files to distribution folder
            sourceFiles: {
              cwd: '<%= config.srcFolderName %>',
              src: [ '**' ],
              dest: '<%= config.distFolderName %>/<%= pkg.name %>',
              expand: true
            },
            //copy main app file to dist folder
            mainAppFile: {
                src: '<%= config.appFileName %>',
                dest: '<%= config.distFolderName %>/<%= pkg.name %>/<%= config.appFileName %>'
            },
            copyPackage:{
                src: 'package.json',
                dest: '<%= config.distFolderName %>/<%= pkg.name %>/package.json'
            },
            //copy all source test files to distribution folder
            testFiles: {
              cwd: '<%= config.testSourceFolderName %>',
              src: [ '**' ],
              dest: '<%= config.distFolderName %>/<%= config.testDestFolderName %>',
              expand: true
            }
          },
          clean : {
              build : {
                  src : [ '<%=config.distFolderName%>/','apidoc/' ]
              },
              pkgJson : {
                  src : ['<%= config.distFolderName %>/<%= pkg.name %>/package.json']
              }
          },
          uglify: {
              serverCode:{
                  files: [{
                      expand:true,
                      cwd:'<%= config.distFolderName %>/<%= pkg.name %>/server',
                      src:'**/*.js',
                      dest:'<%= config.distFolderName %>/<%= pkg.name %>/server'
                  }]
              },
              clientCode:{
                  files: [{
                      expand:true,
                      cwd:'<%= config.distFolderName %>/<%= pkg.name %>/client/js/application',
                      src:'**/*.js',
                      dest:'<%= config.distFolderName %>/<%= pkg.name %>/client/js/application'
                  }]
              },
              mainAppFile: {
                  files: {
                       '<%= config.distFolderName %>/<%= pkg.name %>/<%= config.appFileName %>':['<%= config.distFolderName %>/<%= pkg.name %>/<%= config.appFileName %>']
                  }
              }
          },
          jshint:{
              serverCode:{
                  files:[{
                      expand:true,
                      cwd:'<%= config.distFolderName %>/<%= pkg.name %>/server',
                      src:'**/*.js'
                  }]
              },
              clientCode:{
                  files: [{
                      expand:true,
                      cwd:'<%= config.distFolderName %>/<%= pkg.name %>/client/js/application',
                      src:'**/*.js'
                  }]
              },
                  clientTestCode:{
                  files: [{
                      expand:true,
                      cwd:'<%= config.distFolderName %>/<%= config.testDestFolderName %>/unit/client/js',
                      src:'**/*.js'
                  }]
              },
                  serverTestCode:{
                  files: [{
                      expand:true,
                      cwd:'<%= config.distFolderName %>/<%= config.testDestFolderName %>/server',
                      src:'**/*.js'
                  }]
              }
          },
          //mocha is used to automate unit testing of server side nodejs/express code.
          simplemocha: {
            options: {
                globals: ['expect'],
                timeout: 3000,
                ignoreLeaks: false,
                ui: 'bdd',
                reporter: 'tap'
            },
            all: { src: ['dist/Test/unit/server/**/*.js'] }
        },
        //karma is used to automate unit testing of client side angular/javascript test cases writtin in jasmine.
        karma: {
            unit: {
                configFile: 'dist/Test/unit/client/config/karma.conf.js',
                background: false
            }
        },
        protractor: {
                    options: {
                          configFile: "protractor-config.js", //your protractor config file
                          keepAlive: true, // If false, the grunt process stops when the test fails.
                          noColor: false, // If true, protractor will not use colors in its output.
                          args: {
                              // Arguments passed to the command
                          }
                      },
                    chrome: {
                        options: {
                              args: {
                                    browser: "chrome"
                              }
                          }
                    },
                    safari: {
                        options: {
                            args: {
                                browser: "safari"
                            }
                        }
                    },
                    firefox: {
                        options: {
                            args: {
                                browser: "firefox"
                            }
                        }
                    }
                },
         exec: {
                  generateAPIDoc : {
                      command: '<%= config.apiDocCommand %>'
                  },
                  buildDependencies :{
                      command: '<%= config.npmInstallCommand %>'
                  },
                  webdriverStart :{
                      command: 'node <%= config.protractorPath %>/bin/webdriver-manager start &'
                  },
                          webdriverSop :{
                      command: 'start http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer'
                  },

                  protractorStart :{
                      command: 'node <%= config.protractorPath %>/bin/protractor ./dist/Test/integration/config/protractor-config.js'
                  }

          }
    });

    // load our tasks
    grunt.loadNpmTasks('grunt-contrib-copy');
    grunt.loadNpmTasks('grunt-contrib-clean');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-simple-mocha');
    grunt.loadNpmTasks('grunt-karma');
    grunt.loadNpmTasks('grunt-protractor-runner');
    //for running executables
    grunt.loadNpmTasks('grunt-exec');

    grunt.registerTask('start-server', 'Start a custom web server', function() {
        grunt.log.writeln('Started web server on port 3000');
        require('./dist/ThemeLibrary/server.js');
    });

    //                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            the tasks
    grunt.registerTask('build',
            'Compiles all of the assets and copies the files to the build directory for Dev', 
            [ 'clean:build', 'clean:pkgJson','copy','exec:buildDependencies','jshint','exec:generateAPIDoc','uglify:serverCode','uglify:clientCode','uglify:mainAppFile','simplemocha','start-server', 'karma:unit']
    );
    grunt.registerTask('build-dev',
            'Only copies the source files for Dev', 
            [ 'copy:sourceFiles','copy:mainAppFile', 'copy:testFiles', 'jshint', 'simplemocha','start-server','karma:unit','exec:webdriverSop','exec:webdriverStart', 'exec:protractorStart']
    );
};
Was it helpful?

Solution

I stopped using grunt to run protractor commands, since grunt swallows most of the meaningful stacktraces from protractor.

Instead, I recommend using multiple protractor.conf.js files, and executing them in your build processes (travis, jenkins, etc.).

For instance, I use protractor.conf.js for our CICD validation, protractor.e2e.conf.js for our staging-specific tests, and others as neeeded (integration, regression-only).

You should probably kick off a selenium server (selenium-server if you installed via brew), making sure to background its output. Then, fire off your protractor tests with protractor test/proctractor.conf.js. It's much simpler that way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top