Test Example in Ruby

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard
Not for use with personal data

Be sure to check out the full Appium setup guide with Axe DevTools Mobile if you're just getting started, or more examples of Axe DevTools Mobile for Appium in other languages.

Full Example with UIAutomator2

require 'appium_lib'
require 'rspec'

describe 'DebugTest' do
  before(:all) do
    @tags = ['appium', 'qa']
    @api_key = '<DEQUE_APIKEY>'
    @project_id = '<DEQUE_PROJECT_ID>'

    caps = {
      platformName: 'Android',
      deviceName: 'Android',
      appPackage: '<YOUR_APP_PACKAGE_NAME>',
      appActivity: '.MainActivity',
      automationName: 'AxeUiAutomator2',
      uiautomator2ServerLaunchTimeout: 60000,
      uiautomator2ServerInstallTimeout: 60000,
      adbExecTimeout: 60000,
      ignoreHiddenApiPolicyError: true,
      disableWindowAnimation: true,
      waitForIdle: true,
      commandTimeout: 300,
      noReset: false,
      fullReset: false
    }

    appium_opts = {
      caps: caps,
      appium_lib: {
        server_url: 'http://localhost:4723/'
      }
    }

    @driver = Appium::Driver.new(appium_opts, true)
    @driver.start_driver

    # ignoreRules is passed directly into each 'mobile: axeScan' call
    @scan_settings = {
      # tags and ignoreRules are deprecated and will be removed once we fully transition to Axe Developer Hub
      ignoreRules: ['ScreenOrientation'],
      tags: @tags
    }

    # Make a one-time call to set up your session for posting to Axe Developer Hub
    # This also accepts `axeAccountURL` in case of a private instance
    # The `axe_settings` object still accepts `apiKey` with `axeAccountURL`, but is not required
    # if you are going to make one time before(:all) call to 'mobile: axeStartSession'
    axe_settings = {
      apiKey: @api_key,
      projectId: @project_id,
      axeUploadResults: true # default - set to false to keep results local only
    }
    @driver.execute_script('mobile: axeStartSession', axe_settings)
  end

  after(:all) do
    if @driver
      # Generate an HTML report from all accumulated scans before quitting
      # The report aggregates every 'mobile: axeScan' call made during this session.
      begin
        report_settings = {
          scanName: 'My Accessibility Report',
          axeHtmlReportPath: 'build/AxeDevToolsMobileResults'
        }

        report_result = @driver.execute_script(
          'mobile: axeGenerateHtmlReportAndSummary', report_settings
        )

        if report_result.key?('axeError')
          puts "Report generation failed: #{report_result['axeError']}"
        else
          puts "HTML report saved to: #{report_result['localDirectory']}"
        end
      rescue StandardError => e
        puts "Failed to generate HTML report: #{e.message}"
      end

      @driver.driver_quit
    end
  end

  def dismiss_system_ui_error
    begin
      system_popup = @driver.find_element(:xpath, '//*[contains(@text, "System UI")]')
      wait = Selenium::WebDriver::Wait.new(timeout: 5)
      wait.until { system_popup.displayed? }

      if system_popup.displayed?
        wait_button = @driver.find_element(:xpath, '//*[contains(@text, "Wait")]')
        wait = Selenium::WebDriver::Wait.new(timeout: 5)
        wait.until { wait_button.displayed? }
        wait_button.click
        puts "Dismissed the System UI error popup by clicking 'Wait'."
      end
    rescue Selenium::WebDriver::Error::TimeoutError, Selenium::WebDriver::Error::NoSuchElementError => e
      puts 'No System UI error popup appeared.'
    end
  end

  def launch_app
    begin
      @driver.terminate_app('<YOUR_APP_PACKAGE_NAME>')
      sleep(1) # Give the app time to fully terminate
    rescue StandardError => e
      puts "App was not running or failed to terminate: #{e.message}"
    end

    @driver.activate_app('<YOUR_APP_PACKAGE_NAME>')

    begin
      element = @driver.find_element(:xpath, '//*[contains(@text, "Screen Name")]')
      wait = Selenium::WebDriver::Wait.new(timeout: 30)
      wait.until { element.displayed? }
    rescue Selenium::WebDriver::Error::TimeoutError => e
      dismiss_system_ui_error
      # Try again after dismissing the error (if not, then fail)
      element = @driver.find_element(:xpath, '//*[contains(@text, "Screen Name")]')
      wait = Selenium::WebDriver::Wait.new(timeout: 30)
      wait.until { element.displayed? }
    end
  end

  before(:each) do
    launch_app
  end

  # Now since your session is authenticated you can keep making 'mobile: axeScan' call
  # like below in test1 and test2. The scans will be uploaded to the dashboard and also grouped in Developer Hub.
  it 'test1' do
    element = @driver.find_element(:xpath, '//*[contains(@text, "Screen Name")]')
    wait = Selenium::WebDriver::Wait.new(timeout: 10)
    wait.until { element.displayed? }
    puts element.text

    appium_scan_result = @driver.execute_script('mobile: axeScan', @scan_settings)
    results = appium_scan_result['axeRuleResults']
    puts "debug: Total results: #{results.length}"
  end

  it 'test2' do
    element = @driver.find_element(:xpath, '//*[contains(@text, "Screen Name")]')
    wait = Selenium::WebDriver::Wait.new(timeout: 10)
    wait.until { element.displayed? }
    element.click
    @driver.find_element(:xpath, '//*[contains(@text, "announced by a screen")]')

    appium_scan_result = @driver.execute_script('mobile: axeScan', @scan_settings)
    results = appium_scan_result['axeRuleResults']
    puts "debug: Total results: #{results.length}"
  end
end

Full Example with XCUITest

require 'appium_lib'
require 'rspec'

describe 'iOS Maps DebugTest' do
  before(:all) do
    @tags = ['appium', 'qa', 'ios']
    @api_key = '<DEQUE_APIKEY>'
    @project_id = '<DEQUE_PROJECT_ID>'

    # Matching the working sample - minimal capabilities
    caps = {
      platformName: 'iOS',
      automationName: 'AxeXCUITest',
      udid: '<YOUR_DEVICE_OR_SIMULATOR_UDID>',
      bundleId: 'com.apple.Maps',
      wdaLaunchTimeout: 960000 # 16 minutes like the working sample
      # NOT specifying platformVersion - let it auto-detect
    }

    appium_opts = {
      caps: caps,
      appium_lib: {
        server_url: 'http://127.0.0.1:4723/'
      }
    }

    @driver = Appium::Driver.new(appium_opts, true)
    @driver.start_driver

    # ignoreRules is passed directly into each 'mobile: axeScan' call
    @scan_settings = {
      # tags and ignoreRules are deprecated and will be removed once we fully transition to Axe Developer Hub
      ignoreRules: ['ScreenOrientation'],
      tags: @tags
    }

    # Make a one-time call to set up your session for posting to Axe Developer Hub
    # This also accepts `axeAccountURL` in case of a private instance
    # The `axe_settings` object still accepts `apiKey` with `axeAccountURL`, but is not required
    # if you are going to make one time before(:all) call to 'mobile: axeStartSession'
    axe_settings = {
      apiKey: @api_key,
      projectId: @project_id,
      axeAccountURL: 'https://mobile-qa.dequelabs.com',
      axeUploadResults: true # default - set to false to keep results local only
    }
    @driver.execute_script('mobile: axeStartSession', axe_settings)
  end

  after(:all) do
    if @driver
      # Generate HTML reports before quitting the driver
      @driver.execute_script('mobile: axeGenerateHtmlReportAndSummary', {})

      # Alternative: Generate HTML reports to a custom path
      # @driver.execute_script('mobile: axeGenerateHtmlReportAndSummary', {
      #   outputPath: '/Users/me/MyReports'
      # })

      sleep(1)
      @driver.driver_quit
    end
  end

  def launch_app
    @driver.activate_app('com.apple.Maps')
  end

  before(:each) do
    launch_app
  end

  # Now since your session is authenticated you can keep making 'mobile: axeScan' call
  # like below in test1 and test2. The scans will be uploaded to the dashboard and also grouped in Dev Hub.
  it 'test1 - scan main screen' do
    appium_scan_result = @driver.execute_script('mobile: axeScan', @scan_settings)
    results = appium_scan_result['axeRuleResults']
    puts "debug: Total results: #{results.length}"
  end

  it 'test2 - click search and scan' do
    appium_scan_result = @driver.execute_script('mobile: axeScan', @scan_settings)
    results = appium_scan_result['axeRuleResults']
    puts "debug: Total results: #{results.length}"
  end
end