Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReferenceError: before is not defined (mocha/protractor)

I am using protractor with mocha in react application. When trying to use before() or after() functions it gives me an error:

ReferenceError: before is not defined

However using beforeEach() or afterEach() works perfectly fine.

Here is how I configured protractor.conf.js

exports.config = {
  capabilities: {
    browserName: 'chrome'
  },
  frameworks: ['mocha', 'chai'],
  onPrepare: function() {
    browser.ignoreSynchronization = true;
  }
};

PS. full error:

Stacktrace:
    ReferenceError: before is not defined
    at [object Object].<anonymous> (/myApp/tests/e2e/routes.js:10:5)
    at normalLoader (/myApp/node_modules/babel-core/lib/babel/api/register/node.js:160:5)
    at Object.require.extensions.(anonymous function) [as .js] (/myApp/node_modules/babel-core/lib/babel/api/register/node.js:173:7)
    at require (module.js:380:17)
    at Function.promise (/myApp/node_modules/protractor/node_modules/q/q.js:650:9)
    at _fulfilled (/myApp/node_modules/protractor/node_modules/q/q.js:797:54)
    at self.promiseDispatch.done (/myApp/node_modules/protractor/node_modules/q/q.js:826:30)
    at Promise.promise.promiseDispatch (/myApp/node_modules/protractor/node_modules/q/q.js:759:13)
    at /myApp/node_modules/protractor/node_modules/q/q.js:525:49
    at flush (/myApp/node_modules/protractor/node_modules/q/q.js:108:17)
    at process._tickCallback (node.js:419:13)
like image 544
Max Avatar asked Jul 22 '26 21:07

Max


2 Answers

I was able to manage by adding framework: jasmine2 to protractor.conf.js and instead of before() and after() I wrote beforeAll() and afterAll(). Now it works as a charm.

The details about that issue can be found in this gitHub comment by @juliemr

Edit: Typo

like image 82
Max Avatar answered Jul 25 '26 18:07

Max


This question might be dead though I'll put a little more info in here for those who wonder through. The accepted answer seems confusing to the original question and so we should do go on a little journey to get us back on track.

What's wrong with the accepted answer?

As @Tomas Dermisek suggests, it should just be a matter of using mocha as the framework. It seems that @Max has decided to use jasmine instead of mocha which is actually an alternative test spec to mocha. That would appear to be why @Max needed to use jasmines beforeAll() and afterAll() instead of the desired before() and after() from mocha.

Further evidence of using jasmine is available from the addition of jasmine2 to the framework of the protractor.conf.js

Before we continue there are some things to note between jasmine and mocha

Since someone reading this may have tried the jasmine approach because "it's easier", then you might be using the jasmine expect that comes with jasmine out of the box. If you're now looking at actually using mocha it's worth being aware of a couple of nuances that caught me.

  1. It seems that protractor interactions like element(by.css('app-root h1')).getText() will return a promise. @cnishina pointed out to me today that protractor wraps Jasmine with angular/jasminewd and that's why jasmine appears to work out of the box. This means that in jasmine expect(element(by.css('app-root h1')).getText()).toEqual('Car search POC'); will work perfectly. If you try and do the equivalent in mocha then it will fail for things like TypeError and many other hard to get your head around errors
  2. You need a little help from chai and chai-as-promised
    • chai will give you the expect and other syntax candy that you would like
    • chai-as-promised enriches your candy with .eventually so that you don't need to do then() promise resolution all over your tests
    • At the time of writing this the latest chai-as-promised dependency didn't work with chai. Not as-promised anyway (sorry I couldn't resist). These are the versions used by the protractor project with a protractor version I've seen in a working package.json

package.json fragment

"devDependencies": {
  ...
  "chai": "~3.5.0",
  "chai-as-promised": "~5.3.0",
  "protractor": "~5.1.0",
  ...
}

The following configuration should get you off the ground

protractor.conf.js

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

exports.config = {
  allScriptsTimeout: 11000, // Timeout of each script
  specs: [
    './e2e/**/*.e2e-spec.ts'  // pattern for your tests
  ],
  baseUrl: 'http://localhost:4200/', // URL of your SUT
  capabilities: { 
    'browserName': 'chrome' // name of the browser you want to test in
  },
  directConnect: true, // No need to run selenium server for chrome and firefox
  framework: 'mocha', // The framework we want to use instead of say jasmine
  mochaOpts: { // Some reasonable mocha config
    reporter: "spec",
    slow: 3000,
    ui: 'bdd',
    timeout: 30000
  },
  beforeLaunch: function() { // If you're using type script then you need compiler options
    require('ts-node').register({
      project: 'tsconfig.e2e.json'
    });
  },
  onPrepare: function() { // making chai available globally. in your test use `const expect = global['chai'].expect;`
    var chai = require('chai');
    var chaiAsPromised = require("chai-as-promised");
    chai.use(chaiAsPromised);
    global.chai = chai;
  }
};

tsconfig.e2e.json

{
  "compilerOptions": {
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "es2016"
    ],
    "outDir": "../dist/out-tsc-e2e",
    "module": "commonjs",
    "target": "es6",
    "types":[
      "mocha",
      "chai",
      "node"
    ]
  }
}

Now we've done the plumbing and explaining let's get to the point and answer the OP and demonstrate a working before

An example spec file might look like the spec below and would give this output

  search page
I do something in a before!
    √ will display its title

It's also worth taking note of the const expect = global['chai'].expect; being used in the spec

e2e/sample.e2e-spec.js

import { browser, element, by } from 'protractor';
import {SearchPage} from './search.po';
const expect = global['chai'].expect;

describe('search page', () => {
  let page: SearchPage;

  before(() => {
    console.log('I do something in a before!');
  });


  beforeEach(() => {
    page = new SearchPage();
  });

  it('will display its title', () => {
    page.navigateTo();

    const title = element(by.css('app-root h1')).getText();
    expect(title).to.eventually.contain('A cool title');
  });
});
like image 25
Arran Bartish Avatar answered Jul 25 '26 16:07

Arran Bartish