👍 🎉 Thank you for taking your time to contribute. The main goal of Berg is to have an automated UI test suite for HAL a.k.a webconsole for WildFly Application Server. Berg is a test suite, that is driven by Cypress framework. Yes, we are integrating the world of dynamically-typed language (JavaScript) into the beatiful statically-typed world of Java. With the use help of TypeScript, we are tried to bridge these two worlds as close as possible. With that in mind, we/me/the author is definitely a wizard in JavaScript/TypeScript world and is definitely welcoming contributions of all kinds to this project 😊.
├── packages
| ├── berg
| ├── commands
| ├── resources
| ├── testsuite
-
berg
is responsible for launching HAL standalone container. -
testsuite
is the main test package. Tests should be placed undertestsuite/cypress/e2e
folder. Test file name should include the tested UI part and test name in thedescribe
method should include information on how to navigate to the tested resource. -
commands
is the package where the WildFly CLI abstractions are being put. This package should also include just the operations, that are present in thejboss-cli.sh
but are not available via REST API (commands such asdata-source add ...
,module add ...
) -
resources
package serves mostly to build Java deployments/JARs (such as JDBC drivers), basically anything related to the WildFly Java world.
When developing in Cypress, you need to understand two different JavaScript runtimes
- The one Cypress bundles into the browser under test
- System wide JavaScript
Since using TestContainers to launch containers shouldn't be bundled into browser under test, starting the WildFly container is being done using Cypress arbitrary Node code running handle - cy.task
, use
cy.startWildFlyContainer
method, which is a wrapper for
cy.task("start:wildfly:container")
to start the container. Note that despite starting the web server being marked as an anti-pattern, starting the WildFly server clean has its benefits in terms of a clean environment per test and also it introduces means for test parallelization (we know what we're doing 🙂). This method/task also automatically sets the deployed HAL container endpoint in the allowed-origins
attribute. Both of the approaches would return the management endpoint of the deployed WildFly instance.
Communication with the WildFly management interface is also being done using Cypress task, execute:cli
to be precise. A better example of running /system-property=to-add:add(value=myVal)
in JBoss CLI in Berg using cy.task
would be
cy.task("execute:cli", {
managementApi: `${managementEndpoint}/management`,
operation: "add",
address: ["system-property", "to-add"],
value: "myVal"
});
- To start developing tests, you can copy paste following example into your
packages/testsuite/cypress/e2e/test-to-be-added.cy.ts
. - Added tests should be prefixed with "test-" followed by navigation crumbs of the tested UI area.
- When developing new tests, prefer to test viable minimum per test, e.g if a page has a vertical navigation list elements, test one of the element per test file.
- Currently, our GH actions are running test matrix nightly, where the tests are being grouped by regular expressions (see
jobs.test_matrix.strategy.matrix.specs
). If you're developing a new test that would enhance mentioned test groups, make sure to edit GH workflows as well.
// "describe" method is an equivalent of a TestClass
// Please keep the "TESTS:" in the "test class" name followed by
// navigation crumbs in the management console
describe("TESTS: Path => To => Tested => Resource", () => {
const configurationFormId = "resource-form";
let managementEndpoint: string;
// Here we start our WildFly container prior to test execution
before(() => {
// Obtains WildFly management endpoint, that will be used
// for backend data retrieval and validation
// cy.startWildflyContainer also starts the WildFly container under
// the name of the spec/test file, e.g in our case: test_to_be_added
// This could be useful (however it shouldn't happen) when you want to see which test didn't stop the WildFly container (maybe the "after" hook failed for some reason)
cy.startWildflyContainer().then((result) => {
managementEndpoint = result as string;
});
});
// Here we stop & remove started WildFly container and other containers
// e.g postgres (see packages/testsuite/cypress/e2e/test-configuration-datasource-postgre-finder.cy.ts)
after(() => {
cy.task("stop:containers");
});
// "it" method is an equivalent of a @Test annotated method,
// First argument is the name of the test, second is a lambda test function
it("Edit default-extended-persistence-inheritance", () => {
// Navigates to the UI page
// http://localhost:<mapped_hal_port>?connect=http://localhost:<mapped_wildfly_port>#<token>
cy.navigateTo(managementEndpoint, "token");
// Clicks on the "Edit" button of the form to be edited
cy.editForm(configurationFormId);
// Fills in "sample" into the #resource-form-module-editing input
cy.text(configurationFormId, "module", "sample");
// Clicks on the "Save" button of the form
cy.saveForm(configurationFormId);
// Verifies a succesful notification has been displayed in the UI
cy.verifySuccess();
// Checks that /path=to/tested=resource:read-attribute(name=module)
// returns "sample" and is succesful
cy.verifyAttribute(managementEndpoint, ["path", "to", "tested", "resource"], "module", "sample");
});
});