Troubleshooting Zoom out issue in Appium

Qxf2 has steadily been improving the mobile automation capabilities of our Test automation framework that wraps around Appium. We wanted to add support for the traditional pinch-to-zoom method in our framework. To achieve this, we used the SwagLabs as the application under test and developed this feature. In this post, we’ll discuss a particular challenge we faced with the zoom functionality on the SwagLabs application.

The issue:

While implementing the Zoom gestures, we encountered a problem with the Zoom out functionality. Despite the zoom in gesture working perfectly, the zoom out gesture failed to execute correctly, hindering our testing process and necessitating further investigation to identify the cause.
The following was our implementation of the Zoom out gesture

            #Perform zoom out
            actions = ActionChains(self.driver)
            finger1 = actions.w3c_actions.add_pointer_input('touch', 'finger1')
            finger2 = actions.w3c_actions.add_pointer_input('touch', 'finger2')
 
            finger1.create_pointer_move(x=center_x-400, y=center_y)
            finger1.create_pointer_down(button=MouseButton.LEFT)
            finger1.create_pause(0.5)
            finger1.create_pointer_move(x=center_x-100, y=center_y, duration=100)
            finger1.create_pointer_up(button=MouseButton.LEFT)
 
            finger2.create_pointer_move(x=center_x+400, y=center_y)
            finger2.create_pointer_down(button=MouseButton.LEFT)
            finger2.create_pause(0.5)
            finger2.create_pointer_move(x=center_x+100, y=center_y, duration=100)
            finger2.create_pointer_up(button=MouseButton.LEFT)
 
            actions.perform()

Quick Solution

TL;DR:
The zoom out gesture in the mobile test was not functioning correctly due to the insufficient pinch duration. By increasing the pinch duration from 100ms to 500ms, the issue was resolved.

            #Perform zoom
            actions = ActionChains(self.driver)
            finger1 = actions.w3c_actions.add_pointer_input('touch', 'finger1')
            finger2 = actions.w3c_actions.add_pointer_input('touch', 'finger2')
 
            finger1.create_pointer_move(x=center_x-400, y=center_y)
            finger1.create_pointer_down(button=MouseButton.LEFT)
            finger1.create_pause(0.5)
            finger1.create_pointer_move(x=center_x-100, y=center_y, duration=500)
            finger1.create_pointer_up(button=MouseButton.LEFT)
 
            finger2.create_pointer_move(x=center_x+400, y=center_y)
            finger2.create_pointer_down(button=MouseButton.LEFT)
            finger2.create_pause(0.5)
            finger2.create_pointer_move(x=center_x+100, y=center_y, duration=500)
            finger2.create_pointer_up(button=MouseButton.LEFT)
 
            actions.perform()

Detailed Walkthrough:

Here, is a walkthrough of how we arrived at the solution for those interested in reading further.

1. Understanding the Problem

As mentioned, the zoom in gesture was working flawlessly, while the zoom out gesture was not. This suggested that the issue was not with the overall implementation but with a specific detail in the zoom out logic.

Zoom gesture working fine
Zoom in gesture working fine

2. Initial Investigation

We began our investigation by comparing the zoom in and zoom out gesture implementations. Both gestures used similar logic, which initially led us to believe that the issue might lie in the coordinates or the sequence of actions.

3. Troubleshooting Steps

1. Coordinate Adjustment:
We experimented with different start and end coordinates for the pinch gesture, assuming that the initial coordinates might be incorrect or too abrupt. This did not resolve the issue, despite us manually figuring out the coordinates of the element to be zoomed and using those in the test.
This helped us confirm that coordinates was not the issue

2. Direction of Zoom:
Initially, we were zooming along the horizontal axis. We wanted to try zooming along the vertical axis and see if that made any difference.

 
            #Perform zoom
            actions = ActionChains(self.driver)
            finger1 = actions.w3c_actions.add_pointer_input('touch', 'finger1')
            finger2 = actions.w3c_actions.add_pointer_input('touch', 'finger2')
 
            finger1.create_pointer_move(y=center_y-400, y=center_y)
            finger1.create_pointer_down(button=MouseButton.LEFT)
            finger1.create_pause(0.5)
            finger1.create_pointer_move(y=center_y-100, y=center_y, duration=500)
            finger1.create_pointer_up(button=MouseButton.LEFT)
 
            finger2.create_pointer_move(y=center_+y400, y=center_y)
            finger2.create_pointer_down(button=MouseButton.LEFT)
            finger2.create_pause(0.5)
            finger2.create_pointer_move(y=center_y+100, y=center_y, duration=500)
            finger2.create_pointer_up(button=MouseButton.LEFT)
 
            actions.perform()

But unfortunately this didn’t work either

3. Gesture Sequence:
We reviewed the sequence of actions for zoom out gesture to ensure they were logically sound, which it was. But, we wanted to try our luck out anyways by mixing things up a bit like any good engineer (Just kidding), only to make matters worse. So we rolled back the changes and stared at the screen for some magic to happen(which did).

4. Key Discovery: Pinch Duration
While staring at the screen we got an idea to manually perform the zoom out gesture on the element we were testing. We attempted zooming out in different directions, zooming out slow, zooming out fast, zooming out really fast, and there, we found the culprit. The speed at which we zoomed out turned out to be the problem. The zoom gesture had a short duration of 100ms, which was too quick for the system to register as a valid zoom out action.

Implementing the Solution

By increasing the pinch duration from 100ms to 500ms, we allowed the gesture to be recognized as a deliberate, controlled action. This adjustment resolved the issue, enabling the zoom out gesture to function correctly.

Here is the complete method for the zoom out gesture after the fix was implemented:

    def zoom_out(self, zoom_element_locator):
        """
        Perform zoom out gesture.
        """
        try:
            #Get the element to be zoomed
            zoom_element = self.get_element(zoom_element_locator)
 
            #Get the zoom element location
            zoom_element_location = zoom_element.location
            zoom_x = zoom_element_location['x']
            zoom_y = zoom_element_location['y']
 
            #Get the zoom element size and center
            zoom_element_size = zoom_element.size
            center_x = zoom_x + zoom_element_size['width'] / 2
            center_y = zoom_y + zoom_element_size['height'] / 2
 
            #Perform zoom
            actions = ActionChains(self.driver)
            finger1 = actions.w3c_actions.add_pointer_input('touch', 'finger1')
            finger2 = actions.w3c_actions.add_pointer_input('touch', 'finger2')
 
            finger1.create_pointer_move(x=center_x-400, y=center_y)
            finger1.create_pointer_down(button=MouseButton.LEFT)
            finger1.create_pause(0.5)
            finger1.create_pointer_move(x=center_x-100, y=center_y, duration=500)
            finger1.create_pointer_up(button=MouseButton.LEFT)
 
            finger2.create_pointer_move(x=center_x+400, y=center_y)
            finger2.create_pointer_down(button=MouseButton.LEFT)
            finger2.create_pause(0.5)
            finger2.create_pointer_move(x=center_x+100, y=center_y, duration=500)
            finger2.create_pointer_up(button=MouseButton.LEFT)
 
            actions.perform()
 
            size_after_zoom = zoom_element.size
            if size_after_zoom != zoom_element_size:
                return True
            else:
                return False
 
        except Exception as e:
            self.write(str(e), 'debug')
            self.exceptions.append("An exception occured when zooming out")
Zoom out gesture fix
Zoom out working fine after increasing the pinch duration

Key Takeaways

  • Importance of Timing: Gesture recognition can be sensitive to timing. Ensuring an appropriate duration can make the difference between a failed and successful gesture.
  • Systematic Troubleshooting: Breaking down the problem and testing different parameters methodically can help identify subtle issues.
  • Stay tuned for our upcoming blog, where we’ll delve into the latest improvements to mobile testing within the Qxf2 Page Object Model framework. We’ll also guide you through the entire end-to-end test process for the Weather Shopper application.


    Hire technical QE from Qxf2

    Qxf2 is the home of the technical tester. Our testers have excellent testing fundamentals and advanced technical skills. This allows us to work with top development talent as well as collaborate with business facing folks. We are committed to open source software and sharing what we learn. Our own test automation framework has been open sourced and is used by over 150 companies all over the world. If you are looking to work with excellent testers who are technical, get in touch with us.


    Leave a Reply

    Your email address will not be published. Required fields are marked *