E2E testing with env variables with Protractor and Angular 6

Vijay Goel, MD
Building the Stack
Published in
2 min readJun 15, 2018

Loving how the new angular.json in the Angular 6 CLI just solved the polling issue with protractor/ e2e testing for me.

Background: I have a carousel that rotates pictures at the top of my home page, using

return from(array).pipe(
repeat(100),
interval(x),

)

It looks like this (it’s a website for catering in Los Angeles)

I was attempting to use NgZone.runOutsideAngular(), which still doesn’t really work for a repeated output that triggers change detection. I was stalling with the timeout error in protractor that hung my tests:

Timed out waiting for asynchronous Angular tasks to finish after 11 seconds

There’s a new solution available to this issue made possible by Angular 6, that works great with Nx/ monorepos (and all that fancy lib import of environments)!

Here’s how you do it with a prod build:

// in angular.json"projects": {
"app1": {
"architect": {
"build": {
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/app1/src/environments/environment.ts",
"with": "apps/app1/src/environments/environment.prod.ts"
}
],

So to enable it in a test build for app1, it looks like:

"projects": {
"app1": {
"architect": {
"build": {
"configurations": {
"production": {
...
},
"test": {
"fileReplacements": [
{
"replace": "apps/app1/src/environments/environment.ts",
"with": "apps/app1/src/environments/environment.e2e.ts"
}
]
}

And to make it available, add a serve-e2e section under architect

"projects": {
"app1": {
"architect": {
"build": {
...
},
"serve-e2e": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "app1:build"
},
"configurations": {
"test": {
"browserTarget": "app1:build:test"
}
}

Add to serve it up:

"app1-e2e": {
"root": "apps/app1-e2e/",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "apps/app1-e2e/protractor.conf.js",
"devServerTarget": "app1:serve-e2e:test"
}
},

Now I can use an env variable to turn on or off a component rather than running it in a zone

if(!environment.testing) {
return nonBlockingObservable
}
return blockingObservable

Fun addition: for libs in NX with env variables you can inject the testing boolean value

\\environment.e2e.tsexport const environment = {
production: false,
testing: true,
};
\\ app.module.ts@NgModule({
providers: [
{ provide: TEST_SETTING, useValue: environment.testing }
]
})\\ tested.component.tsconstructor(@Inject(TEST_SETTING) private testSetting: boolean)myFunction() {
if(this.testSetting === false) {
return whateverIsScrewingUpTheTest
}
return aTestSafeVersion
}

Many thanks to Loudghiri Ahmed for showing the way on stackoverflow

--

--

Vijay Goel, MD
Building the Stack

Improving operations via technology and structured thinking (current focus chefs and catering)