Vue Nightwatch e2e tests on Travis CI in Chrome

Travis CI is a great continuous integration tool available for free for open source projects with seamless GitHub integration. It can test various projects thanks to different virtual machine images available. However if you need to mix languages, things get a bit more complex.

If you have a JavaScript project with e2e tests using Nightwatch, you won’t be able to run them on NodeJS Travis image. Nightwatch depends on Java to run the Selenium server. Fortunately the Java image contains node, npm and nvm. So to make it work, I used the following Travis configuration in .travis.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sudo: required
dist: trusty
language: java
addons:
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
jdk:
- oraclejdk8
node_js:
- 6
before_install:
- export CHROME_BIN=chromium-browser
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- nvm install 6.9.5
- npm install -g yarn
install:
- yarn install
script:
- yarn test

The sudo is required to install chrome. The latest Nightwatch requires Java 8. I am not sure if the node_js has any effect and might as well try to remove it. I think the image is running only an older version of node. The before_install part sets environmental properties to point to chrome and a virtual display. Then the xvfb creates the virtual display that is used by chrome. Last the version of node that I am using for development is installed. Finally yarn is installed and tests are run through yarn.

Gradle Release Plugin in Multi project Gradle build

The typical software release at the end of iteration includes incrementing the software version, tagging the release in version control and publishing production artifacts. The Gradle Release Plugin does all that and more. It makes releasing a Gradle project very easy. Until you need to release a multi-project gradle build. The official workaround did not work for me, so I have created my own.

The problem

When simply adding the release plugin to the root project, tasks that should be run only once (such as VCS tagging) are run multiple times, thus failing the build. When adding the release plugin to the subprojects, there are issues with the separate versions and the fact that the VCS repository root is in the parent directory.

Official workaround

The workaround described on the plugin homepage recommends to add the release plugin to the root and then run the release tasks separately for sub-projects. In my opinion, this creates a confusion between versions (i.e. each sub-project is released on its own, increasing the version every time).

My workaround

Based on the official workaround, it automates the release process and avoids creating multiple versions. The solution is to disable the release task in sub-projects to skip any release tasks executing on a wrong level while still publishing all sub-projects artifacts. Note that I am using the gradle wrapper, so I have added it to the script example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
plugins {
id 'net.researchgate.release' version '2.3.5'
}
allprojects {
apply plugin: 'maven-publish'
}
subprojects {
task release(overwrite: true) {
//overwrite release task in the subprojects
}
}
afterReleaseBuild.dependsOn(':moduleA:publish', ':moduleB:publish')
task wrapper(type: Wrapper) {
gradleVersion = '2.11'
}

To disable the release task in all sub-modules, it’s possible to overwrite it in the main script subprojects part with an empty task. To enable publishing of the sub-modules artifacts, the dependency on the sub-project publish task must be defined as per the example for each sub-project that should have its artifacts published.

To release the project, simply run:

1
gradlew release

Hosting a Maven Repository in Amazon S3

We had a simple requirement to host our internal deployed artifacts in the Amazon Cloud. We have migrated most of our builds to Gradle. Since version 2.4, Gradle added support for repositories hosted in Amazon AWS S3.

Ivy vs. Maven

Both Ivy and Maven repositories in S3 are supported by Gradle. But since Ivy is trying to mimic maven and we already had a maven repo, I picked maven.

Setup

I’ve created an S3 bucket and inside a simple structure:

1
2
3
maven
|- snapshots
|- internal

Getting dependencies

The following code in build.gradle enables download of the dependencies:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apply plugin: 'maven'
repositories {
maven {
name "s3snapshots"
url "s3://bucket-name/maven/snapshots"
credentials(AwsCredentials) {
accessKey "aws access key"
secretKey "aws secret key"
}
}
maven {
name "s3internal"
url "s3://bucket-name/maven/internal"
credentials(AwsCredentials) {
accessKey "aws access key"
secretKey "aws secret key"
}
}
}

Publishing dependencies

I played with the uploadArchives gradle task, but it was creating the Ivy structure. I have decided to go with the newer maven-publish plugin.

The following shows how to switch between two repositories and how to reference previously defined repositories. The switching works very well
with Gradle Release Plugin that we are using now.

1
2
3
4
5
6
7
8
9
10
11
12
apply plugin: 'maven-publish'
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
repositories {
add project.version.endsWith('-SNAPSHOT') ? project.repositories.s3RepoSnapshots : project.repositories.s3RepoInternal
}
}

To include source jars, test jars or other archives, e.g. from distribution plugin, add this to the publication.
Group Id, Artifact Id can be set here as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
groupId `group`
artifactId 'artifact'
from components.java
artifact sourceJar {
classifier "sources"
}
artifact testJar {
classifier "test"
}
artifact distZip {
classifier "zip"
}
}
}
}

Migration from other maven repositories

I have successfully migrated Apache Archiva to S3 simply by copying the whole directory structure from Archiva’s data folder to S3. Any maven repository should be possible to migrate the same way.

Missing features

The main disadvantage of this solution is the lack of administration and inability to prune snapshots. I am planning to create a utility that will take care of that.

Fortunately the S3 cost is very small so this will do for now.

Example

You can find an example implementation on GitHub.