RequireJS modules in Protractor specs. Is it possible?

时间:2015-06-15 15:19:29

标签: requirejs protractor amd angularjs-e2e e2e-testing

Important information: I'm using TypeScript compiled to ES5.

My final goal with this would be to have modular specs that could on the fly load helpers and ease the use of the PageObject pattern. Something like (I'll post my protractor.conf.js file at the end of the question):

/// <reference path="./references.ts"/>

import HomePage = require('../ui/HomePage');

describe('Application should run without errors', function () {
    var homePage = new HomePage();

    describe('Home Page Functionality', function () {
        beforeAll(function() {
            browser.get(homePage.getUrl());
        });

        it('should be possible to navigate to the home page', function () {
            expect(browser.getTitle()).toEqual(homePage.getTitle());
            expect(browser.getCurrentUrl()).toEqual(homePage.getUrl());
        });
    });
});

Right now I get Error: ReferenceError: define is not defined when I run this. If I remove the HomePage import and anything that uses the object, the test passes, so it's pretty clear loading the AMD module is what's making Protractor have a hard time, but I can't figure out how to tell it to load RequireJS before it starts the tests.


Things I tried

A few answers (one here I think) mentioned using r.js to have RequireJS modules loadable by Node. However, this didn't work so well since adding the require methods in my modules resulted in the TypeScript compiler putting it inside the generated define(), hence defeating the purpose.

I also couldn't find how to tell Protractor to load scripts before booting up, so I thought about adding RequireJS as a spec, thinking it would load the required methods for my tests, mainly the define() and require() functions, but that didn't work either.


My protractor.conf.js file:

var HtmlScreenshotReporter = require('protractor-html-screenshot-reporter');

function onPrepareFunction() {
    browser.driver.manage().window().maximize();
    browser.ignoreSynchronization = true;

    var TestsReporter = require('jasmine2-reporter').Jasmine2Reporter;

    jasmine.getEnv().addReporter(new TestsReporter());

    /**
     * We are using a fork here, because the original would not work with jasmine2.
     * We need to keep an eye on it.
     */
    jasmine.getEnv().addReporter(new HtmlScreenshotReporter({baseDirectory: 'reports/acceptance-tests-results'}));

    var jasmineReporters = require('jasmine-reporters');
    jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
        consolidateAll: true,
        filePrefix: 'acceptance-tests-results',
        savePath: 'reports'
    }));
}

exports.onPrepareFunction = onPrepareFunction;
exports.config = {
    framework: "jasmine2",
    specs: [
        'js/tests/acceptance/*.spec.js'
    ],
    baseUrl: 'http://localhost:9000',
    multiCapabilities: [
        {
            browserName: 'phantomjs',
            'phantomjs.binary.path': require('phantomjs').path,
            seleniumAddress: 'http://localhost:4444/wd/hub'
        }
    ],
    jasmineNodeOpts: {
        'print': function() {}
    },
    onPrepare: onPrepareFunction
};

1 个答案:

答案 0 :(得分:0)

你可以用&#34; amdefine&#34; lib(https://github.com/jrburke/amdefine)。

在您的devDependencies中加入"amdefine": ">=0.1.0",并在量角器配置中将require('amdefine/intercept');添加到onPrepare函数。它会自动插入以下代码段

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

在Node加载的每个.js文件中。之后该节点将能够加载requirejs依赖项。

或者您可以在包含define函数调用的文件中手动包含上述代码段。