Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Shared UIA Element Channel #97

Merged
merged 4 commits into from
Nov 28, 2014
Merged

Conversation

krukow
Copy link
Contributor

@krukow krukow commented Nov 23, 2014

With iOS 8 there seems to be a race condition between UIAutomation and Calabash when writing to the shared preferences (NSUserDefaults). This means that occasionally we experience a missed read or write to the preferences from one of: the Preferences-based UIA channel, the UI Automation process itself or from the application itself writing to preferences (see, e.g.: calabash/calabash-ios#585).

With this pull request, a new type of Channel for communicating with UIAutomation from the Calabash Server is defined. The channel is called "Shared Element" because it consists of an UIKit object (LPSharedUIATextField) which is accessible to both UIAutomation and the CalabashServer (LPUIASharedElementChannel).

The main benefits are

  1. Avoid use of shared preferences (e.g., permanently Solves Intermittent timeouts performing gestures in Xcode 6.1 targeting iOS 8.1 simulators calabash-ios#585).
  2. Does not share anything with the application (private communication channel as opposed to NSUserDefaults).
  3. As fast as using preferences.
  4. Works on simulator and device.
  5. Simpler implementation which uses fewer CPU resources (no spin-loop in Calabash server, uses delegate/callbacks instead).

The trick that is used is to create a synchronized UITextField visible to UIAutomation and LPUIASharedElementChannel. When Calabash wants to send a command to UIAutomation, the setText method is called. When UIAutomation wants to send the reply back setValue is also called on the corresponding UIATextField object.

At first I did not like this solution (it has been discussed before) because in order for UIAutomation to get a reference to the UIATextField, it must be in the view hiearchy (potentially messing with the application view). Also calling setValue on a text field from UIAutomation would cause the keyboard to appear.

However, I realized that we can detach the UITextField from the key window as soon as LPUIASharedElementChannel and UIAutomation has made an initial handshake. After the handshake the textfield is a secret shared object that is not accessible to the application. Also if we set the textfield as enabled = 'NO' then the keyboard doesn't appear.

The high-level process is:

  1. Lazily create the LPSharedUIATextField when the first UIAutomation command arrives. At this time we know that the key window must be initialized.
  2. If this is the first command, do an initial handshake ([LPSharedUIATextField synchronizeWithUIAutomation] and await [LPSharedUIATextField isSynchronized]). Also, setup LPUIASharedElementChannel as the delegate of LPSharedUIATextField (the delegate will receive responses from UIAutomation) via a call-back (when [LPSharedUIATextField setText] is called).
  3. LPUIASharedElementChannel serializes the command as JSON and calls the [LPSharedUIATextField setText:] method. It then asynchronously awaits a response.
  4. UIAutomation spin-loops to get the request/command, executes it and writes the result (as JSON) back to LPSharedUIATextField using the setValue method of UIAutomation.
  5. The setValue method on UIA eventually triggers the setText: method of LPSharedUIATextField which parses the JSON can calls the delegate.

I've not done comprehensive testing but the initial results look good.

  • We need to test for stability in long-running suites and interaction with other UIAutomation features.
  • We also need to test on other iOS versions (I've only tested latests (iOS 8.1)).
  • Code review (@jmoody)

NOTE

Requires run_loop 1.1.1.pre4 and using the new :uia_strategy: :shared_element.

@krukow
Copy link
Contributor Author

krukow commented Nov 28, 2014

Merging this now. Will keep working with this.

krukow added a commit that referenced this pull request Nov 28, 2014
@krukow krukow merged commit da39bef into develop Nov 28, 2014
@krukow krukow deleted the uia-strategy-shared-element branch November 28, 2014 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant