testcentricity_mobile 4.0.7 → 4.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +205 -6
- data/lib/testcentricity_mobile/app_core/appium_connect_helper.rb +5 -1
- data/lib/testcentricity_mobile/app_core/screen_object.rb +24 -26
- data/lib/testcentricity_mobile/app_elements/list.rb +11 -4
- data/lib/testcentricity_mobile/version.rb +1 -1
- metadata +6 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 1ce3b763ec417328c83163d601d7c7ae3beb499c7033ce65c3afc9204949f561
         | 
| 4 | 
            +
              data.tar.gz: 82b625a3e675c295dca2b21a04330f68b7ee38f5939b3c82a2af35aa9a5a12aa
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 761a2aa1a5bdebd8dde858e83f8a8fb966d36d63da741e31f80c4cc46443665f2d399edc7b7f9c2bf124821129369f39c078c050883a0f3984c8ab84ae54f28d
         | 
| 7 | 
            +
              data.tar.gz: 03310a90555a41b1966a68fa027000b1ca08434d8f29b65536443b42d7025010e395ac2ae5fbc4f109afa69475153a4e4189d1ac519ef3167c98a463179bae9a
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,6 +2,26 @@ | |
| 2 2 | 
             
            All notable changes to this project will be documented in this file.
         | 
| 3 3 |  | 
| 4 4 |  | 
| 5 | 
            +
            ## [4.0.8] - 03-JUNE-2024
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ### Fixed
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            * When testing using locally hosted iOS simulators or physical devices, and when not passing an options hash to specify 
         | 
| 10 | 
            +
            desired capabilities, the `AppiumConnect.initialize_appium` method now correctly sets the following XCUItest capabilities:
         | 
| 11 | 
            +
              * `appium:webviewConnectTimeout` capability is now correctly specified as an `Integer`
         | 
| 12 | 
            +
              * `appium:maxTypingFrequency` set to 15 keystrokes per minute to resolve an issue where characters are intermittently
         | 
| 13 | 
            +
                dropped during text entry by `AppUIElement.set`, `AppUIElement.send_keys`, or `BaseScreenSectionObject.populate_data_fields`
         | 
| 14 | 
            +
                methods.
         | 
| 15 | 
            +
            * `AppList.list_item` attribute now defaults to `XCUIElementTypeOther`class for iOS/iPadOS platform and `android.view.ViewGroup`
         | 
| 16 | 
            +
            class for Android platform.
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            ### Changed
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            * Updated `appium_lib` gem to version 15.1.0.
         | 
| 21 | 
            +
            * Updated `appium_lib_core` gem to version 9.1.1.
         | 
| 22 | 
            +
            * Updated `selenium-webdriver` gem to version 4.21.1.
         | 
| 23 | 
            +
             | 
| 24 | 
            +
             | 
| 5 25 | 
             
            ## [4.0.7] - 05-MAY-2024
         | 
| 6 26 |  | 
| 7 27 | 
             
            ### Added
         | 
    
        data/README.md
    CHANGED
    
    | @@ -492,6 +492,7 @@ Single `AppUIElement` declarations have the following format: | |
| 492 492 | 
             
              - `xpath:`
         | 
| 493 493 | 
             
              - `predicate:` (iOS only)
         | 
| 494 494 | 
             
              - `class_chain:` (iOS only)
         | 
| 495 | 
            +
              - `uiautomator:` (Android only)
         | 
| 495 496 | 
             
              - `css:` (WebViews in hybrid apps only).
         | 
| 496 497 | 
             
            * The `locator_identifier` is the value or attribute that uniquely and unambiguously identifies the `AppUIElement`.
         | 
| 497 498 |  | 
| @@ -606,10 +607,10 @@ The optional `wait_time` parameter is used to specify the time (in seconds) to w | |
| 606 607 | 
             
            viable for data entry (the `AppUIElement` must be visible and enabled) before entering the associated data value. This
         | 
| 607 608 | 
             
            option is useful in situations where entering data, or setting the state of a `AppUIElement` might cause other `AppUIElements`
         | 
| 608 609 | 
             
            to become visible or active. Specifying a wait_time value ensures that the subsequent `AppUIElements` will be ready to
         | 
| 609 | 
            -
            be interacted with as states are changed. If the wait time is `nil`, then the wait time will be 5 seconds.
         | 
| 610 | 
            +
            be interacted with as states are changed. If the wait time is `nil`, then the default wait time will be 5 seconds.
         | 
| 610 611 |  | 
| 611 612 | 
             
            If any of the specified UI elements are not currently visible, the `populate_data_fields` method will attempt to scroll
         | 
| 612 | 
            -
            the UI object  | 
| 613 | 
            +
            the UI object into view on the vertical axis (scrolls down until found, then scrolls up if not found).
         | 
| 613 614 | 
             
            ```ruby
         | 
| 614 615 | 
             
                def enter_data(user_data)
         | 
| 615 616 | 
             
                  fields = {
         | 
| @@ -642,8 +643,8 @@ containing key/hash pairs of UI elements and their properties or attributes to b | |
| 642 643 | 
             
                 verify_ui_states(ui)
         | 
| 643 644 | 
             
            ```
         | 
| 644 645 | 
             
            The `verify_ui_states` method automatically scrolls UI elements that are expected to be visible into view. Auto-scrolling
         | 
| 645 | 
            -
            only occurs on the vertical axis (down, then up). Setting the `auto_scroll` parameter | 
| 646 | 
            -
            from occurring.
         | 
| 646 | 
            +
            only occurs on the vertical axis (scrolls down until found, then scrolls up if not found). Setting the `auto_scroll` parameter
         | 
| 647 | 
            +
            to `false` prevents automatic scrolling from occurring.
         | 
| 647 648 |  | 
| 648 649 | 
             
            The `verify_ui_states` method queues up any exceptions that occur while verifying each object's properties until all
         | 
| 649 650 | 
             
            `AppUIElements`and their properties have been checked, and then posts any exceptions encountered upon completion. Posted
         | 
| @@ -678,6 +679,15 @@ The `verify_ui_states` method supports the following property/state pairs: | |
| 678 679 |  | 
| 679 680 | 
             
                :checked Boolean
         | 
| 680 681 |  | 
| 682 | 
            +
            **Radio Buttons:**
         | 
| 683 | 
            +
             | 
| 684 | 
            +
                :selected Boolean
         | 
| 685 | 
            +
             | 
| 686 | 
            +
            **Lists and SelectLists**
         | 
| 687 | 
            +
             | 
| 688 | 
            +
                :items     Array of Strings
         | 
| 689 | 
            +
                :itemcount Integer
         | 
| 690 | 
            +
             | 
| 681 691 | 
             
            #### Comparison States
         | 
| 682 692 |  | 
| 683 693 | 
             
            The `verify_ui_states` method supports comparison states using property/comparison state pairs:
         | 
| @@ -829,6 +839,195 @@ Baseline translation strings are stored in `.yml` files in the `config/locales/` | |
| 829 839 | 
             
                    └── README.md
         | 
| 830 840 |  | 
| 831 841 |  | 
| 842 | 
            +
            ### Working With Custom AppUIElements
         | 
| 843 | 
            +
             | 
| 844 | 
            +
            #### Vertical Scrolling ListView
         | 
| 845 | 
            +
             | 
| 846 | 
            +
            `AppUIElements` like ListViews (`AppList` class) are typically made up of multiple composite UI component types, which will
         | 
| 847 | 
            +
            be different for iOS vs. Android mobile platforms. Below is an example of the vertical scrolling ListView implementations
         | 
| 848 | 
            +
            for a cross-platform application implemented using React Native (iOS version on the left, Android version on the right).
         | 
| 849 | 
            +
            Each ListView contains 30 items:
         | 
| 850 | 
            +
             | 
| 851 | 
            +
            
         | 
| 852 | 
            +
             | 
| 853 | 
            +
            While the iOS and Android ListViews appear to be identical in the app, performing an inspection of each application's GUI
         | 
| 854 | 
            +
            using Appium Inspector reveals differences in the object hierarchy as depicted below (iOS version on left, Android version
         | 
| 855 | 
            +
            on the right):
         | 
| 856 | 
            +
             | 
| 857 | 
            +
            
         | 
| 858 | 
            +
             | 
| 859 | 
            +
            The inspection of the ListView object hierarchy reveals that for the iOS version of the app, list items are made up of
         | 
| 860 | 
            +
            `XCUIElementTypeOther` objects, and that for the Android version of the app, list items are made up of `android.view.ViewGroup`
         | 
| 861 | 
            +
            objects.
         | 
| 862 | 
            +
             | 
| 863 | 
            +
            The other, more notable difference is that while the iOS inspection shows all 30 list items, only 13 list items are shown
         | 
| 864 | 
            +
            in the inspection of the Android app, which corresponds to the list items that are visible on the Android device screen.
         | 
| 865 | 
            +
            When testing Android apps using the `UiAutomator2` driver for Appium, UI objects that are not displayed on screen cannot
         | 
| 866 | 
            +
            be detected by Appium Inspector or by Appium based frameworks until the objects are scrolled into view.
         | 
| 867 | 
            +
             | 
| 868 | 
            +
            The `AppList.define_list_elements` method provides a means of specifying the objects that make up the list item components
         | 
| 869 | 
            +
            of an `AppList` control, and the axis in which scrolling of the list items occurs. The method accepts a hash that can contain
         | 
| 870 | 
            +
            up to two key-value pairs. Valid key designators are `:list_item`and `:scrolling`. The `AppList.define_list_elements` method
         | 
| 871 | 
            +
            is typically called in the `initialize` method of the `ScreenObject` or `ScreenSection` that contains the associated `AppList`
         | 
| 872 | 
            +
            control.
         | 
| 873 | 
            +
             | 
| 874 | 
            +
            The code snippets below demonstrate the use of the `AppList.define_list_elements` method in the `CloudListScreen` screen
         | 
| 875 | 
            +
            object's `initialize` method to define the list item components that make up the Clouds vertical scrolling ListView from
         | 
| 876 | 
            +
            the above examples. It is not necessary to specify the scroll axis in the code below, as `:vertical` is the default scroll
         | 
| 877 | 
            +
            axis that is set when instantiating an `AppList` element.
         | 
| 878 | 
            +
             | 
| 879 | 
            +
            iOS Cloud List `ScreenObject`
         | 
| 880 | 
            +
            ```ruby
         | 
| 881 | 
            +
                class CloudListScreen < ScreenObject
         | 
| 882 | 
            +
                  trait(:screen_name)    { 'Cloud List' }
         | 
| 883 | 
            +
                  trait(:screen_locator) { { class_chain: '**/XCUIElementTypeWindow/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther' } }
         | 
| 884 | 
            +
             | 
| 885 | 
            +
                  # Cloud List screen UI elements
         | 
| 886 | 
            +
                  list :cloud_list, { class_chain: '**/XCUIElementTypeScrollView/XCUIElementTypeOther' }
         | 
| 887 | 
            +
             | 
| 888 | 
            +
                  def initialize
         | 
| 889 | 
            +
                    super
         | 
| 890 | 
            +
                    # define the list item element for the Cloud list object
         | 
| 891 | 
            +
                    list_spec = { list_item: { class: 'XCUIElementTypeOther' } }
         | 
| 892 | 
            +
                    cloud_list.define_list_elements(list_spec)
         | 
| 893 | 
            +
                  end
         | 
| 894 | 
            +
                end
         | 
| 895 | 
            +
            ```
         | 
| 896 | 
            +
             | 
| 897 | 
            +
            Android CloudListScreen `ScreenObject`
         | 
| 898 | 
            +
            ```ruby
         | 
| 899 | 
            +
                class CloudListScreen < ScreenObject
         | 
| 900 | 
            +
                  trait(:screen_name)    { 'Cloud List' }
         | 
| 901 | 
            +
                  trait(:screen_locator) { { xpath: '//android.widget.FrameLayout[@resource-id="android:id/content"]/android.view.ViewGroup' } }
         | 
| 902 | 
            +
             | 
| 903 | 
            +
                  # Cloud List screen UI elements
         | 
| 904 | 
            +
                  list :cloud_list, { xpath: '//android.widget.ScrollView/android.view.ViewGroup' }
         | 
| 905 | 
            +
             | 
| 906 | 
            +
                  def initialize
         | 
| 907 | 
            +
                    super
         | 
| 908 | 
            +
                    # define the list item element for the Cloud list object
         | 
| 909 | 
            +
                    list_spec = { list_item: { class: 'android.view.ViewGroup' } }
         | 
| 910 | 
            +
                    cloud_list.define_list_elements(list_spec)
         | 
| 911 | 
            +
                  end
         | 
| 912 | 
            +
                end
         | 
| 913 | 
            +
            ```
         | 
| 914 | 
            +
             | 
| 915 | 
            +
             | 
| 916 | 
            +
            #### Horizontal Scrolling ListView
         | 
| 917 | 
            +
             | 
| 918 | 
            +
            Below is an example of a horizontal scrolling "Carousel" style ListView implementations on the Swipe screen of a cross-platform
         | 
| 919 | 
            +
            application. Each ListView contains 6 list items.
         | 
| 920 | 
            +
             | 
| 921 | 
            +
            
         | 
| 922 | 
            +
             | 
| 923 | 
            +
            While the iOS and Android ListViews appear to be identical in the app, performing an inspection of each application's GUI
         | 
| 924 | 
            +
            using Appium Inspector reveals differences in the object hierarchy as depicted below (iOS version on left, Android version
         | 
| 925 | 
            +
            on the right):
         | 
| 926 | 
            +
             | 
| 927 | 
            +
            
         | 
| 928 | 
            +
             | 
| 929 | 
            +
            As in the previous example for the vertical scrolling ListView, the inspection of the Carousel ListView object hierarchy
         | 
| 930 | 
            +
            reveals that for the iOS version of the app, list items are again made up of `XCUIElementTypeOther` objects, and that for
         | 
| 931 | 
            +
            the Android version of the app, list items are again made up of `android.view.ViewGroup` objects.
         | 
| 932 | 
            +
             | 
| 933 | 
            +
            As in the previous examples, the iOS inspection shows all 6 list items, while only 2 list items are shown in the inspection
         | 
| 934 | 
            +
            of the Android app, which corresponds to the list items that are visible on the Android device screen.
         | 
| 935 | 
            +
             | 
| 936 | 
            +
            The code snippets below demonstrate the use of the `AppList.define_list_elements` method in the `SwipeScreen` screen object's
         | 
| 937 | 
            +
            `initialize` method to define the scroll axis and list item components that make up the Carousel horizontal scrolling ListView
         | 
| 938 | 
            +
            from the above examples.
         | 
| 939 | 
            +
             | 
| 940 | 
            +
            iOS Swipe `ScreenObject`
         | 
| 941 | 
            +
            ```ruby
         | 
| 942 | 
            +
                class SwipeScreen < ScreenObject
         | 
| 943 | 
            +
                  trait(:screen_name)    { 'Swipe' }
         | 
| 944 | 
            +
                  trait(:screen_locator) { { accessibility_id: 'Swipe-screen' } }
         | 
| 945 | 
            +
             | 
| 946 | 
            +
                  # Swipe screen UI elements
         | 
| 947 | 
            +
                  list :carousel_list, { accessibility_id: 'Carousel' }
         | 
| 948 | 
            +
             | 
| 949 | 
            +
                  def initialize
         | 
| 950 | 
            +
                    super
         | 
| 951 | 
            +
                    # define the list item element for the Carousel list object
         | 
| 952 | 
            +
                    list_spec = {
         | 
| 953 | 
            +
                      list_item: { xpath: '//XCUIElementTypeOther[contains(@name, "__CAROUSEL_ITEM_")]' },
         | 
| 954 | 
            +
                      scrolling: :horizontal
         | 
| 955 | 
            +
                    }
         | 
| 956 | 
            +
                    carousel_list.define_list_elements(list_spec)
         | 
| 957 | 
            +
                  end
         | 
| 958 | 
            +
                end
         | 
| 959 | 
            +
            ```
         | 
| 960 | 
            +
             | 
| 961 | 
            +
            Android Swipe `ScreenObject`
         | 
| 962 | 
            +
            ```ruby
         | 
| 963 | 
            +
                class SwipeScreen < ScreenObject
         | 
| 964 | 
            +
                  trait(:screen_name)    { 'Swipe' }
         | 
| 965 | 
            +
                  trait(:screen_locator) { { accessibility_id: 'Swipe-screen' } }
         | 
| 966 | 
            +
             | 
| 967 | 
            +
                  # Swipe screen UI elements
         | 
| 968 | 
            +
                  list :carousel_list, { accessibility_id: 'Carousel' }
         | 
| 969 | 
            +
             | 
| 970 | 
            +
                  def initialize
         | 
| 971 | 
            +
                    super
         | 
| 972 | 
            +
                    # define the list item element for the Carousel list object
         | 
| 973 | 
            +
                    list_spec = {
         | 
| 974 | 
            +
                      list_item: { xpath: '//android.view.ViewGroup[contains(@resource-id, "__CAROUSEL_ITEM_")]' },
         | 
| 975 | 
            +
                      scrolling: :horizontal
         | 
| 976 | 
            +
                    }
         | 
| 977 | 
            +
                    carousel_list.define_list_elements(list_spec)
         | 
| 978 | 
            +
                  end
         | 
| 979 | 
            +
                end
         | 
| 980 | 
            +
            ```
         | 
| 981 | 
            +
             | 
| 982 | 
            +
             | 
| 983 | 
            +
            #### Popup and PickerWheel Style ListViews
         | 
| 984 | 
            +
             | 
| 985 | 
            +
            Below is an example of a PickerWheel (iOS) and Popup (Android) style ListView implementations on the Form Components screen
         | 
| 986 | 
            +
            of a cross-platform application. 
         | 
| 987 | 
            +
             | 
| 988 | 
            +
            
         | 
| 989 | 
            +
             | 
| 990 | 
            +
            Performing an inspection of each application's GUI using Appium Inspector reveals differences in the object hierarchy as
         | 
| 991 | 
            +
            depicted below (iOS version on left, Android version on the right):
         | 
| 992 | 
            +
             | 
| 993 | 
            +
            
         | 
| 994 | 
            +
             | 
| 995 | 
            +
            The inspection of the PickerWheel and Popup ListView object hierarchies reveals that for the iOS version of the app, list
         | 
| 996 | 
            +
            items are again made up of `XCUIElementTypeOther` objects, and that for the Android version of the app, list items are made
         | 
| 997 | 
            +
            up of `android.widget.CheckedTextView` objects.
         | 
| 998 | 
            +
             | 
| 999 | 
            +
            However, `XCUIElementTypePickerWheel` controls present testability challenges with Appium, as the `XCUIElementTypeOther`
         | 
| 1000 | 
            +
            objects that comprise the individual list items cannot be reliably interacted with or validated. When inspecting each of
         | 
| 1001 | 
            +
            the `XCUIElementTypeOther` list items of the `XCUIElementTypePickerWheel` control, there are no `text`, `accessibility_id`,
         | 
| 1002 | 
            +
            `label`, or `value` element attributes available which could be used to determine whether the correct caption strings are
         | 
| 1003 | 
            +
            displayed for each list item. The `AppList.get_item_count` or `get_list_items` methods do not support `XCUIElementTypePickerWheel`
         | 
| 1004 | 
            +
            controls, and will raise an exception if called for such a control.
         | 
| 1005 | 
            +
             | 
| 1006 | 
            +
            For the Android version of the app, the `android.widget.CheckedTextView` list items can be interacted with and validated,
         | 
| 1007 | 
            +
            as the `text` element attribute for each list item are visible in the inspection.
         | 
| 1008 | 
            +
             | 
| 1009 | 
            +
            The code snippet below demonstrate the use of the `AppList.define_list_elements` method in the `FormScreen` screen object's
         | 
| 1010 | 
            +
            `initialize` method to define the list item components that make up the Android Popup style ListView from the above example.
         | 
| 1011 | 
            +
             | 
| 1012 | 
            +
            Android FormScreen `ScreenObject`
         | 
| 1013 | 
            +
            ```ruby
         | 
| 1014 | 
            +
                class FormScreen < ScreenObject
         | 
| 1015 | 
            +
                  trait(:screen_name)    { 'Form' }
         | 
| 1016 | 
            +
                  trait(:screen_locator) { { accessibility_id: 'Forms-screen' } }
         | 
| 1017 | 
            +
             | 
| 1018 | 
            +
                  # Form screen UI elements
         | 
| 1019 | 
            +
                  list :drop_down_menu, { id: 'com.wdiodemoapp:id/select_dialog_listview' }
         | 
| 1020 | 
            +
             | 
| 1021 | 
            +
                  def initialize
         | 
| 1022 | 
            +
                    super
         | 
| 1023 | 
            +
                    # define the list item element for the drop-down list object
         | 
| 1024 | 
            +
                    list_spec = { list_item: { class: 'android.widget.CheckedTextView' } }
         | 
| 1025 | 
            +
                    drop_down_menu.define_list_elements(list_spec)
         | 
| 1026 | 
            +
                  end
         | 
| 1027 | 
            +
                end
         | 
| 1028 | 
            +
            ```
         | 
| 1029 | 
            +
             | 
| 1030 | 
            +
             | 
| 832 1031 | 
             
            ---
         | 
| 833 1032 | 
             
            ## Instantiating ScreenObjects and Utilizing the ScreenManager
         | 
| 834 1033 |  | 
| @@ -868,7 +1067,7 @@ scenarios are executed: | |
| 868 1067 | 
             
                include WorldScreens
         | 
| 869 1068 | 
             
                WorldPages.instantiate_screen_objects
         | 
| 870 1069 | 
             
            ```
         | 
| 871 | 
            -
            **NOTE:** If you intend to use the ` | 
| 1070 | 
            +
            **NOTE:** If you intend to use the `ScreenManager`, you must define a `screen_name` trait for each of the `ScreenObjects`
         | 
| 872 1071 | 
             
            to be registered.
         | 
| 873 1072 |  | 
| 874 1073 |  | 
| @@ -1005,7 +1204,7 @@ endpoint is used. | |
| 1005 1204 | 
             
            You can run your automated tests on locally hosted iOS simulators or physically connected devices using Appium and XCode
         | 
| 1006 1205 | 
             
            on macOS. You must install Appium, XCode, and the iOS version-specific device simulators for XCode. Information about
         | 
| 1007 1206 | 
             
            Appium setup and configuration requirements with the XCUITest driver for testing on physically connected iOS devices can
         | 
| 1008 | 
            -
            be found on [this page](https://github.com/appium/appium-xcuitest-driver/blob/master/docs/real-device-config.md). Refer to [this page](https://appium.github.io/appium-xcuitest-driver/5.12/capabilities/) for information regarding specifying Appium capabilities that are
         | 
| 1207 | 
            +
            be found on [this page](https://github.com/appium/appium-xcuitest-driver/blob/master/docs/preparation/real-device-config.md). Refer to [this page](https://appium.github.io/appium-xcuitest-driver/5.12/capabilities/) for information regarding specifying Appium capabilities that are
         | 
| 1009 1208 | 
             
            specific to the XCUITest driver.
         | 
| 1010 1209 |  | 
| 1011 1210 | 
             
            ##### Local iOS Simulators or Physical Devices using Environment Variables
         | 
| @@ -439,7 +439,11 @@ module TestCentricity | |
| 439 439 | 
             
                    caps[:'appium:appActivity'] = ENV['APP_ACTIVITY'] if ENV['APP_ACTIVITY']
         | 
| 440 440 | 
             
                    caps[:'appium:appPackage'] = ENV['APP_PACKAGE'] if ENV['APP_PACKAGE']
         | 
| 441 441 | 
             
                    caps[:'appium:forceSimulatorSoftwareKeyboardPresence'] = ENV['SHOW_SIM_KEYBOARD'] if ENV['SHOW_SIM_KEYBOARD']
         | 
| 442 | 
            -
                     | 
| 442 | 
            +
                    if Environ.is_ios?
         | 
| 443 | 
            +
                      caps[:'appium:webviewConnectTimeout'] = 90000
         | 
| 444 | 
            +
                      caps[:'appium:maxTypingFrequency'] = 15
         | 
| 445 | 
            +
                      caps[:'appium:respectSystemAlerts'] = true
         | 
| 446 | 
            +
                    end
         | 
| 443 447 |  | 
| 444 448 | 
             
                    if ENV['BUNDLE_ID']
         | 
| 445 449 | 
             
                      caps[:'appium:bundleId'] = ENV['BUNDLE_ID']
         | 
| @@ -379,36 +379,34 @@ module TestCentricity | |
| 379 379 | 
             
                  url = if deep_link.include?("://")
         | 
| 380 380 | 
             
                          deep_link
         | 
| 381 381 | 
             
                        elsif !Environ.current.deep_link_prefix.blank?
         | 
| 382 | 
            -
                           | 
| 383 | 
            -
             | 
| 384 | 
            -
             | 
| 385 | 
            -
             | 
| 386 | 
            -
             | 
| 387 | 
            -
             | 
| 388 | 
            -
             | 
| 389 | 
            -
             | 
| 390 | 
            -
             | 
| 382 | 
            +
                          "#{Environ.current.deep_link_prefix}://#{deep_link}"
         | 
| 383 | 
            +
                        end
         | 
| 384 | 
            +
             | 
| 385 | 
            +
                  if Environ.is_android?
         | 
| 386 | 
            +
                    Environ.appium_driver.execute_script('mobile:deepLink', { url: url, package: Environ.current.android_app_id })
         | 
| 387 | 
            +
                  elsif Environ.is_ios?
         | 
| 388 | 
            +
                    if Environ.is_device? && Environ.device_os_version.to_f < 16.4
         | 
| 389 | 
            +
                      # launch Safari browser on iOS real device if iOS version is below 16.4
         | 
| 390 | 
            +
                      Environ.appium_driver.execute_script('mobile: launchApp', { bundleId: 'com.apple.mobilesafari' })
         | 
| 391 | 
            +
                      unless Environ.appium_driver.is_keyboard_shown
         | 
| 392 | 
            +
                        begin
         | 
| 393 | 
            +
                          # attempt to find and click URL button on iOS 15 Safari browser
         | 
| 394 | 
            +
                          find_element(:accessibility_id, 'TabBarItemTitle').click
         | 
| 395 | 
            +
                        rescue
         | 
| 396 | 
            +
                          # fall back to URL button on iOS 14 Safari browser
         | 
| 397 | 
            +
                          find_element(:xpath, '//XCUIElementTypeButton[@name="URL"]').click
         | 
| 391 398 | 
             
                        end
         | 
| 392 | 
            -
                  # deeplink handler for iOS devices
         | 
| 393 | 
            -
                  if Environ.is_ios? && Environ.is_device? && Environ.device_os_version.to_f < 16.4
         | 
| 394 | 
            -
                    # launch Safari browser on iOS real device if iOS version is below 16.4
         | 
| 395 | 
            -
                    Environ.appium_driver.execute_script('mobile: launchApp', { bundleId: 'com.apple.mobilesafari' })
         | 
| 396 | 
            -
                    unless Environ.appium_driver.is_keyboard_shown
         | 
| 397 | 
            -
                      begin
         | 
| 398 | 
            -
                        # attempt to find and click URL button on iOS 15 Safari browser
         | 
| 399 | 
            -
                        find_element(:accessibility_id, 'TabBarItemTitle').click
         | 
| 400 | 
            -
                      rescue
         | 
| 401 | 
            -
                        # fall back to URL button on iOS 14 Safari browser
         | 
| 402 | 
            -
                        find_element(:xpath, '//XCUIElementTypeButton[@name="URL"]').click
         | 
| 403 399 | 
             
                      end
         | 
| 400 | 
            +
                      # enter deep-link URL
         | 
| 401 | 
            +
                      wait_for_object(:xpath, '//XCUIElementTypeTextField[@name="URL"]', 5).send_keys("#{url}\uE007")
         | 
| 402 | 
            +
                      # wait for and accept the popup modal
         | 
| 403 | 
            +
                      wait_for_object(:xpath, '//XCUIElementTypeButton[@name="Open"]', 10).click
         | 
| 404 | 
            +
                    else
         | 
| 405 | 
            +
                      # iOS version is >= 16.4 so directly load screen via deepLink
         | 
| 406 | 
            +
                      Environ.appium_driver.get(url)
         | 
| 404 407 | 
             
                    end
         | 
| 405 | 
            -
                    # enter deep-link URL
         | 
| 406 | 
            -
                    wait_for_object(:xpath, '//XCUIElementTypeTextField[@name="URL"]', 5).send_keys("#{url}\uE007")
         | 
| 407 | 
            -
                    # wait for and accept the popup modal
         | 
| 408 | 
            -
                    wait_for_object(:xpath, '//XCUIElementTypeButton[@name="Open"]', 10).click
         | 
| 409 408 | 
             
                  else
         | 
| 410 | 
            -
                    #  | 
| 411 | 
            -
                    Environ.appium_driver.get(url)
         | 
| 409 | 
            +
                    raise "#{Environ.device_os} is not supported"
         | 
| 412 410 | 
             
                  end
         | 
| 413 411 | 
             
                  verify_screen_exists
         | 
| 414 412 | 
             
                end
         | 
| @@ -8,9 +8,16 @@ module TestCentricity | |
| 8 8 | 
             
                  def initialize(name, parent, locator, context)
         | 
| 9 9 | 
             
                    super
         | 
| 10 10 | 
             
                    @type = :list
         | 
| 11 | 
            -
                    @list_item = nil
         | 
| 12 | 
            -
                    @scrolling = :vertical
         | 
| 13 11 | 
             
                    @item_objects = nil
         | 
| 12 | 
            +
                    @scrolling = :vertical
         | 
| 13 | 
            +
                    @list_item = case Environ.device_os
         | 
| 14 | 
            +
                                 when :ios
         | 
| 15 | 
            +
                                   { class: 'XCUIElementTypeOther' }
         | 
| 16 | 
            +
                                 when :android
         | 
| 17 | 
            +
                                   { class: 'android.view.ViewGroup' }
         | 
| 18 | 
            +
                                 else
         | 
| 19 | 
            +
                                   nil
         | 
| 20 | 
            +
                                 end
         | 
| 14 21 | 
             
                  end
         | 
| 15 22 |  | 
| 16 23 | 
             
                  def define_list_elements(element_spec)
         | 
| @@ -163,9 +170,9 @@ module TestCentricity | |
| 163 170 | 
             
                  def get_list_item_locator
         | 
| 164 171 | 
             
                    if @list_item.nil?
         | 
| 165 172 | 
             
                      if Environ.device_os == :ios
         | 
| 166 | 
            -
                        define_list_elements({ :list_item => { class: ' | 
| 173 | 
            +
                        define_list_elements({ :list_item => { class: 'XCUIElementTypeOther' } } )
         | 
| 167 174 | 
             
                      else
         | 
| 168 | 
            -
                        define_list_elements({ :list_item => { class: 'android. | 
| 175 | 
            +
                        define_list_elements({ :list_item => { class: 'android.view.ViewGroup' } } )
         | 
| 169 176 | 
             
                      end
         | 
| 170 177 | 
             
                    end
         | 
| 171 178 | 
             
                    @list_item
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: testcentricity_mobile
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 4.0. | 
| 4 | 
            +
              version: 4.0.8
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - A.J. Mrozinski
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2024- | 
| 11 | 
            +
            date: 2024-06-03 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -128,14 +128,14 @@ dependencies: | |
| 128 128 | 
             
                requirements:
         | 
| 129 129 | 
             
                - - "~>"
         | 
| 130 130 | 
             
                  - !ruby/object:Gem::Version
         | 
| 131 | 
            -
                    version: 15. | 
| 131 | 
            +
                    version: 15.1.0
         | 
| 132 132 | 
             
              type: :runtime
         | 
| 133 133 | 
             
              prerelease: false
         | 
| 134 134 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 135 135 | 
             
                requirements:
         | 
| 136 136 | 
             
                - - "~>"
         | 
| 137 137 | 
             
                  - !ruby/object:Gem::Version
         | 
| 138 | 
            -
                    version: 15. | 
| 138 | 
            +
                    version: 15.1.0
         | 
| 139 139 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 140 140 | 
             
              name: childprocess
         | 
| 141 141 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -212,14 +212,14 @@ dependencies: | |
| 212 212 | 
             
                requirements:
         | 
| 213 213 | 
             
                - - '='
         | 
| 214 214 | 
             
                  - !ruby/object:Gem::Version
         | 
| 215 | 
            -
                    version: 4. | 
| 215 | 
            +
                    version: 4.21.1
         | 
| 216 216 | 
             
              type: :runtime
         | 
| 217 217 | 
             
              prerelease: false
         | 
| 218 218 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 219 219 | 
             
                requirements:
         | 
| 220 220 | 
             
                - - '='
         | 
| 221 221 | 
             
                  - !ruby/object:Gem::Version
         | 
| 222 | 
            -
                    version: 4. | 
| 222 | 
            +
                    version: 4.21.1
         | 
| 223 223 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 224 224 | 
             
              name: test-unit
         | 
| 225 225 | 
             
              requirement: !ruby/object:Gem::Requirement
         |