Support sunset sync promo for RemoveAllAccounts & RemoveAccounts action
Bug:40283739,40255960
This changes the fix supports
1. Support new sunset sync promos and label changes
2. Supports new flow to remove signed in accounts
No-Try:true
No-Presubmit: true
Change-Id: I6998b71cc0d207dd5c9cb304f9f129ddfeb987eb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/tools/franky/+/6218102
Commit-Queue: Himabindu Vedantam <himabinduv@chromium.org>
Reviewed-by: Lindsay Pasricha <lindsayw@chromium.org>
Reviewed-by: Yue She <yueshe@google.com>
diff --git a/franky/actions/settings.py b/franky/actions/settings.py
index 428afb0..58bf8fb 100644
--- a/franky/actions/settings.py
+++ b/franky/actions/settings.py
@@ -49,14 +49,15 @@
_ACCOUNT_SIGNOUT_CELL_PATH = 'kSettingsAccountsTableViewId'
_ACCOUNT_CELL_PATH = 'kSettingsAccountCellId'
_SIGNIN_CELL_PATH = 'kSettingsSignInCellId'
-_SIGNIN_CELL_PROMO_PATH = 'kSigninPromoViewId'
+_IOS_CONTINUE_AS_BUTTON_PATH= 'WebSigninPrimaryButtonAccessibilityIdentifier'
+_SIGNIN_CELL_PROMO_PATH = '//XCUIElementTypeTable[@name="kSettingsTableViewId"]/XCUIElementTypeCell[1]'
_CLOSE_BUTTON_PATH = 'ic_close'
_COLLECTIONVIEW_PATH = 'kSettingsTableViewId'
_HISTORY_PATH = 'History'
_IMPORT_DATA_CELL_PATH = 'kImportDataKeepSeparateCellId'
_PASSWORD_PATH = 'Enter your password'
_PRIVACY_CELL_PATH = 'kSettingsPrivacyCellId'
-_REMOVE_BUTTON_PATH = 'Remove'
+_REMOVE_BUTTON_PATH = 'RemoveAlertAction'
_SETTINGS_CELL_PATH = 'Settings'
_USERNAME_PATH = 'Email or phone'
@@ -64,8 +65,8 @@
'//XCUIElementTypeTable["kSettingsTableViewId"]/'
'XCUIElementTypeCell[1]')
_IOS_GOT_IT_BUTTON_PATH = 'Ok, Got it'
-_IOS_YES_IMIN_BUTTTON_PATH = "kConfirmationAccessibilityIdentifier"
-_IOS_CONTINUE_BUTTON_PATH = 'Continue'
+_IOS_YES_IMIN_BUTTTON_PATH= "PromoStylePrimaryActionAccessibilityIdentifier"
+_IOS_CONTINUE_BUTTON_PATH = 'kImportDataContinueButtonId'
_IOS_NEXT_BUTTON_PATH = '(//XCUIElementTypeButton[@name="Next"])[1]'
_IOS_FIRST_SETTINGS_ACCOUNT_CELL_PATH = (
'//XCUIElementTypeTable["kSettingsAccountsTableViewId"]//'
@@ -166,175 +167,42 @@
tap.IOSTap().TapOnElementByID(driver_provider, _IOS_CONTINUE_BUTTON_PATH)
def RemoveAllAccounts(self, driver_provider, unused_step):
- loop_count = 0
- while loop_count < 20:
- loop_count += 1
- time.sleep(1)
- pagesource = driver_provider.driver.page_source
- tree = ET.fromstring(pagesource.encode('utf-8'))
- #Check if screen contains SignInPromo:
- xpath = './/XCUIElementTypeOther[@name="'+ _SIGNIN_CELL_PROMO_PATH +'"]'
- ele = tree.findall(xpath)
- #Check if the element is present in the XMLTree.
- #On IPads SignIn Promo is always Present but not Visible if the screen
- # is in background.
- if ele and ele[0].attrib['visible'] == 'true':
- promo_cell_element = element.IOSElement().GetElementsByID(
- driver_provider, _SIGNIN_CELL_PROMO_PATH)[0]
- x = promo_cell_element.size.get('width') * 0.5
- y = promo_cell_element.size.get('height') * 0.8
- tap.IOSTap().TapWithOptions(driver_provider,
- promo_cell_element, x, y)
- continue
- #Check If Unified Consent Screen is present
- xpath = './/*[@name="kUnifiedConsentScrollViewIdentifier"]'
- ele = tree.findall(xpath)
+ # Check if screen contains SignInPromo:
+ ele = element.IOSElement().IsElementBySeleniumLocatorPresent(
+ driver_provider, 'id', _SIGNIN_CELL_PATH, timeout_util.WAIT_FOR_PRESENCE_TIMEOUT)
if ele:
- # If "ADD ACCOUNT button is present that means there are no accounts
- # present on the device.
- # Tap Cancel to Dismiss the screen and exit while loop.
- add_account_xpath = './/*[@name="kAddAccountAccessibilityIdentifier"]'
- add_account_element = tree.findall(add_account_xpath)
- if add_account_element:
- tap.IOSTap().TapOnElementByID(driver_provider, 'kSkipSigninAccessibilityIdentifier')
- return
- #If accounts are present on the device, the Choose an account UI
- # is displayed.
- choose_account_xpath = './/*[@name="Choose an Account"]'
- choose_account_element = tree.findall(choose_account_xpath)
- if choose_account_element:
- tap.IOSTap().TapOnElementByXPATH(driver_provider, '//XCUIElementTypeCell[1]')
- tap.IOSTap().TapOnElementByID(driver_provider, "kConfirmationAccessibilityIdentifier")
- continue
- #If the user is already singed in.
- xpath = './/*[@name="' + _ACCOUNT_CELL_PATH + '"]'
- ele = tree.findall(xpath)
- if ele and ele[0].attrib['visible'] == 'true':
- tap.IOSTap().TapOnElementByID(driver_provider, _ACCOUNT_CELL_PATH)
- continue
- # Tap on Sign into Chrome cell if the user is not signed in.
- # Handles a case with New Sign In Promo is not displayed.
- xpath = './/*[@name="' +_SIGNIN_CELL_PATH +'"]'
- ele = tree.findall(xpath)
- if ele and ele[0].attrib['visible'] == 'true':
- tap.IOSTap().TapOnElementByID(driver_provider, _SIGNIN_CELL_PATH)
- continue
-
- # All accounts are removed if Chrome Sign in screen is found.
- # This is old flow (Without Unified Consent)
- xpath = './/*[@name="' +_USERNAME_PATH +'"]'
- ele = tree.findall(xpath)
- if ele and ele[0].attrib['visible'] == 'true':
- tap.IOSTap().TapOnElementByIDAtIndex(driver_provider,
- _CLOSE_BUTTON_PATH, index=-1)
- return
- # User could be redirected to Chrome account info screen after taping
- # on first cell on Settings screen if user was previously signed into
- # Chrome.
- xpath = './/*[@name="' + _ACCOUNT_SIGNOUT_CELL_PATH + '"]'
- ele = tree.findall(xpath)
- if ele and ele[0].attrib['visible'] == 'true':
- self._RemoveFirstAccount(driver_provider)
- continue
-
- # Tap Continue button if displayed. OLD UI Case:
- xpath = './/*[@name="'+_IOS_CONTINUE_BUTTON_PATH+'"]'
- ele = tree.findall(xpath)
- if ele:
- tap.IOSTap().TapOnElementByID(driver_provider,
- _IOS_CONTINUE_BUTTON_PATH)
- continue
-
- # Tap OK, Got It if displayed. OLD UI Case:
- xpath = './/*[@name="'+_IOS_GOT_IT_BUTTON_PATH+'"]'
- ele = tree.findall(xpath)
- if ele:
- tap.IOSTap().TapOnElementByID(driver_provider,
- _IOS_GOT_IT_BUTTON_PATH)
- tap.IOSTap().TapOnElementByXPATH(driver_provider,
- _FIRST_COLLECTION_CELL_PATH)
- self._RemoveFirstAccount(driver_provider)
- continue
-
- # Handle import data flow.
- xpath = './/*[@name="' + _IMPORT_DATA_CELL_PATH + '"]'
- ele = tree.findall(xpath)
- if ele and ele[0].attrib['visible'] == 'true':
- tap.IOSTap().TapOnElementByID(driver_provider,
- _IMPORT_DATA_CELL_PATH)
- tap.IOSTap().TapOnElementByID(driver_provider,
- _IOS_CONTINUE_BUTTON_PATH)
- #http://crbug/958823 Unified Consent with screen doesn't
- # disable background elements. So wait few seconds before continue.
- time.sleep(3)
- continue
-
- raise action_error.TooManyElementsFoundError(
- 'Exceeded loop count when trying to remove all accounts.')
-
- # TODO(crbug/959903): Remove this method later.
- def RemoveAllAccounts_OLD(self, driver_provider, unused_step):
- """See description in base class.
-
- Args:
- driver_provider: An instance of DriverProvider class.
- unused_step: A Step tuple.
-
- Raises:
- TooManyElementsFoundError: Excessive looping trying to remove accounts.
- """
- # Remove accounts from Chrome one by one until all are gone.
- loop_count = 0
- while loop_count < 25:
- loop_count += 1
- if element.IOSElement().IsElementBySeleniumLocatorPresent(
- driver_provider, step_module.ID, _COLLECTIONVIEW_PATH, _TIMEOUT):
- # Tap on the account cell if the user is signed in.
- if element.IOSElement().IsElementBySeleniumLocatorPresent(
- driver_provider, step_module.ID, _ACCOUNT_CELL_PATH, _TIMEOUT):
- tap.IOSTap().TapOnElementByID(driver_provider, _ACCOUNT_CELL_PATH)
- # If the new sign in Promo is displayed.
- elif element.IOSElement().IsElementBySeleniumLocatorPresent(
- driver_provider, step_module.ID, _SIGNIN_CELL_PROMO_PATH, _TIMEOUT):
- promo_cell_element = element.IOSElement().GetElementsByID(
- driver_provider, _SIGNIN_CELL_PROMO_PATH)[0]
- x = promo_cell_element.size.get('width') * 0.5
- y = promo_cell_element.size.get('height') * 0.8
- tap.IOSTap().TapWithOptions(driver_provider, promo_cell_element, x, y)
- # Tap on Sign in to Chrome cell if the user is not signed in.
- else:
tap.IOSTap().TapOnElementByID(driver_provider, _SIGNIN_CELL_PATH)
- # All accounts are removed if Chrome Sign in screen is found.
- if element.IOSElement().IsElementBySeleniumLocatorPresent(
- driver_provider, step_module.ID, _USERNAME_PATH,
- timeout_util.WAIT_FOR_PRESENCE_TIMEOUT):
- tap.IOSTap().TapOnElementByIDAtIndex(
- driver_provider, _CLOSE_BUTTON_PATH, index=-1)
- return
- # User could be redirected to Chrome account info screen after taping on
- # first cell on Settings screen if user was previously signed into Chrome.
- if element.IOSElement().IsElementBySeleniumLocatorPresent(
- driver_provider, step_module.ID, _ACCOUNT_SIGNOUT_CELL_PATH,
- _TIMEOUT):
- self._RemoveFirstAccount(driver_provider)
- # User could be redirected to Sign in screen after taping on the first
- # cell on Settings screen if user was previously signed out of Chrome.
- else:
- tap.IOSTap().TapOnElementByID(driver_provider,
- _IOS_CONTINUE_BUTTON_PATH)
- # Handle import data flow.
- if element.IOSElement().IsElementBySeleniumLocatorPresent(
- driver_provider, step_module.ID, _IMPORT_DATA_CELL_PATH, _TIMEOUT):
- tap.IOSTap().TapOnElementByID(driver_provider, _IMPORT_DATA_CELL_PATH)
- tap.IOSTap().TapOnElementByID(driver_provider,
- _IOS_CONTINUE_BUTTON_PATH)
- # Carry on with Sign in flow.
- tap.IOSTap().TapOnElementByID(driver_provider, _IOS_GOT_IT_BUTTON_PATH)
- tap.IOSTap().TapOnElementByXPATH(driver_provider,
- _FIRST_COLLECTION_CELL_PATH)
- self._RemoveFirstAccount(driver_provider)
- raise action_error.TooManyElementsFoundError(
- 'Exceeded loop count when trying to remove all accounts.')
+ # If accounts are present on the device, then sign in to chrome prompt
+ # is displayed.
+ continue_as = element.IOSElement().IsElementBySeleniumLocatorPresent(
+ driver_provider, 'id', _IOS_CONTINUE_AS_BUTTON_PATH, timeout_util.WAIT_FOR_PRESENCE_TIMEOUT)
+ if continue_as:
+ tap.IOSTap().TapOnElementByID(driver_provider, _IOS_CONTINUE_AS_BUTTON_PATH)
+ tap.IOSTap().TapOnElementByID(driver_provider, _IOS_YES_IMIN_BUTTTON_PATH)
+ time.sleep(2)
+ # if user already signed in
+ ele = element.IOSElement().IsElementBySeleniumLocatorPresent(
+ driver_provider, 'id', _ACCOUNT_CELL_PATH, timeout_util.WAIT_FOR_PRESENCE_TIMEOUT)
+ if ele:
+ tap.IOSTap().TapOnElementByXPATH(driver_provider, _SIGNIN_CELL_PROMO_PATH)
+ screen_element = element.IOSElement().GetElementBySeleniumLocator(driver_provider, 'id',
+ 'ManageSyncTableViewAccessibilityIdentifier',
+ timeout=None)
+ scroll.IOSScroll().DragInsideWithOptions(driver_provider,
+ screen_element, step_module.Point(0.5, 0.9),
+ step_module.Point(0.5, 0.1), 2000)
+ time.sleep(1)
+ tap.IOSTap().TapOnElementByXPATH(driver_provider,
+ '//XCUIElementTypeCell[@name="Manage accounts on this device…"]')
+ self._RemoveAccounts(driver_provider)
+ time.sleep(1)
+ return
+ # If no accounts are available in device
+ if element.IOSElement().IsElementBySeleniumLocatorPresent(driver_provider, 'id', 'Create account',
+ timeout_util.WAIT_FOR_PRESENCE_TIMEOUT):
+ tap.IOSTap().TapOnElementByID(driver_provider, 'close')
+ return
+ raise action_error.TooManyElementsFoundError('Failed to remove all accounts')
def TapOnFirstAccountInSettingsAccounts(self, driver_provider, unused_step):
"""See description in base class.
@@ -364,17 +232,24 @@
tap.IOSTap().TapOnElementByID(driver_provider, 'Delete browsing dataAlertAction')
time.sleep(3)
- def _RemoveFirstAccount(self, driver_provider):
- """Removes the first account from Chrome account info screen.
+ def _RemoveAccounts(self, driver_provider):
+ """Removes all accounts from Chrome account info screen.
Args:
driver_provider: An instance of DriverProvider class.
"""
- self.TapOnFirstAccountInSettingsAccounts(driver_provider, unused_step=None)
time.sleep(1)
- tap.IOSTap().TapOnElementByID(driver_provider, 'Remove Account from this Device')
- tap.IOSTap().TapOnElementByID(driver_provider, _REMOVE_BUTTON_PATH)
- time.sleep(1)
+ accounts = element.IOSElement().GetElementsByID(
+ driver_provider, 'chevron')
+ allaccounts = len(accounts)
+ for account in accounts:
+ tap.IOSTap().TapOnElementByXPATH(driver_provider,
+ '(//XCUIElementTypeTable["SettingsAccountsTableViewId"]/XCUIElementTypeCell[' +
+ str(allaccounts) + '])[2]', timeout_util.WAIT_FOR_PRESENCE_TIMEOUT)
+ tap.IOSTap().TapOnElementByID(driver_provider, 'Remove from this deviceAlertAction')
+ tap.IOSTap().TapOnElementByID(driver_provider, _REMOVE_BUTTON_PATH)
+ time.sleep(1)
+ allaccounts = allaccounts - 1
class AndroidSettings(Settings):