{"id":15877,"date":"2022-08-29T07:00:00","date_gmt":"2022-08-29T05:00:00","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=15877"},"modified":"2023-05-10T15:47:04","modified_gmt":"2023-05-10T13:47:04","slug":"using-kotlin-language-functionalities-to-enrich-the-ui-tests-written-in-java","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/en\/using-kotlin-language-functionalities-to-enrich-the-ui-tests-written-in-java\/","title":{"rendered":"Using Kotlin language functionalities to enrich the UI tests written in Java"},"content":{"rendered":"\n<p>We \u2013 the Java people \u2013 are doomed to the object-oriented paradigm. Don\u2019t take it as a bad feature of the language, though. As the 3 Billion Devices Run Java installer shows (invariably since the beginning of this century), Java has entered into the programming canon and it\u2019s very difficult to find a person in IT who hasn\u2019t heard of this language.<\/p>\n\n\n\n<p>It\u2019s been over 25 years since the first release of Java, and although it\u2019s still evolving, we can\u2019t change one truth about it \u2013 Java wasn\u2019t created with functional programming in mind. However, this statement has become less bitter after the Java 8 update, which introduced <a href=\"https:\/\/sii.pl\/blog\/wyrazenie-lambda-w-javie\/?category=development-na-twardo&amp;tag=java,software-development,wyrazenie-lambda\" target=\"_blank\" rel=\"noreferrer noopener\">lambda expressions<\/a> and streams into our code.&nbsp;<\/p>\n\n\n\n<p>Nowadays, the JVM universe isn\u2019t limited to Java only. Many noteworthy programming languages have been created. Some of them are more focused on functional programming, which perfectly complements Java.&nbsp;&nbsp;<\/p>\n\n\n\n<p>In this article, I\u2019d like to familiarize you with selected functionalities of the Kotlin language that will <strong>enrich and facilitate writing automatic UI tests, based on the example of web testing<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Kotlin \u2013 first steps<\/strong><\/h2>\n\n\n\n<p>An introduction to Kotlin has already been described in the article by <a href=\"https:\/\/sii.pl\/blog\/java-2-0-czyli-kotlin\/\" target=\"_blank\" rel=\"noreferrer noopener\">Rafa\u0142 Ha\u0142asa<\/a>. Also, the Jetbrains company prepared a very interesting <a href=\"https:\/\/play.kotlinlang.org\/byExample\/overview\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >introduction to the language<\/a>. Those who are not familiar with Kotlin yet are welcome to have a closer look at both the article and the tutorial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Using Kotlin in a project&nbsp;<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>IntelliJ environment&nbsp;<\/strong><\/h3>\n\n\n\n<p>In the case of IntelliJ, most of the work with adding support to Kotlin will be done for us by IDE. The user has to add the Kotlin plugin in IDE and create a new Kotlin file (.kt) in the project structure. Then, IntelliJ will automatically detect the usage of Kotlin and ask if we want to configure the project. The essential changes in dependency (adding kotlin-stdlib) and plugin will be made automatically.&nbsp;&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Another environment&nbsp;<\/strong><\/h3>\n\n\n\n<p>If you use an IDE other than IntelliJ, check a guidebook to implementing Kotlin in <a href=\"https:\/\/kotlinlang.org\/docs\/gradle.html\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >Gradle<\/a> and <a href=\"https:\/\/kotlinlang.org\/docs\/maven.html\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >Maven<\/a> projects.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Fun facts&nbsp;<\/strong><\/h2>\n\n\n\n<p>The Kotlin language was created to be fully cooperative with Java. When searching for a solution for a problem with a code, we can search for sources both in Java and Kotlin languages. If we copy the Java code and paste it into the .kt file, IntelliJ will ask us whether we want to translate the pasted code to Kotlin:&nbsp;<\/p>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/java-to-kotlin.mp4\"><\/video><figcaption><em><em>Sample translation of Java into Kotlin<\/em><\/em><\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Why does it work?&nbsp;<\/strong><\/h3>\n\n\n\n<p>Both Java and Kotlin compile to Java bytecode. The code snippet written in Kotlin may serve as an example:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nfun main() {\n        val numbers = listOf(1, 2, 3, 4, 5).map { it * it }\n    }\n<\/pre><\/div>\n\n\n<p>IntelliJ enables previewing the bytecode which generates this snippet. The option is located under the path:<br><strong>Tools<\/strong>&nbsp;\u2192&nbsp;<strong>Kotlin<\/strong>&nbsp;\u2192&nbsp;<strong>Show Kotlin Bytecode<\/strong><\/p>\n\n\n\n<p>A part of the bytecode is presented below&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic final  static  main()V\n\nL0\n\nLINENUMBER 5 L0\n\nICONST_5\n\nANEWARRAY java\/lang\/Integer\n\nDUP\n\nICONST_0\n\nICONST_1\n\nINVOKESTATIC java\/lang\/Integer.valueOf (I)Ljava\/lang\/Integer;\n\n\u2026\n<\/pre><\/div>\n\n\n<p>We can now decompile this bytecode back into Java. The result is not satisfying, though. The computer has translated the instructions into Java, but the style of the code leaves much to be desired:&nbsp;&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic static  final  void  main() {\n\nIterable $this$map$iv = (Iterable)CollectionsKt.listOf(new  Integer&#x5B;]{1, 2, 3, 4, 5});\n\nint $i$f$map = false;\n\nCollection destination$iv$iv = (Collection)(new  ArrayList(CollectionsKt.collectionSizeOrDefault($this$map$iv, 10)));\n\nint $i$f$mapTo = false;\n\nIterator var6 = $this$map$iv.iterator();\n\nwhile(var6.hasNext()) {\n\nObject item$iv$iv = var6.next();\n\nint  it = ((Number)item$iv$iv).intValue();\n\nint var9 = false;\n\nInteger var11 = it * it;\n\ndestination$iv$iv.add(var11);\n\n}\n\nList numbers = (List)destination$iv$iv;\n\n}\n<\/pre><\/div>\n\n\n<p>Nevertheless, it is equivalent (from the JVM point of view) with the code written in Kotlin.&nbsp;<\/p>\n\n\n\n<p>The IntelliJ environment has a fine-tuned Java \u2192 Kotlin code swap, and a code created in this way is structurally acceptable in most cases. Java classes can be easily used in Kotlin code. This relation works both ways, which means Kotlin code can also be implemented in Java.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Let\u2019s take a sample class written in Kotlin:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nclass Person(private val name: String, private val age: Int) {\n    fun greet() = println(&quot;My name is $name and I am $age ${if (age &gt; 1) &quot;years&quot; else &quot;year&quot;} old.&quot;)\n}\n<\/pre><\/div>\n\n\n<p>We can now use it in the .java file:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class Foo {\n    public static void main(String&#x5B;] args) {\n        new Person(&quot;Tom&quot;, 24).greet();\n    }\n}\n<\/pre><\/div>\n\n\n<p>Output:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nMy name is Tom and I am 24 years old.\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Kotlin language functionalities in practice&nbsp;<\/h2>\n\n\n\n<p>Let\u2019s move on to the main body of the article. In it, I will present two approaches of the Kotlin language that will make writing and maintaining the code easier.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Delegate by Locator<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em><em>Wait until the fridge is visible and open it. Wait until you see the eggs and take them out.<\/em><\/em><\/p><\/blockquote>\n\n\n\n<p>When giving the instructions to be carried out, we often skip the obvious details we are certain that everyone will assume before performing the assigned task. A simple example can be clicking the elements on the screen. We simply expect them to be visible before we click on them.&nbsp;<\/p>\n\n\n\n<p>By using the <a href=\"https:\/\/kotlinlang.org\/docs\/delegated-properties.html\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >\u2018by\u2019 delegators<\/a> and the <a href=\"https:\/\/kotlinlang.org\/docs\/lambdas.html\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >higher-order functions<\/a>, we can build a nice mechanism for searching web elements and deciding when they should be interactive:&nbsp;&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nprivate val usernameField by Id(&quot;username&quot;)\nprivate val passwordField by Id(&quot;password&quot;)\nprivate val loginButton by Xpath(&quot;.\/\/button&#x5B;@type=&#039;submit&#039;]&quot;) {\n    \/\/poczekaj a\u017c pola username i password zostan\u0105 wype\u0142nione\n    it.isDisplayed &amp;&amp; usernameField.getAttribute(&quot;value&quot;).isNotEmpty() &amp;&amp; passwordField.getAttribute(&quot;value&quot;).isNotEmpty()\n}\n(\u2026)\n\nfun pressLoginButton() = loginButton.click()\n<\/pre><\/div>\n\n\n<p>Such an approach allows hiding the expectation of web elements availability and focusing exclusively on the logic of the test scenario.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>What it looks like from the inside<\/strong><em>&nbsp;<\/em><\/h4>\n\n\n\n<p><strong><strong>Preliminary assumptions<\/strong>&nbsp;<\/strong><\/p>\n\n\n\n<p>The project uses the <a href=\"https:\/\/www.selenium.dev\/documentation\/\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >Selenium<\/a> library. There is a reference to WebDriver in the project, which operates UI tests. We create a <a href=\"https:\/\/www.selenium.dev\/selenium\/docs\/api\/java\/org\/openqa\/selenium\/support\/ui\/FluentWait.html\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >FluentWait<\/a> object that we will use to wait for web elements.&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nval wait: FluentWait&lt;WebDriver&gt; = FluentWait(driver)\n    .withTimeout(Duration.ofSeconds(System.getProperty(&quot;wait.timeout&quot;)?.toLong() ?: 10L))\n    .pollingEvery(Duration.ofMillis(200))\n    .ignoring(NoSuchElementException::class.java)\n<\/pre><\/div>\n\n\n<div class=\"wp-block-group is-layout-flow wp-block-group-is-layout-flow\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-1 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:10%\">\n<figure class=\"wp-block-image size-full is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png\" alt=\"\" class=\"wp-image-15469\" width=\"59\" height=\"59\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png 512w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-300x300.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-150x150.png 150w\" sizes=\"(max-width: 59px) 100vw, 59px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:80%\">\n<p><\/p>\n\n\n\n<p><br>The wait object doesn\u2019t have to be a field of any class. Defining it outside the body of classes means global access to this object.<\/p>\n<\/div>\n<\/div>\n\n\n\n<p>We create an abstract <em>Locator<\/em> class, which expands the <a href=\"https:\/\/kotlinlang.org\/api\/latest\/jvm\/stdlib\/kotlin.properties\/-read-only-property\/\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >ReadOnlyProperty<\/a> class. The Locator class will contain all the logic concerning operating on web elements.&nbsp;<\/p>\n\n\n\n<p><strong><strong>Description of class parameters:<\/strong>&nbsp;<\/strong><\/p>\n\n\n\n<p>locator \u2013 the selected mechanism for finding elements (e.g., Id, Xpath, CssSelector, etc.)&nbsp;&nbsp;<\/p>\n\n\n\n<p>path \u2013 the value of the path that points to the searched web element&nbsp;<\/p>\n\n\n\n<p>accessRule \u2013 a function that takes a web element as a parameter and returns boolean (a condition for interaction with the web element).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nabstract class Locator(\n    private val locator: (String) -&gt; By,\n    private val path: String,\n    private val accessRule: (WebElement) -&gt; Boolean\n) : ReadOnlyProperty&lt;Any?, WebElement&gt; {\n    private val element: WebElement by lazy {\n        wait.until { driver.findElement(locator(path)) }\n    }\n \n    override fun getValue(thisRef: Any?, property: KProperty&lt;*&gt;): WebElement {\n        wait.until { accessRule(webElement) }\n        return webElement\n    }\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-columns is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-2 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:10%\">\n<figure class=\"wp-block-image size-full is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png\" alt=\"\" class=\"wp-image-15469\" width=\"59\" height=\"59\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png 512w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-300x300.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-150x150.png 150w\" sizes=\"(max-width: 59px) 100vw, 59px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:80%\">\n<p><\/p>\n\n\n\n<p><br>The <strong>By lazy<\/strong> delegator means lazy evaluation. The element field will not be calculated until it is first used.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-3 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:10%\">\n<figure class=\"wp-block-image size-full is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png\" alt=\"\" class=\"wp-image-15469\" width=\"59\" height=\"59\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png 512w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-300x300.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-150x150.png 150w\" sizes=\"(max-width: 59px) 100vw, 59px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:80%\">\n<p><\/p>\n\n\n\n<p><br>We can freely extend the getValue method with further instructions on accessing the web element. However, there are some cases when we don\u2019t want to wait until the object is visible. Such objects can be marked with any annotation (e.g., @Hidden). We will get access to the delegated object through the property argument.&nbsp;&nbsp;<\/p>\n<\/div>\n<\/div>\n\n\n\n<p>All that\u2019s left is creating the classes we need to extend Locator, according to our needs:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nclass Xpath(\n    path: String,\n    \/\/ poczekaj a\u017c b\u0119dzie widoczny\n    accessRule: (WebElement) -&gt; Boolean = { it.isDisplayed }\n) : Locator(By::xpath, path, accessRule)\n\nclass Id(\n    id: String,\n    \/\/zwracaj zawsze\n    accessRule: (WebElement) -&gt; Boolean = { true }\n) : Locator(By::id, id, accessRule)\n<\/pre><\/div>\n\n\n<p>And using them as in the example above.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Integration with Java<\/strong>&nbsp;<\/h3>\n\n\n\n<p>As I\u2019ve already mentioned, we can use Kotlin code in a Java class. However, the Java language doesn\u2019t have the function of expressing \u2018by\u2019 delegators. An idea for integration is defining web elements in the .kt class and expanding the .java class with it:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nclass MyScreenPageObject extends MyScreenKotlinPageObject {\n(\u2026)\n    public void clickLoginButton() {\n        getLoginButton().click();\n    }\n}\n<\/pre><\/div>\n\n\n<p>Getters for the fields defined by delegators were automatically generated for operating in Java, but all logic for accessing and evaluating elements remained intact.&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-columns is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-4 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:10%\">\n<figure class=\"wp-block-image size-full is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png\" alt=\"\" class=\"wp-image-15469\" width=\"59\" height=\"59\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png 512w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-300x300.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-150x150.png 150w\" sizes=\"(max-width: 59px) 100vw, 59px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:80%\">\n<p><\/p>\n\n\n\n<p><br>Bear in mind that in this case the access modifier in the .kt class may not be set to private.<\/p>\n<\/div>\n<\/div>\n\n\n\n<div class=\"wp-block-columns is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-5 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:10%\">\n<figure class=\"wp-block-image size-full is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png\" alt=\"\" class=\"wp-image-15469\" width=\"59\" height=\"59\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png 512w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-300x300.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-150x150.png 150w\" sizes=\"(max-width: 59px) 100vw, 59px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:80%\">\n<p><\/p>\n\n\n\n<p><br>All Kotlin classes (except for the abstract ones) are \u2018final\u2019 by default, meaning that one cannot inherit from them. In this case, it is required to mark the .kt class with the word <em>open<\/em> (the inverse of the meaning of \u2018final\u2019).&nbsp;<\/p>\n<\/div>\n<\/div>\n\n\n\n<p>For comparison, this is the same code \u2013 Vanilla Java + Selenium (simplified):&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nclass MyScreen {\n(\u2026)\n    public void clickLoginButton() {\n        WebElement usernameField = getWait().until(ExpectedConditions.visibilityOfElementLocated(By.id(&quot;username&quot;)));\n        WebElement passwordField = getWait().until(ExpectedConditions.visibilityOfElementLocated(By.id(&quot;password&quot;)));\n        getWait().until(driver -&gt; !usernameField.getAttribute(&quot;value&quot;).isEmpty()\n                &amp;&amp;\n                !passwordField.getAttribute(&quot;value&quot;).isEmpty());\n        getWait().until(ExpectedConditions.visibilityOfElementLocated(By.xpath(&quot;.\/\/button&#x5B;@type=&#039;submit&#039;]&quot;))).click();\n    }\n}\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">Robot pattern<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em>On the login page, enter your username.<\/em><\/p><p><em>On the login page, enter your password.<\/em><\/p><p><em>On the login page, click the Login button.<\/em><\/p><\/blockquote>\n\n\n\n<p>When performing steps within one web app page, we know the context. Referring to the object each time to call a method can be onerous, especially when there are a dozen steps.&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nloginPage.fillCredentialsForUser(&quot;blogersii001);\nloginPage.pressLoginButton();\nloginPage.verifyUserIsSuccessfullyLoggedIn();\n<\/pre><\/div>\n\n\n<p>An idea for improvement idea is to use high-order functions again and create a pleasant mechanism for creating scopes where the context is already known.&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Test\nfun `user can access website and log in`() {\n    mainPage {\n        verifyHeaderTitleIsEqualTo(&quot;&lt;bloger_sii\/&gt;&quot;)\n        clickOnSignInButton()\n    }\n \n    loginPage {\n        fillCredentialsForUser(&quot;blogersii001&quot;)\n        pressLoginButton()\n        verifyUserIsSuccessfullyLoggedIn()\n    }\n}\n<\/pre><\/div>\n\n\n<div class=\"wp-block-columns is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-6 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:10%\">\n<figure class=\"wp-block-image size-full is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png\" alt=\"\" class=\"wp-image-15469\" width=\"59\" height=\"59\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png 512w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-300x300.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-150x150.png 150w\" sizes=\"(max-width: 59px) 100vw, 59px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:85%\">\n<p><\/p>\n\n\n\n<p><br>Functions in Kotlin can be named by standard camelCase or by any other string of characters marked between the \u2018 \u2019 (back quote) characters.&nbsp;<\/p>\n<\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>What it looks like from the inside<\/strong>&nbsp;<\/h3>\n\n\n\n<p>Above I showed that the test stages are divided into scopes, called \u2018robots.\u2019 Each robot has a reference to the PageObject object for which a set of functions is executed. The only available functions in each robot are those that are defined in the <a href=\"https:\/\/www.selenium.dev\/documentation\/test_practices\/encouraged\/page_object_models\/\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >PageObject<\/a> class that the robot was created for.&nbsp;&nbsp;<\/p>\n\n\n\n<p>The secret of this approach is a \u2018robot\u2019 function that takes the methods of one particular page (defined in PageObject) and executes them in the order they are given:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nfun loginPage(func: LoginPage.() -&gt; Unit) {\n    LoginPage().func()\n}\n<\/pre><\/div>\n\n\n<p>The argument of the loginPage function is a function that <strong>exists in the LoginPage class and returns a Unit value <\/strong>(equivalent to <em>void<\/em> in Java). The loginPage function creates a new object of the LoginPage class and applies all the methods given as arguments to it.&nbsp;<\/p>\n\n\n\n<p>Similarly, a robot for the MainPage class will be created from the example above.&nbsp;&nbsp;<\/p>\n\n\n\n<div class=\"wp-block-columns is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:10%\">\n<figure class=\"wp-block-image size-full is-resized is-style-default\"><img decoding=\"async\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png\" alt=\"\" class=\"wp-image-15469\" width=\"59\" height=\"59\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1.png 512w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-300x300.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/ikona-zarowki-1-150x150.png 150w\" sizes=\"(max-width: 59px) 100vw, 59px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-bottom is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:85%\">\n<p><\/p>\n\n\n\n<p><br>Robots can be accessed globally. Define them in a separate file (e.g., robots.kt) for project cleanliness.&nbsp;<\/p>\n<\/div>\n<\/div>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Integration with Java<\/strong>&nbsp;<\/h3>\n\n\n\n<p>Java doesn\u2019t support the robot mechanism as high-order functions. So what we can do in this situation is to create robot-functions for the already existing PageObject classes written in Java.&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class AddBlogPage {\n(...)\n\n    public void addBlogTitle(String blogTitle) {\n        (...)\n    }\n\n    public void submitBlogArticle() {\n        (...)\n    }\n}\n<\/pre><\/div>\n\n\n<p>We create a robot-function for the Java class:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\nfun addBlogPage(func: AddBlogPage.() -&gt; Unit) {\n    AddBlogPage().func()\n}\n<\/pre><\/div>\n\n\n<p>And use it in tests written in Kotlin:&nbsp;<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Test\nfun `Integrate Java class in Kotlin robot test`() {\n    addBlogPage {\n        addBlogTitle(&quot;Blogersii - Kotlin&quot;)\n        submitBlogArticle()\n    }\n}\n<\/pre><\/div>\n\n\n<p>One may ask:&nbsp;<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><em>Ok, but why to do that when we know \u2018Builder design pattern\u2019 and \u2018method chaining\u2019 that are available in regular Java?<\/em><\/p><\/blockquote>\n\n\n\n<p>Creating a robot-like structure is possible in Java, but may cause problems.&nbsp;<\/p>\n\n\n\n<p>To chain methods, they must return a reference to the object from which they are called. Each method we want to chain must have the returned type changed from <em>void <\/em>to its own class. In the case of Kotlin, code refactoring is not required. The improvement is added without changes to the body of the PageObject classes.&nbsp;<\/p>\n\n\n\n<p><strong><strong>An example of chaining methods \u2013 Vanilla Java:<\/strong>&nbsp;<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class AddBlogPage {\n\t(...)\n\n    public AddBlogPage addBlogTitle(String blogTitle) {\n        (...)\n        return this;\n    }\n\n    public AddBlogPage submitBlogArticle() {\n        (...)\n        return this;\n    }\n}\n<\/pre><\/div>\n\n\n<p><strong><strong>Usage in tests:<\/strong><\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Test\nvoid javaTest(){\n\tnew AddBlogPage()\n\t.addBlogTitle(&quot;Blogersii - Kotlin&quot;)\n\t.submitBlogArticle();\n}\n<\/pre><\/div>\n\n\n<p>The second approach, less known and applied to achieve a similar result in Java is initializing objects using double brace initialization. In this case, we don\u2019t have to change the return types in the AddBlogPage class, since the reference to the class inside the braces in executed through the \u2018<strong>this\u2019<\/strong> value.&nbsp;<\/p>\n\n\n\n<p><strong><strong>Usage in tests:&nbsp;<\/strong>&nbsp;<\/strong><\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Test\nvoid javaTest(){\n    new AddBlogPage(){{\n        addBlogTitle(&quot;Blogersii - Kotlin&quot;);\n        submitBlogArticle();\n    }};\n}\n<\/pre><\/div>\n\n\n<p>This approach <strong>carries risks<\/strong>. This way of initialization generates an additional anonymous class inside each time, which extends after the PageObject class. Although using this type of initialization in trace amounts will not hinder the work of the Garbage Collector, initializing objects repeatedly in this way may lead to memory leaks.&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Summary<\/strong>&nbsp;<\/h2>\n\n\n\n<p>Kotlin is still developing. Presenting all the fun facts and improvements it offers is surely far beyond the content of one article.&nbsp;<\/p>\n\n\n\n<p>I hope this article will strengthen the readers\u2019 interest in Kotlin, and the proposed solutions (perhaps after creative modifications) will be useful in your projects.&nbsp;<\/p>\n\n\n\n<p>The article is based on the UI-testing framework I am developing as my hobby.&nbsp;&nbsp;<\/p>\n\n\n\n<p>Source code and examples are located in the <a href=\"https:\/\/github.com\/Tomkowski\/Kotlinium-web\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >public repository<\/a>.&nbsp;<\/p>\n\n\n\n<p>Also, check <a href=\"http:\/\/play.kotlinlang.org\/\" target=\"_blank\" rel=\"noreferrer noopener\" rel=\"nofollow\" >play.kotlinlang.org<\/a> to try out Kotlin online without prior installation.&nbsp;<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;15877&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;5&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;5\\\/5 ( votes: 5)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Using Kotlin language functionalities to enrich the UI tests written in Java&quot;,&quot;width&quot;:&quot;139.5&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 139.5px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            5\/5 ( votes: 5)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>We \u2013 the Java people \u2013 are doomed to the object-oriented paradigm. Don\u2019t take it as a bad feature of &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/en\/using-kotlin-language-functionalities-to-enrich-the-ui-tests-written-in-java\/\">Continued<\/a><\/p>\n","protected":false},"author":401,"featured_media":19771,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":7,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1321],"tags":[1517,1441,1339],"class_list":["post-15877","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-testing","tag-ui-2","tag-java-en","tag-kotlin-en"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2022\/08\/Wykorzystanie-funkcjonalnosci-jezyka-Kotlin-do-urozmaicenia-testow-UI-pisanych-w-jezyku-Java.jpg","category_names":["Testing"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/15877"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/users\/401"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/comments?post=15877"}],"version-history":[{"count":3,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/15877\/revisions"}],"predecessor-version":[{"id":21582,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/posts\/15877\/revisions\/21582"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media\/19771"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/media?parent=15877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/categories?post=15877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/en\/wp-json\/wp\/v2\/tags?post=15877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}