Skip to content

Commit

Permalink
feat(rum): angular integration with apm-rum (#384)
Browse files Browse the repository at this point in the history
* feat(rum): angular integration with apm-rum

* add deps and notice generation script [skip ci]

* add unit tests

* fix spec pattern

* add readme

* set up e2e tests

* use ts-loader config instead of babel

* switch to babel and make tests work on all browsers

* use typescript-eslint for .ts files

* run angular tests on travis and jenkins

* make it publish ready

* fix promise resolution

* address review comments and add more test

* respect active flag and increase coverage

* fix lock file and rebase

* address review comments

* show browser info on tests
  • Loading branch information
vigneshshanmugam authored Sep 3, 2019
1 parent 559870b commit 6ab2450
Show file tree
Hide file tree
Showing 33 changed files with 1,913 additions and 106 deletions.
2 changes: 2 additions & 0 deletions .ci/.jenkins_scope.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
SCOPE:
- "@elastic/apm-rum-core"
- "@elastic/apm-rum"
- "@elastic/apm-rum-react"
- "@elastic/apm-rum-angular"
64 changes: 59 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { readFileSync } = require('fs')
const { join } = require('path')
const { join, resolve } = require('path')
/**
* Helps with using custom eslint rules without creating and publishing as plugin
*/
Expand All @@ -17,9 +17,22 @@ const LICENSE_HEADER =
module.exports = {
env: {
es6: true,
browser: true
browser: true,
node: true
},
extends: ['plugin:prettier/recommended', 'plugin:react/recommended'],
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
ecmaFeatures: {
legacyDecorators: true
}
},
extends: [
'plugin:prettier/recommended',
'plugin:react/recommended',
'prettier/@typescript-eslint',
'plugin:@typescript-eslint/recommended'
],
parser: 'babel-eslint',
plugins: ['standard', 'rulesdir'],
rules: {
Expand All @@ -32,6 +45,47 @@ module.exports = {
license: LICENSE_HEADER
}
],
'react/prop-types': 0
}
'react/prop-types': 0,
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/no-explicit-any': 0
},
settings: {
react: {
version: 'detect'
}
},
overrides: [
{
/**
* babel-eslint does not understand some of the typescript feautes
* so its better to use '@typescript-eslint/parser' for .ts files
*/
files: ['**/*.ts'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module'
}
},
{
/**
* Disable specific rule that are overrided by
* typescript eslint config on js files
*/
files: ['**/*.js'],
rules: {
'@typescript-eslint/no-var-requires': 0,
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-use-before-define': 0,
'@typescript-eslint/camelcase': 0,
'@typescript-eslint/no-unused-vars': 0,
'@typescript-eslint/no-this-alias': 0,
'no-var': 0,
'prefer-const': 0,
'prefer-rest-params': 0,
'prefer-spread': 0
}
}
]
}
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ jobs:
env:
- STACK_VERSION=7.0.0
- SCOPE=@elastic/apm-rum-react
- stage: test
env:
- STACK_VERSION=7.0.0
- SCOPE=@elastic/apm-rum-angular
addons:
apt:
packages:
Expand Down
49 changes: 33 additions & 16 deletions dev-utils/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,23 @@ const DEFAULT_BROWSER_PRESET = [

const PACKAGE_TYPES = {
DEFAULT: 'DEFAULT',
REACT: 'REACT'
REACT: 'REACT',
ANGULAR: 'ANGULAR'
}

function getAngularConfig(options) {
return Object.assign({}, options, {
presets: options.presets.concat(['@babel/preset-typescript']),
plugins: options.plugins.concat([
/**
* Angular dependency injection will not work
* if we dont have this plugin enabled
*/
'babel-plugin-transform-typescript-metadata',
['@babel/plugin-proposal-decorators', { legacy: true }],
['@babel/plugin-proposal-class-properties', { loose: true }]
])
})
}

function getReactConfig(options) {
Expand All @@ -83,6 +99,15 @@ function getReactConfig(options) {
})
}

function getOptions(options, packageType) {
if (packageType === PACKAGE_TYPES.REACT) {
return getReactConfig(options)
} else if (packageType === PACKAGE_TYPES.ANGULAR) {
return getAngularConfig(options)
}
return options
}

function getBabelConfig(bundleType, packageType) {
let options = {
comments: false,
Expand All @@ -95,22 +120,13 @@ function getBabelConfig(bundleType, packageType) {
case NODE_DEV:
case NODE_PROD:
options = { ...options, presets: DEFAULT_NODE_PRESET }
if (packageType === PACKAGE_TYPES.REACT) {
return getReactConfig(options)
}
return options
return getOptions(options, packageType)
case NODE_ES_PROD:
if (packageType === PACKAGE_TYPES.REACT) {
return getReactConfig(options)
}
return options
return getOptions(options, packageType)
case BROWSER_DEV:
case BROWSER_PROD:
options = { ...options, presets: DEFAULT_BROWSER_PRESET }
if (packageType === PACKAGE_TYPES.REACT) {
return getReactConfig(options)
}
return options
return getOptions(options, packageType)
default:
return options
}
Expand All @@ -134,13 +150,14 @@ function getWebpackConfig(bundleType, packageType) {

const config = {
stats: {
colors: true
colors: true,
warnings: false
},
devtool: isEnvProduction ? 'source-map' : 'cheap-module-source-map',
module: {
rules: [
{
test: /\.(js|jsx)$/,
test: /\.(js|jsx|ts)$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: getBabelConfig(bundleType, packageType)
Expand All @@ -150,7 +167,7 @@ function getWebpackConfig(bundleType, packageType) {
mode: isEnvProduction ? 'production' : 'development',
plugins: [new EnvironmentPlugin(getWebpackEnv())],
resolve: {
extensions: ['.js', '.jsx']
extensions: ['.js', '.jsx', '.ts']
}
}

Expand Down
3 changes: 2 additions & 1 deletion dev-utils/karma.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ const baseLaunchers = getBrowserList().map(launcher => ({
base: 'SauceLabs',
...launcher
}))
const specPattern = 'test/{*.spec.js,!(e2e|integration|node)/*.spec.js}'
const specPattern =
'test/{*.spec.+(js|ts),!(e2e|integration|node)/*.spec.+(js|ts)}'
const { tunnelIdentifier } = getSauceConnectOptions()

/**
Expand Down
3 changes: 2 additions & 1 deletion dev-utils/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ function buildE2eBundles(basePath, callback) {
colors: true,
chunks: false,
assets: false,
modules: false
modules: false,
warnings: false
})
)
cb()
Expand Down
37 changes: 24 additions & 13 deletions dev-utils/webdriver.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,8 @@ function getWebdriveBaseConfig(
* Skip setting timeouts on firefox and microsoftedge since they
* result in NullPointerException issue from selenium driver
*/
const browserName = getBrowserName()
if (browserName === 'firefox' || browserName === 'microsoftedge') {
const { name } = getBrowserInfo()
if (name === 'firefox' || name === 'microsoftedge') {
return
}

Expand All @@ -196,15 +196,21 @@ function getWebdriveBaseConfig(
* */
if (!test.passed && isChromeLatest()) {
const response = browser.getLogs('browser')
console.log('[Browser Logs]:', JSON.stringify(response, undefined, 2))
console.log(
'[Chrome Browser Logs]:',
JSON.stringify(response, undefined, 2)
)
}
}
}
}

function waitForApmServerCalls(errorCount = 0, transactionCount = 0) {
const { name, version } = getBrowserInfo()
console.log(
`Waiting for minimum ${errorCount} Errors and ${transactionCount} Transactions.`
`Waiting for minimum ${errorCount} Errors and ${transactionCount} Transactions in`,
name,
version
)
const serverCalls = browser.executeAsync(
function(errorCount, transactionCount, done) {
Expand Down Expand Up @@ -292,26 +298,31 @@ function waitForApmServerCalls(errorCount = 0, transactionCount = 0) {
throw new Error('serverCalls is undefined!')
}

console.log(JSON.stringify(serverCalls, null, 2))
console.log(
`Payload in ${name} ${version}`,
JSON.stringify(serverCalls, null, 2)
)
if (serverCalls.error) {
fail(serverCalls.error)
}

return serverCalls
}

function getBrowserName() {
return browser.capabilities.browserName.toLowerCase()
function getBrowserInfo() {
const { version, browserName } = browser.capabilities
return {
name: browserName.toLowerCase(),
version
}
}

function isChromeLatest() {
const browserName = getBrowserName()
const browserVersion = browser.capabilities.version
const isChrome = browserName.indexOf('chrome') !== -1
const isLatest =
isChrome && browserVersion && Number(browserVersion.split('.')[0]) >= 76
const { name, version } = getBrowserInfo()
const isChrome = name.indexOf('chrome') !== -1
const isLatest = isChrome && version && Number(version.split('.')[0]) >= 76

return isChrome && isLatest
return isLatest
}

module.exports = {
Expand Down
Loading

0 comments on commit 6ab2450

Please sign in to comment.