Giter Club home page Giter Club logo

lldo's Introduction

LLDO - LLDB Automation with Swift

Write debugging helpers in Swift, combine them into powerful automation actions and run them as LLDB commands.

Example

LLDO Example

Let's say your app starts with a login form. How often do you fill out that form every day? Wouldn't it be nice to automate this? That's what LLDO is for.

Simply write some automation steps in a login.swift file

UIView.find(byAccessibilityID: "username_input")?.enterText("[email protected]")
UIView.find(byAccessibilityID: "password_input")?.enterText("awesome")
UISwitch.first()?.slide()
UIButton.first()?.tap()

and call the combined action from LLDB: (lldb) login.

Try It

  1. Clone this repo
  2. Open Example/LLDOSwiftHelper.xcodeproj
  3. Run in the Simulator and wait to hit the breakpoint in AppDelegate.applicationDidBecomeActive.
  4. Type the following commands in the LLDB prompt:
  • command script import /path/to/LLDO (make the LLDO commands available in LLDB)
  • lldo ../lldo_actions (load LLDO helpers and automation actions)
  • login (call login action)

Of course, this works for all kinds of forms. Every workflow that brings your app into a desired state can be automated.

Helpers

LLDO comes with a bunch of helper methods that make writing common automation actions very easy. If you're using the example app, you can try out a few of them:

// Poking around
po UIButton.first()
po UIView.current.all(UILabel.self)
po UIView.grep("Pass")
po UIView.find(byAccessibilityID: "username_input")
po UIView.current.tree().filter { $0.isHidden }

// Changing stuff
po UITextField.first()?.enterText("[email protected]")
po UISwitch.first()?.slide()
po UIButton.first()?.tap()

Check the documentation at lurado.github.io/LLDO for a complete list.

Custom Helpers

Helpers need to be extensions on existing classes (see (lldb) help load_swift_file for details). You can develop them like any other code in a Xcode project.

  1. Run an application and pause it to start LLDB
  2. Use the load_swift_file command to load the file
  3. Call your helpers
  4. Adjust the implementation
  5. GOTO 1 (unfortunately loading a files twice in a LLDB session results in duplicate symbols)

⚠️ Do NOT add these files to your target! Helpers commonly contain code that you would never write in your production app. For debugging it's fine though.

Automation Actions

LLDO actions are simple Swift files that contain a series of commands. Each file corresponds to an action of the same name, for example login.swift will be turned into a login action.

To load all actions in a folder, use the lldo or load_lldo_actions commands. By default these commands look for a lldo_actions folder, located next to the source file of the current breakpoint.

⚠️ Again, do NOT add these files to your target either! They are for debugging purpose only and should not be shipped with your app.

Setup and Usage

To not have to manually import the path to LLDO in every LLDB session, add the following line to your ~/.lldbinit:

command script import /path/to/LLDO

This always loads LLDO's LLDB commands and makes them available in every project.

You can use breakpoints to further automate the initialization. For example a symbolic breakpoint in @objc <module>.<AppDelegate>.init (e.g. @objc LLDO.AppDelegate.init) can be used to load LLDO.

Symbolic Breakpoint to load LLDO

This would also load all actions in a lldo_actions folder next to your Xcode project/workspace file.

Likewise breakpoints can be used to trigger actions. For instance a breakpoint in applicationDidBecomeActive can be used to call the login action in the example app.

Breakpoint to call the login action

It's important to check "Automatically continue" for those breakpoints. Otherwise you would have to press "Continue" every time the breakpoints are hit.

If your whole team uses LLDO, you can share common breakpoints by right clicking them and selecting "Share Breakpoint".

Pure Objective-C Projects On a Device

To be able to use the Swift helpers (and thus LLDO) in an Objective-C project on an iOS device, you need to bundle the necessary Swift runtime libraries:

  1. Add a single Swift file
  2. Do not create a bridging header
  3. make sure you import UIKit

If you are curious why this is necessary, see (lldb) help load_swift_runtime for details.

Credits

This project has been heavily inspired by @kastiglione. You should check out his talk.

LICENSE

MIT - see LICENSE file.

lldo's People

Contributors

dependabot[bot] avatar jlnr avatar sebastianludwig avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

lukas2

lldo's Issues

Add documentation on how to write scripts

  1. Be able to write scripts
    • LLDB command to print the project path (parse source info)
    • LLDB command to take a project relative path to a directory containing .lldb files. Create alias <file> command source <file>.lldb for every file in that directory.
  2. Write documentation
    • Create a breakpoint anywhere in your code
      • Swift:
        • a symbolic breakpoint in @objc <module>.<AppDelegate>.init (@objc LLDO.AppDelegate.init)
      • ObjC
        • In your main function: Symbol main in your module (LLDO)
        • In any implemented AppDelegate method
    • execute debugger command create_actions <path>. Depending on where you set your breakpoint, path might need be be adjusted (give or take a ..)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.