What code coverage tool to use for the javascript code in a Kotlin Multiplatform project? - kotlin-js

I can use jacoco on the JVM side, but what can I use on the JS side of the Multiplatform project?

For now, there are no integrated code coverage tools.
But you can implement it manually using karma.config.d and https://karma-runner.github.io/0.8/config/coverage.html.
Note: you can do it only with browser target
How to setup:
Necessary to add dependencies, ideally dev dependencies into test source set, but dev dependencies are possible only since 1.4-M3, so they can be replaced with usual npm
implementation(devNpm("istanbul-instrumenter-loader", "3.0.1"))
implementation(devNpm("karma-coverage-istanbul-reporter", "3.0.3"))
After that create js file in karma.config.d folder in the project folder
;(function(config) { // just IIFE to protect local variabled
const path = require("path") // native Node.JS module
config.reporters.push("coverage-istanbul")
config.plugins.push("karma-coverage-istanbul-reporter")
config.webpack.module.rules.push(
{
test: /\.js$/,
use: {loader: 'istanbul-instrumenter-loader'},
include: [path.resolve(__dirname, '../module-name/kotlin/')] // here is necessary to use module-name in `build/js/packages`
}
)
config.coverageIstanbulReporter = {
reports: ["html"]
}
}(config));
It works with Kotlin code (but honestly report is arguable) but anyway, it provides both statistics for js and Kt files, but for js indicate 0%.
I created a feature request: https://youtrack.jetbrains.com/issue/KT-40460
Update:
The HTML file with results is in build/js/packages/{$module-name}-test/coverage/index.html. You can run build or browserTest task.
NOTE: If you on Windows you have to change include: [path.resolve(__dirname, '../module-name/kotlin/')] to include: [path.resolve(__dirname, '..\\module-name\\kotlin\\')]

Related

Is possible see the "WDIO Configuration" added in a project already build?

Is possible to see the "WDIO Configuration" added to a project already built?
I mean, as we can see in the picture added, I wanna see the list of configurations added but in a project that is already built... exist a specific command in WDIO to do that?
More context:
My main objective is to know the configuration of the following line
Here the image link
https://ibb.co/Jqn75N7
Thanks in advance !
The place where you can see all the different configurations selected at the begining is wdio.conf.js or wdio.conf.ts
Based on the wdio documentation, if you want to use TypeScript:
You will need typescript and ts-node installed as devDependencies. WebdriverIO will automatically detect if these dependencies are installed and will compile your config and tests for you. If you need to configure how ts-node runs please use the environment variables for ts-node or use wdio config's autoCompileOpts section.
Basically, it means that wdio automatically detects if you are using javascript or typescript.
But also it allows you to set specific configurations for typescript by setting an autoCompileOpts entry in your wdio.conf.ts file:
export const config = {
// ...
autoCompileOpts: {
autoCompile: true,
// see https://github.com/TypeStrong/ts-node#cli-and-programmatic-options
// for all available options
tsNodeOpts: {
transpileOnly: true,
project: 'tsconfig.json'
},
// tsconfig-paths is only used if "tsConfigPathsOpts" are provided, if you
// do please make sure "tsconfig-paths" is installed as dependency
tsConfigPathsOpts: {
baseUrl: './'
}
}
}
Hope it helps to clarify your doubt!

How can I reduce the webpack bundle size for a Vue.js / Nuxt.js project incorporating AWS SDK?

Summary:
I have created projects, with Vue.js and Nuxt.js, where I have installed aws-amplify (which automatically installs aws-sdk) in order that I can implement authentication with AWS Cognito.
In both cases, this works very nicely, but the problems come when I build production versions.
In both cases, I end up with massive bundle sizes which (thanks to webpack-bundle-analyzer) I can immediately see are caused by the aws-sdk which appears to contain code to implement every AWS service, under the sun, despite the fact that I am only importing AWS Cognito's: "Auth" (import { Auth } from 'aws-amplify')
I have tried creating a custom AWS SDK for JavaScript, which only includes the service: AWS.CognitoIdentity, but despite incorporating that (presumably incorrectly), I still end up with the same bundle size (and aws-sdk files) when I build the projects.
As I say, this is happening in both Nuxt and Vue project, but in order to simplify this, I for now just want to find the solution to a very basic sample project created with Vue.
I think I must be doing something dumb, but I can't work out what that is.
Any help would be greatly appreciated! :-)
Steps to reproduce:
Create a basic Vue.js project with defaults. Run: vue create vue-aws-sdk-inv
[Note: Steps 2 - 4, are not crucial to reproduce issue, but install webpack-bundle-analyzer which provides useful extra info.]
In the new project, install webpack-bundle-analyzer. Run: npm install --save-dev webpack-bundle-analyzer
Create root file: vue.config.js
Add the following code to vue.config.js:
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = {
configureWebpack: {
plugins: [new BundleAnalyzerPlugin()]
}
};
As a benchmark, build the project. Run: npm run build
At this stage, the project will build (with no console warnings) and webpack-bundle-analyzer will launch (in the browser) showing the file: chunk-vendors..js, at the top of the tree, containing a bunch of other .js files, all of acceptable size.
Install AWS Amplify (and by default aws-sdk). Run: npm i aws-amplify
Open src/components/HelloWorld.vue and add the following under the tag: import { Auth } from "aws-amplify";
Build the project. Run: npm run build
At this stage, the project will build WITH console warnings regarding the following files being too large:
File Size Gzipped
dist/js/chunk-vendors.013ac3f0.js 3055.78 KiB 550.49 KiB
dist/js/app.fa2a21c4.js 4.67 KiB 1.67 KiB
dist/css/app.53019c4c.css 0.33 KiB 0.23 KiB
If installed, webpack-bundle-analyzer should launch (in the browser) showing an inflated: chunk-vendors..js, due to a hefty: aws-sdk.
aws-sdk will include api: .json files and lib: .js files for every AWS service I can think of!
The attempt to rectify:
Navigate to: https://sdk.amazonaws.com/builder/js/
Clear all services.
Select just: AWS.CognitoIdentity
Download "Minified" aws-sdk-.js
Download "Default" aws-sdk-.min.js
[Note: the following are the steps I am guessing I'm getting wrong?...]
In the project, search the node_modules directory for aws-sdk.js and aws-sdk.min.js.
They were found in /node_modules/aws-sdk/dist
Replace both files with the downloaded files (renaming to aws-sdk.js and aws-sdk.min.js respectively.)
Build the project. Run: npm run build
Project will build with same console warnings and same massive aws-sdk, as before, containing all the same .js and .json files for a bunch of services that are not actually imported in the application.
Final pieces of analysis:
Remove aws-sdk.js and aws-sdk.min.js from project's: /node_modules/aws-sdk/dist
Build the project. Run: npm run build
Project is built without even referencing these files.
Rename /node_modules/aws-sdk to /node_modules/TEMP_aws-sdk and attempt to build the project.
Build fails, and this proves (I think) that I was at least trying to add the custom versions, of aws-sdk.js and aws-sdk.min.js, somewhere in the correct directory!
Source Code:
vue.config.js:
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = {
configureWebpack: {
plugins: [new BundleAnalyzerPlugin()]
}
};
src/components/HelloWorld.vue:
import { Auth } from "aws-amplify";
As said before, any help would be greatly appreciated! :-)
It looks like import { Auth } from "aws-amplify"; doesn't currently allow for tree shaking according to this issue.
Reading through several related issues, it appears that:
import Auth from '#aws-amplify/auth';
is the best you can currently do. I suspect that over time, the AWS team will figure out a way to better separate the internals.
For readers looking for a way to reduce bundle sizes for the aws-sdk package, see this section of the docs.
In my case:
import S3 from 'aws-sdk/clients/s3';
import AWS from 'aws-sdk/global';
cut the bundle size down by quite a lot. That gets it down to ~57k gz to use S3.
Also, for anyone using nuxt you can just run nuxt build -a to get the build analyzer.

Load debug version of pre-built module via npm/webpack

There is a javascript library, pre-built and available on npm, that I wish to develop with/debug. In my case, it is openlayers.
In the classic way of requiring a javascript file and wanting to debug, one would just switch the script url from the production version to the debug version, ie:
to
However, when using webpack and then importing via npm:
import openlayers from 'openlayers'
Gets you the production distribution of the library, the same as the ol.js script from above.
On a side note, to stop webpack trying to parse a prebuilt library and throw a warning about that you must include something like this:
// Squash OL whinging
webpackConfig.module.noParse = [
/\/dist\/ol.*\.js/, // openlayers is pre-built
]
Back to the problem at hand: how can I conditionally load a different entry-point for a module prebuilt and imported like this?
Of course, I can do it in a hacky way. By going into the node_modules/openlayers/package.json and switching the browser field from
"browser": "dist/ol.js",
to
"browser": "dist/ol-debug.js",
Is there a way I can request a different entry point via webpack or by using a different import syntax? Do I first have to petition the library maintainers to update the browser field to allow different entry point hints to browsers, according to the spec? https://github.com/defunctzombie/package-browser-field-spec
Thoughts on a more effective way to make this happen? Yearning to be able to programmatically switch loading of the production and debug versions of a library based on env variables.
Webpack has configuration options for replacing a module into a different path: https://webpack.github.io/docs/configuration.html#resolve-alias
This resolves the openlayers import to use the debug version:
webpackConfig.resolve.alias: {
openlayers: 'openlayers/dist/ol-debug.js'
}
In my build system I have a function that takes the environment type and returns the matching webpackConfig. Based on the parameter I include the above snippet or not.
Full code: webpack-multi-config.js
I have two different (gulp-) tasks for development and production. For example the production task: webpackProduction.js
Line 1 imports the config script with production as type.
My build system is based on gulp starter.

How to integrate karma in webpack

I am a webpack newbie and have a question about testing.
I have a project which uses webpack, typescript and karma as test runner and I would like to run my tests on every file change (e.g. in "watch" mode)
I am aware of karma-webpack and it works well when I run karma as own process (karma start ...)
But what I want is to integrate karma in the webpack flow.
So, from my naive point of view, I thought karma has to be defined in preloading of webpack (such as a linter).
But I found nothing....
I can not believe that this common workflow is not possible (run tests on every source change)
Can anybody of you give me a suggestion?
Time flies and it's June 2018 already. As there isn't much documentation about this online I want to give out my 2 cents.
I have currently a setup working where I bundle my tests with webpack a watch for changes in order to rerun automatically the tests.
I'm using karma-webpack using the configuration explained in the Alternative usage section and I think it's the proper way to solve the problem asked in the question.
karma.conf.js
{
...
files: [
// only specify one entry point
// and require all tests in there
'test/index_test.js'
],
preprocessors: {
// add webpack as preprocessor
'test/index_test.js': [ 'webpack' ]
},
...
}
test/index_test.js
// require all modules ending in "_test" from the
// current directory and all subdirectories
const testsContext = require.context(".", true, /_test$/)
testsContext.keys().forEach(testsContext)
Watching for changes of the whole bundle as #Adi Prasetyo suggests is wrong in my opinion. We should only watch for changes in the tests files and the files that are imported inside them, which can be achieved with configuration shown in the last URL.
Very important for hot reloading to work (at least in my case it was what made it work), you need to setup webpack-dev-middleware configuration in order to update the tests bundle everytime a change happens in some test file or the files being imported inside them. This is the config I'm using:
karma.config.js
{
...
webpackMiddleware: {
watchOptions: {
aggregateTimeout: 300,
poll: 1000, // customize depending on PC power
},
},
...
}
More info about it here.
I have same problem, as the TDD workflow that i use. After writing test then change the code the test doesn't re-run. Run test on every file change is possible.
As karma files have 3 options: Included, served, watched.
You can specify the bundle as pattern then tell karma to watch it
karma.config.js
files: [
// watch final file so when source change and it's final file, re run the test
{ pattern: './dist/js/*.wp.js', watched: true},
],
but when we use karma start no webpack active and watching. So use concurrently to run karma and webpack. Note that webpack should watch only the source code and karma should watch the bundle file.
Then we can add script property to package.json like so
package.json
"scripts": {
"test": "karma start karma.config.js",
"build": "webpack",
"dev": "concurrently \"webpack --progress --colors --watch\" \"karma start karma.config.js --colors\"",
},
Then run npm run dev to start coding
Well I've never heard of webpack up until now, but I know karma fairly well. I'm not 100% sure what you are asking here, so let me know if this isn't helpful at all. You can setup karma to do exactly what you want it to do (run tests on every file change).
There are two options that you must set in the karma.conf.js file: autoWatch: true and singleRun: false.
karma.conf.js
module.exports = function(config) {
config.set({
// set other options and stuff...
autoWatch: true,
singleRun: false
});
};
autoWatch set to true enables watching files and executing tests whenever any file changes. Setting singleRun to false means that you only need to execute karma start (or however you integrate it into webpack) once to run your tests, instead of having to enter the command every single time you make a change or want to run your suite; it just keeps karma running in the background.

IntelliJ 13 select Groovy SDK from Gradle dependencies

For my Android project I want to run a test HTTP server for my integration tests. I've created a Configuration and have written a task to run my Groovy script the sets up the HTTP server
configurations {
stubs {
description = "Classpath for HTTP server for stubbed data"
visible = false
}
}
dependencies {
compile "com.android.support:support-v13:+"
stubs "org.codehaus.groovy:groovy:2.3.4"
stubs "com.github.tomakehurst:wiremock:1.46"
}
When I edit the Groovy script IntelliJ tells me that the Groovy SDK hasn't been configured.
How can I have IntelliJ use the Groovy SDK that is part of the stubs Configuration? I can't create a Groovy SDK configuration using the Gradle fetched libraries as IntelliJ tells me that the Groovy distribution is broken because the version number can't be determined.
Am I forced to have to download the distribution manually?
The solution was to separate out the project for the HTTP server into a separate project and use Gradle's multiproject's ability to set up the Android tests to depend on the HTTP server being started. Because the separate project is a Groovy project, IntelliJ reads the Groovy version to use from the project's dependencies and all is well.
dependencies {
compile "com.android.support:support-v13:+"
stubs project(":integration-server")
}
/*
* The android plugin defers creation of tasks in such a way that they can't be accessed eagerly as usual
* #see http://stackoverflow.com/questions/16853130/run-task-before-compilation-using-android-gradle-plugin
*/
gradle.projectsEvaluated {
connectedAndroidTest.dependsOn(":integration-server:startBackgroundServer")
// Note: finalizedBy is still #Incubating
connectedAndroidTest.finalizedBy(":integration-server:stopBackgroundServer")
}
integration-server/build.gradle
apply plugin: "groovy"
apply plugin: "spawn"
dependencies {
compile "org.codehaus.groovy:groovy:2.3.4"
compile "org.codehaus.groovy:groovy-ant:2.3.4"
compile "com.github.tomakehurst:wiremock:1.46"
}
task startBackgroundServer(type: SpawnProcessTask, dependsOn: "build") {
def cp = sourceSets.main.runtimeClasspath.asPath
command "java -cp $cp server"
ready "Started DelayableSocketConnector#0.0.0.0:8089"
}
task stopBackgroundServer(type: KillProcessTask)
To prevent the Gradle build blocking I'm using a Gradle Spawn Plugin to launch the HTTP server in the background.