Skip to content

Commit 01133e7

Browse files
jongyoulclaude
andcommitted
fix(integration): fix login race conditions in Selenium integration tests
The Selenium test InterpreterModeActionsIT.testPerUserIsolatedAction fails intermittently due to multiple race conditions in the login flow: 1. Pre-existing modal backdrop blocks navbar Login button click. Fixed by dismissing any modal/backdrop via JS before starting. 2. sendKeys may not populate the field if Angular hasn't finished initializing the form. Fixed by falling back to JavaScript-based value injection with Angular input event trigger. 3. After login, wait for the user dropdown to appear (proves login succeeded and DOM updated) instead of waiting for modal invisibility which can race with Angular's digest cycle. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 33214d4 commit 01133e7

1 file changed

Lines changed: 47 additions & 3 deletions

File tree

zeppelin-integration/src/test/java/org/apache/zeppelin/AbstractZeppelinIT.java

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,61 @@ abstract public class AbstractZeppelinIT {
5151
protected static final long MAX_PARAGRAPH_TIMEOUT_SEC = 120;
5252

5353
protected void authenticationUser(String userName, String password) {
54+
// Dismiss any pre-existing modal backdrop that may block clicks
55+
try {
56+
((JavascriptExecutor) manager.getWebDriver()).executeScript(
57+
"document.querySelectorAll('.modal-backdrop').forEach(e => e.remove());"
58+
+ "$('#loginModal').modal('hide');");
59+
ZeppelinITUtils.sleep(500, false);
60+
} catch (Exception e) {
61+
// ignore if jQuery/Bootstrap not ready
62+
}
63+
5464
clickableWait(
5565
By.xpath("//div[contains(@class, 'navbar-collapse')]//li//button[contains(.,'Login')]"),
5666
MAX_BROWSER_TIMEOUT_SEC).click();
5767

58-
visibilityWait(By.xpath("//*[@id='userName']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(userName);
59-
visibilityWait(By.xpath("//*[@id='password']"), MAX_BROWSER_TIMEOUT_SEC).sendKeys(password);
68+
WebElement userNameField = visibilityWait(By.xpath("//*[@id='userName']"), MAX_BROWSER_TIMEOUT_SEC);
69+
userNameField.clear();
70+
userNameField.sendKeys(userName);
71+
72+
WebElement passwordField = visibilityWait(By.xpath("//*[@id='password']"), MAX_BROWSER_TIMEOUT_SEC);
73+
passwordField.clear();
74+
passwordField.sendKeys(password);
75+
76+
// Verify credentials were entered before submitting — use JS as a fallback
77+
ZeppelinITUtils.sleep(300, false);
78+
String enteredUser = userNameField.getAttribute("value");
79+
if (enteredUser == null || enteredUser.isEmpty()) {
80+
((JavascriptExecutor) manager.getWebDriver()).executeScript(
81+
"document.getElementById('userName').value = arguments[0];"
82+
+ "angular.element(document.getElementById('userName')).triggerHandler('input');",
83+
userName);
84+
((JavascriptExecutor) manager.getWebDriver()).executeScript(
85+
"document.getElementById('password').value = arguments[0];"
86+
+ "angular.element(document.getElementById('password')).triggerHandler('input');",
87+
password);
88+
ZeppelinITUtils.sleep(200, false);
89+
}
90+
6091
clickableWait(
6192
By.xpath("//*[@id='loginModalContent']//button[contains(.,'Login')]"),
6293
MAX_BROWSER_TIMEOUT_SEC).click();
6394

64-
ZeppelinITUtils.sleep(1000, false);
95+
// Wait for the logged-in navbar user dropdown to appear
96+
visibilityWait(
97+
By.xpath("//div[contains(@class, 'navbar-collapse')]//li//button[contains(@class, 'nav-btn dropdown-toggle ng-scope')]"),
98+
MAX_BROWSER_TIMEOUT_SEC);
99+
100+
// Dismiss any lingering modal backdrop via JavaScript
101+
try {
102+
((JavascriptExecutor) manager.getWebDriver()).executeScript(
103+
"document.querySelectorAll('.modal-backdrop').forEach(e => e.remove());"
104+
+ "$('#loginModal').modal('hide');");
105+
} catch (Exception e) {
106+
// ignore if jQuery/Bootstrap not ready
107+
}
108+
ZeppelinITUtils.sleep(500, false);
65109
}
66110

67111
protected void logoutUser(String userName) throws URISyntaxException {

0 commit comments

Comments
 (0)