Masquerade - Regression Testing Automation for CUBA

I’m proud to announce our new Open Source tool! Masquerade - testing library for CUBA-based applications.

masquerade-announce

Masquerade is a set of libraries for automating user interface testing and ensuring regressions get caught. You can easily build tests that catch everything from UI changes to database quirks, maintain the test in any JVM language and run them manually or in your CI environment.

The library provides an ability to create UI tests for CUBA-based applications using masquerade-web module. Also, you can create REST-API tests with masquerade-connector module.

Essentially, masquerade is based on well-known libraries such as selenium and retrofit2 and brings a lot of features for testing of CUBA applications. It makes it easier to start writing UI tests without hustle.

If we look closely enough we will see that UI tests could be simple and expressive:

public class LoginWindowTest {
    @Test
    public void loginTest() {
        open("http://localhost:8080/app");

        LoginWindow loginWindow = Components.wire(LoginWindow.class);

        loginWindow.loginField
                .shouldBe(EDITABLE)
                .shouldBe(ENABLED);

        loginWindow.loginField.setValue("admin");
        loginWindow.passwordField.setValue("admin");
        loginWindow.rememberMeCheckBox.setChecked(true);

        loginWindow.loginSubmitButton
                .shouldBe(VISIBLE)
                .shouldBe(ENABLED)
                .shouldHave(caption("Submit"));

        loginWindow.loginSubmitButton.click();
    }
}

And no HTML magic required!

We are already using masquerade tool suite for the platform itself. Moreover, it is used in products and projects that we are building at Haulmont for almost a year now.

You can learn more about masquerade on Github and in the demo project.

If you have any questions feel free to ask them here on forum.

Find regressions before your users do!

8 Likes

Decent set of instructions. Got it working surprisingly quickly. Here’s what the test looks like when converted into Kotlin:

import com.haulmont.masquerade.Components
import org.junit.Test

import com.codeborne.selenide.Selenide.open
import com.haulmont.masquerade.Conditions.*

class LoginWindowTest {
    @Test
    fun loginTest() {

        doLogin()
    }

    private fun doLogin() {
        open("http://localhost:8080/app")

        val loginWindow = Components.wire(LoginWindow::class.java)

        loginWindow.loginField?.shouldBe(EDITABLE)?.shouldBe(ENABLED)

        loginWindow.loginField?.value = "admin"
        loginWindow.passwordField?.value = "admin"
        loginWindow.rememberMeCheckBox?.isChecked = true

        loginWindow.loginSubmitButton
                ?.shouldBe(VISIBLE)
                ?.shouldBe(ENABLED)
                ?.shouldHave(caption("Submit"))

        loginWindow.loginSubmitButton?.click()
    }
}

I probably should’ve left it as Java …

I’d recommend introducing get methods for Composite fields and then rewrite code in more idiomatic way:

class KotlinLoginTest {

    @Test
    fun test() {
        open("http://localhost:8080/app")

        val loginWindow = Components.wire(LoginWindow::class.java)

        loginWindow.apply {
            loginField
                    .shouldBe(EDITABLE)
                    .shouldBe(ENABLED)

            loginField.value = "masquerade"
            passwordField.value = "rulezzz"

            rememberMeCheckBox.isChecked = true

            loginButton
                    .shouldBe(VISIBLE)
                    .shouldBe(ENABLED)
                    .shouldHave(caption("Submit"))

            loginButton.click()
        }
    }
}

Yeah, that looks better. I’ll give that a try.

Thanks.

How did you set up the composite fields?

Okay, managed to get it working by setting up the fields like this:

package com.willowparkmedia.peertest

import com.haulmont.masquerade.Components
import com.haulmont.masquerade.base.Composite
import com.haulmont.masquerade.components.*
import org.openqa.selenium.By

class LoginWindow : Composite<LoginWindow>() {

    val loginField: TextField = Components.wire(TextField::class.java, By.cssSelector(".c-login-username") )
    val passwordField: PasswordField = Components.wire(PasswordField::class.java, By.cssSelector(".c-login-password"))
    val rememberMeCheckBox: CheckBox = Components.wire(CheckBox::class.java, "rememberMeCheckBox")
    val loginSubmitButton: Button = Components.wire(Button::class.java, "loginFormLayout", "loginButton")

}

TL;DR Use approach mentioned below: Masquerade - Regression Testing Automation for CUBA - #11 от пользователя artamonov - CUBA.Platform

Don’t do this. It is ugly and you lose many features of automatic injection.

Just define composite in the following form:

class LoginWindow : Composite<LoginWindow>() {
    @field: Wire
    private var _loginField: TextField? = null

    val loginField : TextField
        get() = this._loginField!!
}

Mmmm. I think we’re going to have to agree to disagree on that one.

Your solution needs two fields for each component, and one of those is still a nullable.

Mine is less lines and uses immutable objects which I prefer, though It does mean I need to set ids and/or classes on the components I need to reference.

Unfortunately, it requires a lot of boilerplate instead of declarative syntax

And the private field has to share the name of the cuba id on the element for this to work, so I think the private var field has to be called loginField

I’ve found the best approach! lateinit modifier!

class LoginWindow : Composite<LoginWindow>() {
    @field: Wire
    lateinit var loginField: TextField
}
1 Like

Yes! That’s the one! I didn’t know about the lateinit!

Thanks for sticking with this.

if I want test menu item of main app shouldBe(VISIBLE) . How can I do it ? I want test if showed an item menù when I login with differents users roles. If present I can using :slight_smile:

 _$(AppMenu.class).openItem("administration", "sec$User.browse");

but if menu administrator is hidden how can I test ?

Hi,

There is no such feature for that yet, so welcome to the issue tracker: Issues · cuba-platform/masquerade · GitHub

Can you provide a sample how use a table UI ? For example check existing columns and row cell navigation to check values

Hi,

We have just added a small tutorial on Tables: How to work with tables · cuba-platform/masquerade Wiki · GitHub

2 Likes

Hi,

I’d like to know if there is also a recorder functionality available with this addon? This would be great for our testing guys as they don`t want to be bothered with coding ;-). Or is there an integration with the regular Selenium IDE?

Thank you.

Best regards,
Markus

Hi,

The main focus of the library is coding, simple and convenient code for tests. That’s why we are not planning to implement a recorder or visual tool for now.

Hi Yuriy,

alright, thank you for the quick reply.

Best regards,
Markus

Just to clarify, the idea of visual tool for testing is great. Unfortunately, it requires a lot of resources. We will see if we can go in this direction in the future.