How to setup protractor to import AMD modules with

2019-02-18 14:07发布

I'm trying to import an AMD module (ES6 module transpiled in ES5) in a protractor test. I'm using the Page Object pattern. And the Page Object is the module I'm trying to import.

Here is the ES6 code:

import {HelloPage} from 'HelloPage';

describe('The demo app', function () {

  beforeEach(function () {
    browser.get('http://localhost:3000/index.html');
  });

  it('should say hello',function(){
    var helloPage = new HelloPage();
    helloPage.setFirstName('Martin');
    helloPage.submit();
    // then, expect statement.
  })

});

The generated ES5 code looks like this:

define(['HelloPage'], function($__0) {
  "use strict";
  if (!$__0 || !$__0.__esModule)
    $__0 = {default: $__0};
  var HelloPage = $__0.HelloPage;
  describe('The demo app', function() {
    beforeEach(function() {
      browser.get('http://localhost:3000/index.html');
    });
    it('should say hello', function() {
      var helloPage = new HelloPage();
      helloPage.setFirstName('Martin');
      helloPage.submit();
    });
  });
  return {};
});

The problem is the fact I'm using define() from requirejs. But I never declared anywhere that I was using requirejs. So I get the following error :

Failures:

  1) Exception loading: build/test/e2e/Hello.spec.js Error
   Message:
     ReferenceError: define is not defined

The protractor conf file is like that :

exports.config = {
  capabilities: {
    'browserName': 'chrome'
  },

  specs: [ 'build/test/e2e/**/*.js'],

  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000
  }
};

Where I should declare in this configuration file that I'm using requirejs to execute tests ?

3条回答
别忘想泡老子
2楼-- · 2019-02-18 14:47

I would recommand not to transpile first and then import, but just use ES6 in protractor. Put following at the top of the protractor.conf.js file. Now, you can just use import statements.

For Babel 6 version put following at the top (or in onPrepare) of the protractor.conf.js:

require("babel-core/register")({
    presets: [
        "es2015"
    ]
});
查看更多
Evening l夕情丶
3楼-- · 2019-02-18 14:52

You can also use amdefine as said Martin, but without prepending each file with
if (typeof define !== 'function') { var define = require('amdefine')(module) }

Just include "amdefine": ">=0.1.0" in your devDependencies and add require('amdefine/intercept'); to onPrepare function in your protractor config. It will automatically insert the above snippet in each .js file loaded by Node.

查看更多
女痞
4楼-- · 2019-02-18 14:57

A solution is to use amdefine as it is described in requirejs.org/docs/node.html#3 the drawback of this solution is that you need to prepend every module by the following line :

if (typeof define !== 'function') { var define = require('amdefine')(module) }

In my specific case, because I'm using traceur to transpile ES6 files, I chose to use commonjs module instead of AMD for e2e tests. The reason it's different from unit tests executed by Karma (where I can easily use AMD) is the fact that protractor tests are executed by Node.js and not by the browser. So, I changed the traceur modules options for e2e tests only to this:

{
      "modules": "commonjs",
      "script": false,
      "types": true,
      "annotations": true,
      "memberVariables":true,
      "outputLanguage": "es5"
}
查看更多
登录 后发表回答