Skip to content

Commit de62fe8

Browse files
authored
Seems UI is still hopping between legacy msa ui and fluent ui, changes to support both, Fixes AB#3246594 (#2634)
It seems that the fluent ui at the time of writing this PR (4/29/2025) is still not fully complete, some manual testing showed that the legacy ui and fluent ui are still appearing at random points. This PR will make a change using regex to support both UI's and pass the test regardless of which UI we get. [AB#3246594](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3246594)
1 parent 346bae9 commit de62fe8

2 files changed

Lines changed: 80 additions & 7 deletions

File tree

uiautomationutilities/src/main/java/com/microsoft/identity/client/ui/automation/interaction/microsoftsts/AadLoginComponentHandler.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class AadLoginComponentHandler implements IMicrosoftStsLoginComponentHand
5858
private final long mFindLoginUiElementTimeout;
5959

6060
public AadLoginComponentHandler() {
61-
mFindLoginUiElementTimeout = CommonUtils.FIND_UI_ELEMENT_TIMEOUT_SHORT;
61+
mFindLoginUiElementTimeout = CommonUtils.FIND_UI_ELEMENT_TIMEOUT;
6262
}
6363

6464
/**
@@ -74,22 +74,21 @@ public void handleEmailField(@NonNull final String username) {
7474
UiAutomatorUtils.handleInput("i0116", username, mFindLoginUiElementTimeout);
7575
handleNextButton();
7676
} catch (AssertionError e) {
77-
// If we can't find email field, we can try without resource id
78-
UiAutomatorUtils.handleInputByClass("android.widget.EditText", username);
77+
UiAutomatorUtils.handleInputByClass("android.widget.EditText", username, mFindLoginUiElementTimeout);
7978
handleNextButtonByText();
8079
}
8180
}
8281

8382
@Override
8483
public void handlePasswordField(@NonNull final String password) {
8584
Logger.i(TAG, "Handle Aad Login Password UI..");
85+
UiAutomatorUtils.obtainUiObjectWithText("password", mFindLoginUiElementTimeout);
8686
try {
87+
UiAutomatorUtils.handleInputByClass("android.widget.EditText", password, mFindLoginUiElementTimeout);
88+
handleNextOrSignInButtonByRegex();
89+
} catch (AssertionError e) {
8790
UiAutomatorUtils.handleInput("i0118", password, mFindLoginUiElementTimeout);
8891
handleNextButton();
89-
} catch (AssertionError e) {
90-
// If we can't find password field, we can try without resource id
91-
UiAutomatorUtils.handleInputByClass("android.widget.EditText", password);
92-
handleSignInButtonByText();
9392
}
9493
}
9594

@@ -119,6 +118,10 @@ public void handleRegistrationButton() {
119118
UiAutomatorUtils.handleButtonClickForObjectWithExactText("Register");
120119
}
121120

121+
public void handleNextOrSignInButtonByRegex() {
122+
UiAutomatorUtils.handleButtonClickForObjectWithRegexMatch("Next|Sign in");
123+
}
124+
122125
@Override
123126
public void handleAccountPicker(@NonNull final String username) {
124127
Logger.i(TAG, "Handle Account Picker UI..");

uiautomationutilities/src/main/java/com/microsoft/identity/client/ui/automation/utils/UiAutomatorUtils.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,30 @@ public static UiObject obtainUiObjectWithText(@NonNull final String text, final
127127
);
128128
}
129129

130+
/**
131+
* Obtain an instance of the UiObject with text matching given regex.
132+
*
133+
* @param regex the regex pattern to match
134+
* @return the UiObject associated to the supplied regex
135+
*/
136+
public static UiObject obtainUiObjectWithRegex(@NonNull final String regex) {
137+
Logger.i(TAG, "Obtain an instance of the UiObject with regex pattern:" + regex);
138+
return obtainUiObjectWithRegex(regex, FIND_UI_ELEMENT_TIMEOUT);
139+
}
140+
141+
/**
142+
* Obtain an instance of the UiObject with text matching given regex.
143+
*
144+
* @param regex the regex pattern to match
145+
* @param existsTimeout time to wait until ui object with text exists.
146+
* @return the UiObject associated to the supplied regex
147+
*/
148+
public static UiObject obtainUiObjectWithRegex(@NonNull final String regex, final long existsTimeout) {
149+
Logger.i(TAG, "Obtain an instance of the UiObject with regex pattern:" + regex);
150+
return obtainUiObjectWithUiSelector(new UiSelector().textMatches(regex),
151+
existsTimeout);
152+
}
153+
130154
/**
131155
* Obtain an instance of the UiObject for the given text.
132156
*
@@ -164,6 +188,18 @@ public static UiObject obtainUiObjectWithClass(@NonNull final String clazz) {
164188
FIND_UI_ELEMENT_TIMEOUT);
165189
}
166190

191+
/**
192+
* Obtain an instance of the UiObject for the class.
193+
*
194+
* @param clazz the class name of the element to obtain
195+
* @return the UiObject associated to the supplied text
196+
*/
197+
public static UiObject obtainUiObjectWithClass(@NonNull final String clazz, final long existsTimeout) {
198+
Logger.i(TAG, "Obtain an instance of the UiObject with class name:" + clazz);
199+
return obtainUiObjectWithUiSelector(new UiSelector().className(clazz),
200+
existsTimeout);
201+
}
202+
167203
/**
168204
* Obtain an instance of the UiObject for a given resource id.
169205
*
@@ -327,6 +363,27 @@ public static void handleInputByClass(@NonNull final String clazz,
327363
}
328364
}
329365

366+
/**
367+
* Fills the supplied text into the input element of a given class.
368+
*
369+
* @param clazz classname of the object to give input
370+
* @param inputText the text to enter
371+
* @param existsTimeout how long to wait for object to exist
372+
*/
373+
public static void handleInputByClass(@NonNull final String clazz,
374+
@NonNull final String inputText,
375+
final long existsTimeout) {
376+
Logger.i(TAG, "Handling input for class: " + clazz);
377+
final UiObject inputField = obtainUiObjectWithClass(clazz, existsTimeout);
378+
379+
try {
380+
inputField.setText(inputText);
381+
closeKeyboardIfNeeded();
382+
} catch (final UiObjectNotFoundException e) {
383+
throw new AssertionError(e);
384+
}
385+
}
386+
330387
/**
331388
* Clicks the button element associated to the supplied resource id.
332389
*
@@ -455,6 +512,19 @@ public static void handleButtonClickForObjectWithTextSafely(@NonNull final Strin
455512
}
456513
}
457514

515+
/**
516+
* Clicks the button element that contains text matching the supplied regex
517+
*/
518+
public static void handleButtonClickForObjectWithRegexMatch(@NonNull final String regex) {
519+
final UiObject button = obtainUiObjectWithRegex(regex);
520+
521+
try {
522+
button.click();
523+
} catch (final UiObjectNotFoundException e) {
524+
Logger.w(TAG, "Button with regex \"" + regex + "\" was not found: " + e.getMessage());
525+
}
526+
}
527+
458528
/**
459529
* Presses the device back button on the Android device.
460530
*/

0 commit comments

Comments
 (0)