{"id":29008309,"url":"https://github.com/jmix-framework/jmix-ui-tests","last_synced_at":"2025-06-25T14:04:46.043Z","repository":{"id":50863750,"uuid":"290137906","full_name":"jmix-framework/jmix-ui-tests","owner":"jmix-framework","description":"Jmix v.1 Classic UI test suite","archived":false,"fork":false,"pushed_at":"2023-04-26T12:59:18.000Z","size":23290,"stargazers_count":1,"open_issues_count":4,"forks_count":5,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-04-16T18:09:35.660Z","etag":null,"topics":["jmix","selenium","testing"],"latest_commit_sha":null,"homepage":"https://www.jmix.io","language":"Groovy","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jmix-framework.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-25T06:53:47.000Z","updated_at":"2023-07-05T14:09:45.000Z","dependencies_parsed_at":"2023-01-23T10:15:52.896Z","dependency_job_id":null,"html_url":"https://github.com/jmix-framework/jmix-ui-tests","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jmix-framework/jmix-ui-tests","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmix-framework%2Fjmix-ui-tests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmix-framework%2Fjmix-ui-tests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmix-framework%2Fjmix-ui-tests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmix-framework%2Fjmix-ui-tests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmix-framework","download_url":"https://codeload.github.com/jmix-framework/jmix-ui-tests/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmix-framework%2Fjmix-ui-tests/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261888103,"owners_count":23225137,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jmix","selenium","testing"],"created_at":"2025-06-25T14:04:30.585Z","updated_at":"2025-06-25T14:04:46.029Z","avatar_url":"https://github.com/jmix-framework.png","language":"Groovy","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jmix-ui-tests\n\nJmix UI test suite\n\n## Dependencies\n\n1. JUnit 5 (https://junit.org/junit5/)\n2. Selenide (https://ru.selenide.org/)\n3. Testcontainers (https://www.testcontainers.org/)\n4. SpringBoot (https://spring.io/projects/spring-boot)\n5. Liquibase (https://www.liquibase.org/)\n6. Jmix Masquerade (https://github.com/Haulmont/jmix-masquerade)\n\n## Description\n\nThere are two packages in `jmix-ui-tests`:\n1. `ui`- contains UI tests for testing Jmix projects\n2. `sampler`- contains UI tests for testing [Jmix Sampler project](https://github.com/Haulmont/jmix-sampler)\n\n#### Properties\n* Use ```jmix.tests.ui.baseHost``` property to define the base host of the main application for selenide browsers in ui package; \n* Use ```jmix.tests.sampler.baseUrl``` property to define the base url for selenide browsers in sampler package; \n\n### SpringBoot tests\n\nAll tests in UI package are based on Spring Boot tests. This means that you do not need to separately launch the main \napplication. The application instance is launched along with the tests. The test application instance runs on a random port, \nusing `SpringBootTest.WebEnvironment.RANDOM_PORT` the setting. This way you can run multiple tests at the same time, as \nwell as run tests while the main application is running.\n\nIn order to have JUnit 5 library support, you need to add the [SpringBootExtension](./src/test/groovy/io/jmix/tests/ui/extension/SpringBootExtension.groovy) \nin your tests.\n\nTests in sampler package are not based on Spring Boot tests. Therefore, they need to be launched only when the Jmix \nSampler application is already running.\n\n### Selenide browser containers\n\nTest browser containers are used to instantiate web browsers. Creation of browser containers is fast, so it's actually \nquite feasible to have a totally fresh browser instance for every test.\nThere are two browser containers in `jmix-ui-tests`:\n1. [ChromeExtension](./src/test/groovy/io/jmix/tests/base/extension/ChromeExtension.groovy) - a junit5 extension that \ncreates a test container with Chrome browser for each test:\n   ```groovy\n   @ExtendWith(ChromeExtension)\n   class UiTest {\n       @Test\n       void test() {\n          ...\n       }\n   }\n   ```\n2. [FirefoxExtension](./src/test/groovy/io/jmix/tests/base/extension/FirefoxExtension.groovy) - a junit5 extension that \ncreates a test container with Firefox browser for each test:\n   ```groovy\n   @ExtendWith(FirefoxExtension)\n   class UiTest {\n       @Test\n       void test() {\n          ...\n       }\n   }\n   ```\n\n#### Debugging browser in test container\n\nEach test browser container contains VNC recorder for debugging tests. You can find the following line in the logs when \nstarting the test:\n```\nINFO 5504 --- [Test worker] i.j.t.extension.BrowserExtension : VNC recorder url: vnc://localhost:32903, password='secret'\n```\nThen open the page from the URL in your browser and enter the password provided.\n\n#### Locally installed browser drivers\n\nPlease note that you need to download one of the latest versions of the web driver \ndepending on the browser you want to use to testing. For Chrome browser this is \n[chromedriver](http://chromedriver.chromium.org/downloads), for Firefox this is \n[geckodriver](https://github.com/mozilla/geckodriver/releases). Also, you  need to \nremove the use of `@ExtendWith(ChromeExtension)` annotation for test class.\n\n#### Locally installed Chrome browser driver\n\nIf you run your tests in Chrome browser, you need to edit standard\ntest configuration for the test project in IntelliJ. To do so, click the \n*Select Run/Debug Configuration* button and select *Edit Configurations*  in the \ndrop-down list. In the VM options field, add the following:\n\n* UI package\n```\n-Pselenide.browser=chrome \n-Pwebdriver.chrome.driver=\u003cyour_path\u003e/chromedriver.exe \n-Pjmix.tests.ui.baseHost=http://localhost\n```\n![Ui Chrome Test Configuration](images/uiChromeTestConfiguration.png)\n\n* Sampler package\n```\n-Pselenide.browser=chrome \n-Pwebdriver.chrome.driver=\u003cyour_path\u003e/chromedriver.exe \n-Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler\n```\n![Sampler Chrome Test Configuration](images/samplerChromeTestConfiguration.png)\n\nwhere `\u003cyour_path\u003e` is the path to the chrome driver on your computer.\n\nAfter that select the simple test or the test class you want to run, right \nclick on it and select *Debug* option.\n\nTo run the tests using Gradle, run the following task in the terminal:\n* UI package\n```\ngradle testUi -Pselenide.browser=chrome -Pwebdriver.chrome.driver=\u003cyour_path\u003e/chromedriver.exe -Pjmix.tests.ui.baseHost=http://localhost\n```\n\n* Sampler package\n```\ngradle testSampler -Pselenide.browser=chrome -Pwebdriver.chrome.driver=\u003cyour_path\u003e/chromedriver.exe -Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler\n```\n    \nwhere `\u003cyour_path\u003e` is the path to the chrome driver on your computer.\n\n#### Locally installed Firefox browser driver\n\nIf you run your tests in Firefox browser, you need to edit standard\ntest configuration for the test project in IntelliJ. To do so, click the \n*Select Run/Debug Configuration* button and select *Edit Configurations*  in the \ndrop-down list. In the VM options field, add the following:\n\n* UI package\n```\n-Pselenide.browser=firefox\n-Pwebdriver.gecko.driver=\u003cyour_path\u003e/geckodriver.exe \n-Pjmix.tests.ui.baseHost=http://localhost\n```\n![Ui Firefox Test Configuration](images/uiFirefoxTestConfiguration.png)\n\n* Sampler package\n```\n-Pselenide.browser=firefox \n-Pwebdriver.gecko.driver=\u003cyour_path\u003e/geckodriver.exe \n-Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler\n```\n![Sampler Firefox Test Configuration](images/samplerFirefoxTestConfiguration.png)\n\nwhere `\u003cyour_path\u003e` is the path to the firefox driver on your computer.\n\nAfter that select the simple test or the test class you want to run, right \nclick on it and select *Debug* option.\n\nTo run the tests using Gradle, run the following task in the terminal:\n* UI package\n```\ngradle testUi -Pselenide.browser=firefox -Pwebdriver.gecko.driver=\u003cyour_path\u003e/geckodriver.exe -Pjmix.tests.ui.baseHost=http://localhost\n```\n\n* Sampler package\n```\ngradle testSampler -Pselenide.browser=firefox -Pwebdriver.gecko.driver=\u003cyour_path\u003e/geckodriver.exe -Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler\n```\n    \nwhere `\u003cyour_path\u003e` is the path to the firefox driver on your computer.\n\n### Database containers\nThe database containers are used from the `Testcontainers` library. For example, in order to add a container with a \n`postgreSql` database, you need to add two dependencies:\n* `testRuntime 'org.postgresql:postgresql:42.2.16'` - a PostgreSql database implmentation;\n* `testImplementation 'org.testcontainers:postgresql:1.14.3'` - a test container implementation.\n\nA fresh database is created for each test class. In order to determine what data should be initialized in the database, \nliquibase contexts are used. The context for main application is **\"base\"**, it must always be added to the list of \ncontexts for the application to work correctly.\n\nTo create UI test that uses a test dataset in addition to the base dataset, you need to follow these steps:\n1. Create an extension to define database test container:\n```\nclass PostgreSQLExtension extends SpringExtension {\n\n    private PostgreSQLContainer postgreSQLContainer\n\n    @Override\n    void beforeAll(ExtensionContext context) throws Exception {\n        postgreSQLContainer = new PostgreSQLContainer()\n                .withDatabaseName(\"postgres-test-db\")\n                .withUsername(\"test\")\n                .withPassword(\"pass\")\n        postgreSQLContainer.start()\n\n        getApplicationContext(context).getBean(JmixLiquibase).afterPropertiesSet()\n    }\n\n    @Override\n    void afterAll(ExtensionContext context) throws Exception {\n        postgreSQLContainer.stop()\n    }\n}\n```\n2. Create a Spring Initializer or `application.properties` file  to define datasource properties:\n```\nclass TestContextInitializer implements ApplicationContextInitializer\u003cConfigurableApplicationContext\u003e {\n\n    @Override\n    void initialize(ConfigurableApplicationContext applicationContext) {\n        TestPropertyValues.of(\n                \"main.datasource.jdbcUrl=jdbc:tc:postgresql:9.6.12:///postgres-test-db\",\n                \"main.datasource.username=test\",\n                \"main.datasource.password=pass\",\n                \"jmix.data.dbmsType=postgres\",\n                \"jmix.liquibase.dropFirst=true\"\n        ).applyTo(applicationContext.getEnvironment())\n    }\n}\n```\n3. Create a [changeSet](./src/main/resources/io/jmix/tests/liquibase/changelog/test/2020/08/31-010-init-selenium-role.xml) \nand define a context for it:\n```\n    \u003cchangeSet id=\"4\" author=\"jmix-ui-tests\" context=\"test-role\"\u003e\n\n        \u003cinsert tableName=\"SEC_ROLE_ENTITY\"\u003e\n            \u003ccolumn name=\"ID\" value=\"cc9e420a-2b7a-4c42-8654-a9027ee14083\"/\u003e\n            \u003ccolumn name=\"VERSION\" value=\"1\"/\u003e\n            \u003ccolumn name=\"NAME\" value=\"test-selenium\"/\u003e\n            \u003ccolumn name=\"CODE\" value=\"test-selenium\"/\u003e\n        \u003c/insert\u003e\n\n    \u003c/changeSet\u003e\n```\nIn the above example, we have created a change set with the `test-role` context.\n4. Create a Spring Boot test, define `jmix.liquibase.contexts` property inside `@SpringBootTest` annotation and define \nthe initializer class inside `@ContextConfiguration` annotation:\n```\n@ExtendWith([\n        SpringBootExtension,\n        PostgreSQLExtension\n])\n@SpringBootTest(classes = JmixUiTestsApplication,\n        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,\n        properties = ['jmix.liquibase.contexts=base,test-role'])\n@ContextConfiguration(initializers = TestContextInitializer)\nclass UserUiTest extends BaseUiTest {\n\n    @Test\n    void test() {\n        ...\n    }\n}\n```\nAs a result, your tests will have data from two contexts: `base` and `test-role`.\n\n## Run tests\n\n* Tests in UI package - ```gradle testUI```\n* Tests in Sampler package - ```gradle testSampler```\n* All tests ```gradle test```\n\n## Sample test in UI package\n\n```\n@ExtendWith([\n        SpringBootExtension,\n        ChromeExtension\n])\n@SpringBootTest(classes = JmixUiTestsApplication,\n        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,\n        properties = ['jmix.liquibase.contexts=base,test-role'])\n@ContextConfiguration(initializers = PostgreSQLContextInitializer)\nclass UserUiTest extends BaseUiTest {\n\n    @Test\n    @DisplayName(\"Creates new user\")\n    void createNewUser() {\n        loginAsAdmin()\n\n        $j(MainScreen).with {\n            sideMenu.openItem(USER_BROWSE)\n                    .createUser()\n        }\n\n        $j(UserEditor).with {\n            usernameField.setValue('newUsername')\n            passwordField.setValue('qO4Hn6o')\n            confirmPasswordField.setValue('qO4Hn6o')\n\n            addBtn.click()\n\n            $j(RoleModelLookup).with {\n                roleModelsTable.getCell(withText('test-selenium'))\n                        .click()\n                lookupSelectAction.click()\n            }\n\n            windowCommitAndClose.click()\n        }\n\n        $j(UserBrowse).usersTable\n                .getCell(withText('newUsername'))\n                .shouldBe(visible)\n    }\n}\n```\n## Sample test in Sampler package\n```groovy\n@ExtendWith(ChromeExtension)\nclass ButtonSamplerUiTest extends BaseSamplerUiTest {\n\n    @Test\n    @DisplayName(\"Checks that user can click on simple button\")\n    void clickOnSimpleButton() {\n        openSample('button-simple')\n\n        $j(Button.class, 'helloButton')\n                .shouldHave(caption('Say Hello!'))\n                .click()\n\n        $j(Notification.class)\n                .shouldHave(caption('Hello, world!'))\n    }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmix-framework%2Fjmix-ui-tests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmix-framework%2Fjmix-ui-tests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmix-framework%2Fjmix-ui-tests/lists"}