Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Automating Legacy Desktop Applications with JRu...

Avatar for turtleyacht turtleyacht
November 11, 2021

Automating Legacy Desktop Applications with JRuby and Sikuli (No Notes)

Desktop applications supporting line-of-business, enterprise functions live on as massive, complex beasts. Without an easy route into its internals and modernization falling by the wayside, it's up to you to make sure any small change doesn't break — well — everything. In this talk, we'll discuss the journey of bringing up a Windows VM to poke at an app using screenshots, image recognition, and Minitest to create our own Robotic Process Automation (RPA) framework.

Avatar for turtleyacht

turtleyacht

November 11, 2021
Tweet

More Decks by turtleyacht

Other Decks in Technology

Transcript

  1. A universe for apple pie • ed transforms • “Fairly

    vanilla” Windows • “From scratch” Vagrant fi le
  2. Sneak ed in • Lexicographically ordered using 001-, 002- conventions.

    • Inspired by iterative database changes, Docker layering, Jenkins .groovy scripting
  3. A regex scalpel • / — use a regex to

    “go to” a line • a — append • . — exit insert mode • w — write • q — quit • Don’t forget the newline at the end!
  4. A fresh, free cup of Java • Pull in AdoptOpenJDK

    for `java` • Command Prompt > Run as Administrator • Let’s get to JRuby ASAP (soon)
  5. Every block has its end • / — go to

    the end of fi le • -1 — go one line above it • a — okay, now start append • . — done • w — write • q — quit • (newline)
  6. [SOLVED] with indirection • Some kind of script (.bat, .ps1,

    etc.) • Create an .ed transform mapping
  7. Rinse and repeat • Retrieve Vagrant image • Apply transforms

    • `vagrant up` and `vagrant reload` • xfreerdp
  8. Reliable drive mapping • Scheduled task • Need XML to

    disable all conditions • .ps1 supports HEREDOC
  9. Step 7: kiosk mode • 007-schedule-to-start-pos-on-login.ed
 Start up application on

    remote login (kiosk mode) • Scheduled task starts scripts/schedule- start-pos.ps1
  10. Sikuli! (Or, canst thou see it?) • Take a screenshot

    with Sikuli • Prove Xvfb provides a rendered context
  11. It’s just zeroes and ones • javax.imageio.ImageIO in JRuby •

    Write Sikuli Region as .png; Screen provides desktop width and height
  12. Vagrant fi le as task runner • .ed adds to

    Vagrant fi le • Vagrant executes speci fi ed script
  13. Promises, promises • Initial batch of screenshots for image recognition

    • Development work fl ow solidifying • Conform to corporate code conventions
  14. Each step pro fi ts • .ed to specify script:

    startup task • .ed to specify script: install Visual C++ redist
  15. HOWTO screen recording • `ncat` to stop recording • Start

    and Stop recording are separate .bat scripts
  16. VLC setup script • Bundle VLC 3.0.14 to avoid download

    • 013-install-vlc.ed
 Runs scripts/install-vlc.bat
  17. Wonderful, beautiful, shiny • Gem list: brakeman, bundler-audit, fl og,

    reek • Internal gems: tcs-con fi g, tcs-rubocop
  18. Silent VLC, add minitest gem • Nit: Install VLC in

    a place without spaces • Add minitest gem
  19. Reset dropdowns • A bit of refactoring to the PoC

    to be more reliable: reset before setting values
  20. Loading in Sikuli • Import SikuliX API • Follow Raymond

    Hocke’s recommendations (Launchpad post)
  21. Debug (logging), global con fi g • Set Debug level

    to 3 (most verbose) • Specify global images path
  22. A (UI) tree of wonder • *.sikuli represented as type-of

    under parent folder (AppImageRoot) • SikuliTestEnvironment::Component as parent of UI components • PosComponents < Components
  23. Strings as a source of truth • (Helper methods) •

    Automatic mapping: 
 components[key] = value
  24. • Components in test respond to intentful service calls •

    Underlying types and clicks simpli fi ed by object hierarchy
  25. 1 o’ the hardest problems in CS • Bug fi

    x: use base_bundle_path instead of «base-bundle-path»/app
  26. To /app or not to /app • Add con fi

    guration/.yml parser lib
  27. • Caller never invokes primitives, only sends messages of intent

    • Public/private separation ensures a useful interface for collaboration and interaction