<?xml version="1.0" encoding="UTF-8"?>
<robot generator="Robot 7.4.2 (Python 3.12.3 on linux)" generated="2026-05-05T19:39:03.173450" rpa="false" schemaversion="5">
<suite id="s1" name="01 Page Loading" source="/home/lukas/Volume/repo/BanGUI/e2e/tests/01_page_loading.robot">
<test id="s1-t1" name="Login Page Loads Without Error" line="6">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:03.375328" level="INFO">{"browser": "chromium", "headless": true, "chromiumSandbox": false, "devtools": false, "handleSIGHUP": true, "handleSIGINT": true, "handleSIGTERM": true, "slowMo": 0.0, "timeout": 30000.0, "tracesDir": "/home/lukas/Volume/repo/BanGUI/e2e/browser/traces/temp/fff9f30c-e589-4ae0-acc2-4addbd55aab7"}</msg>
<msg time="2026-05-05T19:39:03.380965" level="INFO">Starting Browser process /home/lukas/Volume/repo/BanGUI/.venv/lib/python3.12/site-packages/Browser/wrapper/index.js using at 127.0.0.1:59711</msg>
<msg time="2026-05-05T19:39:03.957479" level="INFO">Successfully created browser with options: {"browser":"chromium","headless":true,"chromiumSandbox":false,"devtools":false,"handleSIGHUP":true,"handleSIGINT":true,"handleSIGTERM":true,"slowMo":0,"timeout":30000,"tracesDir":"/home/lukas/Volume/repo/BanGUI/e2e/browser/traces/temp/fff9f30c-e589-4ae0-acc2-4addbd55aab7"}</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:03.374737" elapsed="0.583036"/>
</kw>
<kw name="New Page" owner="Browser">
<msg time="2026-05-05T19:39:04.017789" level="INFO">Successfully initialized new page object and opened url: about:blank</msg>
<msg time="2026-05-05T19:39:04.017865" level="INFO">No context was open. New context was automatically opened when this page is created.</msg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Open a new Page.</doc>
<status status="PASS" start="2026-05-05T19:39:03.958145" elapsed="0.059859"/>
</kw>
<kw name="Go To" owner="Browser">
<msg time="2026-05-05T19:39:04.517439" level="INFO">Successfully opened URL http://localhost:5173/login</msg>
<arg>${FRONTEND_URL}/login</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.018193" elapsed="0.499455"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-05-05T19:39:04.634322" level="INFO">Waited for Element with selector css=form at state visible</msg>
<arg>css=form</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-05-05T19:39:04.517892" elapsed="0.116558"/>
</kw>
<kw name="Get Text" owner="Browser">
<msg time="2026-05-05T19:39:04.659952" level="INFO">Text: 'BanGUI\nEnter your master password to continue.\nPassword*\nSign in'</msg>
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.634610" elapsed="0.025452"/>
</kw>
<kw name="Close Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.688238" level="INFO">Closed browser</msg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="PASS" start="2026-05-05T19:39:04.660218" elapsed="0.028167"/>
</kw>
<doc>Login must run before Login As Admin — use New Page to avoid session cookie.
Vite SPA always returns 200; focus on DOM assertions after client-side routing.</doc>
<status status="PASS" start="2026-05-05T19:39:03.373886" elapsed="1.314646"/>
</test>
<test id="s1-t2" name="Setup Page Loads Without Error" line="16">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.696415" level="INFO">{"browser": "chromium", "headless": true, "chromiumSandbox": false, "devtools": false, "handleSIGHUP": true, "handleSIGINT": true, "handleSIGTERM": true, "slowMo": 0.0, "timeout": 30000.0, "tracesDir": "/home/lukas/Volume/repo/BanGUI/e2e/browser/traces/temp/60026f36-199b-4876-95b2-0ef31f553a2a"}</msg>
<msg time="2026-05-05T19:39:04.751133" level="INFO">Successfully created browser with options: {"browser":"chromium","headless":true,"chromiumSandbox":false,"devtools":false,"handleSIGHUP":true,"handleSIGINT":true,"handleSIGTERM":true,"slowMo":0,"timeout":30000,"tracesDir":"/home/lukas/Volume/repo/BanGUI/e2e/browser/traces/temp/60026f36-199b-4876-95b2-0ef31f553a2a"}</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.695765" elapsed="0.056063"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.758900" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.759038" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': '15e2fb57-c104-4f69-ab11-a5d95bb38bca', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.759165" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.752931" elapsed="0.006257"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.760056" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.759344" elapsed="0.000742"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.760662" elapsed="0.000122"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.760932" elapsed="0.000117"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.761289" elapsed="0.000157"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.761602" elapsed="0.000117"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.761842" elapsed="0.000083"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.760193" elapsed="0.001788"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.760165" elapsed="0.002886"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.764706" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.764168" elapsed="0.000570"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.765491" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.765043" elapsed="0.000475"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.766196" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.765632" elapsed="0.000589"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.773780" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.773861" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=401, reason=Unauthorized 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '162', 'content-type': 'application/json', 'x-correlation-id': 'fcda12ce-c348-4ba2-9ace-b33f61728c43', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"authentication_required","detail":"No password is configured — run setup first.","metadata":{},"correlation_id":"fcda12ce-c348-4ba2-9ace-b33f61728c43"} 
 </msg>
<msg time="2026-05-05T19:39:04.773987" level="FAIL">HTTPError: 401 Client Error: Unauthorized for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.766325" elapsed="0.009993">HTTPError: 401 Client Error: Unauthorized for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.776648" elapsed="0.000105"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.776877" elapsed="0.000063"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.777036" elapsed="0.000067"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.752345" elapsed="0.024899">HTTPError: 401 Client Error: Unauthorized for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/setup</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.777360" elapsed="0.000073"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=form,button</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.777567" elapsed="0.000132"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.777928" elapsed="0.000311"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.778375" elapsed="0.000074"/>
</kw>
<doc>Setup wizard accessible before auth; may redirect to /login if already done.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.693592" elapsed="0.085213">HTTPError: 401 Client Error: Unauthorized for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<test id="s1-t3" name="Dashboard Page Loads Without Error" line="25">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.789952" level="INFO">Switching browser to browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.792120" level="INFO">Successfully changed active browser: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.792254" level="INFO">Reusing existing browser with id: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.789168" elapsed="0.003156"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.799504" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.799582" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': 'f903c47a-343d-4e00-bcb0-8d9d0a068e0e', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.799689" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.793287" elapsed="0.006423"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.800508" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.799858" elapsed="0.000677"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.800875" elapsed="0.000063"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.801030" elapsed="0.000049"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.801158" elapsed="0.000042"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.801272" elapsed="0.000043"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.801503" elapsed="0.000048"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.800626" elapsed="0.000957"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.800603" elapsed="0.001015"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.801909" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.801680" elapsed="0.000251"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.802314" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.802005" elapsed="0.000330"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.802689" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.802419" elapsed="0.000291"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.809402" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.809474" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=429, reason=Too Many Requests 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'retry-after': '60', 'content-length': '186', 'content-type': 'application/json', 'x-correlation-id': '681bc9a0-464e-434e-8ae9-1b471dba7d77', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"rate_limit_exceeded","detail":"Too many login attempts. Please try again later.","metadata":{"retry_after_seconds":60.0},"correlation_id":"681bc9a0-464e-434e-8ae9-1b471dba7d77"} 
 </msg>
<msg time="2026-05-05T19:39:04.809587" level="FAIL">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.802789" elapsed="0.007168">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.810145" elapsed="0.000093"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.810375" elapsed="0.000056"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.810514" elapsed="0.000048"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.792741" elapsed="0.017914">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.810739" elapsed="0.000053"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=main</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.810868" elapsed="0.000045"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.810992" elapsed="0.000062"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.811129" elapsed="0.000044"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.786268" elapsed="0.025022">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<test id="s1-t4" name="Map Page Loads Without Error" line="33">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.817318" level="INFO">Switching browser to browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.818847" level="INFO">Successfully changed active browser: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.818937" level="INFO">Reusing existing browser with id: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.816817" elapsed="0.002165"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.822914" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.822985" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': '6377f3ad-048e-45a2-90c4-8bc5dd97981f', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.823202" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.819543" elapsed="0.003691"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.824039" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.823413" elapsed="0.000655"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.824438" elapsed="0.000057"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.824574" elapsed="0.000203"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.824871" elapsed="0.000047"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.824991" elapsed="0.000062"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.825119" elapsed="0.000041"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.824158" elapsed="0.001032"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.824136" elapsed="0.001088"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.825549" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.825283" elapsed="0.000287"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.825973" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.825650" elapsed="0.000351"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.826405" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.826120" elapsed="0.000314"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.834505" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.834578" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=429, reason=Too Many Requests 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'retry-after': '60', 'content-length': '186', 'content-type': 'application/json', 'x-correlation-id': '50194cf2-57cb-4c05-a696-776920d73d39', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"rate_limit_exceeded","detail":"Too many login attempts. Please try again later.","metadata":{"retry_after_seconds":60.0},"correlation_id":"50194cf2-57cb-4c05-a696-776920d73d39"} 
 </msg>
<msg time="2026-05-05T19:39:04.834666" level="FAIL">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.826520" elapsed="0.008529">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.835210" elapsed="0.000087"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.835398" elapsed="0.000048"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.835518" elapsed="0.000048"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.819246" elapsed="0.016407">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/map</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.835736" elapsed="0.000049"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=canvas,svg,.map-container</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.835859" elapsed="0.000042"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.835979" elapsed="0.000077"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.836135" elapsed="0.000042"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.815163" elapsed="0.021123">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<test id="s1-t5" name="Jails Page Loads Without Error" line="41">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.842215" level="INFO">Switching browser to browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.843586" level="INFO">Successfully changed active browser: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.843669" level="INFO">Reusing existing browser with id: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.841703" elapsed="0.002009"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.850588" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.850670" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': 'e906034a-f457-4e1a-9cea-bb9e0849f3dd', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.850879" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.844514" elapsed="0.006395"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.851982" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.851248" elapsed="0.000786"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.852370" elapsed="0.000054"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.852502" elapsed="0.000044"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.852625" elapsed="0.000041"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.852738" elapsed="0.000041"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.852841" elapsed="0.000039"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.852139" elapsed="0.000768"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.852117" elapsed="0.000821"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.853259" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.852993" elapsed="0.000289"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.853694" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.853363" elapsed="0.000351"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.854207" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.853806" elapsed="0.000426"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.859832" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.859906" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=429, reason=Too Many Requests 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'retry-after': '60', 'content-length': '186', 'content-type': 'application/json', 'x-correlation-id': '931bccb1-7194-467d-8d2d-ceb5a978b69f', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"rate_limit_exceeded","detail":"Too many login attempts. Please try again later.","metadata":{"retry_after_seconds":60.0},"correlation_id":"931bccb1-7194-467d-8d2d-ceb5a978b69f"} 
 </msg>
<msg time="2026-05-05T19:39:04.859994" level="FAIL">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.854329" elapsed="0.005996">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.860515" elapsed="0.000093"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.860716" elapsed="0.000048"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.860843" elapsed="0.000050"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.843977" elapsed="0.017107">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/jails</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.861223" elapsed="0.000061"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=main,table,.jails-list</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.861366" elapsed="0.000047"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.861499" elapsed="0.000060"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.861649" elapsed="0.000063"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.839832" elapsed="0.022062">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<test id="s1-t6" name="Jail Detail Page Loads Without Error" line="49">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.870123" level="INFO">Switching browser to browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.871428" level="INFO">Successfully changed active browser: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.871503" level="INFO">Reusing existing browser with id: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.869594" elapsed="0.001951"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.875129" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.875345" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': '70927f95-6bba-4adc-80f8-1ad987233a78', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.875547" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.872051" elapsed="0.003526"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.876269" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.875707" elapsed="0.000586"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.876585" elapsed="0.000056"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.876717" elapsed="0.000046"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.876838" elapsed="0.000046"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.876955" elapsed="0.000044"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.877072" elapsed="0.000050"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.876371" elapsed="0.000782"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.876352" elapsed="0.000833"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.877516" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.877242" elapsed="0.000302"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.878148" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.877636" elapsed="0.000543"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.878750" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.878295" elapsed="0.000483"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.885674" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.885744" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=429, reason=Too Many Requests 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'retry-after': '60', 'content-length': '186', 'content-type': 'application/json', 'x-correlation-id': '20e88f18-e33c-4cc0-8619-9375a4429415', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"rate_limit_exceeded","detail":"Too many login attempts. Please try again later.","metadata":{"retry_after_seconds":60.0},"correlation_id":"20e88f18-e33c-4cc0-8619-9375a4429415"} 
 </msg>
<msg time="2026-05-05T19:39:04.885828" level="FAIL">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.878904" elapsed="0.007245">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.886303" elapsed="0.000101"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.886500" elapsed="0.000047"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.886616" elapsed="0.000040"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.871779" elapsed="0.014955">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="GET" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/jails</arg>
<doc>Sends a GET request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.886811" elapsed="0.000045"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${jails}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.886923" elapsed="0.000040"/>
</kw>
<kw name="Get Length" owner="BuiltIn">
<var>${count}</var>
<arg>${jails}</arg>
<doc>Returns and logs the length of the given item as an integer.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.887044" elapsed="0.000045"/>
</kw>
<if>
<branch type="IF" condition="${count} &gt; 0">
<kw name="Get From List" owner="Collections">
<var>${first_jail}</var>
<arg>${jails}</arg>
<arg>0</arg>
<doc>Returns the value specified with an ``index`` from ``list``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.887250" elapsed="0.000042"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${jail_name}</var>
<arg>${first_jail}[name]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.887359" elapsed="0.000038"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Using jail: ${jail_name}</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.887460" elapsed="0.000037"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.887152" elapsed="0.000372"/>
</branch>
<branch type="ELSE">
<kw name="Set Variable" owner="BuiltIn">
<var>${jail_name}</var>
<arg>manual-Jail</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.887633" elapsed="0.000146"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>No jails found; using fallback name: ${jail_name}</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.887853" elapsed="0.000040"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.887551" elapsed="0.000369"/>
</branch>
<status status="NOT RUN" start="2026-05-05T19:39:04.887136" elapsed="0.000808"/>
</if>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/jails/${jail_name}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.888002" elapsed="0.000047"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=main,h1,h2,.jail-detail</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.888120" elapsed="0.000038"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.888227" elapsed="0.000037"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.888333" elapsed="0.000038"/>
</kw>
<doc>Guard: check jail exists via GET /api/jails first; use first jail name.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.867780" elapsed="0.020696">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<test id="s1-t7" name="Config Page Loads Without Error" line="73">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.893959" level="INFO">Switching browser to browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.897089" level="INFO">Successfully changed active browser: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.897184" level="INFO">Reusing existing browser with id: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.893386" elapsed="0.003849"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.900558" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.900621" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': '6afffb05-0a80-464d-85d0-e76d457ad99a', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.900771" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.897787" elapsed="0.003010"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.901471" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.900917" elapsed="0.000579"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.901790" elapsed="0.000057"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.901927" elapsed="0.000048"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.902060" elapsed="0.000047"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.902180" elapsed="0.000045"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.902288" elapsed="0.000043"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.901572" elapsed="0.000788"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.901554" elapsed="0.000837"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.902663" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.902446" elapsed="0.000239"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.903062" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.902763" elapsed="0.000320"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.903430" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.903165" elapsed="0.000285"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.908380" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.908448" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=429, reason=Too Many Requests 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'retry-after': '60', 'content-length': '186', 'content-type': 'application/json', 'x-correlation-id': '62345c0c-072c-4fb1-b579-776d24a721d3', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"rate_limit_exceeded","detail":"Too many login attempts. Please try again later.","metadata":{"retry_after_seconds":60.0},"correlation_id":"62345c0c-072c-4fb1-b579-776d24a721d3"} 
 </msg>
<msg time="2026-05-05T19:39:04.908690" level="FAIL">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.903524" elapsed="0.005459">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.909138" elapsed="0.000095"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.909330" elapsed="0.000046"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.909446" elapsed="0.000040"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.897498" elapsed="0.012066">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/config</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.909642" elapsed="0.000069"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=main,.tabs,.config-editor</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.909784" elapsed="0.000041"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.909898" elapsed="0.000041"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.910023" elapsed="0.000041"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.891905" elapsed="0.018264">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<test id="s1-t8" name="History Page Loads Without Error" line="81">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.915548" level="INFO">Switching browser to browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.916833" level="INFO">Successfully changed active browser: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.916903" level="INFO">Reusing existing browser with id: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.915083" elapsed="0.001862"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.920348" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.920411" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': '55b641d4-f5dd-4ee4-92bd-f259b726178f', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.920576" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.917495" elapsed="0.003109"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.921258" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.920729" elapsed="0.000553"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.921575" elapsed="0.000048"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.921697" elapsed="0.000042"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.921816" elapsed="0.000040"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.921925" elapsed="0.000042"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.922036" elapsed="0.000041"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.921356" elapsed="0.000751"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.921339" elapsed="0.000810"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.922470" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.922229" elapsed="0.000271"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.922997" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.922612" elapsed="0.000416"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.923391" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.923115" elapsed="0.000298"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.928230" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.928401" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=429, reason=Too Many Requests 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'retry-after': '60', 'content-length': '186', 'content-type': 'application/json', 'x-correlation-id': '1615aebf-f0fa-4ab4-a156-88bc8e689b00', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"rate_limit_exceeded","detail":"Too many login attempts. Please try again later.","metadata":{"retry_after_seconds":60.0},"correlation_id":"1615aebf-f0fa-4ab4-a156-88bc8e689b00"} 
 </msg>
<msg time="2026-05-05T19:39:04.928493" level="FAIL">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.923492" elapsed="0.005293">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.928937" elapsed="0.000097"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.929134" elapsed="0.000048"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.929251" elapsed="0.000043"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.917212" elapsed="0.012163">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/history</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.929455" elapsed="0.000060"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=main,table,.history-table</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.929617" elapsed="0.000050"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.929742" elapsed="0.000044"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.929863" elapsed="0.000062"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.913563" elapsed="0.016496">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<test id="s1-t9" name="Blocklists Page Loads Without Error" line="89">
<kw name="New Browser" owner="Browser">
<msg time="2026-05-05T19:39:04.936038" level="INFO">Switching browser to browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.937150" level="INFO">Successfully changed active browser: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<msg time="2026-05-05T19:39:04.937213" level="INFO">Reusing existing browser with id: browser=1965d4f7-7156-47f2-9aa5-859a0466429c</msg>
<arg>chromium</arg>
<arg>headless=${TRUE}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-05-05T19:39:04.935538" elapsed="0.001717"/>
</kw>
<kw name="Login As Admin" owner="auth">
<kw name="GET" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.940504" level="INFO">GET Request : url=http://localhost:8000/api/v1/setup 
 path_url=/api/v1/setup 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'} 
 body=None 
 </msg>
<msg time="2026-05-05T19:39:04.940568" level="INFO">GET Response : url=http://localhost:8000/api/v1/setup 
 status=200, reason=OK 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'content-length': '18', 'content-type': 'application/json', 'x-correlation-id': 'ee85940c-9907-4a46-a5aa-fc51bcd28f9f', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"completed":true} 
 </msg>
<msg time="2026-05-05T19:39:04.940725" level="INFO">${response} = &lt;Response [200]&gt;</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/setup</arg>
<doc>Sends a GET request.</doc>
<status status="PASS" start="2026-05-05T19:39:04.937742" elapsed="0.003006"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.941422" level="INFO">${body} = {'completed': True}</msg>
<var>${body}</var>
<arg>${response.json()}</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.940873" elapsed="0.000576"/>
</kw>
<if>
<branch type="IF" condition="${body}[completed] == ${false}">
<kw name="Set Variable" owner="BuiltIn">
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.941750" elapsed="0.000050"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.941876" elapsed="0.000041"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<var>${setup_payload}</var>
<arg>master_password=${hashed}</arg>
<arg>database_path=</arg>
<arg>fail2ban_socket=</arg>
<arg>timezone=UTC</arg>
<arg>session_duration_minutes=60</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.941992" elapsed="0.000046"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<arg>${BACKEND_URL}/api/v1/setup</arg>
<arg>json=${setup_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.942108" elapsed="0.000039"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<doc>Sends a POST request.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.942209" elapsed="0.000037"/>
</kw>
<status status="NOT RUN" start="2026-05-05T19:39:04.941527" elapsed="0.000747"/>
</branch>
<status status="PASS" start="2026-05-05T19:39:04.941508" elapsed="0.000795"/>
</if>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.942563" level="INFO">${password} = Hallo123!</msg>
<var>${password}</var>
<arg>Hallo123!</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-05-05T19:39:04.942357" elapsed="0.000227"/>
</kw>
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.942960" level="INFO">${hashed} = sha256('Hallo123!'.encode()).hexdigest()</msg>
<var>${hashed}</var>
<arg>"sha256('${password}'.encode()).hexdigest()"</arg>
<arg>modules=hashlib</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-05-05T19:39:04.942661" elapsed="0.000320"/>
</kw>
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-05-05T19:39:04.943438" level="INFO">${login_payload} = {'password': "sha256('Hallo123!'.encode()).hexdigest()"}</msg>
<var>${login_payload}</var>
<arg>password=${hashed}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-05-05T19:39:04.943074" elapsed="0.000384"/>
</kw>
<kw name="POST" owner="RequestsLibrary">
<msg time="2026-05-05T19:39:04.951148" level="INFO">POST Request : url=http://localhost:8000/api/v1/auth/login 
 path_url=/api/v1/auth/login 
 headers={'User-Agent': 'python-requests/2.32.5', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '56', 'Content-Type': 'application/json'} 
 body=b'{"password": "sha256(\'Hallo123!\'.encode()).hexdigest()"}' 
 </msg>
<msg time="2026-05-05T19:39:04.951219" level="INFO">POST Response : url=http://localhost:8000/api/v1/auth/login 
 status=429, reason=Too Many Requests 
 headers={'date': 'Tue, 05 May 2026 17:39:04 GMT', 'server': 'uvicorn', 'retry-after': '60', 'content-length': '186', 'content-type': 'application/json', 'x-correlation-id': '83b3f9b0-e0d9-4d6c-b833-2af9994a35d9', 'content-security-policy': "default-src 'self'", 'x-frame-options': 'DENY', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block'} 
 body={"code":"rate_limit_exceeded","detail":"Too many login attempts. Please try again later.","metadata":{"retry_after_seconds":60.0},"correlation_id":"83b3f9b0-e0d9-4d6c-b833-2af9994a35d9"} 
 </msg>
<msg time="2026-05-05T19:39:04.951308" level="FAIL">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</msg>
<var>${response}</var>
<arg>${BACKEND_URL}/api/v1/auth/login</arg>
<arg>json=${login_payload}</arg>
<doc>Sends a POST request.</doc>
<status status="FAIL" start="2026-05-05T19:39:04.943533" elapsed="0.008088">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Get Cookie" owner="Browser">
<var>${session_cookie}</var>
<arg>bangui_session</arg>
<tag>BrowserControl</tag>
<tag>Getter</tag>
<doc>Returns information of cookie with ``name`` as a Robot Framework dot dictionary or a string.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.951774" elapsed="0.000103"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${session_cookie}</arg>
<arg>${session_cookie}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.951976" elapsed="0.000090"/>
</kw>
<kw name="Log" owner="BuiltIn">
<arg>Logged in as admin.</arg>
<doc>Logs the given message with the given level.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.952139" elapsed="0.000043"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.937475" elapsed="0.014786">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</kw>
<kw name="Go To" owner="Browser">
<arg>${FRONTEND_URL}/blocklists</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Navigates to the given ``url``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.952339" elapsed="0.000046"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<arg>css=main,.blocklists-panel,.panel</arg>
<arg>visible</arg>
<arg>timeout=15s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.952459" elapsed="0.000039"/>
</kw>
<kw name="Get Text" owner="Browser">
<arg>css=body</arg>
<arg>not contains</arg>
<arg>Something went wrong</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns text attribute of the element found by ``selector``.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.952569" elapsed="0.000038"/>
</kw>
<kw name="Close Browser" owner="Browser">
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="NOT RUN" start="2026-05-05T19:39:04.952680" elapsed="0.000038"/>
</kw>
<status status="FAIL" start="2026-05-05T19:39:04.934036" elapsed="0.018785">HTTPError: 429 Client Error: Too Many Requests for url: http://localhost:8000/api/v1/auth/login</status>
</test>
<status status="FAIL" start="2026-05-05T19:39:03.174196" elapsed="1.781754"/>
</suite>
<statistics>
<total>
<stat pass="1" fail="8" skip="0">All Tests</stat>
</total>
<tag>
</tag>
<suite>
<stat name="01 Page Loading" id="s1" pass="1" fail="8" skip="0">01 Page Loading</stat>
</suite>
</statistics>
<errors>
<msg time="2026-05-05T19:39:03.365742" level="ERROR">Error in file '/home/lukas/Volume/repo/BanGUI/e2e/resources/common.resource' on line 5: Processing variable file '/home/lukas/Volume/repo/BanGUI/e2e/resources/../../.env' failed: Importing variable file '/home/lukas/Volume/repo/BanGUI/e2e/resources/../../.env' failed: Module name cannot contain dots when importing by path.</msg>
</errors>
</robot>
