From 2bbedd083d6c436bb922a402a85cb1df31785016 Mon Sep 17 00:00:00 2001 From: lucasew Date: Wed, 1 Jul 2026 15:02:25 -0300 Subject: [PATCH] cockpit: deal with data races in tests Signed-off-by: lucasew Assisted-by: Grok (xAI) --- nixos/tests/cockpit.nix | 57 ++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/nixos/tests/cockpit.nix b/nixos/tests/cockpit.nix index 6144450d3469..1bce4e584c06 100644 --- a/nixos/tests/cockpit.nix +++ b/nixos/tests/cockpit.nix @@ -102,7 +102,6 @@ in from selenium.webdriver.firefox.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC - from time import sleep def log(msg): @@ -129,7 +128,7 @@ in wait.until(EC.presence_of_element_located((by, query))) - def wait_title_contains(title, timeout=10): + def wait_title_contains(title, timeout=30): wait = WebDriverWait(driver, timeout) wait.until(EC.title_contains(title)) @@ -138,11 +137,6 @@ in return driver.find_element(by, query) - def set_value(elem, value): - script = 'arguments[0].value = arguments[1]' - return driver.execute_script(script, elem, value) - - log("Waiting for the homepage to load") # cockpit sets initial title as hostname @@ -151,36 +145,45 @@ in log("Homepage loaded!") + # Prefer send_keys over setting .value via JS: Cockpit's login + # form (and PatternFly widgets) do not always react to the latter. log("Filling out username") login_input = find_element(By.CSS_SELECTOR, 'input#login-user-input') - set_value(login_input, "${user}") + login_input.clear() + login_input.send_keys("${user}") log("Filling out password") - password_input = find_element(By.CSS_SELECTOR, 'input#login-password-input') - set_value(password_input, "${password}") + password_input = find_element( + By.CSS_SELECTOR, 'input#login-password-input' + ) + password_input.clear() + password_input.send_keys("${password}") log("Submitting credentials for login") driver.find_element(By.CSS_SELECTOR, 'button#login-button').click() - # driver.implicitly_wait(1) - # driver.get("https://server:7890/system") - log("Waiting dashboard to load") wait_title_contains("${user}@server") - log("Waiting for the frontend to initialize") - sleep(1) - log("Looking for that banner that tells about limited access") - container_iframe = find_element(By.CSS_SELECTOR, 'iframe.container-frame') + wait_elem(By.CSS_SELECTOR, 'iframe.container-frame', timeout=30) + container_iframe = find_element( + By.CSS_SELECTOR, 'iframe.container-frame' + ) driver.switch_to.frame(container_iframe) - - assert "Web console is running in limited access mode" in driver.page_source + # Wait for the overview iframe to render the limited-access alert. + # Fixed sleeps were flaky after Cockpit 364 (slower SPA init). + phrase = "Web console is running in limited access mode" + WebDriverWait(driver, 30).until( + lambda d: phrase in d.page_source + ) log("Clicking the sudo button") + # Button label is "Turn on administrative access" for button in driver.find_elements(By.TAG_NAME, "button"): - if 'admin' in button.text: + if 'admin' in button.text.casefold(): button.click() + break driver.switch_to.default_content() log("Checking that /nonexistent is not a thing") @@ -189,13 +192,17 @@ in log("Checking plugin path") driver.get("https://server:7890/hello-test") - sleep(2) + wait_elem(By.CSS_SELECTOR, 'iframe.container-frame', timeout=30) for iframe in driver.find_elements(By.TAG_NAME, "iframe"): if "hello-test" in (iframe.get_attribute("src") or ""): driver.switch_to.frame(iframe) break - text = driver.find_element(By.ID, "output").text - sleep(1) + output = find_element(By.ID, "output") + WebDriverWait(driver, 30).until( + lambda d: "SUCCESS: Hello, world!" in output.text + or output.text.startswith("FAILED:") + ) + text = output.text assert "SUCCESS: Hello, world!" in text, f"Plugin failed: {text}" driver.close() @@ -215,8 +222,10 @@ in server.wait_for_unit("sockets.target") server.wait_for_open_port(7890) + # Port open is not enough: cockpit-ws may still be finishing startup. + server.wait_until_succeeds("curl -k https://127.0.0.1:7890 -o /dev/null") - client.succeed("curl -k https://server:7890 -o /dev/stderr") + client.wait_until_succeeds("curl -k https://server:7890 -o /dev/stderr") print(client.succeed("whoami")) client.succeed('PYTHONUNBUFFERED=1 selenium-script') '';