I want to do e2e testing on a hello world app in Angular2 with specs written in typescript. However, protractor crashes with the following message:
Using the selenium server at http://localhost:4444/wd/hub
[launcher] Running 1 instances of WebDriver
[launcher] Error: ReferenceError: System is not defined
at Object.<anonymous> (C:\Dev\d2ipm\test\e2e\overview.js:1:1)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at C:\Users\%username%\AppData\Roaming\npm\node_modules\protractor\node_modules\jasmine\lib\jasmine.js:63:5
at Array.forEach (native)
at Jasmine.loadSpecs (C:\Users\%username%\AppData\Roaming\npm\node_modules\protractor\node_modules\jasmine\lib\jasmine.js:62:18)
[launcher] Process exited with error code 100
Since I use SystemJS as Angular2 suggests by default, System
is contained in every compiled .js file, including the test specs. My index.html configures System as suggested in the tutorials, and the app works:
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<!-- 2. Configure SystemJS -->
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
},
globalEvaluationScope: false
});
System.import('app/boot')
.then(null, console.error.bind(console));
</script>
Running tests written in pure JS works fine. How can I make my test environment see System
?
When you run an e2e test through Protractor, there are actually 2 environments:
Even if you load libraries in your index.html file, the your e2e-spec file won't have access to them. That includes systemjs. This is an issue when the Typescript compiler uses "module": "system"
One solution is to configure your build process so that the e2e-spec files are compiled with the "module": "commonjs"
option. If you want to be able to import files from your web application into the test spec, you would have to compile the whole application twice (though I am not sure there are much use cases where it makes sense to do so).
For example, using gulp
const gulpTypings = require('gulp-typings')
const sourcemaps = require('gulp-sourcemaps')
const ts = require('gulp-typescript')
const tsProject = ts.createProject('tsconfig.json')
const tsProjectE2E = ts.createProject('tsconfig-e2e.json')
const tsFiles = [
'typings/index.d.ts',
'app/**/*.ts',
'!**/*.e2e-spec.ts',
'!node_modules/**/*'
]
const tsFilesE2E = [
'typings/index.d.ts',
'app/**/*.e2e-spec.ts',
'app/**/*.ts', // You should not need that unless you use your app files in your tests
'!node_modules/**/*'
]
gulp.task('typings', () => gulp
.src('./typings.json')
.pipe(gulpTypings())
)
gulp.task('ts', ['typings'], () => gulp
.src(tsFiles)
.pipe(sourcemaps.init())
.pipe(ts(tsProject))
.js
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('app'))
)
gulp.task('ts-e2e', ['typings'], () => gulp
.src(tsFilesE2E)
.pipe(sourcemaps.init())
.pipe(ts(tsProjectE2E))
.js
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('e2e')) // Note that your compiled tests files are put in the e2e/ folder now
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With