From 3ada41ce4594b1f914f8dc4bc5cdb1e6c9c7d9f7 Mon Sep 17 00:00:00 2001 From: Alan Egan Date: Mon, 15 Feb 2016 20:58:04 +0000 Subject: [PATCH 1/5] Adding text input command --- commands/FBTextInputCommands.py | 71 +++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 commands/FBTextInputCommands.py diff --git a/commands/FBTextInputCommands.py b/commands/FBTextInputCommands.py new file mode 100644 index 0000000..4f87991 --- /dev/null +++ b/commands/FBTextInputCommands.py @@ -0,0 +1,71 @@ +#!/usr/bin/python + +# Copyright (c) 2016, Facebook, Inc. +# All rights reserved. +# +# This source code is licensed under the BSD-style license found in the +# LICENSE file in the root directory of this source tree. An additional grant +# of patent rights can be found in the PATENTS file in the same directory. + +import os + +import lldb +import fblldbbase as fb +import fblldbviewhelpers as viewHelpers + +ACCESSIBILITY_ID = 0 +REPLACEMENT_TEXT = 1 + + +def lldbcommands(): + return [ + FBInputTextCommand(), + ] + + +class FBInputTextCommand(fb.FBCommand): + def name(self): + return 'input' + + def description(self): + return 'Input text into text field or text view by accessibility id.' + + def args(self): + return [ + fb.FBCommandArgument(arg='accessibilityId', type='string', help='The accessibility ID of the input view.'), + fb.FBCommandArgument(arg='replacementText', type='string', help='The text to set.') + ] + + def run(self, arguments, options): + rootView = fb.evaluateObjectExpression('[[UIApplication sharedApplication] keyWindow]') + self.findView(rootView, arguments[ACCESSIBILITY_ID], arguments[REPLACEMENT_TEXT]) + + def findView(self, view, searchIdentifier, replacementText): + views = self.subviewsOfView(view) + for index in range(0, self.viewsCount(views)): + subview = self.subviewAtIndex(views, index) + self.findView(subview, searchIdentifier, replacementText) + else: + identifier = self.accessibilityIdentifier(view) + if self.isEqualToString(identifier, searchIdentifier): + self.setTextInView(view, replacementText) + +# Some helpers + def subviewsOfView(self, view): + return fb.evaluateObjectExpression('[%s subviews]' % view) + + def subviewAtIndex(self, views, index): + return fb.evaluateObjectExpression('[%s objectAtIndex:%i]' % (views, index)) + + def viewsCount(self, views): + return int(fb.evaluateExpression('(int)[%s count]' % views)) + + def accessibilityIdentifier(self, view): + return fb.evaluateObjectExpression('[%s accessibilityIdentifier]' % view) + + def isEqualToString(self, identifier, needle): + return fb.evaluateBooleanExpression('[%s isEqualToString:@"%s"]' % (identifier, needle)) + + def setTextInView(self, view, text): + fb.evaluateObjectExpression('[%s setText:@"%s"]' % (view, text)) + viewHelpers.flushCoreAnimationTransaction() From 12a1e2fbe366df411eadea61d6c33a80e6ec8321 Mon Sep 17 00:00:00 2001 From: Alan Egan Date: Tue, 16 Feb 2016 12:34:03 +0000 Subject: [PATCH 2/5] Setting text on first responder with input command. Changing previous command to be setxt --- commands/FBTextInputCommands.py | 76 +++++++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/commands/FBTextInputCommands.py b/commands/FBTextInputCommands.py index 4f87991..b1ffcaf 100644 --- a/commands/FBTextInputCommands.py +++ b/commands/FBTextInputCommands.py @@ -15,20 +15,22 @@ ACCESSIBILITY_ID = 0 REPLACEMENT_TEXT = 1 +INPUT_TEXT = 0 def lldbcommands(): return [ - FBInputTextCommand(), + FBInputTexByAccessibilityIdCommand(), + FBInputTexToFirstResponderCommand(), ] -class FBInputTextCommand(fb.FBCommand): +class FBInputTexByAccessibilityIdCommand(fb.FBCommand): def name(self): - return 'input' + return 'setxt' def description(self): - return 'Input text into text field or text view by accessibility id.' + return 'Set text on text on a view by accessibility id.' def args(self): return [ @@ -37,35 +39,73 @@ def args(self): ] def run(self, arguments, options): - rootView = fb.evaluateObjectExpression('[[UIApplication sharedApplication] keyWindow]') - self.findView(rootView, arguments[ACCESSIBILITY_ID], arguments[REPLACEMENT_TEXT]) + self.findView(rootView(), arguments[ACCESSIBILITY_ID], arguments[REPLACEMENT_TEXT]) def findView(self, view, searchIdentifier, replacementText): - views = self.subviewsOfView(view) - for index in range(0, self.viewsCount(views)): - subview = self.subviewAtIndex(views, index) + views = subviewsOfView(view) + for index in range(0, viewsCount(views)): + subview = subviewAtIndex(views, index) self.findView(subview, searchIdentifier, replacementText) else: - identifier = self.accessibilityIdentifier(view) - if self.isEqualToString(identifier, searchIdentifier): - self.setTextInView(view, replacementText) + identifier = accessibilityIdentifier(view) + if isEqualToString(identifier, searchIdentifier): + setTextInView(view, replacementText) + + +class FBInputTexToFirstResponderCommand(fb.FBCommand): + def name(self): + return 'input' + + def description(self): + return 'Input text into text field or text view that is first responder.' + + def args(self): + return [ + fb.FBCommandArgument(arg='inputText', type='string', help='The text to input.') + ] + + def run(self, arguments, options): + self.findFirstResponder(rootView(), arguments[INPUT_TEXT]) + + def findFirstResponder(self, view, replacementText): + views = subviewsOfView(view) + for index in range(0, viewsCount(views)): + subview = subviewAtIndex(views, index) + self.findFirstResponder(subview, replacementText) + else: + if isFirstResponder(view): + setTextInView(view, replacementText) + # Some helpers - def subviewsOfView(self, view): +def rootView(): + return fb.evaluateObjectExpression('[[UIApplication sharedApplication] keyWindow]') + +def subviewsOfView(view): + if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(subviews)]' % view): return fb.evaluateObjectExpression('[%s subviews]' % view) - def subviewAtIndex(self, views, index): +def subviewAtIndex(views, index): + if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(objectAtIndex:)]' % views): return fb.evaluateObjectExpression('[%s objectAtIndex:%i]' % (views, index)) - def viewsCount(self, views): +def viewsCount(views): + if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(count)]' % views): return int(fb.evaluateExpression('(int)[%s count]' % views)) - def accessibilityIdentifier(self, view): +def accessibilityIdentifier(view): + if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(accessibilityIdentifier)]' % view): return fb.evaluateObjectExpression('[%s accessibilityIdentifier]' % view) - def isEqualToString(self, identifier, needle): +def isEqualToString(identifier, needle): + if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(isEqualToString:)]' % identifier): return fb.evaluateBooleanExpression('[%s isEqualToString:@"%s"]' % (identifier, needle)) - def setTextInView(self, view, text): +def setTextInView(view, text): + if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(setText:)]' % view): fb.evaluateObjectExpression('[%s setText:@"%s"]' % (view, text)) viewHelpers.flushCoreAnimationTransaction() + +def isFirstResponder(view): + if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(isFirstResponder)]' % view): + return fb.evaluateBooleanExpression('[%s isFirstResponder]' % view) From 018d61e8b9a3e6744fd9328bb9e9da7a643d2268 Mon Sep 17 00:00:00 2001 From: Alan Egan Date: Thu, 18 Feb 2016 20:17:02 +0000 Subject: [PATCH 3/5] responding to commends, removing guards --- commands/FBTextInputCommands.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/commands/FBTextInputCommands.py b/commands/FBTextInputCommands.py index b1ffcaf..4f92636 100644 --- a/commands/FBTextInputCommands.py +++ b/commands/FBTextInputCommands.py @@ -82,30 +82,23 @@ def rootView(): return fb.evaluateObjectExpression('[[UIApplication sharedApplication] keyWindow]') def subviewsOfView(view): - if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(subviews)]' % view): - return fb.evaluateObjectExpression('[%s subviews]' % view) + return fb.evaluateObjectExpression('[%s subviews]' % view) def subviewAtIndex(views, index): - if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(objectAtIndex:)]' % views): - return fb.evaluateObjectExpression('[%s objectAtIndex:%i]' % (views, index)) + return fb.evaluateObjectExpression('[%s objectAtIndex:%i]' % (views, index)) def viewsCount(views): - if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(count)]' % views): - return int(fb.evaluateExpression('(int)[%s count]' % views)) + return int(fb.evaluateExpression('(int)[%s count]' % views)) def accessibilityIdentifier(view): - if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(accessibilityIdentifier)]' % view): - return fb.evaluateObjectExpression('[%s accessibilityIdentifier]' % view) + return fb.evaluateObjectExpression('[%s accessibilityIdentifier]' % view) def isEqualToString(identifier, needle): - if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(isEqualToString:)]' % identifier): - return fb.evaluateBooleanExpression('[%s isEqualToString:@"%s"]' % (identifier, needle)) + return fb.evaluateBooleanExpression('[%s isEqualToString:@"%s"]' % (identifier, needle)) def setTextInView(view, text): - if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(setText:)]' % view): - fb.evaluateObjectExpression('[%s setText:@"%s"]' % (view, text)) - viewHelpers.flushCoreAnimationTransaction() + fb.evaluateObjectExpression('[%s setText:@"%s"]' % (view, text)) + viewHelpers.flushCoreAnimationTransaction() def isFirstResponder(view): - if fb.evaluateBooleanExpression('[%s respondsToSelector:@selector(isFirstResponder)]' % view): - return fb.evaluateBooleanExpression('[%s isFirstResponder]' % view) + return fb.evaluateBooleanExpression('[%s isFirstResponder]' % view) From 30e7cc64e74e28d39e8197ed8e008461477a32bf Mon Sep 17 00:00:00 2001 From: Alan Egan Date: Thu, 18 Feb 2016 20:25:48 +0000 Subject: [PATCH 4/5] move first responder check above loop --- commands/FBTextInputCommands.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/commands/FBTextInputCommands.py b/commands/FBTextInputCommands.py index 4f92636..13c1230 100644 --- a/commands/FBTextInputCommands.py +++ b/commands/FBTextInputCommands.py @@ -69,12 +69,12 @@ def run(self, arguments, options): def findFirstResponder(self, view, replacementText): views = subviewsOfView(view) - for index in range(0, viewsCount(views)): - subview = subviewAtIndex(views, index) - self.findFirstResponder(subview, replacementText) - else: - if isFirstResponder(view): + if isFirstResponder(view): setTextInView(view, replacementText) + else: + for index in range(0, viewsCount(views)): + subview = subviewAtIndex(views, index) + self.findFirstResponder(subview, replacementText) # Some helpers From 222708926d16e84b7c4a54bf942b8e9b9e2abc1a Mon Sep 17 00:00:00 2001 From: Alan Egan Date: Thu, 18 Feb 2016 20:28:28 +0000 Subject: [PATCH 5/5] changing command names --- commands/FBTextInputCommands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/FBTextInputCommands.py b/commands/FBTextInputCommands.py index 13c1230..ffbffa3 100644 --- a/commands/FBTextInputCommands.py +++ b/commands/FBTextInputCommands.py @@ -27,7 +27,7 @@ def lldbcommands(): class FBInputTexByAccessibilityIdCommand(fb.FBCommand): def name(self): - return 'setxt' + return 'settext' def description(self): return 'Set text on text on a view by accessibility id.' @@ -54,7 +54,7 @@ def findView(self, view, searchIdentifier, replacementText): class FBInputTexToFirstResponderCommand(fb.FBCommand): def name(self): - return 'input' + return 'setinput' def description(self): return 'Input text into text field or text view that is first responder.'