Git Product home page Git Product logo

jmix-ui-tests's Introduction

jmix-ui-tests

Jmix UI test suite

Dependencies

  1. JUnit 5 (https://junit.org/junit5/)
  2. Selenide (https://ru.selenide.org/)
  3. Testcontainers (https://www.testcontainers.org/)
  4. SpringBoot (https://spring.io/projects/spring-boot)
  5. Liquibase (https://www.liquibase.org/)
  6. Jmix Masquerade (https://github.com/Haulmont/jmix-masquerade)

Description

There are two packages in jmix-ui-tests:

  1. ui- contains UI tests for testing Jmix projects
  2. sampler- contains UI tests for testing Jmix Sampler project

Properties

  • Use jmix.tests.ui.baseHost property to define the base host of the main application for selenide browsers in ui package;
  • Use jmix.tests.sampler.baseUrl property to define the base url for selenide browsers in sampler package;

SpringBoot tests

All tests in UI package are based on Spring Boot tests. This means that you do not need to separately launch the main application. The application instance is launched along with the tests. The test application instance runs on a random port, using SpringBootTest.WebEnvironment.RANDOM_PORT the setting. This way you can run multiple tests at the same time, as well as run tests while the main application is running.

In order to have JUnit 5 library support, you need to add the SpringBootExtension in your tests.

Tests in sampler package are not based on Spring Boot tests. Therefore, they need to be launched only when the Jmix Sampler application is already running.

Selenide browser containers

Test browser containers are used to instantiate web browsers. Creation of browser containers is fast, so it's actually quite feasible to have a totally fresh browser instance for every test. There are two browser containers in jmix-ui-tests:

  1. ChromeExtension - a junit5 extension that creates a test container with Chrome browser for each test:
    @ExtendWith(ChromeExtension)
    class UiTest {
        @Test
        void test() {
           ...
        }
    }
  2. FirefoxExtension - a junit5 extension that creates a test container with Firefox browser for each test:
    @ExtendWith(FirefoxExtension)
    class UiTest {
        @Test
        void test() {
           ...
        }
    }

Debugging browser in test container

Each test browser container contains VNC recorder for debugging tests. You can find the following line in the logs when starting the test:

INFO 5504 --- [Test worker] i.j.t.extension.BrowserExtension : VNC recorder url: vnc://localhost:32903, password='secret'

Then open the page from the URL in your browser and enter the password provided.

Locally installed browser drivers

Please note that you need to download one of the latest versions of the web driver depending on the browser you want to use to testing. For Chrome browser this is chromedriver, for Firefox this is geckodriver. Also, you need to remove the use of @ExtendWith(ChromeExtension) annotation for test class.

Locally installed Chrome browser driver

If you run your tests in Chrome browser, you need to edit standard test configuration for the test project in IntelliJ. To do so, click the Select Run/Debug Configuration button and select Edit Configurations in the drop-down list. In the VM options field, add the following:

  • UI package
-Pselenide.browser=chrome 
-Pwebdriver.chrome.driver=<your_path>/chromedriver.exe 
-Pjmix.tests.ui.baseHost=http://localhost

Ui Chrome Test Configuration

  • Sampler package
-Pselenide.browser=chrome 
-Pwebdriver.chrome.driver=<your_path>/chromedriver.exe 
-Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler

Sampler Chrome Test Configuration

where <your_path> is the path to the chrome driver on your computer.

After that select the simple test or the test class you want to run, right click on it and select Debug option.

To run the tests using Gradle, run the following task in the terminal:

  • UI package
gradle testUi -Pselenide.browser=chrome -Pwebdriver.chrome.driver=<your_path>/chromedriver.exe -Pjmix.tests.ui.baseHost=http://localhost
  • Sampler package
gradle testSampler -Pselenide.browser=chrome -Pwebdriver.chrome.driver=<your_path>/chromedriver.exe -Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler

where <your_path> is the path to the chrome driver on your computer.

Locally installed Firefox browser driver

If you run your tests in Firefox browser, you need to edit standard test configuration for the test project in IntelliJ. To do so, click the Select Run/Debug Configuration button and select Edit Configurations in the drop-down list. In the VM options field, add the following:

  • UI package
-Pselenide.browser=firefox
-Pwebdriver.gecko.driver=<your_path>/geckodriver.exe 
-Pjmix.tests.ui.baseHost=http://localhost

Ui Firefox Test Configuration

  • Sampler package
-Pselenide.browser=firefox 
-Pwebdriver.gecko.driver=<your_path>/geckodriver.exe 
-Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler

Sampler Firefox Test Configuration

where <your_path> is the path to the firefox driver on your computer.

After that select the simple test or the test class you want to run, right click on it and select Debug option.

To run the tests using Gradle, run the following task in the terminal:

  • UI package
gradle testUi -Pselenide.browser=firefox -Pwebdriver.gecko.driver=<your_path>/geckodriver.exe -Pjmix.tests.ui.baseHost=http://localhost
  • Sampler package
gradle testSampler -Pselenide.browser=firefox -Pwebdriver.gecko.driver=<your_path>/geckodriver.exe -Pjmix.tests.sampler.baseUrl=http://localhost:8080/sampler

where <your_path> is the path to the firefox driver on your computer.

Database containers

The database containers are used from the Testcontainers library. For example, in order to add a container with a postgreSql database, you need to add two dependencies:

  • testRuntime 'org.postgresql:postgresql:42.2.16' - a PostgreSql database implmentation;
  • testImplementation 'org.testcontainers:postgresql:1.14.3' - a test container implementation.

A fresh database is created for each test class. In order to determine what data should be initialized in the database, liquibase contexts are used. The context for main application is "base", it must always be added to the list of contexts for the application to work correctly.

To create UI test that uses a test dataset in addition to the base dataset, you need to follow these steps:

  1. Create an extension to define database test container:
class PostgreSQLExtension extends SpringExtension {

    private PostgreSQLContainer postgreSQLContainer

    @Override
    void beforeAll(ExtensionContext context) throws Exception {
        postgreSQLContainer = new PostgreSQLContainer()
                .withDatabaseName("postgres-test-db")
                .withUsername("test")
                .withPassword("pass")
        postgreSQLContainer.start()

        getApplicationContext(context).getBean(JmixLiquibase).afterPropertiesSet()
    }

    @Override
    void afterAll(ExtensionContext context) throws Exception {
        postgreSQLContainer.stop()
    }
}
  1. Create a Spring Initializer or application.properties file to define datasource properties:
class TestContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    void initialize(ConfigurableApplicationContext applicationContext) {
        TestPropertyValues.of(
                "main.datasource.jdbcUrl=jdbc:tc:postgresql:9.6.12:///postgres-test-db",
                "main.datasource.username=test",
                "main.datasource.password=pass",
                "jmix.data.dbmsType=postgres",
                "jmix.liquibase.dropFirst=true"
        ).applyTo(applicationContext.getEnvironment())
    }
}
  1. Create a changeSet and define a context for it:
    <changeSet id="4" author="jmix-ui-tests" context="test-role">

        <insert tableName="SEC_ROLE_ENTITY">
            <column name="ID" value="cc9e420a-2b7a-4c42-8654-a9027ee14083"/>
            <column name="VERSION" value="1"/>
            <column name="NAME" value="test-selenium"/>
            <column name="CODE" value="test-selenium"/>
        </insert>

    </changeSet>

In the above example, we have created a change set with the test-role context. 4. Create a Spring Boot test, define jmix.liquibase.contexts property inside @SpringBootTest annotation and define the initializer class inside @ContextConfiguration annotation:

@ExtendWith([
        SpringBootExtension,
        PostgreSQLExtension
])
@SpringBootTest(classes = JmixUiTestsApplication,
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        properties = ['jmix.liquibase.contexts=base,test-role'])
@ContextConfiguration(initializers = TestContextInitializer)
class UserUiTest extends BaseUiTest {

    @Test
    void test() {
        ...
    }
}

As a result, your tests will have data from two contexts: base and test-role.

Run tests

  • Tests in UI package - gradle testUI
  • Tests in Sampler package - gradle testSampler
  • All tests gradle test

Sample test in UI package

@ExtendWith([
        SpringBootExtension,
        ChromeExtension
])
@SpringBootTest(classes = JmixUiTestsApplication,
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        properties = ['jmix.liquibase.contexts=base,test-role'])
@ContextConfiguration(initializers = PostgreSQLContextInitializer)
class UserUiTest extends BaseUiTest {

    @Test
    @DisplayName("Creates new user")
    void createNewUser() {
        loginAsAdmin()

        $j(MainScreen).with {
            sideMenu.openItem(USER_BROWSE)
                    .createUser()
        }

        $j(UserEditor).with {
            usernameField.setValue('newUsername')
            passwordField.setValue('qO4Hn6o')
            confirmPasswordField.setValue('qO4Hn6o')

            addBtn.click()

            $j(RoleModelLookup).with {
                roleModelsTable.getCell(withText('test-selenium'))
                        .click()
                lookupSelectAction.click()
            }

            windowCommitAndClose.click()
        }

        $j(UserBrowse).usersTable
                .getCell(withText('newUsername'))
                .shouldBe(visible)
    }
}

Sample test in Sampler package

@ExtendWith(ChromeExtension)
class ButtonSamplerUiTest extends BaseSamplerUiTest {

    @Test
    @DisplayName("Checks that user can click on simple button")
    void clickOnSimpleButton() {
        openSample('button-simple')

        $j(Button.class, 'helloButton')
                .shouldHave(caption('Say Hello!'))
                .click()

        $j(Notification.class)
                .shouldHave(caption('Hello, world!'))
    }
}

jmix-ui-tests's People

Contributors

flaurite avatar glebfox avatar maistrenkoiulia avatar maxkatyshev avatar owlet1997 avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jmix-ui-tests's Issues

Fix audit tests in CI

EntityLogViewTest.checkModifiedRecordSetup(Checks modified record for changes with logged setup) io.jmix.tests.ui.test.audit
EntityLogViewTest.checkRemovedAndRestoredRecord(Checks removed and restored entity record) io.jmix.tests.ui.test.audit
EntityLogViewTest.checkCreatedRecord(Checks created setup record) io.jmix.tests.ui.test.audit

Cover dymanic attribute component by autotests

see http://jmix-testit.haulmont.com/projects/5/tests?isolatedSection=1e463e9a-9cbc-4db2-81f6-2ad0e7921cc1
TCs:

  • Check category display for categorized entity;
  • Checks category display for categorized entity;
  • Edit category attribute;
  • Remove category attribute;
  • Check calculated values for entity attribute;
  • Create dynamic attribute category;
  • Edit dynamic attribute category;
  • Remove dynamic attribute category;
  • Check boolean type attribute;
  • Check date type attribute;
  • Check date without time type attribute;
  • Check double type attribute;
  • Check entity type attribute;
  • Check enum type attribute;
  • Check Fixed-point number type attribute;
  • Check Integer type attribute;
  • Check String type attribute;
  • Check category localization;
  • Check attribute localization;
  • Check enum localization (disabled "https://github.com/Haulmont/jmix-dynattr/issues/96");
  • Creates category attribute;

First test fails with initialization error sometimes

Description

Sometimes first test has initialization error, however next tests work fine.

Stacktrace
io.jmix.tests.ui.test.audit.EntityLogSetupTest.initializationError
01:28:01       org.rnorth.ducttape.TimeoutException: Timeout waiting for result with exception
01:28:01       org.rnorth.ducttape.TimeoutException: Timeout waiting for result with exception
        at app//org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:54)
        at app//org.testcontainers.containers.BrowserWebDriverContainer.getWebDriver(BrowserWebDriverContainer.java:292)
        at org.testcontainers.containers.BrowserWebDriverContainer$getWebDriver$0.call(Unknown Source)
        at app//org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at app//org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
        at app//org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
        at app//io.jmix.tests.extension.BrowserExtension.startBrowser(BrowserExtension.groovy:45)
        at app//io.jmix.tests.extension.BrowserExtension.beforeAll(BrowserExtension.groovy:23)
        at app//org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$10(ClassBasedTestDescriptor.java:381)
        at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at app//org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:381)
        at app//org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:205)
        at app//org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:80)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:148)
        at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
        at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
        at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
        at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1541)
        at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
        at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
        at app//org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
        at app//org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
        at app//org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
        at app//org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
        at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at app//org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
        at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
        at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
        at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at [email protected]/java.lang.reflect.Method.invoke(Method.java:566)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
        at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
        at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
        at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
        at com.sun.proxy.$Proxy2.stop(Unknown Source)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
        at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
        at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
        at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
        at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
        at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
        at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
        Suppressed: java.lang.NullPointerException: Cannot invoke method stop() on null object
          at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:91)
          at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:44)
          at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
          at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:34)
          at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
          at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
          at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:130)
          at io.jmix.tests.ui.extension.PostgreSQLExtension.afterAll(PostgreSQLExtension.groovy:25)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$16(ClassBasedTestDescriptor.java:447)
          at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$17(ClassBasedTestDescriptor.java:447)
          at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllCallbacks(ClassBasedTestDescriptor.java:447)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:229)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:80)
          at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:161)
          at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
          at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:161)
          ... 47 more
        Suppressed: java.lang.IllegalStateException: No webdriver is bound to current thread: 1. You need to call open(url) first.
          at com.codeborne.selenide.impl.WebDriverThreadLocalContainer.getWebDriver(WebDriverThreadLocalContainer.java:138)
          at com.codeborne.selenide.WebDriverRunner.getWebDriver(WebDriverRunner.java:112)
          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.base/java.lang.reflect.Method.invoke(Method.java:566)
          at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:107)
          at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
          at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:1956)
          at groovy.lang.MetaClassImpl.getProperty(MetaClassImpl.java:3843)
          at org.codehaus.groovy.runtime.callsite.ClassMetaClassGetPropertySite.getProperty(ClassMetaClassGetPropertySite.java:50)
          at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:329)
          at io.jmix.tests.extension.BrowserExtension.stopBrowser(BrowserExtension.groovy:53)
          at io.jmix.tests.extension.BrowserExtension.afterAll(BrowserExtension.groovy:38)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$16(ClassBasedTestDescriptor.java:447)
          at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$17(ClassBasedTestDescriptor.java:447)
          at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllCallbacks(ClassBasedTestDescriptor.java:447)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:229)
          at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:80)
          at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:161)
          at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
          at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:161)
          ... 47 more
      Caused by: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
        at app//org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:70)
        at app//org.rnorth.ducttape.timeouts.Timeouts.getWithTimeout(Timeouts.java:43)
        at app//org.testcontainers.containers.BrowserWebDriverContainer.lambda$getWebDriver$1(BrowserWebDriverContainer.java:293)
        at app//org.rnorth.ducttape.unreliables.Unreliables.lambda$retryUntilSuccess$0(Unreliables.java:43)
        at [email protected]/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at [email protected]/java.lang.Thread.run(Thread.java:829)
      Caused by: java.util.concurrent.TimeoutException
        at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:204)
        at org.rnorth.ducttape.timeouts.Timeouts.callFuture(Timeouts.java:65)
        ... 7 more

For this problem there is an issue in testcontainers: testcontainers/testcontainers-java#5833
And issue in Selenium: SeleniumHQ/selenium#10984

In Selenium fix presents since 4.5.1.
The latest Selenide version is 6.9.0 does not include this fix. Need to update when patch version will be released.

For now there are workarounds from above tickets:
1)

browser = new BrowserWebDriverContainer()
        .withCapabilities(capabilities)
        .withEnv("SE_OPTS", "--session-retry-interval 1") as BrowserWebDriverContainer
  1. See awaitility library.
private static FirefoxOptions firefoxOptions = new FirefoxOptions();

@Container
BrowserWebDriverContainer<?> firefox = new BrowserWebDriverContainer<>()
        .withNetwork(network)
        .withCapabilities(firefoxOptions);

@BeforeEach
void beforeEach() {
    RemoteWebDriver remoteWebDriver = await().atMost(20, TimeUnit.SECONDS).until(() -> {
        return new RemoteWebDriver(firefox.getSeleniumAddress(), firefoxOptions);
    }, Objects::nonNull);
    ...
}

Waiting new version of Selenide with fixes.
Waiting test containers 1.17.7 release.

Cover Table in sampler project by autotests

1.Simple table
-check 'multiselect' option
-check 'sortable' option
-check 'columnControlVisible' option
-check 'reorderingAllowed' option
-check 'showSelection' option
2.Table with max text lenght
-check field with value <= maxTextLength+10
-check field with value > maxTextLength+10
3.Table actions
-check availability of buttons with actions in button panel
-check availability of buttons with actions in context menu
-check availability of buttons with actions using shortcuts
4.Editable table
-check ability to edit value of textField, checkbox, dropdown list
5.Table with formatter
-check formatting of column toUpperCase()
-check formatting of column toLowerCase()
6.Table with icon provider
-check icon depending on entity status value
7.Table with style provier
-check field coloring depending on value
8.ItemClick and EnterPress action
-check setItemClickAction (double click on entity)
-check setEnterPressAction (Enter click on selected entity)
9.Table with generated columns
-check addGeneratedColumn with lookupField
10.Table with aggregation
-check aggregation with type = 'sum'
-check custom AggregationStrategy (most frequet grade)
11.Table without header
-check absence of header i table with columnHeaderVisible="false"
12.Table with key-value container
-TODO
13.GroupTable
-check grouping by default column
-check grouping by several columns
14.GroupTable with style provider
-check coloring of row depemding of field value
15.GroupTable with AggregationDistributionProvider
-check AggregationDistributionProvider(change aggregated recalculates rows value)
16.TreeTable
-TODO

Move the cursor to the lower right corner

Sometimes a random click on a menu item in the lower left corner of the screen is triggered, so after opening the screen, you need to move the cursor to the lower right corner.

Caused by: NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"[j-test-id='edit']"}
Element not found {By.jTestId: edit}
Expected: not enabled

image

Caused by: NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":".v-window-modal"}
Element not found {.v-window-modal}
Expected: visible

image

Failed tests:

  1. io.jmix.tests.sampler.datagrid.DataGridBasicSettingsUiTest#checkDataGridSortableOptionIsOff(Checks sortable option is off for dataGrid)
  2. io.jmix.tests.sampler.datagrid.DataGridAggregatableUiTest.checkDataGridCustomAggregation(Check custom aggregation for dataGrid)
  3. io.jmix.tests.sampler.datagrid.DataGridActionsUiTest.checkDataGridCreateActionInContextMenu(Check DataGrid create action in context menu)
  4. io.jmix.tests.sampler.datagrid.DataGridEditorUiTest.checkDataGridCInlineEditorWhileEditorBufferedOff(Check dataGrid inline editor while editorBuffered is off)
  5. io.jmix.tests.sampler.datagrid.DataGridActionsUiTest.checkDataGridEditActionInContextMenu(Check DataGrid edit action in context menu)
  6. io.jmix.tests.sampler.datagrid.DataGridActionsUiTest.checkDataGridCustomActionOnButtonPanel(Check dataGrid custom action on button panel)
  7. io.jmix.tests.sampler.datagrid.DataGridBasicSettingsUiTest.checkDataGridColumnsCollapsingAllowedOptionIsOff(Checks columnsCollapsingAllowed option is off for dataGrid)
  8. io.jmix.tests.sampler.datagrid.DataGridEditorActionsUiTest.checkDataGridOverriddenCreateAction(Check dataGrid overridden create action)
  9. io.jmix.tests.sampler.datagrid.DataGridActionsUiTest.checkDataGridRemoveActionInContextMenu(Check DataGrid remove action in context menu)

Cover Button in sampler project by autotests

1.Simple button
2.Localized button
3.Button with action
4.Button with programmatically created button
5.LinkButton
6.Simple PopupButton
7.PopupButton with custom popup layout

Cover DataGrid in sampler project by autotests

  1. DataGrid basic settings
    -check sortable is on/off
    -check reordering is on/off - TODO (jmix-framework/jmix-masquerade#7)
    -check columnsCollapsingAllowed is on/off
  2. DataGrid actions
    -check custom action by button panel/context menu
    -check create action by button panel/context menu
    -check edit action by button panel/context menu
    -check remove action by button panel/context menu
    -check create/edit/remove action using shortcut -TODO (jmix-framework/jmix-masquerade#4)
  3. DataGrid selection mode
    -check datagrid with single/multi/multiCheck/none mode
  4. DataGrid frozen columns
    -check non-frozen/frozen/last-frozen column
  5. DataGrid withot header
  6. DataGrid with style providers
  7. DataGrid with large dataset
  8. ItemClick and EnterPress actions
  9. DataGrid with generated columns
  10. DataGrid with formatter
  11. DataGrid with renderer
    check ImageRenderer/ClickableTextRenderer/NumberRenderer
  12. DataGrid with description providers
  13. Heared and footer
    check header/footer
  14. DataGrid with key-value container - TODO
  15. DataGrid inline editor
    check for editorBuffered is on/off
  16. DataGrid with overriden actions
  17. DataGrid editor events
  18. DataGrid with DetailsGenerator
  19. DataGrid with aggregation
  20. TreeDataGrid - todo

CustomMessageMissingMethodException occurs on the start of project

org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: 
    Could not find method testRuntime() for arguments [org.junit.jupiter:junit-jupiter-engine:5.7.1] on object of type 
    org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

Cover TextField in sampler project by autotests

  1. Simple textField
    -check input value for field without maxLength
    -check input value for field with maxLength
  2. Data-aware textField
    -check predefined value in field
    -change value of field
  3. TextField with datatype
    -input correct/incorrect type of value to fields
  4. TextField with validator
    -input correct/incorrect value to field with positive validator
    -input correct/incorrect value to field with border value validator
  5. TextField with trim attribute
    -check value with spase in the end while trim is on/off
    -check string containing spaces only while trim is on/off
  6. TextField with EnterPress listener
    -set value and press enter
  7. TextField with TextChange listener
    -check changing value of field
  8. TextField with TextChange EventMode
    -check TextChangeEventMode with EAGER value
    -check TextChangeEventMode with LAZY value
    -check TextChangeEventMode with BLUR value
    -check TextChangeEventMode with TIMEOUT value
  9. MaskedField
    -check output for valueMode=masked
    -check output for valueMode=clear
  10. PaswordField
    -check ability to hide password and view value using passwordField.getValue()

works correctly with https://github.com/Haulmont/jmix-sampler/tree/maistrenko

Fix createReportForOneEntityWithoutWizard, createReportParameterEntityAndEntitiesList and EntityLogSetupTest tests

fix failed tests:

io.jmix.tests.ui.test.reports.reportactions.CreateReportUiTest.createReportForOneEntityWithoutWizard(Creates a report for one entity without using wizard)
io.jmix.tests.ui.test.reports.editreport.ReportParameterActionUiTest.createReportParameterEntityAndEntitiesList(Creates report parameter with Entity and Entities List types)
io.jmix.tests.ui.test.audit.EntityLogSetupTest.initializationError

https://teamcity-cuba.haulmont.com/buildConfiguration/PlatformNew_Jmix_Continuous_JmixUiTests/3835678?hideProblemsFromDependencies=false&hideTestsFromDependencies=false&expandBuildTestsSection=true&expandBuildProblemsSection=true

Improve Reports UI tests

Actual situation:
many tests are using the simple report created and removed each time

Classes:

  • ReportHistoryButtonUITest
  • ReportBrowserUITest
  • ReportGroupActionUITest

It is a huge waste of time execution

Solution:
import existing report with a unique name instead of creating a new one each time

UPD:
one more scenario is automated
creating a report without wisard

Fix dynamic attributes tests that uses DynamicAttributesPanel component

Description

Failed due to the following changes: jmix-projects/jmix-ui#677

Tests:

  • CategorizedEntityTest.checkCategoryDisplay(Checks category display for categorized entity)
  • LocalizationDynamicAttributesTest.checkCategoryLocalization(Checks category localization)
Caused by: NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"[j-test-id='categoryField']"}

Fix Security test cases after review

List of changes:

  • add to any test filling of Description field
  • add role saving to tests:
  • add Specific policy to Resource role
  • delete tests:
  • simple creating resource role
  • deleting resource role
  • simple creating row level role
  • deleting row level role
  • simple creating entity policy for resource role
  • deleting entity policy for resource role
  • simple creating JPQL policy for row level role
  • deleting JPQL policy for row level role
  • change test's descriptions:
  • edit resource role
  • edit entity policy for resource role
  • edit row level role
  • edit JPQL policy for row level role

PSQLException: ERROR: column "id" does not exist

Run UserUiTest

2021-05-04 04:02:46.114  WARN 31752 --- [o-auto-1-exec-3] eclipselink.logging.all                  : Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.7.7.2-jmix): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.postgresql.util.PSQLException: ERROR: column "id" does not exist
Position: 8
Error Code: 0
Call: SELECT ID, EMAIL, ENABLED, FIRST_NAME, LAST_NAME, PASSWORD, USERNAME, VERSION FROM USER WHERE (USERNAME = ?)
  bind => [username]
Query: ReadAllQuery(referenceClass=User sql="SELECT ID, EMAIL, ENABLED, FIRST_NAME, LAST_NAME, PASSWORD, USERNAME, VERSION FROM USER WHERE (USERNAME = ?)")
FetchGroup(){firstName, lastName, password, id, version, email, enabled, username}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.