Combining locators in protractor

I’d like to start with the following service announcement,

you really shouldn’t need this.

That being said; I’ve started using a third party component library which led to a use-case for this.

It so happened that i was creating a page object for a component library called ag-grid. At first glance i thought nothing special about it; and that i could retrieve rows normally. ag-grid however supports the pinning of columns to the left and/or right side of the list. And these rows then fall inside their own respective markups.

Now you can easily create a structure allowing me to target the (non-)pinned columns. But for ease of use being able to get full set of cells can also be useful and might be more suited for the test case.

This led to the creation of the following code.

As you can see it returns a new ElementArrayFinder which is the return type for the all locator and thus what we need for the aggregate.

In order to create the aggregate response it resolves each locator’s getWebElements response through Promise.all. It then fulfils the deferredAggregate with the promised results reduced to a single WebElement array.

In this implementation the combinedLocator.toString is also supplied. This is to ensure that feedback for this aggregation also contains all locators in the message. For the creation of the ElementArrayFinder itself it is not required though

TypeScript and ES6 import syntax

When I started using TypeScript for my Angular applications, I was confused about all the different ways with which you could import other modules.

import './polyfills.ts';
import { Component } from '@angular/core';
import HomeComponent from './pages/home/home-page.component';
import * as _ from 'lodash';
import assert = require('assert');

At first, I thought that as a programmer you could choose whether you wanted to use curly braces or not, but I quickly found out that that was not the case. It all depends on how the module that you are importing is structured.

I have created an overview of the different ways by which a module can be exported, together with their corresponding import syntax. Most of them are actually plain ECMAScript 2015 (ES6) module syntax that TypeScript uses as well.

Continue reading

Ratpacked: Assert No Exceptions Are Thrown With RequestFixture

Writing unit tests for our handlers in Ratpack is easy with RequestFixture. We invoke the handle method and use a Handler or Chain we want to test as argument. We can provide extra details on the fixture instance with a second argument, for example adding objects to the registry or setting the request method. The handle method returns a HandlingResult object. This object has the method exception that we can use to see if an exception occurred in our code under test. The method throws a HandlerExceptionNotThrownException if the expected exception doesn’t occurr.

Continue reading

Spocklight: Indicate Specification As Pending Feature

Sometimes we are working on a new feature in our code and we want to write a specification for it without yet really implementing the feature. To indicate we know the specification will fail while we are implementing the feature we can add the @PendingFeature annotation to our specification method. With this annotation Spock will still execute the test, but will set the status to ignored if the test fails. But if the test passes the status is set to failed. So when we have finished the feature we need to remove the annotation and Spock will kindly remind us to do so this way.

Continue reading

Awesome Asciidoctor: Nested Tables

Defining tables in Asciidoctor is very easy. The start and end of the table are defined by |===. But if we want to add a new table to a table cell we cannot use the same syntax. To define a nested table we must replace the | separator with !. So instead of |=== to indicate the table boundaries we use !===. Also the cell separators are now ! instead of |. Finally we must make sure the table cell or column supports Asciidoc markup, so the table is properly created. We must configure the cell or column with a so the nested table is created.

In the following example Asciidoctor markup we have a simple table with a nested table in the second column and row. Notice we can still apply all table configuration to the nested table as well:

When we run Asciidoctor to create HTML for this markup we get the following result:

Written with Asciidoctor 1.5.5.

Original post

Gradle Goodness: Using Incremental Task Action

Gradle has incremental build support to speed up our builds. This means Gradle checks input and output for a task and if something changed the task is executed, otherwise the task is skipped. In previous posts we learned how to add incremental build support to our tasks with annotations and inputs and outputs property of a task. When we have a task that has an output file for an input file, like with transformations, we can have a more efficient task using an incremental task action. With an incremental task action we have extra information on the files that are handled by the task. We can have different actions based on if an input file is out of date or removed. This way we can handle only the input files that have changed or removed with incremental builds, instead of all the input files.

To create an incremental task action we must have a task action method (annotated with @TaskAction) that has a single argument of type IncrementalTaskInputs. The IncrementalTaskInputs class has the method outOfDate and removed. These methods take an action, that can be implemented with a closure, with an instance of InputFileDetails as argument. We can get to the input file via this instance and use that for our task logic. When an input file is out of date, because the file contents has changed or the output file has been removed, the action we defined for the outOfDate method is invoked. If the input file is removed the action for the method removed is invoked.

Continue reading

Gradle Goodness: Change Local Build Cache Directory

Gradle 3.5 introduced the build cache. With the build cache we can reuse task output from builds that can come from different computers. We can also use the build cache feature for our local builds. By default the directory to store the cache is located in the Gradle user home directory on our computer (USER_HOME/.gradle/caches/build-cache-1). We can change the directory for the local cache via settings.gradle of our Gradle project. For example we could configure a directory in our project file structure to be the build cache directory. Then it is easy to clean the cache, because it is a directory not shared by other Gradle projects. With the default directory location in the Gradle user home directory the caches of all Gradle projects we run on our computer are stored in a single directory. And the cache doesn’t shrink and will only grow we might want to have more control of where the cache of a single Gradle project is stored. This way we can easily clean the cache, because all files of a project are stored in the directory for that project.

In the following example settings.gradle file we configure our build cache directory to be the directory build-cache in the root directory of our project where we store our settings.gradle file:

Written with Gradle 3.5.

Original post

Gradle Goodness: Enable Build Cache For All Builds

Gradle 3.5 introduced the build cache. With the build cache we can share task output between builds on different computers. For example the build output from a continuous integration server can be used on a developer’s computer. To use the build cache feature we use the command-line option --build-cache. Instead of using the command-line option --build-cache we can set the Gradle property org.gradle.caching with the value true in the file of our project. To set this property for all our projects we set the property in the file in the Gradle home directory, which is usually at USER_HOME/.gradle/

In the following example we set the property org.gradle.caching in ~/.gradle/

If we want to disable the build cache feature set via the global property we can use the command-line option --no-build-cache to disable the build cache for a particular build.

Written with Gradle 3.5.

Original post

Jenkins Joy: Shared library for Jenkins Declarative Pipeline

Since the introduction of the Jenkins Declarative Pipeline syntax (as opposed to the Scripted Pipeline syntax) the concept of a shared library has become more important as we are otherwise restricted to the sections of the pipeline model. So we’ll make a basic set-up with Continue reading