Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: appium webdriver setup #926

Merged
merged 29 commits into from
Feb 11, 2025
Merged

chore: appium webdriver setup #926

merged 29 commits into from
Feb 11, 2025

Conversation

cimigree
Copy link
Contributor

@cimigree cimigree commented Jan 29, 2025

closes #908

Description of Choices Made

Driver:

Because we decided to use Browserstack and Appium, that lead naturally to the use of UIAutomator. That is what Browserstack uses with Appium. BrowserStack abstracts the driver implementation, and they implement UiAutomator with Appium automatically. In addition, UIAutomator can theoretically be used with our web app. Espresso is available through Browserstack, but it is its own entity, not the standard Appium implementation. We may want to test system-level features like GPS and Wi-Fi, which Espresso doesn’t handle well. I decided to go with the most supported, most fleshed out driver available on Browserstack.

Client:

Basically the same thing. I chose to use Webdriver IO because it is well-documented and actively maintained.
Great for multi-platform testing (mobile, web, and Electron). It has built-in integrations for BrowserStack and easier configuration for parallel test runs. It also has a large plugin ecosystem.

Test Framework:

I chose Mocha, a widely-used, flexible, and lightweight JavaScript test framework. It allows you to use any assertion library (e.g., Chai, Assert). It supports hooks like before, after, beforeEach, afterEach. It has simple syntax: describe and it. caveat... I am not sold on Mocha. Jasmine might be better and I am open to reconsidering.

Test Reporter:

I chose spec reporter. It provides quick and easy viewing of test results during local development and debugging with simple, human-readable output. It's pretty basic, imo ideal for getting started and debugging minimal test suites.

Testing

I wrote a simple test to check the first two screens and that you can get from the first screen to the second. It was not easy to figure out how to select text to test. I got my testing language from Browserstack's guidelines. But the same guidelines are available via WebdriverIO. It would be much much easier to look for text if we used accessibilityLabels on the text... Something to consider for the future?

Configuration file

I am really including the almost minimum that one can include in the configuration file. A lot more can be done with that, like testing on multiple devices, increasing number of instances, etc. Here's how the file can be adjusted from the docs: https://webdriver.io/docs/configurationfile/

Workflow

I built this based on previous work by Erik and Gregor -- Erik for signing into Expo and building using EAS. Gregor for building an apk. That increase to JavaHeapSpace (because I ran into out of memory errors when building) and work with caching and freeing up disc space (this makes the building of the apk at least 50% faster) comes from him. I wanted the test to not only fail in Github if the E2E tests failed, but I wanted an easy way for the PR maker to see why, since we only get 2 logins to Browserstack with our free account. In order to get that to work, each time someone makes a push, there is a file included summarizing the test results (this is where spec reporter comes in handy.

How to test

Push a new commit or open a PR to feat/appium-webdriver-setup.
GitHub Actions will automatically:
Build the APK using EAS.
Upload the APK to BrowserStack.
Run WebdriverIO tests on BrowserStack.
You should see the results as an artifact on the Workflow. LMK if you want my login to see how things look on Browserstack. With it I think you go to this link

To test locally

  • Update the capabilities in wdio.conf.ts.
capabilities: [
  {
    platformName: 'android',
    'appium:platformVersion': '12.0',
    'appium:deviceName': 'Samsung Galaxy S22 Ultra', // whatever your local device is
    'appium:automationName': 'UIAutomator2',
    'appium:app': '/path/to/local/apk/app-debug.apk', // path to your apk
    'appium:autoGrantPermissions': true,
  },
],

Start an Android emulator or connect a real device.
Run Appium in a separate terminal:
npx appium
Execute WebdriverIO:
npx wdio run wdio.conf.ts
or
npm run wdio
You will have to install appium locally to do this.

Next Steps:

  • Add multiple devices
  • Consider Jasmine instead of Mocha?
  • Improve element selection (add accessibilityLabels?)
  • Expand tests to cover more screens & flows

@cimigree cimigree changed the title Feat/appium webdriver setup chore: appium webdriver setup Feb 3, 2025
@awana-lockfile-bot
Copy link

awana-lockfile-bot bot commented Feb 3, 2025

package-lock.json changes

Summary

Status Count
ADDED 197
UPDATED 16
Click to toggle table visibility
Name Status Previous Current
@browserstack/ai-sdk-node ADDED - 1.5.17
@colors/colors ADDED - 1.6.0
@esbuild/aix-ppc64 ADDED - 0.23.1
@esbuild/android-arm ADDED - 0.23.1
@esbuild/android-arm64 ADDED - 0.23.1
@esbuild/android-x64 ADDED - 0.23.1
@esbuild/darwin-arm64 ADDED - 0.23.1
@esbuild/darwin-x64 ADDED - 0.23.1
@esbuild/freebsd-arm64 ADDED - 0.23.1
@esbuild/freebsd-x64 ADDED - 0.23.1
@esbuild/linux-arm ADDED - 0.23.1
@esbuild/linux-arm64 ADDED - 0.23.1
@esbuild/linux-ia32 ADDED - 0.23.1
@esbuild/linux-loong64 ADDED - 0.23.1
@esbuild/linux-mips64el ADDED - 0.23.1
@esbuild/linux-ppc64 ADDED - 0.23.1
@esbuild/linux-riscv64 ADDED - 0.23.1
@esbuild/linux-s390x ADDED - 0.23.1
@esbuild/linux-x64 ADDED - 0.23.1
@esbuild/netbsd-x64 ADDED - 0.23.1
@esbuild/openbsd-arm64 ADDED - 0.23.1
@esbuild/openbsd-x64 ADDED - 0.23.1
@esbuild/sunos-x64 ADDED - 0.23.1
@esbuild/win32-arm64 ADDED - 0.23.1
@esbuild/win32-ia32 ADDED - 0.23.1
@esbuild/win32-x64 ADDED - 0.23.1
@inquirer/checkbox ADDED - 3.0.1
@inquirer/confirm ADDED - 4.0.1
@inquirer/core ADDED - 9.2.1
@inquirer/editor ADDED - 3.0.1
@inquirer/expand ADDED - 3.0.1
@inquirer/figures ADDED - 1.0.9
@inquirer/input ADDED - 3.0.1
@inquirer/number ADDED - 2.0.1
@inquirer/password ADDED - 3.0.1
@inquirer/prompts ADDED - 6.0.1
@inquirer/rawlist ADDED - 3.0.1
@inquirer/search ADDED - 2.0.1
@inquirer/select ADDED - 3.0.1
@inquirer/type ADDED - 2.0.0
@open-draft/until ADDED - 1.0.3
@percy/appium-app ADDED - 2.0.9
@percy/sdk-utils ADDED - 1.30.6
@percy/selenium-webdriver ADDED - 2.2.2
@promptbook/utils ADDED - 0.69.5
@puppeteer/browsers ADDED - 2.7.0
@sec-ant/readable-stream ADDED - 0.4.1
@tootallnate/quickjs-emscripten ADDED - 0.23.0
@types/gitconfiglocal ADDED - 2.0.3
@types/json-schema UPDATED 7.0.11 7.0.15
@types/lodash UPDATED 4.14.199 4.17.14
@types/mocha ADDED - 10.0.10
@types/mute-stream ADDED - 0.0.4
@types/sinonjs__fake-timers ADDED - 8.1.5
@types/triple-beam ADDED - 1.3.5
@types/which ADDED - 2.0.2
@types/wrap-ansi ADDED - 3.0.0
@types/ws ADDED - 8.5.14
@types/yauzl ADDED - 2.10.3
@vitest/pretty-format ADDED - 2.1.8
@vitest/snapshot ADDED - 2.1.8
@wdio/browserstack-service ADDED - 9.7.1
@wdio/cli ADDED - 9.7.2
@wdio/config ADDED - 9.7.2
@wdio/dot-reporter ADDED - 9.6.3
@wdio/globals ADDED - 9.7.1
@wdio/local-runner ADDED - 9.7.2
@wdio/logger ADDED - 9.4.4
@wdio/mocha-framework ADDED - 9.6.4
@wdio/protocols ADDED - 9.7.0
@wdio/repl ADDED - 9.4.4
@wdio/reporter ADDED - 9.6.3
@wdio/runner ADDED - 9.7.2
@wdio/spec-reporter ADDED - 9.6.3
@wdio/types ADDED - 9.6.3
@wdio/utils ADDED - 9.7.2
@zip.js/zip.js ADDED - 2.7.54
ansi-colors ADDED - 4.1.3
aria-query ADDED - 5.3.2
async-exit-hook ADDED - 2.0.1
axios ADDED - 1.7.9
bare-fs ADDED - 4.0.1
bare-os ADDED - 3.4.0
bare-path ADDED - 3.0.0
bare-stream ADDED - 2.6.4
basic-ftp ADDED - 5.0.5
binary-extensions ADDED - 2.3.0
browser-stdout ADDED - 1.3.1
browserstack-local ADDED - 1.5.6
call-bind-apply-helpers ADDED - 1.0.1
call-bound ADDED - 1.0.3
cheerio-select ADDED - 2.1.0
cheerio ADDED - 1.0.0
chokidar ADDED - 4.0.3
create-require ADDED - 1.1.1
css-shorthand-properties ADDED - 1.1.2
css-value ADDED - 0.0.1
csv-writer ADDED - 1.6.0
data-uri-to-buffer ADDED - 6.0.2
deepmerge-ts ADDED - 7.1.4
degenerator ADDED - 5.0.1
detect-libc UPDATED 2.0.2 2.0.3
diff ADDED - 7.0.0
dunder-proto ADDED - 1.0.1
duplexer ADDED - 0.1.2
easy-table ADDED - 1.2.0
edge-paths ADDED - 3.0.5
edgedriver ADDED - 6.1.1
ejs ADDED - 3.1.10
encoding-sniffer ADDED - 0.2.0
es-define-property UPDATED 1.0.0 1.0.1
esbuild ADDED - 0.23.1
event-stream ADDED - 3.3.4
expect-webdriverio ADDED - 5.0.5
extract-zip ADDED - 2.0.1
fast-xml-parser ADDED - 4.5.1
fd-slicer ADDED - 1.1.0
fecha ADDED - 4.2.3
fetch-blob ADDED - 3.2.0
filelist ADDED - 1.0.4
flat ADDED - 5.0.2
follow-redirects ADDED - 1.15.9
formdata-node ADDED - 5.0.1
formdata-polyfill ADDED - 4.0.10
from ADDED - 0.1.7
fsevents UPDATED 2.3.2 2.3.3
geckodriver ADDED - 5.0.0
get-intrinsic UPDATED 1.2.4 1.2.7
get-proto ADDED - 1.0.1
get-tsconfig ADDED - 4.10.0
get-uri ADDED - 6.0.4
git-repo-info ADDED - 2.1.1
gitconfiglocal ADDED - 2.1.0
gopd UPDATED 1.0.1 1.2.0
grapheme-splitter ADDED - 1.0.4
has-symbols UPDATED 1.0.3 1.1.0
he ADDED - 1.2.0
headers-utils ADDED - 1.2.5
htmlfy ADDED - 0.6.0
htmlparser2 ADDED - 9.1.0
immediate ADDED - 3.0.6
import-meta-resolve ADDED - 4.1.0
is-binary-path ADDED - 2.1.0
is-running ADDED - 2.1.0
jake ADDED - 10.9.2
jszip ADDED - 3.10.1
lie ADDED - 3.3.0
locate-app ADDED - 2.5.0
lodash.clonedeep ADDED - 4.5.0
lodash.flattendeep ADDED - 4.4.0
lodash.pickby ADDED - 4.6.0
lodash.union ADDED - 4.6.0
lodash.zip ADDED - 4.2.0
logform ADDED - 2.7.0
loglevel-plugin-prefix ADDED - 0.8.4
loglevel ADDED - 1.9.2
magic-string ADDED - 0.30.17
make-error ADDED - 1.3.6
map-stream ADDED - 0.1.0
math-intrinsics ADDED - 1.1.0
mocha ADDED - 10.8.2
netmask ADDED - 2.0.2
node-domexception ADDED - 1.0.0
node-request-interceptor ADDED - 0.6.3
object-inspect UPDATED 1.13.1 1.13.3
pac-proxy-agent ADDED - 7.1.0
pac-resolver ADDED - 7.0.1
pako ADDED - 1.0.11
parse5-htmlparser2-tree-adapter ADDED - 7.1.0
parse5-parser-stream ADDED - 7.1.2
pathe ADDED - 1.1.2
pause-stream ADDED - 0.0.11
pend ADDED - 1.2.0
plist UPDATED 3.0.6 3.1.0
proxy-agent ADDED - 6.5.0
ps-tree ADDED - 1.2.0
query-selector-shadow-dom ADDED - 1.0.1
recursive-readdir ADDED - 2.2.3
resolve-pkg-maps ADDED - 1.0.0
resq ADDED - 1.11.0
rgb2hex ADDED - 0.2.5
safaridriver ADDED - 1.0.0
send UPDATED 0.18.0 0.19.0
serve-static UPDATED 1.15.0 1.16.2
shell-quote UPDATED 1.7.4 1.8.2
side-channel-list ADDED - 1.0.0
side-channel-map ADDED - 1.0.1
side-channel-weakmap ADDED - 1.0.2
socks-proxy-agent UPDATED 8.0.2 8.0.5
socks UPDATED 2.8.1 2.8.3
spacetrim ADDED - 0.11.59
stream-combiner ADDED - 0.0.4
streamx UPDATED 2.19.0 2.21.1
strict-event-emitter ADDED - 0.1.0
strnum ADDED - 1.0.5
temp-fs ADDED - 0.9.9
tinyrainbow ADDED - 1.2.0
triple-beam ADDED - 1.4.1
ts-node ADDED - 9.1.1
tsx ADDED - 4.19.2
unbzip2-stream ADDED - 1.4.3
unicorn-magic ADDED - 0.3.0
urlpattern-polyfill ADDED - 10.0.0
userhome ADDED - 1.0.1
wait-port ADDED - 1.1.0
webdriver ADDED - 9.7.2
webdriverio ADDED - 9.7.2
winston-transport ADDED - 4.9.0
workerpool ADDED - 6.5.1
yargs-unparser ADDED - 2.0.0
yauzl ADDED - 3.2.0
yn ADDED - 3.1.1
yoctocolors-cjs ADDED - 2.1.2

@cimigree cimigree marked this pull request as ready for review February 3, 2025 21:00
@cimigree cimigree requested a review from ErikSin February 3, 2025 21:00
Copy link
Contributor

@ErikSin ErikSin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a review per-se. More just questions and comments. I think it would be good for @gmaclennan to take a look at this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we create a readme in the config plugins folder to document what the increase in memory is for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I need Gregor's help with that. I know that the build fails and what the error message is, but I don't exactly know why.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha I'm not sure either. Maybe just a doc to say "increase java memory to make builds work on CI"!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok done.

it('should launch the app, grant permissions, and navigate to the next screen', async () => {
await browser.pause(15000);
const description = await $(
'android=new UiSelector().text("Map your world, together")',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we write reusable functions for these "strings"? Something like

function selectText(textToFind:string){
     return `android=new UiSelector().text("${textToFind}")`
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do that in next PR when adding more tests. Thanks for suggestion but trying to keep things as simple as possible for this iteration.

wdio.conf.ts Outdated
Comment on lines 25 to 38
platformName: 'android',
'appium:platformVersion': '12.0',
'appium:deviceName': 'Samsung Galaxy S22 Ultra',
'appium:automationName': 'UIAutomator2',
'appium:app': process.env.BROWSERSTACK_APP_URL,
'appium:autoGrantPermissions': true,
'bstack:options': {
projectName: 'CoMapeo',
buildName: 'CoMapeo Android Build',
sessionName: 'Launch App and Grant Permissions',
appiumVersion: '2.12.1',
debug: true,
networkLogs: true,
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where are you getting this syntax from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A combination of from here:
https://appium.io/docs/en/2.0/guides/caps/ (specifies the appium prefix for all capabilities)
And here:
https://www.browserstack.com/docs/app-automate/capabilities
click legacy, node.js
Maybe you found syntax for Appium 1? This is for Appium 2+...

@ErikSin ErikSin requested a review from gmaclennan February 4, 2025 20:16
Copy link
Member

@gmaclennan gmaclennan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work on this Cindy, I can see that a lot has gone into this, and it's amazing you were able to get all the moving pieces to line up and make this work. The overview about why choices were made is helpful too and the choices make sense to me based on what we know at this time. I think this is ok to merge and start using, and we can evolve and learn from it as we add more tests.

@cimigree cimigree requested a review from ErikSin February 11, 2025 05:24
@cimigree
Copy link
Contributor Author

@ErikSin, before I merge this, are you good with running it

on:
  pull_request:
    branches:
      - main
      - develop
    types: [opened, synchronize, reopened, ready_for_review]

(for the workflow yml file?)

@ErikSin
Copy link
Contributor

ErikSin commented Feb 11, 2025

on:
pull_request:
branches:
- main
- develop
types: [opened, synchronize, reopened, ready_for_review]

I think it is good to merge. Perhaps in the future, if it takes a long time and is resource intensive, we could remove syncronize and have it only run on review_requested. But we can talk about it after it is built

@cimigree cimigree merged commit 7946423 into develop Feb 11, 2025
7 checks passed
@cimigree cimigree deleted the feat/appium-webdriver-setup branch February 11, 2025 20:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Setup Minimal Appium E2E Test for CI Compatibility
3 participants