Compare commits

...

2 Commits

Author SHA1 Message Date
Tushar Vats
4ec8f81768 fix(tests): wait until the browser has left the idp before returning from idp_login
Leaving the login page is not enough: keycloak's SAML flow returns an
auto-submitting interstitial on the idp host, and the POST it fires is what
actually creates the user in signoz. Returning at the interstitial let tests
query the user before the callback ran — flaky "user not found" in
test_idp_initiated_saml_authn.

Compare hosts instead of full URLs: intra-keycloak hops (login-actions, the
interstitial, a re-rendered form on bad credentials) keep waiting; the wait
ends only once signoz has handled the callback and redirected.
2026-08-04 20:02:36 +05:30
Tushar Vats
0fc257c4c6 fix(tests): make idp_login post-click wait robust to mid-navigation detached nodes
EC.invisibility_of_element re-resolves kc-login and then calls is_displayed()
on it; a same-site document swap between those two calls surfaces as a raw
WebDriverException ("Node with given id does not belong to the document")
that the expected condition does not swallow, failing the wait.

Wait for the navigation instead: URL moved off the login page and kc-login
absent, retrying the poll on any WebDriverException. Bad credentials still
time out (keycloak re-renders the form with kc-login present).

Reproduced 3/400 logins with the old wait, 0/400 with the new one
(chrome 151.0.7922.71, same-site redirect, think time near the poll boundary).
2026-08-04 19:33:46 +05:30

14
tests/fixtures/idp.py vendored
View File

@@ -7,6 +7,7 @@ import pytest
import requests
from keycloak import KeycloakAdmin
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
@@ -370,11 +371,20 @@ def idp_login(driver: webdriver.Chrome) -> Callable[[str, str], None]:
password_field.send_keys(password)
# Click the login button
idp_host = urlparse(driver.current_url).netloc
login_button = wait.until(EC.element_to_be_clickable((By.ID, "kc-login")))
login_button.click()
# Wait till kc-login element has vanished from the page, which means that a redirection is taking place.
wait.until(EC.invisibility_of_element((By.ID, "kc-login")))
# Wait till the browser has left the idp host — not just the login page: keycloak's SAML flow inserts an
# auto-submitting interstitial on the idp whose POST is what creates the user in signoz. The button is
# re-queried per poll; a mid-navigation WebDriverException (detached node) just retries the poll.
def _left_idp(drv: webdriver.Chrome) -> bool:
try:
return urlparse(drv.current_url).netloc != idp_host and not drv.find_elements(By.ID, "kc-login")
except WebDriverException:
return False
wait.until(_left_idp)
return _idp_login