Extending Selenium with page objects

As all who have used it know Selenium is a powerful tool when testing front-end applications. I personally use it in combination with protractor. This is because most of the work I do is with Angular and AngularJS applications.

When you are using Typescript extending classes is an easy thing. In light of this I’ve been experimenting with new approaches to creating page objects. Continue reading

Test code separation

As someone who spends quite some time writing and checking unit and e2e tests I’ve started noticing a trend I’m somewhat confused by. There have been multiple occasions in which I’ve encountered test logic (repeatable and single use) in either test specifications or page objects.

So I decided to share my approach to writing and foremost separating my test code into three categories. Those being: Specifications , Sequences and Page Objects.

Continue reading

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

Unit testing an AngularJS directive’s private functions.

As we all know Javascript gives us the awesome ability to create functions inside functions. This allows us to create private functions which support the main function. It is also something we do often when creating object functions. This structure is used by angular for the creation of providers and directives alike.

Every once in a while I personally come to a point where I would like to test these private functions. This is especially true for use cases in Angular such as directives. Continue reading

Web-components like AngularJS directives

As you may already know web components consist out of a set of technologies which are combined to create a custom element for use in your HTML markup. The main additions, as described in several blogposts, are HTML imports, Shadow Dom and Templates combined with isolated scripts and styling. (If these concepts are new to you i suggest you read up on web components at WebComponents.org).

This blog post has a living example on plnkr.co.

Continue reading

Javascript oneliners: functions are attributes too

Just a small reminder. Javascript allows you to call methods based on their name. So if a DOM element has a addClass and removeClass which both take the same argument we could write:

but we could also write

Sometimes this means you can use this technique to write powerful one liners.

Creating a superelipse with canvas

Today a colleague asked a group of front-end developers how he would create a superelipse.

A superelipse

His current solution was to use a svg mask to remove all non essential visual information. This solution however had a setback, because we used a mask to shield the edges we had no real transparency. Thus we were unable to effectively use it on more graphic backgrounds.

I however thought it should be able to use canvas to provide the solution. The code below is my solution.  Continue reading