1import ./make-test-python.nix (
2 { pkgs, lib, ... }:
3
4 let
5 user = "alice"; # from ./common/user-account.nix
6 password = "foobar"; # from ./common/user-account.nix
7 in {
8 name = "cockpit";
9 meta = {
10 maintainers = with lib.maintainers; [ lucasew ];
11 };
12 nodes = {
13 server = { config, ... }: {
14 imports = [ ./common/user-account.nix ];
15 security.polkit.enable = true;
16 users.users.${user} = {
17 extraGroups = [ "wheel" ];
18 };
19 services.cockpit = {
20 enable = true;
21 openFirewall = true;
22 settings = {
23 WebService = {
24 Origins = "https://server:9090";
25 };
26 };
27 };
28 };
29 client = { config, ... }: {
30 imports = [ ./common/user-account.nix ];
31 environment.systemPackages = let
32 seleniumScript = pkgs.writers.writePython3Bin "selenium-script" {
33 libraries = with pkgs.python3Packages; [ selenium ];
34 } ''
35 from selenium import webdriver
36 from selenium.webdriver.common.by import By
37 from selenium.webdriver.firefox.options import Options
38 from selenium.webdriver.support.ui import WebDriverWait
39 from selenium.webdriver.support import expected_conditions as EC
40 from time import sleep
41
42
43 def log(msg):
44 from sys import stderr
45 print(f"[*] {msg}", file=stderr)
46
47
48 log("Initializing")
49
50 options = Options()
51 options.add_argument("--headless")
52
53 driver = webdriver.Firefox(options=options)
54
55 driver.implicitly_wait(10)
56
57 log("Opening homepage")
58 driver.get("https://server:9090")
59
60 wait = WebDriverWait(driver, 60)
61
62
63 def wait_elem(by, query):
64 wait.until(EC.presence_of_element_located((by, query)))
65
66
67 def wait_title_contains(title):
68 wait.until(EC.title_contains(title))
69
70
71 def find_element(by, query):
72 return driver.find_element(by, query)
73
74
75 def set_value(elem, value):
76 script = 'arguments[0].value = arguments[1]'
77 return driver.execute_script(script, elem, value)
78
79
80 log("Waiting for the homepage to load")
81
82 # cockpit sets initial title as hostname
83 wait_title_contains("server")
84 wait_elem(By.CSS_SELECTOR, 'input#login-user-input')
85
86 log("Homepage loaded!")
87
88 log("Filling out username")
89 login_input = find_element(By.CSS_SELECTOR, 'input#login-user-input')
90 set_value(login_input, "${user}")
91
92 log("Filling out password")
93 password_input = find_element(By.CSS_SELECTOR, 'input#login-password-input')
94 set_value(password_input, "${password}")
95
96 log("Submitting credentials for login")
97 driver.find_element(By.CSS_SELECTOR, 'button#login-button').click()
98
99 # driver.implicitly_wait(1)
100 # driver.get("https://server:9090/system")
101
102 log("Waiting dashboard to load")
103 wait_title_contains("${user}@server")
104
105 log("Waiting for the frontend to initialize")
106 sleep(1)
107
108 log("Looking for that banner that tells about limited access")
109 container_iframe = find_element(By.CSS_SELECTOR, 'iframe.container-frame')
110 driver.switch_to.frame(container_iframe)
111
112 assert "Web console is running in limited access mode" in driver.page_source
113
114 driver.close()
115 '';
116 in with pkgs; [ firefox-unwrapped geckodriver seleniumScript ];
117 };
118 };
119
120 testScript = ''
121 start_all()
122
123 server.wait_for_open_port(9090)
124 server.wait_for_unit("network.target")
125 server.wait_for_unit("multi-user.target")
126 server.systemctl("start", "polkit")
127
128 client.wait_for_unit("multi-user.target")
129
130 client.succeed("curl -k https://server:9090 -o /dev/stderr")
131 print(client.succeed("whoami"))
132 client.succeed('PYTHONUNBUFFERED=1 selenium-script')
133 '';
134 }
135)