RequireJS modules in Protractor specs. Is it possible?

312 views Asked by At

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

There are 1 answers

0
h23 On

You can do it with "amdefine" lib (https://github.com/jrburke/amdefine).

Include "amdefine": ">=0.1.0" in your devDependencies and add require('amdefine/intercept'); to onPrepare function in your protractor config. It will automatically insert following snippet

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

in each .js file loaded by Node. After that node will be able to load requirejs dependencies.

Or you can include above snippet manually in files with define function calls.