Flutter-based application testing with custom SetText keyword in Katalon Studio
Flutter is a UI toolkit for building applications for mobile, web, desktop, and embedded devices from a single codebase.
You can use Mobile keywords to automate your Flutter-based application. However, Katalon Mobile Spy and Recorder currently cannot detect EditText elements in Flutter-based applications. This tutorial provides a workaround to automatically test the Flutter-based application using a custom SetText keyword package.
Katalon Studio partially supports Flutter-based applications. If elements of a Flutter-based app are rendered as in a native app, Katalon Mobile Recorder can capture elements. If those elements are rendered in web view, which is a use case of a hybrid Mobile app, Katalon Studio partially supports elements capturing.
Set up Appium Flutter Driver
To set up Katalon Studio for Flutter-based mobile app testing, you need to use Appium Flutter Driver.
Appium Flutter Driver is an open-source test automation tool for Flutter apps on multiple platforms/OS. Appium Flutter Driver is part of the Appium mobile test automation tool maintained by the community.
To install the latest version of the Appium Flutter Driver (2.8.0), refer to this README file in the Appium GitHub repository: Appium Flutter Driver.
To use Appium Flutter Driver with Katalon Studio, follow these requirements:
- Your Flutter App Under Test (AUT) must be compiled in
debug
orprofile
mode because Flutter Driver does not support running in release mode. - Your Flutter AUT has
enableFlutterDriverExtension()
beforerunApp
in source code.
In Katalon Studio, specify this desired capability to let Katalon Studio run with Appium Flutter Driver: Go to Project Settings > Desired Capabilities > Mobile. Select Android or iOS, then create a desired capabilities, which value is Flutter
.
Run Flutter-based application test with custom SetText keyword
-
In Katalon Studio, open your project and create a new test case. Record your mobile testing script. Use Tap keyword on elements EditText - Email and EditText - Password, then click Save.
-
In the Tests Explorer section on the left side of Katalon Studio, navigate to the Keywords folder and create a new keyword package. Name the package com.kms.katalon.core.mobile.keyword.builtin.
- Right click on the com.kms.katalon.core.mobile.keyword.builtin package and create a new keyword named SetTextKeyword. See also: Introduction to Custom Keywords.
In the SetTextKeyword.groovy file, copy and paste the following script and save it. SetTextKeyword.groovy script:package com.kms.katalon.core.mobile.keyword.builtin import java.text.MessageFormat import org.openqa.selenium.InvalidElementStateException import org.openqa.selenium.Keys import org.openqa.selenium.WebElement import org.openqa.selenium.interactions.KeyInput import org.openqa.selenium.interactions.Sequence; import com.kms.katalon.core.annotation.internal.Action import com.kms.katalon.core.configuration.RunConfiguration import com.kms.katalon.core.exception.StepFailedException import com.kms.katalon.core.helper.KeywordHelper import com.kms.katalon.core.keyword.internal.SupportLevel import com.kms.katalon.core.mobile.constants.StringConstants import com.kms.katalon.core.mobile.keyword.internal.MobileAbstractKeyword import com.kms.katalon.core.mobile.keyword.internal.MobileDriverFactory import com.kms.katalon.core.mobile.keyword.internal.MobileKeywordMain import com.kms.katalon.core.model.FailureHandling import com.kms.katalon.core.testobject.TestObject import com.kms.katalon.selenium.util.SeleniumKeysUtil; import groovy.transform.CompileStatic import io.appium.java_client.AppiumDriver @Action(value = "setText") public class SetTextKeyword extends MobileAbstractKeyword { @CompileStatic @Override public SupportLevel getSupportLevel(Object ...params) { return super.getSupportLevel(params) } @CompileStatic @Override public Object execute(Object ...params) { TestObject to = getTestObject(params[0]) String text = (String) params[1] int timeout = (int) params[2] FailureHandling flowControl = (FailureHandling)(params.length > 3 && params[3] instanceof FailureHandling ? params[3] : RunConfiguration.getDefaultFailureHandling()) setText(to,text,timeout,flowControl) } @CompileStatic public void setText(TestObject to, String text, int timeout, FailureHandling flowControl) throws StepFailedException { MobileKeywordMain.runKeyword({ KeywordHelper.checkTestObjectParameter(to) timeout = KeywordHelper.checkTimeout(timeout) WebElement element = findElement(to, timeout * 1000) if (element == null) { MobileKeywordMain.stepFailed(MessageFormat.format(StringConstants.KW_MSG_OBJ_NOT_FOUND, to.getObjectId()), flowControl, null, true) return } element.clear() try { element.sendKeys(text.toString()) } catch (InvalidElementStateException e) { AppiumDriver driver = MobileDriverFactory.getDriver() element.click() KeyInput keyboard = new KeyInput("keyboard"); Sequence sendKeys = new Sequence(keyboard, 0); for (int i = 0; i < text.length(); i++) { String c = text.charAt(i).toString() sendKeys.addAction(keyboard.createKeyDown(c.codePointAt(0))); } driver.perform(Arrays.asList(sendKeys)); } String readableText = SeleniumKeysUtil.getReadableText(text) logger.logPassed(MessageFormat.format(StringConstants.KW_LOG_PASSED_TEXT_HAS_BEEN_SET_TO_ELEMENT, [ readableText, to.getObjectId()] as Object[])) }, flowControl, true, to != null ? MessageFormat.format(StringConstants.KW_MSG_FAILED_TO_SET_ELEMENT_TEXT, to.getObjectId()) : StringConstants.KW_MSG_FAILED_TO_SET_ELEMENT_TEXT) } }
-
In the toolbar, select Window > Reset Perspective...
-
Create a Test Case and switch to Script mode. Enter Mobile.setText, then select
setText(TestObject to, String text, int timeout, FailureHandling flowcontrol)
. See also: [Mobile] Set Text.
-
Run your Test Case and see if it passes successfully.
How to switch contexts?
For the test engine to know whether you want to automate the native aspects of the app or the web views, Katalon Studio provides two keywords that help you switch contexts:
The following is a code sample that automates elements of the app:
Mobile.switchToWebView()
DriverFactory.changeWebDriver(MobileDriverFactory.getDriver())
TestObject cdmDetails = new TestObject()
cdmDetails.addProperty("id", ConditionType.EQUALS, "119")
WebUI.setText(cdmDetails, "123")
Mobile.switchToNative()