8 Mobile App Testing - essenius/FitNesseFitSharpSelenium GitHub Wiki
The Selenium Fixture also allows you to leverage Appium to do mobile testing. This works because Appium talks the Webdriver protocol. We use Appium Desktop, which is still widely used. We also use a fairly old Android emulator that still requires the old automator called UiAutomator1 (which Appium 2 no longer supports).
We will need to configure Appium the right way to do that. Appium uses a Capabilities map to do that. We're building up this map via the Map fixture. First we create one using a Script table to get a reference to it in a symbol. Then we re-use the fixture (via the symbol) in a Decision table to set the values, and then we use the script table again to read the content. For more information on the values of this map see the Appium Desired Capabilities page.
To make the elements we need to interact with easier to recognize in test workflows, we define them as symbols or variables. Then is the time to start an Appium session. This assumes that Appium is already up and running and is listening to the indicated port, and that you also have an (emulated) device up an running. Here we use an Xh-DPI 4.65" emulator with an x86 running KitKat 4.4 - API 19. We're also increasing the timeout to a minute since Appium interaction can be a bit slow sometimes.The rest should pretty much be self explanatory.
Here is an example:
!|scenario |Wait For Element|element|And Tap|
|wait for element|@element |
|tap element |@element |
Start as a script table so we can put the fixture in a symbol
!|script:map |
|$map=|get fixture|
Add entries to the map
!|decision:$map |
|key |value |
|deviceName |!-Xh-4.65 KitKat 4.4-! |
|automationName |!-UiAutomator1-! |
|appPackage |com.android.launcher |
|appActivity |com.android.launcher2.Launcher|
|newCommandTimeout|300 |
|clearSystemFiles |true |
|adbExecTimeout |30000 |
Put the result in a symbol
!|script |
|$capabilities=|content|
Define variables and symbols for elements so they are easier to recognize.
I prefer using symbols to make the source pages easier to read, but both can work.
Use variables if you want to concatenate text to a value (see e.g. Digit).
!define apps {AccessibilityId:Apps}
!define Calculator {com.android.calculator2:id}
!define Digit(id:${Calculator}/digit)
|script:Selenium |
|$okButton= |echo|!-ClassName:android.widget.Button-! |
|$browser= |echo|XPath://android.widget.TextView[@text = 'Browser'] |
|$calculator= |echo|xpath://*[@text='Calculator'] |
|$deleteArea= |echo|id:com.android.launcher:id/delete_target_text |
|$clearHistory=|echo|XPath://android.widget.TextView[@text = 'Clear history'] |
|$menu= |echo|id:${Calculator}/overflow_menu |
|$clear= |echo|id:${Calculator}/clear |
|$multiply= |echo|accessibilityId:multiply |
|$equals= |echo|accessibilityId:equals |
|$resultBox= |echo|xpath://android.widget.ViewSwitcher/android.widget.EditText|
Start Appium session. Use 127.0.0.1 rather than localhost as localhost is much slower
!define AppiumServer {!-http://127.0.0.1:4723-!}
!|script |
|set timeout |60 |seconds |
|set remote browser|Android|at address|${AppiumServer}|with capabilities|$capabilities|
Go to the Apps page and click away the guidance, and go to the home page
!|script |
|tap element |${apps} |
|wait for element and tap|$okButton|
|press keycode |Home |
|wait for element and tap|${apps} |
Start the calculator, clear the history, execute a simple calculation (7*8=) and check the answer
!|script |
|wait for element and tap|$calculator |
|tap element |$menu |
|wait for element and tap|$clearHistory |
|wait for element and tap|${Digit}7 |
|tap element |$multiply |
|tap element |${Digit}8 |
|check |text in element|$resultBox|7multiplied by8|
|tap element |$equals |
|wait for element |AccessibilityId:56 |
|check |text in element|$resultBox|56 |
Long pressing Home should take you to recent apps, which should now contain Calculator.
!|script |
|press keycode |Home |
|wait for element |$browser |
|long press key code|home |
|wait for text |Calculator|ignoring case|
Go backto the Apps page
!|script |
|press keycode|home|
This is how things should look when the test runs:
Here is an example with a somewhat newer emulated device: a Pixel 2, x86, running Pie 9.0 - API 28. It's dong the same thing: opening the calculator, executing a calculation, going back home, and checking whether calculator is in the recent apps list. Of course Pie behaves a bit differently than KitKat so we need to adapt to that in the test logic.
!|scenario |Wait For Element|element|And Tap|
|wait for element|@element |
|tap element |@element |
!|script:map |
|$map=|get fixture|
!|decision:$map |
|key |value |
|deviceName |Pie |
|automationName |UiAutomator2|
|newCommandTimeout|300 |
|clearSystemFiles |true |
|adbExecTimeout |30000 |
!|script |
|$capabilities=|content|
Define variables and symbols for elements so they are easier to recognize.
!define apps {AccessibilityId:Apps}
!define Calculator {com.android.calculator2:id}
!define Digit {id:${Calculator}/digit_}
For calculator we take a wildcard since in the apps it's android.widget.TextView and in recent apps it's android.widget.FrameLayout
|script:Selenium |
|$appslist= |echo|accessibilityId:Apps list |
|$calculator=|echo|xpath://*[@content-desc = 'Calculator']|
|$browser= |echo|accessibilityId:Chrome |
|$multiply= |echo|accessibilityId:multiply |
|$equals= |echo|accessibilityId:equals |
|$formula= |echo|id:${Calculator}/formula |
|$result= |echo|id:${Calculator}/result |
Start Appium session.
!define AppiumServer {!-http://127.0.0.1:4723-!}
!|script |
|set timeout |60 |seconds |
|set remote browser|Android|at address|${AppiumServer}|with capabilities|$capabilities|
Go home, and then scroll down to the Apps page (which is the same as swiping up).
!|script |
|press keycode|home |
|element |$browser|exists|
|scroll |down |
Start the calculator, clear the history, execute a simple calculation (7*8=) and check the answer
Note that × is not the same as x.
!|script |
|wait for element and tap|$calculator |
|wait for element and tap|${Digit}7 |
|tap element |$multiply |
|tap element |${Digit}8 |
|check |text in element|$formula |7×8 |
|check |text in element|$result |56 |
|tap element |$equals |
|Wait Until Element |$formula |Does Not Exist|
|check |text in element|$result |56 |
Pressing Overview (APP_SWITCH) should take you to recent apps, which should now contain Calculator.
!|script |
|press keycode |Home |
|wait for element|$browser |
|press keycode |KEYCODE_APP_SWITCH|
|wait for element|$calculator |
Go back home
!|script |
|press keycode|home|