Skip to main content

· 3 min read

Easily create Siesta tests for your applications

Siesta is a JavaScript unit and UI testing tool originally written by Mats Bryntse which allows for running tests (for Ext JS (view-) components, amongst others) directly in the web browser (or headless in case you want to use it with your ci tools).

It is conjoon’s favorite among the various testing tools out there (we’re also working with Jest🃏 when there’s no Ext JS involved) and without it, it’s clear that End-to-End tests of some of the features and changes that have made it into conjoon would have slowed the project down due to their cyclic complexity — or even worse, make the software stuck in regression.

extjs-app-webmail alone sports more than 5000 unit and ui tests created with Siesta and they all make sure that the frontend behaves as intended and is free from unwelcomed side effects for any edge case that might occur (we know that’s a bold statement).

To ease the process of setting up a functional Siesta environment, we’re introducing the cli tool create-siesta which can be used with any JavaScript framework that requires a functional Siesta application running in a web browser, or at least a fully fledged infrastructure for running Siesta tests. However, by providing integrated build options for the Ext JS SDK, it is best suited for environments where the Sencha framework is already being used or will be used.

For using the tool, all that is required is a working Node.js installation on your machine. The scaffolding process can then be started by typing

$ npx create-siesta@latest

on the console. create-siesta will then guide you through the installation process and also consider the environment (aka current working directory) it was invoked in, by falling back to already existing Ext JS sources for example, or any other package requirements already available.

Once create-siesta is finished, a folder (defaulting to tests) will be available with your project that contains a scaffolded Siesta environment with templates for additional and future tests you and your team can implement. Tests can then be started with

$ npm run siesta:test

create-siesta builds upon an already available helper tool for creating tests with Siesta, namely **@coon-js/siesta-lib-helper which is already widely used throughout the conjoon** project and the packages it depends on. This means that you will have an additional control at hand with the Siesta application that allows for switching between toolkit dependent tests and dynamically changing timeout values used with

    t.waitForMs()

in tests.

*The additional control made available by siesta-lib-helper allows for switching between the modern M and classic C toolkit and provides a list of timeout values that can be globally used with t.waitForMs() in tests.*

Documentation

The documentation for create-siesta can be found here, the sources are available with the coon.js organization at GitHub, which provides a collection of useful tools for rapid Sencha Ext JS application development, and spawned from the conjoon open source project.

· One min read

JavaScript, function-as-object and the internet

The internet ™️ has caught up on an ad by FERCHAU, found — amongst others — somewhere within the depths of the Berlin subway.

Some devs cringe at the code used with the ad — turns out it can easily get de-mystified with JavaScript’s function-as-object style:

    const careerStuck = () => {};
careerStuck.stop = () => {};

Opinions regarding semantics may differ:

    if (careerStuck() === true) {
careerStuck.stop();
beSmart(); // 👀
}

Further reading

Martin Fowler on FunctionAsObject in an article from 2017. The pattern goes back to the last century when Eugene Wallingford coined the name “Function as Object” in his 1999 pattern language “Envoy”.

· 2 min read

conjoon installer updates

Creating a custom labeled version of conjoon has never been easier.

The installer (i.e. initializer) for conjoon received an update to make setting up a local installation of the frontend more convenient and more intuitive.

The installer requires Node.js 16.14 or above and is started by typing

$ npx create-conjoon@latest

on the command line. Additionally, you have the option to initiate the quick install right away by providing the name and the target directory for the installation:

$ npx create-conjoon@latest "my webmail" ~/webmail

The quick install will continue the installation process by picking the latest release from the package registry (including pre-releases) and configure the installation with fake endpoints returning demo data. You can still connect to production systems later on by using appropriate settings.

If you prefer a guided installation for configuring endpoints for existing backends right away, you can omit any of the arguments. The installer will then present various options to make sure your requirements are met!

In both cases, target directory will contain the files required for developing conjoon and a production build available in the build folder, which is served by typing npm run stage in the target directory.

· One min read

Releasing conjoon 1.0.0-beta.0

🎉 5 years after the (almost) first commit to conjoon’s new home, I’m happy to announce the immediate availability of the first public pre-release of **conjoon**, an open source email client built with JavaScript, PHP and great tools from the open source community.

To install the latest release on your local machine, type

$ npx create-conjoon@latest

then follow the instructions on screen.

Don’t miss out on the documentation for more information about available install and build types.

While I’m confident that conjoon can take its first steps in a production environment, expect a stable first release to be available in the coming days. Until then, a few additions to the documentation and the guides will be made.

Happy coding! 🎈

· 3 min read

Fix: Ext JS Simlets and omitting the status code

I recently stumbled upon a mean error that was hard to track down. Luckily, the issue was caused by a simple carelessness regarding fully configured response-objects of Simlets used in the dev-environment of the conjoon-project and did not require any large refactoring.

The original issue is tracked here: https://github.com/conjoon/extjs-app-webmail/issues/196

The issue

The problem was related to batch-operations in Ext JS: When any operation of the batch fails, the pauseonexception-setting is considered and further processing of any remaining operation is halted. The user then has the option to retry the last failed operation, continuing with the remaining operations if this was finally successful. However, retrying some of the failed operations gave the following error:

The operation that failed — and which is now about to be retried — was already destroyed by Ext JS internal garbage-collector.

The fix

It took some time to find out that the operation was destroyed and that some of the properties required for re-running it were already de-referenced. This took me to the internals of response-handling of XMLHttpRequests of Ext JS and finally to the code where the HTTP status of a request was inspected. Take note that I’m mainly developing with Simlets to avoid costly network roundtrips to any backend.

It is mandatory for the Simlets to properly treat mocked backend-errors by also providing the appropriate status-code.

It was assumed that simply setting the success-property in any of the delete/put/...-methods of a simlet treating the request would later on be parsed internally; setting the status-code of the response automatically to anything other than 200. That is not the case. It is mandatory for the Simlets to properly treat mocked backend-errors by also providing the appropriate status-code.

The flaw was too often overseen since the status-field was not set, as the following code examples show (examples represent code in any of the delete/post/put/...-methods of a Json-Simlet; see Ext.ux.ajax.Simlet):

The following leaves the ret.status-property undefined:

    //....
const ret = {};
ret.responseText = Ext.JSON.encode({
success: false
});
return ret;

… while the following re-uses the predefined value of 200 for the status, even if success=false should indicate that the request could not be processed as expected:

    const 
me = this,
ret = {};

Ext.Array.forEach(me.responseProps, function (prop) {
if (prop in me) {
ret[prop] = me[prop];
}
});

ret.responseText = Ext.JSON.encode({
success: false
});

return ret;

In both cases, Ext.data.request.Ajax would parse the response and its status in the onComplete-method:

    result = Ext.data.request.Ajax.parseStatus(xhr.status, xhr);

An undefined status would cause the response to be treated as not successful (example 1), while anything other than undefined would be parsed and interpreted according to its HTTP-status representative (successful: 200; failure: 404, 500 etc.).

ExtJS would assume that a successful operation is not needed anymore; it is automatically destroyed then. This was unexpected behavior in this case, since the code marked the operation as a failure, but not via the status-code, which was required.