Synchronization between ODP and NSF goes rogue

We develop in a team an XPages application and we experienced that it takes longer time to build a project and to refresh the design of the templates on ACC and PROD environment. We noticed that a lot of files are being replicated so initially I thought it were the files for web-plugins like Datatables was causing troubles. But after I moved these files to a common shared resources NSF this XPages application still had a lot of unclear files in it.

When I analysed the design of the NSF with ScanEZ I saw that it contained almost a 1000 “Eclipse Files”. An analyse of another less frequently developed XPages application gave a similar indication, but here the number of Eclipse Files are a lot less, but still not reasonable:

The files that appear first in the list are “expected” (although for not all clear is clear what their purpose is) but then the list goes on as followed:

For some of the classes I have more than 30 versions of them!

I have stored these classes via the Package Explorer Eclipse view under WebContent\WEB-INF\src folder and added it to the build path. I added them here because it felt more alike to store them here as in Java projects outside of DDE. This seems to work fine from the start and still does except that as side-effect that you seem to get a lot of versions.

So what is the root cause of this misery (when building a project goes slow and it replicates undesired files across NSF’s) I don’t know. We use GitHub and I don’t notice the files in the source code. So they must appear when DDE is synchronising the ODP with the NSF.

So the files only reside in the NSF.

I have no clue how I should avoid the creation of these “version” files except storing the Java classes under the Code\Java section in DDE which has some disadvantages like collapsible packages (unnecessary scrolling) and new methods will be noticed in DDE AFTER I have closed and re-opened the project (SUCK).

Luckily via this approach the version files are being removed when you update the NSF via the “replace design” method. So in restricted-access environments like ACC and PROD this can save you some pain.

So if you have a suggestion and want to save my day, please write down what alternative way works for you. Happy development 🙂

Edit: I add here my painful experience with HCL regarding the issue above. I reported a case at HCL and their first response was that they do not give support on observations made from third-party tools (ScanEz). But when I replied that I make the same observation with HCL’s NotesPeek they replied that I should not place custom Java classes in custom folders in the Package Explorer view and add them as build path but as Code\Java design elements. Then I referred to an online WIKI-article of them where it is demonstrated how and where to create custom Java classes. As reply I got that this was a method for 8.5 and is no longer supported for newer releases. One might wonder what they have changed here after 8.5 but I guess not much.

Seasonal gift

Today I posted “Team Documents” as a seasonal gift as a project on OpenNTF. What is it? Well it is a small document management application for the Notes client. What makes it so unique? First, it is wrapped in an OpenNTF styled “gift-paper” as you can see in the next image:

Second, it has features that makes Notes once the most popular document management platform:

  • Authors and Readers access management
  • Review options
  • Revision (versioning)
  • Expire settings
  • (locked) categorizing
  • Usage of templates

The application has also a nice start-page which gives a short summary of the latest activities of users.

I would say download it and test it out. As with Notes, it is easy to adapt to your requirements. Ho!Ho!Ho!

Using OpenLog for logging/ debugging XPages

Today I opened a database where a developer insists on writing almost all code in SSJS. A bit odd because OpenNTF Domino API is enabled and used in this particular application. I guess JAVA is still frightening. But because of SSJS you get unexpected behaviour which are difficult to catch in OpenLog. Because this implementation requires a component ID, which is hard to get if your code resides in script libraries, I thought it is time to write a simple helper class in Java so at least “some” for of exceptions can be captured. But then I stumbled upon this post where is mentioned that there is a SSJS helper script library in TaskJam which allows you to log to OpenLog without the component ID.

So I added the TaskJam script library, added it as resource and moved the application code in try…catch blocks. In the post are some suggestions to adapt the code in the library. Here are mine:

  • Instead of view.getPageName() I used view.getRequestUrl() to get the full page name including parameters.
  • for the logDbPath variable I re-used the same OpenLog reference in the XSP properties file (added as a resource bundle using path (“/WEB-INF/xsp.properties”) and call it by the variable name you provided e.g. var logDbPath = xspProp[“xsp.openlog.filepath”]

After writing some bad code I noticed the error registered in OpenLog. I am curious what errors will come in from Production for this application…

Happy development 🙂

Making OpenLog entries a bit more lively

I assume you are using the OpenLog project on OpenNTF in most of your projects like I do. And you twist with the SEVERITY options to distinguish the openlog view entries as much as possible. If you feel limited to use one of the three options to get a red + or ++ sign in a column perhaps the emoji-java class is something for you?

Just look at all the available emoji’s and imagine how they could lively up OpenLog!

So what should you do to enable this? Download the emoji library and include them in your code, e.g. an Java agent as an archive:

Then in your code start using them! For example:

will result in something marvelous as:

So don’t complain next time that reading the logs is such a boring task!

Happy development 🙂

XPages hack – visualizing checkboxes that fail validation

In an application I have added some CSS to highlight fields that fail validation. The css looks as followed:

Basically I an looking for the aria-invalid=true attribute on input elements. Works great but not on all input elements. For example re-styling of checkboxes requires some work. But what if you would re-style the element that contains the checkbox?

In the following example I have captured a checkbox control inside a table data cell of 1% width:

For the checkbox control I have defined a custom validator that gets only triggered when a certain element send the xpage to the server (an button control with id btnSendToCommittee)). When the validation fails the checkbox also gets the aria-invalid=true attribute.

To apply a visual indication if a certain checkbox fails I have setup a simple JS function:

This function scans the page for inputs with the aria-invalid=true attribute and for all matches checks if the found item is a checkbox. If so, the parent, containing element (the table data cell) will be applied some styling.

Besides a listing in the xp:messages control I also have a visual indicator for the checkbox on the location of the xpage:

I have not managed to write a single-line css selector therefor I still loop through the found inputs that match the aria-invalid=true attribute. Here your assistance comes in… 😉

Happy coding!

Sticky headers in Bootstrap from ExtLib

I received a request from a customer who would like to preserve the action buttons on an xpage when the user scrolls downs a very long form.

The application is already using the BS theme from the Extension Library with the sticky navbar option in use so this would implement a second ‘sticky element’.

Here is an example how the xpage looks like:

Note: I added some Lorem Ipsum content in stead of form elements for demo purpose, but you get the idea of a endless form to fill in.

So first I added a listener for the scroll event:

window.onscroll = function() {scrollFunction()};

The scrollFunction is as followed:

function scrollFunction() {
if (document.body.scrollTop > 50 || document.documentElement.scrollTop > 50) {
console.log('make SMALL')
$('.navbar').css({
'min-height': '32px',
'height': '32px'
});
$('.navbar-brand').css({
'height': '32px',
'padding-top': '5px',
'padding-bottom': '5px'
});
$('.navbar-nav > li > a').css({
'padding-top': '5px',
'padding-bottom': '5px'
});
$('#infoLanguage > div.dropdown').css({
'padding': '5px 5px'
});
$('#form-header').css({
'display': 'block',
'z-index': '-1'
});
$('#form-header-hidden').css({
'display': 'block',
'position': 'fixed',
'top': '30px',
'height': '30px',
'z-index': '996'
});
$('navbar').addClass('shrink');
} else {
console.log('make LARGE')
$('.navbar').css({
'min-height': '50px',
'height': '50px'
});
$('.navbar-brand').css({
'height': '50px',
'padding-top': '15px',
'padding-bottom': '15px'
});
$('.navbar-nav > li > a').css({
'padding-top': '15px',
'padding-bottom': '15px'
});
$('#infoLanguage > div.dropdown').css({
'padding': '15px 10px'
});
$('#form-header').css({
'display': 'block'
});
$('#form-header-hidden').css({
'display': 'none',
'position': 'fixed',
'top': '0px',
'height': '30px',
'z-index': '0'
});
$('navbar').removeClass('shrink');
}
}

I also added some additional styling for style and transition effects:

<style> 
	#form-header-hidden{ 
	width:100%; 
	background-color:white; 
	height:0px; 
	padding:5px 150px; 
	box-shadow: 0px 3px 5px 0px rgba(182,182,182,0.75); 
	transition: all 0s, opacity 0.5s linear;
} 

#form-header{ 
	transition: all 0s, opacity 0.5s linear;
}

.navbar{
	transition: all 0.5s;
}
.navbar-brand img{
    transition: all 0.5s;
}
</style>

So I basically make 2 form-header elements, on for ‘normal’ display when focus is on the top and one when the user starts to scroll down from a certain point. The form elements are basically the same but more adapted on the height of their container.

One thing I would like to note is that I had to place the ‘smaller’ sticky header under the navbar so it can inherit the same with as its parent. Otherwise I would look not nice with a bit of displacement.

I also noted a small shaking effect when I would use the visibility option to show/hide which form-header to display. Choosing here to play mess with the z-index property solves that issue with shaking when scrolling slowly in the beginning.

Here is the result when the user starts to scroll down. The form header becomes small but sticky under the navbar. The buttons to interact with the form are available where ever the user is in the form:

A small new feature in the app but I think it will bring a lot of user satisfaction! Happy coding 🙂

Fixing the Tooltip function in XPages #2

In a previous post I wrote about the disfunction of the tooltip after validation with the Domino server. It turns out my gigia-form has a lot of fields with visibility properties set that are calculated after partial refresh. To have tooltip fixed for the fields that become visible during interaction with the user I needed to apply another patch.

From the xsnippet for the standby control I took the first part to set up the ability to subscribe to the different partial refresh events. Then I added some lines to subscribe to the partialrefresh-complete state:

The initToolTip function did not changed:

With this subscription the tooltip becomes applied to fields that become visible after validation (when the user continues to fill in the form).

The possibility to subscribe to partialrefresh states is also a use-case for other plugins I use, for example to automatically adapt textareas to user-input.

Fixing the Tooltip function in XPages

A colleague noticed that the tooltip function on a Xpage stopped working after submitting the page to the server and when the validation did not pass. The same behaviour occurred when I added a computed text control that would spit out an anchor reference using a tooltip. Odd.

I found an old post of mine where I described the use of the xe:tooltip control. This control seems to keep working even when the XPage fails to validate. So that is a win.

However, in my case I would have to apply the control on many places which does not make me happy.

I also wanted to alter the layout of the tooltip a bit via a template so I found this piece of code. To my delight I noticed that the tooltip also kept working after a failed validation!

So a simple bit of code can fix tooltip again:

So after applying a template for the tooltip and applying some CSS my tooltip looks a bit more readable and less boring:

Note that I have to set the xp:this.title property for the inputTextArea control. Adding an additional attribute for the placeholder won’t do for the template.

For Nathan T(eacher) Freeman

Today I read the sad news that Nathan T Freeman is no longer among us. I was actually googling last week, curious what he was working on.

I met Nathan a couple of times. The first time was at a Lotussphere sponsor party (by Nokia, 2008?) with a Rock Hero theme. I was honoured you and Tim Tripcony joined our table. Probably because team Sweden was already into heavy (free beer, duh) drinking and getting louder and louder.

I thought you and Tim were the rock heroes in the Domino world. But actually you were more a teacher for me. I actually made a long-long ago a song for all my teachers then, and see: you were one of them.

Thanks for your guidance with helping me find the solutions for my technical challenges!

Uncategorized

TestiNG XPages

Introduction with Selenium IDE

A while ago I started my journey into testing applications. Like most people I started with Selenium IDE since it’s free, easy to install and setup. The idea was to record the workflow in an application and play it back after the development of every new feauture.

A nice idea but it does not work so well with the dynamic ID’s XPages generates for it’s controls. Instead of the id attribute you can then go via XPath and apply parameters. Here is an example for my Edit Box control that has id ‘inputCustusomerName’ -> starts with @id,’view:’ and contains @id,’inputCustusomerName’.

It becomes a lot of fiddling with the IDE and basically it becomes a long, long script (if you have a larger workflow) which you are capable of structuring in smaller pieces via the suite option.

Selenium WebDriver

When talking with more experienced test people they all drop the IDE and go for Selenium Webdriver. I will not go into details on WebDriver but the specs of WebDriver overclasses the IDE by far and it’s available in different languages. Since my XPages applications are already written mostly in Java so one is acquainted in a sense with an Eclipse environment (DDE) the step to start writing code in Eclipse IDE is not that big.

So with WebDriver used across the organization I feel more assured to join that community instead working on tests on an island (with Domino is also in a way). We have actually an infrastructure for WebDriver with Selenium Grid and support via a framework based upon Selenium WebDriver.

TestNG

When you start writing your tests in the beginning you end up like with the Selenium IDE in a long script that can do one thing. If you want to take the next leap then check TestNG. It extends the test capabilities by far and allows to structure and configure your tests to way you want.

ith TestNG your can setup ‘testsuites’ and in those suites you can define which tests to run. I use the suites to run tests in different roles.

At first I looked at the option to run my tests from DDE ( I found some posts/presentations where it looked it should be possible) to avoid moving to another development IDE. But after installing the TestNG plugin in DDE and writing some scripts using WebDriver when running the TestNG suite it searched for files that where outside my NSF (workspace directory location). So the option to remain coding in DDE I gave up.

Test framework

If you work in a larger organization you are probably not the first person who writes tests. I found in my organization a supported test framework that is based upon Selenium WebDriver and TestNG and includes more features like for example ReportNG which allows you to create HTML reports of your tests. Selenium WebDriver has a feature to take a screenshot so that is nice to include in your test report.

The framework has many more features which I have not touched (yet).

Lessons learned

With Selenium WebDriver you will face the same problems with dynamic id’s as in Selenium IDE. Use XPath as selector the web element e.g.:

When accessing lists, like link controls in a repeat control these XPath reference does not work. they all end with the same ID part. So when you register a new customer and that customer will appear in a table you do not know in which row that customer will appear depending on the content in that table. You can even have so many customers in the table so that you need to use a pager.

In Domino it is common you define userroles in your Access Control List and then distribute these roles to users/groups. Especially if you want to test a workflow you access the application in different roles. Via TestNG tend to provide a role as parameter, and for that role I use different user credentials. When working in a team and Git you do not want to expose these credentials so I started to use Jasypt for decrypting these values.

If you have an application that supports multiple languages you also want to check your application in those languages. In WebDriver you can find links by their text and these textes probably differ in languages.

Conclusion

Tests are a common part of development and in modern development test drive development. As a Domino developer you have to adapt to this paradigm. If your team is too small for test developers you probably have to write those test yourself. Writing tests expands your development skills and you talk with colleagues in different areas of your organization you otherwise never would have contact with.

In my situation WebDriver is a common tool and I could not find any JavaScript supported framework available in our organization. Writing test scripts with WebDriver is not a big step for XPages developers and I recommend to take a look at TestNG to be able to structure your tests from the start.

Test is a wide area and I have only explored a part of it. Test is also an important part of CICD (continious integration continious delivery) if you happen to have as goal to deliver an automated process for the build of your Domino applications.

Good luck and enjoy the journey!