admin管理员组

文章数量:1414949

I am very much enjoying AWS Lambda functions, and I'm wondering if what I want to do here is possible. On my local machine, I have a Protractor config file :

// conf.js
exports.config = {
  framework: 'jasmine',
  seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
  specs: ['automation-script.js'],
  capabilities: {
    browserName: 'chrome'
  }
}

and a script that loads up a browser window with a certain url:

describe('Protractor Demo App', function() {
  it('should have a title', function() {
    browser.driver.get('/');

   // Click around and do things here.

  });
});

The purpose my scripts right now are not to black-box test an application that I'm developing, but instead to automate mon browser tasks that I don't feel like doing.

Currently, I'm running the protractor script through my local mand shell like this:

protractor protractor.conf.js 

I'm wondering if it is possibly to run protractor from within another node.js script. My thinking is that I could have the Lambda function kick off a protractor job, possibly by using the browsers available from Browserstack or Sauce Labs, but I can't figure out how to run protractor from a Node.js script.

I am very much enjoying AWS Lambda functions, and I'm wondering if what I want to do here is possible. On my local machine, I have a Protractor config file :

// conf.js
exports.config = {
  framework: 'jasmine',
  seleniumAddress: 'http://127.0.0.1:4444/wd/hub',
  specs: ['automation-script.js'],
  capabilities: {
    browserName: 'chrome'
  }
}

and a script that loads up a browser window with a certain url:

describe('Protractor Demo App', function() {
  it('should have a title', function() {
    browser.driver.get('https://github./');

   // Click around and do things here.

  });
});

The purpose my scripts right now are not to black-box test an application that I'm developing, but instead to automate mon browser tasks that I don't feel like doing.

Currently, I'm running the protractor script through my local mand shell like this:

protractor protractor.conf.js 

I'm wondering if it is possibly to run protractor from within another node.js script. My thinking is that I could have the Lambda function kick off a protractor job, possibly by using the browsers available from Browserstack or Sauce Labs, but I can't figure out how to run protractor from a Node.js script.

Share Improve this question edited Jan 10, 2018 at 0:00 Jim asked Nov 13, 2016 at 15:55 JimJim 4,2111 gold badge33 silver badges63 bronze badges 2
  • 1 I'm not sure, but generally lambdas are for changing/checking files going in and out of S3 storage, responding to certain http calls etc? This seems like something that would be better suited to run on an EC2 instance in Node etc. – adeneo Commented Nov 13, 2016 at 15:59
  • 2 I would think anything that can be done with Ec2 could also be done as a serverless architecture with Lambda. – Jim Commented Nov 13, 2016 at 16:34
Add a ment  | 

1 Answer 1

Reset to default 8 +25

This is a really interesting question. Our organization has been probing how much of our CI/CD pipeline can be done in a serverless fashion. This is right up that alley.

Unfortunately, I don't think there is an elegant way to run protractor from another Node script. That is, protractor doesn't seem to expose an API that makes it easy to consume in such a manner.

It's been asked for, but (as a relative newer to protractor) the ment right before the issue was closed doesn't contain enough detail for me to know how to take that approach. So, the not-so-elegant approach:

Child Process

Prior ments notwithstanding, you can indeed run protractor from within another Node script, including a Node script executing in AWS' Lambda environment. There may be prettier/better ways to do this, but I took this answer and based the following Lambda function on it:

'use strict';

module.exports.runtest = (event, context, callback) => {

  var npm = require('npm');
  var path = require('path');
  var childProcess = require('child_process');
  var args = ['conf.js'];

  npm.load({}, function() {
    var child = childProcess
    .fork(path.join(npm.root, 'protractor/bin/protractor'), args)
    .on('close', function(errorCode) {
      const response = {
        statusCode: 200,
        body: JSON.stringify({
          message: `Selenium Test executed on BrowserStack!  Child process Error Code: ${errorCode}`,
        }),
      };
      callback(null, response);
    });
    process.on('SIGINT', child.kill);
  });
};

var args = ['conf.js']; points to the protractor config file, which in turn points to the test (index.js in this case):

exports.config = {
    'specs': ['./index.js'],
    'seleniumAddress': 'http://hub-cloud.browserstack./wd/hub',
    'capabilities': {
      'browserstack.user': '<BROWSERSTACK_USER>',
      'browserstack.key': '<BROWSERSTACK_KEY>',
      'browserName': 'chrome'
    }
  };

Repository here.

Notes

  • npm is a runtime dependency using this approach, meaning it has to be packaged into your deployable. This makes for a relatively large lambda function. At ~20mb, it's big enough that you don't get to edit code inline in the AWS console anymore. An approach that didn't package npm as a runtime dependency would be much nicer.
  • Don't forget Lambda has a hard 5 minute time limit. Your tests will need to plete in less time than that.
  • Watch the clock. In many instances, my toy example only uses a browser for a couple of seconds, but the overhead (of connecting to BrowserStack, mostly, I presume) makes the Lambda take 12-30 seconds altogether. Paying for 30 seconds of pute to use a browser for 2.5 seconds doesn't sound like a win. Larger batches of tests might be less wasteful.
  • You do get CloudWatch logging of the child process without doing any extra plumbing yourself, which is nice.
  • Disclaimer: My example has only been happy-path tested, and I'm no expert on child processes in Node.

本文标签: