Logo

dev-resources.site

for different kinds of informations.

Scaling Micro-Frontend Reliability: Advanced Techniques in Version Management and Automated Testing

Published at
10/8/2024
Categories
iot
cumulocity
microfrontend
Author
techcomm_sag
Categories
3 categories in total
iot
open
cumulocity
open
microfrontend
open
Author
12 person written this
techcomm_sag
open
Scaling Micro-Frontend Reliability: Advanced Techniques in Version Management and Automated Testing

Introduction

This article is a follow-up to The power of micro frontends – How to dynamically extend Cumulocity IoT Frontends. Since the original publication, significant changes have occurred, with an increasing number of plugins being created by both Cumulocity teams and the community. As the use of micro frontends within the Cumulocity platform grew, new challenges emerged. One of the most frequently mentioned issues in the micro frontend space is dependency version incompatibility. We’ve addressed this challenge using a set of metadata called the version matrix and Cypress tests. But first, let’s look at what’s changed…

What has changed since the first micro frontend article?

A major update to our Web SDK was the deprecation of the @c8y/cli package. It has been replaced by the @c8y/devkit package, which now serves as a builder for ng-cli. In simpler terms, instead of handling all commands through our own CLI, we now extend Angular CLI. This means you don’t call @c8y/devkit directly; instead, all commands start with ng <command>. For more information about ng-cli, check out the Quickstart section.

Another change is that you no longer declare your exports in package.json. Instead, they are now defined in cumulocity.config.ts (which is later compiled to cumulocity.json).

If you’re ready to build your own plugin, refer to the Microfrontends documentation for detailed, step-by-step guidance on creating a plugin.

Version matrix

Introduced in Web SDK version 10.19.0, the version matrix is a part of the plugin designed to ensure compatibility between the plugin, Web SDK, and shell API. To use it, simply add it to your cumulocity.config.ts file.

Here’s an example of how a version matrix might look (content of cumulocity.config.ts):

export default {
  runTime: {
    ...
    versioningMatrix: {
      '2.1.6': {
        sdk: '>=1016.0.0 <1018.0.0',
        api: '>=1016.0.0 <1018.0.0',
      },
      '3.2.1': {
        sdk: '>=1018.0.0',
        api: '>=1018.0.0',
      }
    },
  },
  buildTime: {
    ...
  }
} as const satisfies EnvironmentOptions;

Enter fullscreen mode Exit fullscreen mode

The top-level keys (2.1.6, 3.2.1) represent the plugin versions, while the sdk and api values specify semver ranges of compatible Web SDK and API versions, respectively.

To illustrate how the version matrix works, let’s try installing version 3.2.1 of a plugin with the above matrix into Cockpit version 1017.0.543. You’ll receive this warning:

Plugin installation

As you can see, you can still install the plugin, but you’re warned that versions might be incompatible. Some features might not work, or the plugin could fail to load and potentially break your app. This warning won’t appear for Cockpit version 1018.0.0 or higher.

E2E testing plugins against shell

While the versioning matrix works almost effortlessly when properly declared, how do we determine which versions are compatible with our plugin? Manual testing is always an option, but it’s time-consuming and prone to human error.

This concern led us to develop a solution that informs us about incompatibilities between our plugin and the shell app.

Cypress to the rescue!

The most effective way to ensure our plugin works correctly with a particular shell app (without hiring a new QA specialist) is through end-to-end (E2E) tests. For this type of testing, we use the Cypress library along with cumulocity-cypress and cumulocity-cypress-ctrl packages, developed by our team.

We chose our Cumulocity community plugins repository to introduce this feature. The plan was straightforward - we introduced a new workflow that:

1. Collects shell versions

First, we need to decide which shell versions to test our plugin against. For this purpose, we created the plugins-e2e-setup repository containing a custom Github action collect-shell-versions. This action provides information about the latest versions for relevant distribution tags. By default, it returns the last 3 yearly release tags (and if there aren’t 3 yearly releases yet, it also includes the 1018.0-lts tag). Here’s an example result of this action:

[
  { "tag": "y2025-lts", "version": "1020.26.2" },
  { "tag": "y2024-lts", "version": "1018.503.119" },
  { "tag": "1018.0-lts", "version": "1018.0.278" }
]

Enter fullscreen mode Exit fullscreen mode

2. Builds the plugin

An obvious step - we need to build the plugin to run it in the shell in later steps.

3. Gets shell apps, hosts them, and runs E2E tests

Now that we know which shell versions we want to test our plugin against, we need to obtain builds of these apps. In our previously mentioned plugins-e2e-setup repository, we have a second custom Github action - get-shell-app. This action downloads the build of the requested app (Cockpit, Administration, or Device Management) for the specified version.

With both the shell and plugin apps in hand, we can use cumulocity-cypress-ctrl to host the apps, run Cypress test suites, and verify if the plugins are usable in the shell apps.

Usage of the workflow

Currently, we run this workflow in two scenarios:

  • On each pull request
  • Scheduled with CRON for nightly runs

The first use case helps us detect incompatibilities mainly due to changes in the plugin itself.

First use case

If tests fail, the actions that can be taken are:

  • If tests fail because test suites are out of date - update the tests
  • If tests fail because the plugin is not compatible with some shell versions:
    • Update the versioning matrix to indicate compatible Web SDK versions and align the workflow to test against relevant shell versions
    • Or review the changes and select a different approach to ensure plugin compatibility with the shell

While the first use case is mostly relevant to recent changes in the plugin, the second use case targets changes in the shell app. Even if a new plugin version hasn’t been released for days or weeks, the workflow is triggered every night, and tests are run against current versions of the shell app.

Second use case

Thanks to these scheduled runs, we can receive notifications if a new version of Cockpit is not compatible with our plugin, allowing us to take the actions mentioned above.

Of course, it doesn’t make sense to test the same version of the plugin with the same version of the shell repeatedly. That’s why our CRON job creates a cache of test results, so if no new version of the plugin or shell is released, the test case can be skipped.

The power of cumulocity-cypress-ctrl

You might wonder why we use the cumulocity-cypress-ctrl package instead of simply using the http-server package to host the shell and plugin, letting Cypress handle running test suites. There are several compelling reasons. Read full topic here to find out what they are.

microfrontend Article's
30 articles in total
Favicon
Custom builder for Angular: My way
Favicon
Tech Watch 6
Favicon
What is Microfrontend, and How to Implement It?
Favicon
How to load an MFE module from a shell app (Using Angular + Webpack + Module Federation)?
Favicon
Solucionar erro imagem module-federation
Favicon
The Future of Scalable Frontends: Independent Deployment and Unified UX with Micro Frontends
Favicon
Exploring a new communication pattern for micro-frontends
Favicon
The Evolution of Frontend Development: Exploring Different Architectures
Favicon
Scaling Micro-Frontend Reliability: Advanced Techniques in Version Management and Automated Testing
Favicon
Implementation of Microfrontend with Vite Compiler
Favicon
How to Implement Microfrontend with ejected create-react-app
Favicon
How to Implement Microfrontend with create-react-app
Favicon
Micro Frontend with Module Federation in React
Favicon
Building a MicroApp, Extending Microfrontend Pattern
Favicon
Micro Frontends
Favicon
Webpak 5 Series Part-2
Favicon
Exploring the Power of Microfrontend with React and Webpack 5
Favicon
Micro front-end module federation: Aplicação extensível
Favicon
Webpack 5 series part-4
Favicon
Webpack 5 Series Part-1
Favicon
How I reduced my app size from 14mb to 600kb
Favicon
Exploring an experimental Micro-Frontend Architecture with Server-Side Rendering using React Server Components
Favicon
Exploring Microfrontends with Vite and React: A Step-by-Step Guide
Favicon
Angular: angular/module-federation
Favicon
How to implement Micro Frontend on Salesforce with React
Favicon
Nem tudo precisa de Micro Frontends, as vezes você só precisa de Web Components
Favicon
Micro-frontend architecture alongside Vue 3 migration
Favicon
Exploring Micro Frontends in Modern Web Development
Favicon
Micro frontend frameworks in 2024
Favicon
Creating a web application using micro-frontends and Module Federation

Featured ones: