Skip to content

Commit

Permalink
chore: migrate angular e2e app to ng cli (#974)
Browse files Browse the repository at this point in the history
* chore: migrate angular e2e app to ng cli

* chore: make build system work for e2e

* chore: make saucelabs work

* chore: enable saucelabs test for angular

* chore: fix test scripts

* chore: target es5 and add browserlist

* chore: only run saucelabs test in jenkins

* chore: update prod apmserver url

* chore: transpile apmservermock correctly

* chore: revert jenkinsfile

* chore: fix warnings in build
  • Loading branch information
vigneshshanmugam committed Mar 18, 2021
1 parent 34bd157 commit 859d328
Show file tree
Hide file tree
Showing 22 changed files with 242 additions and 88 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ node_modules
.DS_Store
.idea

# Ignore all e2e related build files
test/e2e/with-router/build
*.e2e-bundle.*
*-e2e.html

Expand Down
55 changes: 33 additions & 22 deletions dev-utils/run-script.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,35 @@ function runSauceTests(packagePath, serve = 'true', ...scripts) {
* Since there is no easy way to reuse the sauce connect tunnel even using same tunnel identifier,
* we launch the sauce connect tunnel before starting all the saucelab tests
*/

if (serve === 'true') {
startServersWithCleanups(join(PROJECT_DIR, packagePath))
}

launchSauceConnect(async sauceConnectProcess => {
if (!sauceLabs) {
return runUnitTests(packagePath)
/**
* Decides the saucelabs test status
*/
let exitCode = 0
const loggerOpts = {
stdout: process.stdout,
stderr: process.stderr
}
const exitProcess = () => process.exit(exitCode)

const runAllAndExit = async commands => {
try {
await runAll(commands, loggerOpts)
} catch (err) {
console.log('runSauceTests failed', err)
exitCode = 1
} finally {
if (sauceConnectProcess) {
sauceConnectProcess.close(exitProcess)
} else {
exitProcess()
}
}
}
/**
* `console.logs` from the tests will be truncated when the process exits
* To avoid truncation, we flush the data from stdout before exiting the process
Expand All @@ -141,26 +160,18 @@ function runSauceTests(packagePath, serve = 'true', ...scripts) {
process.stdout._handle.setBlocking(true)
}

/**
* Decides the saucelabs test status
*/
let exitCode = 0
const loggerOpts = {
stdout: process.stdout,
stderr: process.stderr
}

try {
await runAll(scripts, loggerOpts)
console.log(`Ran all [${scripts.join(', ')}] scripts successfully!`)
} catch (err) {
console.log('Sauce Tests Failed', err)
exitCode = 1
} finally {
sauceConnectProcess.close(() => {
process.exit(exitCode)
})
if (!sauceLabs) {
/**
* For Angular package we use `ng` commands for running the test instead of
* using our custom karma runner
*/
if (packagePath === 'packages/rum-angular') {
return await runAllAndExit(['test:unit'])
} else {
return runUnitTests(packagePath)
}
}
await runAllAndExit(scripts)
})
}

Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@
"stats-lite": "^2.2.0",
"terser-webpack-plugin": "^3.1.0",
"ts-node": "^8.3.0",
"tslib": "^1.10.0",
"typescript": "^3.7.3",
"vue": "^2.6.10",
"vue-loader": "^15.7.2",
Expand Down
56 changes: 54 additions & 2 deletions packages/rum-angular/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,60 @@
"options": {
"main": "test/specs/index.ts",
"tsConfig": "tsconfig.spec.json",
"karmaConfig": "karma.conf.js",
"polyfills": "test/polyfills.ts"
"karmaConfig": "karma.conf.js"
}
}
}
},
"app": {
"projectType": "application",
"schematics": {},
"root": "test/e2e/with-router",
"sourceRoot": "test/e2e/with-router",
"prefix": "",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "test/e2e/with-router/build",
"index": "test/e2e/with-router/index.html",
"main": "test/e2e/with-router/main.ts",
"polyfills": "test/e2e/with-router/polyfills.ts",
"tsConfig": "test/e2e/with-router/tsconfig.app.json",
"aot": true,
"assets": [
"test/e2e/with-router/assets"
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "test/e2e/with-router/environments/environment.ts",
"with": "test/e2e/with-router/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"port": 8000,
"browserTarget": "app:build",
"baseHref": "/test/e2e/with-router/build/"
},
"configurations": {
"production": {
"browserTarget": "app:build:production"
}
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions packages/rum-angular/ng-package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
{
"$schema": "./node_modules/ng-packagr/ng-package.schema.json",
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "dist",
"lib": {
"entryFile": "src/index.ts"
"entryFile": "src/index.ts",
"umdModuleIds": {
"@elastic/apm-rum": "elastic.apmRum",
"@elastic/apm-rum-core": "elastic.apmRumCore"
},
"umdId": "elastic.apmRumAngular"
},
"whitelistedNonPeerDependencies": [
"@elastic/*"
Expand Down
6 changes: 5 additions & 1 deletion packages/rum-angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
},
"scripts": {
"build": "ng build --prod",
"build:e2e": "ng build app --prod",
"test:unit": "ng test",
"test": "MODE=none npm run test:unit",
"test:e2e": "npm run script runE2eTests packages/rum-angular/wdio.conf.js",
"test:sauce": "npm run script runSauceTests packages/rum-angular true test:unit build:e2e test:e2e",
"test": "npm run test:sauce",
"script": "node ../../dev-utils/run-script.js",
"karma:dev": "ng test --watch",
"karma:coverage": "ng test --code-coverage"
},
Expand Down
49 changes: 36 additions & 13 deletions packages/rum-angular/test/e2e/with-router/app.e2e-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,50 @@
const { waitForApmServerCalls } = require('../../../../../dev-utils/webdriver')

describe('Angular router integration', function () {
beforeAll(() => browser.url('/test/e2e/with-router/'))
/**
* Change ELEMENT_KEY to approprioate value when using `devtools`
* automation protocol
* https://github.com/webdriverio/webdriverio/blob/e942ce4d802161ac12579553889d9068dccf317c/packages/devtools/src/constants.ts#L8
*/
const ELEMENT_KEY = 'ELEMENT'
beforeAll(async () => {
await browser.url('test/e2e/with-router/build/')
})

it('should run angular app and capture route-change', function () {
it('should run angular app and capture route-change', async () => {
/**
* Should render home page on load
*/
const notFoundElement = $('app-root app-home h2')
expect(notFoundElement.getText()).toEqual('Home page')
const result = await browser.findElement(
'css selector',
'app-root app-home h2'
)
expect(await browser.getElementText(result[ELEMENT_KEY])).toEqual(
'Home page'
)

browser.waitUntil(
() => {
await browser.waitUntil(
async () => {
/**
* route to /contacts
*/
$('#contacts').click()
const contactListElement = $('app-root app-contact-list')
return contactListElement.getText().indexOf('Name') !== -1
const result = await browser.findElement('css selector', '#contacts')
await browser.elementClick(result[ELEMENT_KEY])
const listResult = await browser.findElement(
'css selector',
'app-root app-contact-list'
)
const isDisplayed = await browser.isElementDisplayed(
listResult[ELEMENT_KEY]
)
return isDisplayed
},
5000,
'expected contact list to be rendered'
10000,
'expected contact list to be rendered',
5000
)

const { sendEvents } = waitForApmServerCalls(0, 2)
const { sendEvents } = await waitForApmServerCalls(0, 2)
const { transactions } = sendEvents
expect(transactions.length).toBe(2)

Expand All @@ -64,6 +85,8 @@ describe('Angular router integration', function () {
const extSpans = routeTransaction.spans.filter(
span => span.type === 'external'
)
expect(extSpans[0].name).toBe('GET /test/e2e/with-router/data.json')
expect(extSpans[0].name).toBe(
'GET /test/e2e/with-router/build/assets/data.json'
)
})
})
25 changes: 13 additions & 12 deletions packages/rum-angular/test/e2e/with-router/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,26 @@
*
*/

import { NgModule, Inject, ErrorHandler } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { NgModule, ErrorHandler } from '@angular/core'
import { HttpClientModule } from '@angular/common/http'
import { Router } from '@angular/router'
import {
ApmModule,
ApmService,
ApmErrorHandler
} from '@elastic/apm-rum-angular'

import { AppRoutingModule } from './app.routing.module'
import { AppRoutingModule } from './app-routing.module'
import { AppComponent } from './app.component'
import { HomeComponent } from './home.component'
import { ContactListComponent } from './contact-list.component'
import { ContactDetailComponent } from './contact-detail.component'
import { PageNotFoundComponent } from './not-found.component'
import { ApmService, ApmErrorHandler } from '../../../../src'
import { initializeApmService } from '../../../index'
import { environment } from '../environments/environment'
import { initializeApmService } from '../../../'

@NgModule({
imports: [BrowserModule, AppRoutingModule, HttpClientModule],
imports: [ApmModule, BrowserModule, AppRoutingModule, HttpClientModule],
declarations: [
AppComponent,
HomeComponent,
Expand All @@ -47,11 +51,7 @@ import { initializeApmService } from '../../../index'
ContactDetailComponent
],
providers: [
{
provide: ApmService,
useClass: ApmService,
deps: [Router]
},
ApmService,
{
provide: ErrorHandler,
useClass: ApmErrorHandler
Expand All @@ -60,8 +60,9 @@ import { initializeApmService } from '../../../index'
bootstrap: [AppComponent]
})
export class AppModule {
constructor(@Inject(ApmService) service: ApmService) {
constructor(service: ApmService) {
initializeApmService(service, {
serverUrl: environment.serverUrl,
serviceName: 'e2e-angular-integration',
logLevel: 'debug'
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { HttpClient } from '@angular/common/http'
providedIn: 'root'
})
export class ContactService {
CONTACT_URL = '/test/e2e/with-router/data.json'
CONTACT_URL = '/test/e2e/with-router/build/assets/data.json'
constructor(private http: HttpClient) {}

getContacts() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* MIT License
*
* Copyright (c) 2017-present, Elasticsearch BV
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/

export const environment = {
production: true,
serverUrl: 'http://apm-server:8200'
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,11 @@
*
*/

const path = require('path')
const {
getWebpackConfig,
PACKAGE_TYPES,
BUNDLE_TYPES
} = require('../../../../../dev-utils/build')
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

module.exports = {
entry: {
app: path.join(__dirname, 'main.ts')
},
output: {
path: path.resolve(__dirname),
filename: '[name].e2e-bundle.js'
},
...getWebpackConfig(BUNDLE_TYPES.BROWSER_PROD, PACKAGE_TYPES.ANGULAR)
export const environment = {
production: false,
serverUrl: 'http://localhost:8001'
}
3 changes: 1 addition & 2 deletions packages/rum-angular/test/e2e/with-router/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<base href="/test/e2e/with-router/" />
<base href="/test/e2e/with-router/build/" />
<title>RUM Angular e2e test</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
Expand All @@ -10,6 +10,5 @@

<body>
<app-root></app-root>
<script type="text/javascript" src="app.e2e-bundle.js"></script>
</body>
</html>
Loading

0 comments on commit 859d328

Please sign in to comment.