Files
Aniworld/output.xml
Lukas 4687a06374 Refactor trigger_rescan to use anime_service
- Use anime_service.rescan() instead of direct trigger_rescan import
- Change Optional[Any] to Optional[Dict[str, Any]] in ConfigUpdate for better type hints
- Add ValidationError handling in ConfigUpdate.apply_to
- Update tests to match new implementation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-27 15:46:22 +02:00

2446 lines
121 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<robot generator="Robot 7.4.2 (Python 3.13.5 on linux)" generated="2026-06-27T15:40:14.896246" rpa="false" schemaversion="5">
<suite id="s1" name="Scheduler" source="/home/lukas/Volume/repo/Aniworld/tests/robot/api/scheduler.robot">
<test id="s1-t1" name="Get Scheduler Config" line="19">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.103360" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:40:15.103215" elapsed="0.000291"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.102899" elapsed="0.000684"/>
</kw>
<kw name="Setup Master Password" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.104388" level="INFO">${payload} = {'master_password': 'TestPass123!', 'anime_directory': '/tmp/aniworld_test_anime', 'name': 'AniworldTest', 'data_dir': 'data', 'scheduler_enabled': 'False', 'logging_level': 'INFO', 'backup_enabled': ...</msg>
<var>${payload}</var>
<arg>master_password=${SETUP_PASSWORD}</arg>
<arg>anime_directory=/tmp/aniworld_test_anime</arg>
<arg>name=AniworldTest</arg>
<arg>data_dir=data</arg>
<arg>scheduler_enabled=False</arg>
<arg>logging_level=INFO</arg>
<arg>backup_enabled=False</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:40:15.104035" elapsed="0.000377"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.107508" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:40:15.107579" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=400, reason=Bad Request
headers={'date': 'Sat, 27 Jun 2026 13:40:14 GMT', 'server': 'uvicorn', 'content-length': '47', 'content-type': 'application/json'}
body={"detail":"Master password already configured"}
</msg>
<msg time="2026-06-27T15:40:15.107666" level="INFO">${resp} = &lt;Response [400]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.104501" elapsed="0.003187"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.108262" elapsed="0.000055"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.108403" elapsed="0.000044"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.107794" elapsed="0.000689"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.107770" elapsed="0.000748"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.108957" elapsed="0.000046"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.109079" elapsed="0.000040"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.108565" elapsed="0.000587"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.108552" elapsed="0.000628"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '400'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.109903" level="INFO">${json} = {'detail': 'Master password already configured'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:40:15.109552" elapsed="0.000372"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.121811" level="INFO">${detail} = ['Master password already configured']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:40:15.110004" elapsed="0.011837"/>
</kw>
<if>
<branch type="IF" condition="'${detail}[0]' == 'Master password already configured'">
<return>
<status status="PASS" start="2026-06-27T15:40:15.122196" elapsed="0.000065"/>
</return>
<status status="PASS" start="2026-06-27T15:40:15.121920" elapsed="0.000378"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.121905" elapsed="0.000420"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Setup failed with 400: ${detail}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.122404" elapsed="0.000045"/>
</kw>
<status status="PASS" start="2026-06-27T15:40:15.109220" elapsed="0.013259"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.109209" elapsed="0.013294"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '201'">
<kw name="Should Be Equal As Integers" owner="BuiltIn">
<arg>${resp.status_code}</arg>
<arg>201</arg>
<doc>Fails if objects are unequal after converting them to integers.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.122627" elapsed="0.000037"/>
</kw>
<return>
<status status="NOT RUN" start="2026-06-27T15:40:15.122699" elapsed="0.000139"/>
</return>
<status status="NOT RUN" start="2026-06-27T15:40:15.122540" elapsed="0.000328"/>
</branch>
<status status="NOT RUN" start="2026-06-27T15:40:15.122530" elapsed="0.000358"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Unexpected status ${resp.status_code} from /api/auth/setup</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.122940" elapsed="0.000077"/>
</kw>
<doc>Configure the master password via the setup endpoint.</doc>
<status status="PASS" start="2026-06-27T15:40:15.103834" elapsed="0.019237"/>
</kw>
<kw name="Create Authenticated Session" owner="common">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.123666" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:40:15.123553" elapsed="0.000226"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.123406" elapsed="0.000420"/>
</kw>
<kw name="Is Auth Configured" owner="common">
<kw name="GET On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.125760" level="INFO">GET Request : url=http://127.0.0.1:8765/api/auth/status
path_url=/api/auth/status
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
body=None
</msg>
<msg time="2026-06-27T15:40:15.126061" level="INFO">GET Response : url=http://127.0.0.1:8765/api/auth/status
status=200, reason=OK
headers={'date': 'Sat, 27 Jun 2026 13:40:14 GMT', 'server': 'uvicorn', 'content-length': '41', 'content-type': 'application/json'}
body={"configured":true,"authenticated":false}
</msg>
<msg time="2026-06-27T15:40:15.126147" level="INFO">${resp} = &lt;Response [200]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/status</arg>
<arg>expected_status=200</arg>
<doc>Sends a GET request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.124166" elapsed="0.002005"/>
</kw>
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.126674" level="INFO">${json} = {'configured': True, 'authenticated': False}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:40:15.126287" elapsed="0.000409"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.136465" level="INFO">${configured} = [True]</msg>
<var>${configured}</var>
<arg>${json}</arg>
<arg>$.configured</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:40:15.126806" elapsed="0.009685"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.136983" level="INFO">${configured_val} = True</msg>
<var>${configured_val}</var>
<arg>${configured}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:40:15.136583" elapsed="0.000421"/>
</kw>
<return>
<value>${configured_val}</value>
<status status="PASS" start="2026-06-27T15:40:15.137045" elapsed="0.000187"/>
</return>
<msg time="2026-06-27T15:40:15.137338" level="INFO">${configured} = True</msg>
<var>${configured}</var>
<doc>Check if the master password has already been configured.</doc>
<status status="PASS" start="2026-06-27T15:40:15.123928" elapsed="0.013428"/>
</kw>
<if>
<branch type="IF" condition="not ${configured}">
<kw name="Setup Master Password" owner="common">
<doc>Configure the master password via the setup endpoint.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.137836" elapsed="0.000060"/>
</kw>
<kw name="Login And Get Token" owner="common">
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.138039" elapsed="0.000212"/>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.138363" elapsed="0.000053"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.137416" elapsed="0.001033"/>
</branch>
<branch type="ELSE IF" condition="'${TOKEN}' == '${EMPTY}'">
<kw name="Login And Get Token" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.139364" level="INFO">${payload} = {'password': 'TestPass123!'}</msg>
<var>${payload}</var>
<arg>password=${SETUP_PASSWORD}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:40:15.139100" elapsed="0.000283"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.146155" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:40:15.146200" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=401, reason=Unauthorized
headers={'date': 'Sat, 27 Jun 2026 13:40:14 GMT', 'server': 'uvicorn', 'content-length': '32', 'content-type': 'application/json'}
body={"detail":"invalid credentials"}
</msg>
<msg time="2026-06-27T15:40:15.146269" level="INFO">${resp} = &lt;Response [401]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.139458" elapsed="0.006829"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>6s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.146898" elapsed="0.000142"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.147146" elapsed="0.000052"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.146360" elapsed="0.000872"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.146344" elapsed="0.000915"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' != '200'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.147981" level="INFO">${json} = {'detail': 'invalid credentials'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:40:15.147633" elapsed="0.000368"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.157468" level="INFO">${detail} = ['invalid credentials']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:40:15.148076" elapsed="0.009417"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.158036" level="INFO">${detail_val} = invalid credentials</msg>
<var>${detail_val}</var>
<arg>${detail}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:40:15.157588" elapsed="0.000470"/>
</kw>
<kw name="Fail" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.158740" level="FAIL">Login failed with 401: invalid credentials</msg>
<arg>Login failed with ${resp.status_code}: ${detail_val}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="FAIL" start="2026-06-27T15:40:15.158139" elapsed="0.000728">Login failed with 401: invalid credentials</status>
</kw>
<status status="FAIL" start="2026-06-27T15:40:15.147299" elapsed="0.011628">Login failed with 401: invalid credentials</status>
</branch>
<status status="FAIL" start="2026-06-27T15:40:15.147287" elapsed="0.011671">Login failed with 401: invalid credentials</status>
</if>
<kw name="Convert String To Json" owner="JSONLibrary">
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.159031" elapsed="0.000191"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<var>${token}</var>
<arg>${json}</arg>
<arg>$.access_token</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.159319" elapsed="0.000052"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${token_str}</var>
<arg>${token}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.159445" elapsed="0.000127"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${TOKEN}</arg>
<arg>${token_str}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.159679" elapsed="0.000077"/>
</kw>
<return>
<value>${token_str}</value>
<status status="NOT RUN" start="2026-06-27T15:40:15.159801" elapsed="0.000053"/>
</return>
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="FAIL" start="2026-06-27T15:40:15.138915" elapsed="0.021019">Login failed with 401: invalid credentials</status>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.160194" elapsed="0.000058"/>
</kw>
<status status="FAIL" start="2026-06-27T15:40:15.138478" elapsed="0.021822">Login failed with 401: invalid credentials</status>
</branch>
<branch type="ELSE">
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${TOKEN}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.160497" elapsed="0.000087"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.160338" elapsed="0.000280"/>
</branch>
<status status="FAIL" start="2026-06-27T15:40:15.137401" elapsed="0.023241">Login failed with 401: invalid credentials</status>
</if>
<doc>Create an authenticated HTTP session. Performs setup if needed, then logs in.
Skips setup/login if already authenticated (suite-level setup done).</doc>
<status status="FAIL" start="2026-06-27T15:40:15.123222" elapsed="0.037477">Login failed with 401: invalid credentials</status>
</kw>
<arg>Create Anonymous Session</arg>
<arg>AND</arg>
<arg>Setup Master Password</arg>
<arg>AND</arg>
<arg>Create Authenticated Session</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="FAIL" start="2026-06-27T15:40:15.102327" elapsed="0.058424">Login failed with 401: invalid credentials</status>
</kw>
<kw name="Delete All Sessions" owner="RequestsLibrary" type="TEARDOWN">
<msg time="2026-06-27T15:40:15.161094" level="INFO">Deleting All Sessions</msg>
<doc>Removes all the session objects</doc>
<status status="PASS" start="2026-06-27T15:40:15.160904" elapsed="0.000249"/>
</kw>
<msg time="2026-06-27T15:40:15.165108" level="INFO">Starting Browser process /home/lukas/miniconda3/lib/python3.13/site-packages/Browser/wrapper/index.js using at 127.0.0.1:53873</msg>
<doc>Retrieve the current scheduler configuration and runtime status.</doc>
<status status="FAIL" start="2026-06-27T15:40:15.101375" elapsed="0.059814">Setup failed:
Login failed with 401: invalid credentials</status>
</test>
<test id="s1-t2" name="Update Scheduler Config" line="33">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.598931" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:40:15.598777" elapsed="0.000266"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.598511" elapsed="0.000593"/>
</kw>
<kw name="Setup Master Password" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.599886" level="INFO">${payload} = {'master_password': 'TestPass123!', 'anime_directory': '/tmp/aniworld_test_anime', 'name': 'AniworldTest', 'data_dir': 'data', 'scheduler_enabled': 'False', 'logging_level': 'INFO', 'backup_enabled': ...</msg>
<var>${payload}</var>
<arg>master_password=${SETUP_PASSWORD}</arg>
<arg>anime_directory=/tmp/aniworld_test_anime</arg>
<arg>name=AniworldTest</arg>
<arg>data_dir=data</arg>
<arg>scheduler_enabled=False</arg>
<arg>logging_level=INFO</arg>
<arg>backup_enabled=False</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:40:15.599540" elapsed="0.000369"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.603054" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:40:15.603142" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=400, reason=Bad Request
headers={'date': 'Sat, 27 Jun 2026 13:40:14 GMT', 'server': 'uvicorn', 'content-length': '47', 'content-type': 'application/json'}
body={"detail":"Master password already configured"}
</msg>
<msg time="2026-06-27T15:40:15.603363" level="INFO">${resp} = &lt;Response [400]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.600003" elapsed="0.003393"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.604564" elapsed="0.000076"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.604739" elapsed="0.000084"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.603636" elapsed="0.001225"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.603586" elapsed="0.001308"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.605378" elapsed="0.000045"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.605497" elapsed="0.000040"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.604940" elapsed="0.000630"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.604927" elapsed="0.000669"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '400'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.606397" level="INFO">${json} = {'detail': 'Master password already configured'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:40:15.606042" elapsed="0.000376"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.616656" level="INFO">${detail} = ['Master password already configured']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:40:15.606491" elapsed="0.010192"/>
</kw>
<if>
<branch type="IF" condition="'${detail}[0]' == 'Master password already configured'">
<return>
<status status="PASS" start="2026-06-27T15:40:15.616975" elapsed="0.000133"/>
</return>
<status status="PASS" start="2026-06-27T15:40:15.616775" elapsed="0.000384"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.616744" elapsed="0.000451"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Setup failed with 400: ${detail}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.617304" elapsed="0.000076"/>
</kw>
<status status="PASS" start="2026-06-27T15:40:15.605633" elapsed="0.012043"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.605622" elapsed="0.012148"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '201'">
<kw name="Should Be Equal As Integers" owner="BuiltIn">
<arg>${resp.status_code}</arg>
<arg>201</arg>
<doc>Fails if objects are unequal after converting them to integers.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.618133" elapsed="0.000062"/>
</kw>
<return>
<status status="NOT RUN" start="2026-06-27T15:40:15.618250" elapsed="0.000058"/>
</return>
<status status="NOT RUN" start="2026-06-27T15:40:15.617875" elapsed="0.000463"/>
</branch>
<status status="NOT RUN" start="2026-06-27T15:40:15.617847" elapsed="0.000517"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Unexpected status ${resp.status_code} from /api/auth/setup</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.618489" elapsed="0.000122"/>
</kw>
<doc>Configure the master password via the setup endpoint.</doc>
<status status="PASS" start="2026-06-27T15:40:15.599318" elapsed="0.019502"/>
</kw>
<kw name="Create Authenticated Session" owner="common">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.619865" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:40:15.619699" elapsed="0.000377"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.619496" elapsed="0.000668"/>
</kw>
<kw name="Is Auth Configured" owner="common">
<kw name="GET On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.622509" level="INFO">GET Request : url=http://127.0.0.1:8765/api/auth/status
path_url=/api/auth/status
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
body=None
</msg>
<msg time="2026-06-27T15:40:15.622567" level="INFO">GET Response : url=http://127.0.0.1:8765/api/auth/status
status=200, reason=OK
headers={'date': 'Sat, 27 Jun 2026 13:40:14 GMT', 'server': 'uvicorn', 'content-length': '41', 'content-type': 'application/json'}
body={"configured":true,"authenticated":false}
</msg>
<msg time="2026-06-27T15:40:15.622653" level="INFO">${resp} = &lt;Response [200]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/status</arg>
<arg>expected_status=200</arg>
<doc>Sends a GET request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.620623" elapsed="0.002050"/>
</kw>
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.623223" level="INFO">${json} = {'configured': True, 'authenticated': False}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:40:15.622804" elapsed="0.000442"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:15.636288" level="INFO">${configured} = [True]</msg>
<var>${configured}</var>
<arg>${json}</arg>
<arg>$.configured</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:40:15.623340" elapsed="0.012991"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.637006" level="INFO">${configured_val} = True</msg>
<var>${configured_val}</var>
<arg>${configured}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:40:15.636484" elapsed="0.000558"/>
</kw>
<return>
<value>${configured_val}</value>
<status status="PASS" start="2026-06-27T15:40:15.637106" elapsed="0.000155"/>
</return>
<msg time="2026-06-27T15:40:15.637401" level="INFO">${configured} = True</msg>
<var>${configured}</var>
<doc>Check if the master password has already been configured.</doc>
<status status="PASS" start="2026-06-27T15:40:15.620342" elapsed="0.017079"/>
</kw>
<if>
<branch type="IF" condition="not ${configured}">
<kw name="Setup Master Password" owner="common">
<doc>Configure the master password via the setup endpoint.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.637957" elapsed="0.000053"/>
</kw>
<kw name="Login And Get Token" owner="common">
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.638160" elapsed="0.000044"/>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:40:15.638288" elapsed="0.000066"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:15.637509" elapsed="0.000877"/>
</branch>
<branch type="ELSE IF" condition="'${TOKEN}' == '${EMPTY}'">
<kw name="Login And Get Token" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:40:15.639385" level="INFO">${payload} = {'password': 'TestPass123!'}</msg>
<var>${payload}</var>
<arg>password=${SETUP_PASSWORD}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:40:15.639101" elapsed="0.000306"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:15.641279" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:40:15.641326" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:40:14 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:40:15.641393" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:15.639493" elapsed="0.001918"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:40:21.642315" level="INFO">Slept 6 seconds.</msg>
<arg>6s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:40:15.641932" elapsed="6.000482"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:21.644983" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:40:21.645037" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:40:20 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:40:21.645129" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:21.642577" elapsed="0.002572"/>
</kw>
<status status="PASS" start="2026-06-27T15:40:15.641485" elapsed="6.003842"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:15.641469" elapsed="6.003899"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' != '200'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:21.646262" level="INFO">${json} = {'detail': 'Too many failed attempts - temporarily locked out'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:40:21.645879" elapsed="0.000407"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:40:21.656831" level="INFO">${detail} = ['Too many failed attempts - temporarily locked out']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:40:21.646376" elapsed="0.010487"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:40:21.657285" level="INFO">${detail_val} = Too many failed attempts - temporarily locked out</msg>
<var>${detail_val}</var>
<arg>${detail}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:40:21.656979" elapsed="0.000329"/>
</kw>
<kw name="Fail" owner="BuiltIn">
<msg time="2026-06-27T15:40:21.657880" level="FAIL">Login failed with 429: Too many failed attempts - temporarily locked out</msg>
<arg>Login failed with ${resp.status_code}: ${detail_val}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="FAIL" start="2026-06-27T15:40:21.657396" elapsed="0.000549">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<status status="FAIL" start="2026-06-27T15:40:21.645424" elapsed="0.012574">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</branch>
<status status="FAIL" start="2026-06-27T15:40:21.645407" elapsed="0.012628">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</if>
<kw name="Convert String To Json" owner="JSONLibrary">
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="NOT RUN" start="2026-06-27T15:40:21.658112" elapsed="0.000056"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<var>${token}</var>
<arg>${json}</arg>
<arg>$.access_token</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="NOT RUN" start="2026-06-27T15:40:21.658244" elapsed="0.000041"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${token_str}</var>
<arg>${token}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:21.658358" elapsed="0.000042"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${TOKEN}</arg>
<arg>${token_str}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-06-27T15:40:21.658479" elapsed="0.000048"/>
</kw>
<return>
<value>${token_str}</value>
<status status="NOT RUN" start="2026-06-27T15:40:21.658566" elapsed="0.000045"/>
</return>
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="FAIL" start="2026-06-27T15:40:15.638894" elapsed="6.019795">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:40:21.658781" elapsed="0.000046"/>
</kw>
<status status="FAIL" start="2026-06-27T15:40:15.638417" elapsed="6.020451">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</branch>
<branch type="ELSE">
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${TOKEN}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:40:21.658995" elapsed="0.000038"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:40:21.658900" elapsed="0.000163"/>
</branch>
<status status="FAIL" start="2026-06-27T15:40:15.637485" elapsed="6.021603">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</if>
<doc>Create an authenticated HTTP session. Performs setup if needed, then logs in.
Skips setup/login if already authenticated (suite-level setup done).</doc>
<status status="FAIL" start="2026-06-27T15:40:15.619228" elapsed="6.039918">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<arg>Create Anonymous Session</arg>
<arg>AND</arg>
<arg>Setup Master Password</arg>
<arg>AND</arg>
<arg>Create Authenticated Session</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="FAIL" start="2026-06-27T15:40:15.598048" elapsed="6.061150">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<kw name="Delete All Sessions" owner="RequestsLibrary" type="TEARDOWN">
<msg time="2026-06-27T15:40:21.659448" level="INFO">Deleting All Sessions</msg>
<doc>Removes all the session objects</doc>
<status status="PASS" start="2026-06-27T15:40:21.659339" elapsed="0.000252"/>
</kw>
<doc>Update scheduler settings and verify they are persisted.</doc>
<status status="FAIL" start="2026-06-27T15:40:15.594983" elapsed="6.064652">Setup failed:
Login failed with 429: Too many failed attempts - temporarily locked out</status>
</test>
<test id="s1-t3" name="Trigger Manual Rescan" line="46">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:21.671142" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:40:21.670992" elapsed="0.000261"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:40:21.670764" elapsed="0.000547"/>
</kw>
<kw name="Setup Master Password" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:40:21.672044" level="INFO">${payload} = {'master_password': 'TestPass123!', 'anime_directory': '/tmp/aniworld_test_anime', 'name': 'AniworldTest', 'data_dir': 'data', 'scheduler_enabled': 'False', 'logging_level': 'INFO', 'backup_enabled': ...</msg>
<var>${payload}</var>
<arg>master_password=${SETUP_PASSWORD}</arg>
<arg>anime_directory=/tmp/aniworld_test_anime</arg>
<arg>name=AniworldTest</arg>
<arg>data_dir=data</arg>
<arg>scheduler_enabled=False</arg>
<arg>logging_level=INFO</arg>
<arg>backup_enabled=False</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:40:21.671723" elapsed="0.000343"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:40:21.673448" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:40:21.673644" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:40:20 GMT', 'server': 'uvicorn', 'content-length': '74', 'content-type': 'application/json'}
body={"detail":"Too many authentication attempts, try again later. IP lockout"}
</msg>
<msg time="2026-06-27T15:40:21.673750" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:40:21.672160" elapsed="0.001619"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:41:06.674918" level="INFO">Slept 45 seconds.</msg>
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:40:21.674463" elapsed="45.000547"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:06.676870" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:41:06.676915" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:41:05 GMT', 'server': 'uvicorn', 'content-length': '74', 'content-type': 'application/json'}
body={"detail":"Too many authentication attempts, try again later. IP lockout"}
</msg>
<msg time="2026-06-27T15:41:06.676993" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:06.675148" elapsed="0.001862"/>
</kw>
<status status="PASS" start="2026-06-27T15:40:21.673891" elapsed="45.003165"/>
</branch>
<status status="PASS" start="2026-06-27T15:40:21.673865" elapsed="45.003225"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:41:51.677981" level="INFO">Slept 45 seconds.</msg>
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:41:06.677603" elapsed="45.000472"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:51.680303" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:41:51.680359" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=400, reason=Bad Request
headers={'date': 'Sat, 27 Jun 2026 13:41:51 GMT', 'server': 'uvicorn', 'content-length': '47', 'content-type': 'application/json'}
body={"detail":"Master password already configured"}
</msg>
<msg time="2026-06-27T15:41:51.680449" level="INFO">${resp} = &lt;Response [400]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:51.678221" elapsed="0.002247"/>
</kw>
<status status="PASS" start="2026-06-27T15:41:06.677137" elapsed="45.003385"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:06.677123" elapsed="45.003436"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '400'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:51.681481" level="INFO">${json} = {'detail': 'Master password already configured'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:41:51.681084" elapsed="0.000422"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:51.691853" level="INFO">${detail} = ['Master password already configured']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:41:51.681599" elapsed="0.010293"/>
</kw>
<if>
<branch type="IF" condition="'${detail}[0]' == 'Master password already configured'">
<return>
<status status="PASS" start="2026-06-27T15:41:51.692183" elapsed="0.000071"/>
</return>
<status status="PASS" start="2026-06-27T15:41:51.691990" elapsed="0.000302"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:51.691973" elapsed="0.000344"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Setup failed with 400: ${detail}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:51.692409" elapsed="0.000058"/>
</kw>
<status status="PASS" start="2026-06-27T15:41:51.680613" elapsed="0.011887"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:51.680596" elapsed="0.011930"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '201'">
<kw name="Should Be Equal As Integers" owner="BuiltIn">
<arg>${resp.status_code}</arg>
<arg>201</arg>
<doc>Fails if objects are unequal after converting them to integers.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:51.692666" elapsed="0.000045"/>
</kw>
<return>
<status status="NOT RUN" start="2026-06-27T15:41:51.692773" elapsed="0.000044"/>
</return>
<status status="NOT RUN" start="2026-06-27T15:41:51.692564" elapsed="0.000278"/>
</branch>
<status status="NOT RUN" start="2026-06-27T15:41:51.692553" elapsed="0.000311"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Unexpected status ${resp.status_code} from /api/auth/setup</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:51.692921" elapsed="0.000041"/>
</kw>
<doc>Configure the master password via the setup endpoint.</doc>
<status status="PASS" start="2026-06-27T15:40:21.671524" elapsed="90.021488"/>
</kw>
<kw name="Create Authenticated Session" owner="common">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:51.693734" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:41:51.693597" elapsed="0.000281"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:41:51.693422" elapsed="0.000531"/>
</kw>
<kw name="Is Auth Configured" owner="common">
<kw name="GET On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:51.695816" level="INFO">GET Request : url=http://127.0.0.1:8765/api/auth/status
path_url=/api/auth/status
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
body=None
</msg>
<msg time="2026-06-27T15:41:51.695864" level="INFO">GET Response : url=http://127.0.0.1:8765/api/auth/status
status=200, reason=OK
headers={'date': 'Sat, 27 Jun 2026 13:41:51 GMT', 'server': 'uvicorn', 'content-length': '41', 'content-type': 'application/json'}
body={"configured":true,"authenticated":false}
</msg>
<msg time="2026-06-27T15:41:51.696114" level="INFO">${resp} = &lt;Response [200]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/status</arg>
<arg>expected_status=200</arg>
<doc>Sends a GET request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:51.694267" elapsed="0.001877"/>
</kw>
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:51.696774" level="INFO">${json} = {'configured': True, 'authenticated': False}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:41:51.696308" elapsed="0.000491"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:51.708049" level="INFO">${configured} = [True]</msg>
<var>${configured}</var>
<arg>${json}</arg>
<arg>$.configured</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:41:51.696904" elapsed="0.011183"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:41:51.708596" level="INFO">${configured_val} = True</msg>
<var>${configured_val}</var>
<arg>${configured}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:41:51.708230" elapsed="0.000392"/>
</kw>
<return>
<value>${configured_val}</value>
<status status="PASS" start="2026-06-27T15:41:51.708676" elapsed="0.000102"/>
</return>
<msg time="2026-06-27T15:41:51.708892" level="INFO">${configured} = True</msg>
<var>${configured}</var>
<doc>Check if the master password has already been configured.</doc>
<status status="PASS" start="2026-06-27T15:41:51.694066" elapsed="0.014843"/>
</kw>
<if>
<branch type="IF" condition="not ${configured}">
<kw name="Setup Master Password" owner="common">
<doc>Configure the master password via the setup endpoint.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:51.709269" elapsed="0.000054"/>
</kw>
<kw name="Login And Get Token" owner="common">
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:51.709463" elapsed="0.000047"/>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:41:51.709587" elapsed="0.000042"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:41:51.708970" elapsed="0.000689"/>
</branch>
<branch type="ELSE IF" condition="'${TOKEN}' == '${EMPTY}'">
<kw name="Login And Get Token" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:41:51.710651" level="INFO">${payload} = {'password': 'TestPass123!'}</msg>
<var>${payload}</var>
<arg>password=${SETUP_PASSWORD}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:41:51.710369" elapsed="0.000304"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:51.712550" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:41:51.712597" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:41:51 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:41:51.712668" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:51.710768" elapsed="0.001919"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:41:57.713499" level="INFO">Slept 6 seconds.</msg>
<arg>6s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:41:51.713170" elapsed="6.000450"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:57.716593" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:41:57.716650" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:41:57 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:41:57.716759" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:57.713836" elapsed="0.002947"/>
</kw>
<status status="PASS" start="2026-06-27T15:41:51.712791" elapsed="6.004050"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:51.712766" elapsed="6.004113"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' != '200'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:57.717782" level="INFO">${json} = {'detail': 'Too many failed attempts - temporarily locked out'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:41:57.717388" elapsed="0.000419"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:57.728534" level="INFO">${detail} = ['Too many failed attempts - temporarily locked out']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:41:57.717898" elapsed="0.010670"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:41:57.729018" level="INFO">${detail_val} = Too many failed attempts - temporarily locked out</msg>
<var>${detail_val}</var>
<arg>${detail}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:41:57.728692" elapsed="0.000349"/>
</kw>
<kw name="Fail" owner="BuiltIn">
<msg time="2026-06-27T15:41:57.729607" level="FAIL">Login failed with 429: Too many failed attempts - temporarily locked out</msg>
<arg>Login failed with ${resp.status_code}: ${detail_val}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="FAIL" start="2026-06-27T15:41:57.729133" elapsed="0.000526">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<status status="FAIL" start="2026-06-27T15:41:57.716933" elapsed="0.012793">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</branch>
<status status="FAIL" start="2026-06-27T15:41:57.716917" elapsed="0.012846">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</if>
<kw name="Convert String To Json" owner="JSONLibrary">
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.729842" elapsed="0.000052"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<var>${token}</var>
<arg>${json}</arg>
<arg>$.access_token</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.729975" elapsed="0.000044"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${token_str}</var>
<arg>${token}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.730207" elapsed="0.000064"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${TOKEN}</arg>
<arg>${token_str}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.730354" elapsed="0.000043"/>
</kw>
<return>
<value>${token_str}</value>
<status status="NOT RUN" start="2026-06-27T15:41:57.730437" elapsed="0.000044"/>
</return>
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="FAIL" start="2026-06-27T15:41:51.710161" elapsed="6.020402">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.730646" elapsed="0.000044"/>
</kw>
<status status="FAIL" start="2026-06-27T15:41:51.709685" elapsed="6.021058">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</branch>
<branch type="ELSE">
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${TOKEN}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.730872" elapsed="0.000040"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:41:57.730777" elapsed="0.000166"/>
</branch>
<status status="FAIL" start="2026-06-27T15:41:51.708956" elapsed="6.022010">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</if>
<doc>Create an authenticated HTTP session. Performs setup if needed, then logs in.
Skips setup/login if already authenticated (suite-level setup done).</doc>
<status status="FAIL" start="2026-06-27T15:41:51.693168" elapsed="6.037862">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<arg>Create Anonymous Session</arg>
<arg>AND</arg>
<arg>Setup Master Password</arg>
<arg>AND</arg>
<arg>Create Authenticated Session</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="FAIL" start="2026-06-27T15:40:21.670306" elapsed="96.060776">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<kw name="Delete All Sessions" owner="RequestsLibrary" type="TEARDOWN">
<msg time="2026-06-27T15:41:57.731333" level="INFO">Deleting All Sessions</msg>
<doc>Removes all the session objects</doc>
<status status="PASS" start="2026-06-27T15:41:57.731221" elapsed="0.000168"/>
</kw>
<doc>Manually trigger a scheduled rescan.</doc>
<status status="FAIL" start="2026-06-27T15:40:21.666396" elapsed="96.065028">Setup failed:
Login failed with 429: Too many failed attempts - temporarily locked out</status>
</test>
<test id="s1-t4" name="Invalid Schedule Time" line="56">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:57.740186" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:41:57.740030" elapsed="0.000267"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:41:57.739801" elapsed="0.000557"/>
</kw>
<kw name="Setup Master Password" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:41:57.741143" level="INFO">${payload} = {'master_password': 'TestPass123!', 'anime_directory': '/tmp/aniworld_test_anime', 'name': 'AniworldTest', 'data_dir': 'data', 'scheduler_enabled': 'False', 'logging_level': 'INFO', 'backup_enabled': ...</msg>
<var>${payload}</var>
<arg>master_password=${SETUP_PASSWORD}</arg>
<arg>anime_directory=/tmp/aniworld_test_anime</arg>
<arg>name=AniworldTest</arg>
<arg>data_dir=data</arg>
<arg>scheduler_enabled=False</arg>
<arg>logging_level=INFO</arg>
<arg>backup_enabled=False</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:41:57.740807" elapsed="0.000360"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:57.743024" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:41:57.743068" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=400, reason=Bad Request
headers={'date': 'Sat, 27 Jun 2026 13:41:57 GMT', 'server': 'uvicorn', 'content-length': '47', 'content-type': 'application/json'}
body={"detail":"Master password already configured"}
</msg>
<msg time="2026-06-27T15:41:57.743135" level="INFO">${resp} = &lt;Response [400]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:57.741263" elapsed="0.001890"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.743641" elapsed="0.000053"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.743786" elapsed="0.000045"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:41:57.743231" elapsed="0.000635"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:57.743213" elapsed="0.000684"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.744280" elapsed="0.000049"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.744406" elapsed="0.000043"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:41:57.743938" elapsed="0.000544"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:57.743927" elapsed="0.000581"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '400'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:57.745208" level="INFO">${json} = {'detail': 'Master password already configured'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:41:57.744866" elapsed="0.000363"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:57.756192" level="INFO">${detail} = ['Master password already configured']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:41:57.745308" elapsed="0.011032"/>
</kw>
<if>
<branch type="IF" condition="'${detail}[0]' == 'Master password already configured'">
<return>
<status status="PASS" start="2026-06-27T15:41:57.756623" elapsed="0.000061"/>
</return>
<status status="PASS" start="2026-06-27T15:41:57.756449" elapsed="0.000284"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:57.756430" elapsed="0.000339"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Setup failed with 400: ${detail}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.756857" elapsed="0.000055"/>
</kw>
<status status="PASS" start="2026-06-27T15:41:57.744545" elapsed="0.012402"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:57.744535" elapsed="0.012441"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '201'">
<kw name="Should Be Equal As Integers" owner="BuiltIn">
<arg>${resp.status_code}</arg>
<arg>201</arg>
<doc>Fails if objects are unequal after converting them to integers.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.757117" elapsed="0.000043"/>
</kw>
<return>
<status status="NOT RUN" start="2026-06-27T15:41:57.757198" elapsed="0.000043"/>
</return>
<status status="NOT RUN" start="2026-06-27T15:41:57.757016" elapsed="0.000250"/>
</branch>
<status status="NOT RUN" start="2026-06-27T15:41:57.757004" elapsed="0.000285"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Unexpected status ${resp.status_code} from /api/auth/setup</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.757346" elapsed="0.000041"/>
</kw>
<doc>Configure the master password via the setup endpoint.</doc>
<status status="PASS" start="2026-06-27T15:41:57.740574" elapsed="0.016865"/>
</kw>
<kw name="Create Authenticated Session" owner="common">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:57.758125" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:41:57.758001" elapsed="0.000234"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:41:57.757833" elapsed="0.000454"/>
</kw>
<kw name="Is Auth Configured" owner="common">
<kw name="GET On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:57.759987" level="INFO">GET Request : url=http://127.0.0.1:8765/api/auth/status
path_url=/api/auth/status
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
body=None
</msg>
<msg time="2026-06-27T15:41:57.760037" level="INFO">GET Response : url=http://127.0.0.1:8765/api/auth/status
status=200, reason=OK
headers={'date': 'Sat, 27 Jun 2026 13:41:57 GMT', 'server': 'uvicorn', 'content-length': '41', 'content-type': 'application/json'}
body={"configured":true,"authenticated":false}
</msg>
<msg time="2026-06-27T15:41:57.760111" level="INFO">${resp} = &lt;Response [200]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/status</arg>
<arg>expected_status=200</arg>
<doc>Sends a GET request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:57.758570" elapsed="0.001559"/>
</kw>
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:57.760625" level="INFO">${json} = {'configured': True, 'authenticated': False}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:41:57.760232" elapsed="0.000415"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:41:57.771294" level="INFO">${configured} = [True]</msg>
<var>${configured}</var>
<arg>${json}</arg>
<arg>$.configured</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:41:57.760740" elapsed="0.010584"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:41:57.771746" level="INFO">${configured_val} = True</msg>
<var>${configured_val}</var>
<arg>${configured}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:41:57.771435" elapsed="0.000334"/>
</kw>
<return>
<value>${configured_val}</value>
<status status="PASS" start="2026-06-27T15:41:57.771815" elapsed="0.000071"/>
</return>
<msg time="2026-06-27T15:41:57.771992" level="INFO">${configured} = True</msg>
<var>${configured}</var>
<doc>Check if the master password has already been configured.</doc>
<status status="PASS" start="2026-06-27T15:41:57.758393" elapsed="0.013618"/>
</kw>
<if>
<branch type="IF" condition="not ${configured}">
<kw name="Setup Master Password" owner="common">
<doc>Configure the master password via the setup endpoint.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.772373" elapsed="0.000053"/>
</kw>
<kw name="Login And Get Token" owner="common">
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.772578" elapsed="0.000044"/>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:41:57.772702" elapsed="0.000048"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:41:57.772074" elapsed="0.000709"/>
</branch>
<branch type="ELSE IF" condition="'${TOKEN}' == '${EMPTY}'">
<kw name="Login And Get Token" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:41:57.773709" level="INFO">${payload} = {'password': 'TestPass123!'}</msg>
<var>${payload}</var>
<arg>password=${SETUP_PASSWORD}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:41:57.773423" elapsed="0.000317"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:41:57.775434" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:41:57.775484" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:41:57 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:41:57.775557" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:41:57.773826" elapsed="0.001750"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:42:03.776429" level="INFO">Slept 6 seconds.</msg>
<arg>6s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:41:57.776069" elapsed="6.000503"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:42:03.778975" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:42:03.779260" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:42:03 GMT', 'server': 'uvicorn', 'content-length': '74', 'content-type': 'application/json'}
body={"detail":"Too many authentication attempts, try again later. IP lockout"}
</msg>
<msg time="2026-06-27T15:42:03.779428" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:42:03.776820" elapsed="0.002640"/>
</kw>
<status status="PASS" start="2026-06-27T15:41:57.775655" elapsed="6.003893"/>
</branch>
<status status="PASS" start="2026-06-27T15:41:57.775638" elapsed="6.003966"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' != '200'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:42:03.781175" level="INFO">${json} = {'detail': 'Too many authentication attempts, try again later. IP lockout'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:42:03.780510" elapsed="0.000708"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:42:03.792122" level="INFO">${detail} = ['Too many authentication attempts, try again later. IP lockout']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:42:03.781367" elapsed="0.010794"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:42:03.792661" level="INFO">${detail_val} = Too many authentication attempts, try again later. IP lockout</msg>
<var>${detail_val}</var>
<arg>${detail}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:42:03.792308" elapsed="0.000377"/>
</kw>
<kw name="Fail" owner="BuiltIn">
<msg time="2026-06-27T15:42:03.793292" level="FAIL">Login failed with 429: Too many authentication attempts, try again later. IP lockout</msg>
<arg>Login failed with ${resp.status_code}: ${detail_val}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="FAIL" start="2026-06-27T15:42:03.792794" elapsed="0.000553">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<status status="FAIL" start="2026-06-27T15:42:03.779696" elapsed="0.013709">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</branch>
<status status="FAIL" start="2026-06-27T15:42:03.779666" elapsed="0.013777">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</if>
<kw name="Convert String To Json" owner="JSONLibrary">
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="NOT RUN" start="2026-06-27T15:42:03.793522" elapsed="0.000060"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<var>${token}</var>
<arg>${json}</arg>
<arg>$.access_token</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="NOT RUN" start="2026-06-27T15:42:03.793660" elapsed="0.000042"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${token_str}</var>
<arg>${token}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-06-27T15:42:03.793785" elapsed="0.000040"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${TOKEN}</arg>
<arg>${token_str}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-06-27T15:42:03.793904" elapsed="0.000044"/>
</kw>
<return>
<value>${token_str}</value>
<status status="NOT RUN" start="2026-06-27T15:42:03.793986" elapsed="0.000043"/>
</return>
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="FAIL" start="2026-06-27T15:41:57.773236" elapsed="6.020870">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:42:03.794188" elapsed="0.000065"/>
</kw>
<status status="FAIL" start="2026-06-27T15:41:57.772812" elapsed="6.021484">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</branch>
<branch type="ELSE">
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${TOKEN}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:42:03.794428" elapsed="0.000044"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:42:03.794329" elapsed="0.000175"/>
</branch>
<status status="FAIL" start="2026-06-27T15:41:57.772059" elapsed="6.022469">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</if>
<doc>Create an authenticated HTTP session. Performs setup if needed, then logs in.
Skips setup/login if already authenticated (suite-level setup done).</doc>
<status status="FAIL" start="2026-06-27T15:41:57.757610" elapsed="6.036979">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<arg>Create Anonymous Session</arg>
<arg>AND</arg>
<arg>Setup Master Password</arg>
<arg>AND</arg>
<arg>Create Authenticated Session</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="FAIL" start="2026-06-27T15:41:57.739353" elapsed="6.055289">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<kw name="Delete All Sessions" owner="RequestsLibrary" type="TEARDOWN">
<msg time="2026-06-27T15:42:03.794935" level="INFO">Deleting All Sessions</msg>
<doc>Removes all the session objects</doc>
<status status="PASS" start="2026-06-27T15:42:03.794796" elapsed="0.000196"/>
</kw>
<doc>Verify that malformed schedule_time is rejected.</doc>
<status status="FAIL" start="2026-06-27T15:41:57.736800" elapsed="6.058230">Setup failed:
Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</test>
<test id="s1-t5" name="Invalid Schedule Days" line="67">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:42:03.803205" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:42:03.803061" elapsed="0.000256"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:42:03.802824" elapsed="0.000559"/>
</kw>
<kw name="Setup Master Password" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:42:03.804154" level="INFO">${payload} = {'master_password': 'TestPass123!', 'anime_directory': '/tmp/aniworld_test_anime', 'name': 'AniworldTest', 'data_dir': 'data', 'scheduler_enabled': 'False', 'logging_level': 'INFO', 'backup_enabled': ...</msg>
<var>${payload}</var>
<arg>master_password=${SETUP_PASSWORD}</arg>
<arg>anime_directory=/tmp/aniworld_test_anime</arg>
<arg>name=AniworldTest</arg>
<arg>data_dir=data</arg>
<arg>scheduler_enabled=False</arg>
<arg>logging_level=INFO</arg>
<arg>backup_enabled=False</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:42:03.803805" elapsed="0.000372"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:42:03.805810" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:42:03.805865" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:42:03 GMT', 'server': 'uvicorn', 'content-length': '74', 'content-type': 'application/json'}
body={"detail":"Too many authentication attempts, try again later. IP lockout"}
</msg>
<msg time="2026-06-27T15:42:03.805951" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:42:03.804417" elapsed="0.001555"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:42:48.806864" level="INFO">Slept 45 seconds.</msg>
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:42:03.806509" elapsed="45.000483"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:42:48.809268" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:42:48.809343" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:42:48 GMT', 'server': 'uvicorn', 'content-length': '74', 'content-type': 'application/json'}
body={"detail":"Too many authentication attempts, try again later. IP lockout"}
</msg>
<msg time="2026-06-27T15:42:48.809477" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:42:48.807201" elapsed="0.002306"/>
</kw>
<status status="PASS" start="2026-06-27T15:42:03.806061" elapsed="45.003528"/>
</branch>
<status status="PASS" start="2026-06-27T15:42:03.806042" elapsed="45.003603"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:43:33.810932" level="INFO">Slept 45 seconds.</msg>
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:42:48.810443" elapsed="45.000611"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:33.814041" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:43:33.814111" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=400, reason=Bad Request
headers={'date': 'Sat, 27 Jun 2026 13:43:33 GMT', 'server': 'uvicorn', 'content-length': '47', 'content-type': 'application/json'}
body={"detail":"Master password already configured"}
</msg>
<msg time="2026-06-27T15:43:33.814230" level="INFO">${resp} = &lt;Response [400]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:33.811255" elapsed="0.003002"/>
</kw>
<status status="PASS" start="2026-06-27T15:42:48.809730" elapsed="45.004598"/>
</branch>
<status status="PASS" start="2026-06-27T15:42:48.809699" elapsed="45.004677"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '400'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:33.815565" level="INFO">${json} = {'detail': 'Master password already configured'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:43:33.815060" elapsed="0.000536"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:33.829029" level="INFO">${detail} = ['Master password already configured']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:43:33.815733" elapsed="0.013332"/>
</kw>
<if>
<branch type="IF" condition="'${detail}[0]' == 'Master password already configured'">
<return>
<status status="PASS" start="2026-06-27T15:43:33.829341" elapsed="0.000069"/>
</return>
<status status="PASS" start="2026-06-27T15:43:33.829159" elapsed="0.000291"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:33.829140" elapsed="0.000340"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Setup failed with 400: ${detail}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:33.829571" elapsed="0.000053"/>
</kw>
<status status="PASS" start="2026-06-27T15:43:33.814449" elapsed="0.015209"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:33.814428" elapsed="0.015257"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '201'">
<kw name="Should Be Equal As Integers" owner="BuiltIn">
<arg>${resp.status_code}</arg>
<arg>201</arg>
<doc>Fails if objects are unequal after converting them to integers.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:33.829841" elapsed="0.000050"/>
</kw>
<return>
<status status="NOT RUN" start="2026-06-27T15:43:33.829929" elapsed="0.000041"/>
</return>
<status status="NOT RUN" start="2026-06-27T15:43:33.829735" elapsed="0.000261"/>
</branch>
<status status="NOT RUN" start="2026-06-27T15:43:33.829722" elapsed="0.000296"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Unexpected status ${resp.status_code} from /api/auth/setup</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:33.830075" elapsed="0.000040"/>
</kw>
<doc>Configure the master password via the setup endpoint.</doc>
<status status="PASS" start="2026-06-27T15:42:03.803598" elapsed="90.026571"/>
</kw>
<kw name="Create Authenticated Session" owner="common">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:33.830861" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:43:33.830728" elapsed="0.000239"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:43:33.830557" elapsed="0.000461"/>
</kw>
<kw name="Is Auth Configured" owner="common">
<kw name="GET On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:33.833091" level="INFO">GET Request : url=http://127.0.0.1:8765/api/auth/status
path_url=/api/auth/status
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
body=None
</msg>
<msg time="2026-06-27T15:43:33.833138" level="INFO">GET Response : url=http://127.0.0.1:8765/api/auth/status
status=200, reason=OK
headers={'date': 'Sat, 27 Jun 2026 13:43:33 GMT', 'server': 'uvicorn', 'content-length': '41', 'content-type': 'application/json'}
body={"configured":true,"authenticated":false}
</msg>
<msg time="2026-06-27T15:43:33.833212" level="INFO">${resp} = &lt;Response [200]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/status</arg>
<arg>expected_status=200</arg>
<doc>Sends a GET request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:33.831492" elapsed="0.001739"/>
</kw>
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:33.833758" level="INFO">${json} = {'configured': True, 'authenticated': False}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:43:33.833339" elapsed="0.000442"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:33.846471" level="INFO">${configured} = [True]</msg>
<var>${configured}</var>
<arg>${json}</arg>
<arg>$.configured</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:43:33.833871" elapsed="0.012635"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:43:33.846977" level="INFO">${configured_val} = True</msg>
<var>${configured_val}</var>
<arg>${configured}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:43:33.846637" elapsed="0.000363"/>
</kw>
<return>
<value>${configured_val}</value>
<status status="PASS" start="2026-06-27T15:43:33.847050" elapsed="0.000070"/>
</return>
<msg time="2026-06-27T15:43:33.847223" level="INFO">${configured} = True</msg>
<var>${configured}</var>
<doc>Check if the master password has already been configured.</doc>
<status status="PASS" start="2026-06-27T15:43:33.831267" elapsed="0.015974"/>
</kw>
<if>
<branch type="IF" condition="not ${configured}">
<kw name="Setup Master Password" owner="common">
<doc>Configure the master password via the setup endpoint.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:33.847609" elapsed="0.000056"/>
</kw>
<kw name="Login And Get Token" owner="common">
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:33.847822" elapsed="0.000049"/>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:43:33.847952" elapsed="0.000045"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:43:33.847300" elapsed="0.000730"/>
</branch>
<branch type="ELSE IF" condition="'${TOKEN}' == '${EMPTY}'">
<kw name="Login And Get Token" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:43:33.848988" level="INFO">${payload} = {'password': 'TestPass123!'}</msg>
<var>${payload}</var>
<arg>password=${SETUP_PASSWORD}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:43:33.848704" elapsed="0.000306"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:33.851126" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:43:33.851194" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:43:33 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:43:33.851295" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:33.849093" elapsed="0.002231"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:43:39.852459" level="INFO">Slept 6 seconds.</msg>
<arg>6s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:43:33.852023" elapsed="6.000528"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:39.855530" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:43:39.855575" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:43:39 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:43:39.855654" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:39.852691" elapsed="0.002981"/>
</kw>
<status status="PASS" start="2026-06-27T15:43:33.851432" elapsed="6.004293"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:33.851412" elapsed="6.004344"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' != '200'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:39.856643" level="INFO">${json} = {'detail': 'Too many failed attempts - temporarily locked out'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:43:39.856270" elapsed="0.000394"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:39.866216" level="INFO">${detail} = ['Too many failed attempts - temporarily locked out']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:43:39.856752" elapsed="0.009491"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:43:39.866707" level="INFO">${detail_val} = Too many failed attempts - temporarily locked out</msg>
<var>${detail_val}</var>
<arg>${detail}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:43:39.866343" elapsed="0.000399"/>
</kw>
<kw name="Fail" owner="BuiltIn">
<msg time="2026-06-27T15:43:39.867477" level="FAIL">Login failed with 429: Too many failed attempts - temporarily locked out</msg>
<arg>Login failed with ${resp.status_code}: ${detail_val}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="FAIL" start="2026-06-27T15:43:39.866864" elapsed="0.000666">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<status status="FAIL" start="2026-06-27T15:43:39.855804" elapsed="0.012226">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</branch>
<status status="FAIL" start="2026-06-27T15:43:39.855791" elapsed="0.012284">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</if>
<kw name="Convert String To Json" owner="JSONLibrary">
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.868163" elapsed="0.000111"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<var>${token}</var>
<arg>${json}</arg>
<arg>$.access_token</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.868355" elapsed="0.000083"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${token_str}</var>
<arg>${token}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.868511" elapsed="0.000084"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${TOKEN}</arg>
<arg>${token_str}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.868671" elapsed="0.000083"/>
</kw>
<return>
<value>${token_str}</value>
<status status="NOT RUN" start="2026-06-27T15:43:39.868792" elapsed="0.000042"/>
</return>
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="FAIL" start="2026-06-27T15:43:33.848505" elapsed="6.020403">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.868988" elapsed="0.000042"/>
</kw>
<status status="FAIL" start="2026-06-27T15:43:33.848059" elapsed="6.021011">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</branch>
<branch type="ELSE">
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${TOKEN}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.869190" elapsed="0.000038"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:43:39.869098" elapsed="0.000161"/>
</branch>
<status status="FAIL" start="2026-06-27T15:43:33.847286" elapsed="6.021997">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</if>
<doc>Create an authenticated HTTP session. Performs setup if needed, then logs in.
Skips setup/login if already authenticated (suite-level setup done).</doc>
<status status="FAIL" start="2026-06-27T15:43:33.830335" elapsed="6.039006">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<arg>Create Anonymous Session</arg>
<arg>AND</arg>
<arg>Setup Master Password</arg>
<arg>AND</arg>
<arg>Create Authenticated Session</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="FAIL" start="2026-06-27T15:42:03.802354" elapsed="96.067055">Login failed with 429: Too many failed attempts - temporarily locked out</status>
</kw>
<kw name="Delete All Sessions" owner="RequestsLibrary" type="TEARDOWN">
<msg time="2026-06-27T15:43:39.869671" level="INFO">Deleting All Sessions</msg>
<doc>Removes all the session objects</doc>
<status status="PASS" start="2026-06-27T15:43:39.869549" elapsed="0.000291"/>
</kw>
<doc>Verify that invalid day abbreviations are rejected.</doc>
<status status="FAIL" start="2026-06-27T15:42:03.799563" elapsed="96.070320">Setup failed:
Login failed with 429: Too many failed attempts - temporarily locked out</status>
</test>
<test id="s1-t6" name="Empty Schedule Days" line="78">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:39.878227" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:43:39.878086" elapsed="0.000252"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:43:39.877859" elapsed="0.000543"/>
</kw>
<kw name="Setup Master Password" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:43:39.879152" level="INFO">${payload} = {'master_password': 'TestPass123!', 'anime_directory': '/tmp/aniworld_test_anime', 'name': 'AniworldTest', 'data_dir': 'data', 'scheduler_enabled': 'False', 'logging_level': 'INFO', 'backup_enabled': ...</msg>
<var>${payload}</var>
<arg>master_password=${SETUP_PASSWORD}</arg>
<arg>anime_directory=/tmp/aniworld_test_anime</arg>
<arg>name=AniworldTest</arg>
<arg>data_dir=data</arg>
<arg>scheduler_enabled=False</arg>
<arg>logging_level=INFO</arg>
<arg>backup_enabled=False</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:43:39.878836" elapsed="0.000339"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:39.881000" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/setup
path_url=/api/auth/setup
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '208', 'Content-Type': 'application/json'}
body=b'{"master_password": "TestPass123!", "anime_directory": "/tmp/aniworld_test_anime", "name": "AniworldTest", "data_dir": "data", "scheduler_enabled": "False", "logging_level": "INFO", "backup_enabled": "False"}'
</msg>
<msg time="2026-06-27T15:43:39.881046" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=400, reason=Bad Request
headers={'date': 'Sat, 27 Jun 2026 13:43:39 GMT', 'server': 'uvicorn', 'content-length': '47', 'content-type': 'application/json'}
body={"detail":"Master password already configured"}
</msg>
<msg time="2026-06-27T15:43:39.881114" level="INFO">${resp} = &lt;Response [400]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:39.879271" elapsed="0.001862"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.881614" elapsed="0.000052"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.881754" elapsed="0.000042"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:43:39.881210" elapsed="0.000617"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:39.881193" elapsed="0.000661"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<arg>45s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.882215" elapsed="0.000038"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/setup</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.882317" elapsed="0.000036"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:43:39.881893" elapsed="0.000616"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:39.881882" elapsed="0.000666"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '400'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:39.883221" level="INFO">${json} = {'detail': 'Master password already configured'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:43:39.882911" elapsed="0.000331"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:39.893690" level="INFO">${detail} = ['Master password already configured']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:43:39.883318" elapsed="0.010406"/>
</kw>
<if>
<branch type="IF" condition="'${detail}[0]' == 'Master password already configured'">
<return>
<status status="PASS" start="2026-06-27T15:43:39.894030" elapsed="0.000059"/>
</return>
<status status="PASS" start="2026-06-27T15:43:39.893821" elapsed="0.000303"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:39.893805" elapsed="0.000346"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Setup failed with 400: ${detail}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.894233" elapsed="0.000048"/>
</kw>
<status status="PASS" start="2026-06-27T15:43:39.882596" elapsed="0.011717"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:39.882584" elapsed="0.011755"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '201'">
<kw name="Should Be Equal As Integers" owner="BuiltIn">
<arg>${resp.status_code}</arg>
<arg>201</arg>
<doc>Fails if objects are unequal after converting them to integers.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.894474" elapsed="0.000040"/>
</kw>
<return>
<status status="NOT RUN" start="2026-06-27T15:43:39.894551" elapsed="0.000035"/>
</return>
<status status="NOT RUN" start="2026-06-27T15:43:39.894377" elapsed="0.000233"/>
</branch>
<status status="NOT RUN" start="2026-06-27T15:43:39.894367" elapsed="0.000265"/>
</if>
<kw name="Fail" owner="BuiltIn">
<arg>Unexpected status ${resp.status_code} from /api/auth/setup</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.894688" elapsed="0.000046"/>
</kw>
<doc>Configure the master password via the setup endpoint.</doc>
<status status="PASS" start="2026-06-27T15:43:39.878616" elapsed="0.016177"/>
</kw>
<kw name="Create Authenticated Session" owner="common">
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:39.895413" level="INFO">Creating Session using : alias=anon, url=http://127.0.0.1:8765, headers={}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<arg>anon</arg>
<arg>${BASE_URL}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="PASS" start="2026-06-27T15:43:39.895279" elapsed="0.000227"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T15:43:39.895131" elapsed="0.000423"/>
</kw>
<kw name="Is Auth Configured" owner="common">
<kw name="GET On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:39.897240" level="INFO">GET Request : url=http://127.0.0.1:8765/api/auth/status
path_url=/api/auth/status
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
body=None
</msg>
<msg time="2026-06-27T15:43:39.897283" level="INFO">GET Response : url=http://127.0.0.1:8765/api/auth/status
status=200, reason=OK
headers={'date': 'Sat, 27 Jun 2026 13:43:39 GMT', 'server': 'uvicorn', 'content-length': '41', 'content-type': 'application/json'}
body={"configured":true,"authenticated":false}
</msg>
<msg time="2026-06-27T15:43:39.897347" level="INFO">${resp} = &lt;Response [200]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/status</arg>
<arg>expected_status=200</arg>
<doc>Sends a GET request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:39.895869" elapsed="0.001494"/>
</kw>
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:39.897849" level="INFO">${json} = {'configured': True, 'authenticated': False}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:43:39.897449" elapsed="0.000422"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:39.907579" level="INFO">${configured} = [True]</msg>
<var>${configured}</var>
<arg>${json}</arg>
<arg>$.configured</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:43:39.897956" elapsed="0.009652"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:43:39.908173" level="INFO">${configured_val} = True</msg>
<var>${configured_val}</var>
<arg>${configured}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:43:39.907711" elapsed="0.000485"/>
</kw>
<return>
<value>${configured_val}</value>
<status status="PASS" start="2026-06-27T15:43:39.908240" elapsed="0.000153"/>
</return>
<msg time="2026-06-27T15:43:39.908487" level="INFO">${configured} = True</msg>
<var>${configured}</var>
<doc>Check if the master password has already been configured.</doc>
<status status="PASS" start="2026-06-27T15:43:39.895650" elapsed="0.012854"/>
</kw>
<if>
<branch type="IF" condition="not ${configured}">
<kw name="Setup Master Password" owner="common">
<doc>Configure the master password via the setup endpoint.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.908885" elapsed="0.000089"/>
</kw>
<kw name="Login And Get Token" owner="common">
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.909111" elapsed="0.000043"/>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:43:39.909225" elapsed="0.000038"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:43:39.908558" elapsed="0.000733"/>
</branch>
<branch type="ELSE IF" condition="'${TOKEN}' == '${EMPTY}'">
<kw name="Login And Get Token" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T15:43:39.910227" level="INFO">${payload} = {'password': 'TestPass123!'}</msg>
<var>${payload}</var>
<arg>password=${SETUP_PASSWORD}</arg>
<doc>Creates and returns a dictionary based on the given ``items``.</doc>
<status status="PASS" start="2026-06-27T15:43:39.909974" elapsed="0.000273"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:39.912070" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:43:39.912112" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:43:39 GMT', 'server': 'uvicorn', 'content-length': '62', 'content-type': 'application/json'}
body={"detail":"Too many failed attempts - temporarily locked out"}
</msg>
<msg time="2026-06-27T15:43:39.912390" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:39.910322" elapsed="0.002092"/>
</kw>
<if>
<branch type="IF" condition="'${resp.status_code}' == '429'">
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T15:43:45.913374" level="INFO">Slept 6 seconds.</msg>
<arg>6s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T15:43:39.912897" elapsed="6.000571"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T15:43:45.915410" level="INFO">POST Request : url=http://127.0.0.1:8765/api/auth/login
path_url=/api/auth/login
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive', 'Content-Length': '28', 'Content-Type': 'application/json'}
body=b'{"password": "TestPass123!"}'
</msg>
<msg time="2026-06-27T15:43:45.915457" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=429, reason=Too Many Requests
headers={'date': 'Sat, 27 Jun 2026 13:43:45 GMT', 'server': 'uvicorn', 'content-length': '74', 'content-type': 'application/json'}
body={"detail":"Too many authentication attempts, try again later. IP lockout"}
</msg>
<msg time="2026-06-27T15:43:45.915539" level="INFO">${resp} = &lt;Response [429]&gt;</msg>
<var>${resp}</var>
<arg>anon</arg>
<arg>/api/auth/login</arg>
<arg>json=${payload}</arg>
<arg>expected_status=any</arg>
<doc>Sends a POST request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T15:43:45.913608" elapsed="0.001951"/>
</kw>
<status status="PASS" start="2026-06-27T15:43:39.912494" elapsed="6.003113"/>
</branch>
<status status="PASS" start="2026-06-27T15:43:39.912477" elapsed="6.003165"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' != '200'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:45.916604" level="INFO">${json} = {'detail': 'Too many authentication attempts, try again later. IP lockout'}</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T15:43:45.916242" elapsed="0.000384"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T15:43:45.926354" level="INFO">${detail} = ['Too many authentication attempts, try again later. IP lockout']</msg>
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T15:43:45.916720" elapsed="0.009663"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T15:43:45.926914" level="INFO">${detail_val} = Too many authentication attempts, try again later. IP lockout</msg>
<var>${detail_val}</var>
<arg>${detail}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T15:43:45.926483" elapsed="0.000453"/>
</kw>
<kw name="Fail" owner="BuiltIn">
<msg time="2026-06-27T15:43:45.927618" level="FAIL">Login failed with 429: Too many authentication attempts, try again later. IP lockout</msg>
<arg>Login failed with ${resp.status_code}: ${detail_val}</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="FAIL" start="2026-06-27T15:43:45.927020" elapsed="0.000650">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<status status="FAIL" start="2026-06-27T15:43:45.915691" elapsed="0.012036">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</branch>
<status status="FAIL" start="2026-06-27T15:43:45.915677" elapsed="0.012098">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</if>
<kw name="Convert String To Json" owner="JSONLibrary">
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="NOT RUN" start="2026-06-27T15:43:45.927857" elapsed="0.000134"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<var>${token}</var>
<arg>${json}</arg>
<arg>$.access_token</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="NOT RUN" start="2026-06-27T15:43:45.928087" elapsed="0.000141"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${token_str}</var>
<arg>${token}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:45.928326" elapsed="0.000053"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<arg>${TOKEN}</arg>
<arg>${token_str}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="NOT RUN" start="2026-06-27T15:43:45.928460" elapsed="0.000040"/>
</kw>
<return>
<value>${token_str}</value>
<status status="NOT RUN" start="2026-06-27T15:43:45.928536" elapsed="0.000043"/>
</return>
<var>${token}</var>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="FAIL" start="2026-06-27T15:43:39.909779" elapsed="6.018874">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${token}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:43:45.928735" elapsed="0.000168"/>
</kw>
<status status="FAIL" start="2026-06-27T15:43:39.909317" elapsed="6.019645">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</branch>
<branch type="ELSE">
<kw name="Create Session" owner="RequestsLibrary">
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${TOKEN}'}</arg>
<doc>Create Session: create a HTTP session to a server</doc>
<status status="NOT RUN" start="2026-06-27T15:43:45.929105" elapsed="0.000048"/>
</kw>
<status status="NOT RUN" start="2026-06-27T15:43:45.928995" elapsed="0.000191"/>
</branch>
<status status="FAIL" start="2026-06-27T15:43:39.908545" elapsed="6.020664">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</if>
<doc>Create an authenticated HTTP session. Performs setup if needed, then logs in.
Skips setup/login if already authenticated (suite-level setup done).</doc>
<status status="FAIL" start="2026-06-27T15:43:39.894945" elapsed="6.034324">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<arg>Create Anonymous Session</arg>
<arg>AND</arg>
<arg>Setup Master Password</arg>
<arg>AND</arg>
<arg>Create Authenticated Session</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="FAIL" start="2026-06-27T15:43:39.877411" elapsed="6.051905">Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</kw>
<kw name="Delete All Sessions" owner="RequestsLibrary" type="TEARDOWN">
<msg time="2026-06-27T15:43:45.929648" level="INFO">Deleting All Sessions</msg>
<doc>Removes all the session objects</doc>
<status status="PASS" start="2026-06-27T15:43:45.929445" elapsed="0.000261"/>
</kw>
<doc>Verify that empty schedule_days is handled.</doc>
<status status="FAIL" start="2026-06-27T15:43:39.874375" elapsed="6.055376">Setup failed:
Login failed with 429: Too many authentication attempts, try again later. IP lockout</status>
</test>
<doc>Scheduler API tests for Aniworld.
Covers get config, update config, trigger rescan, and validation.</doc>
<status status="FAIL" start="2026-06-27T15:40:14.897233" elapsed="211.037324"/>
</suite>
<statistics>
<total>
<stat pass="0" fail="6" skip="0">All Tests</stat>
</total>
<tag>
</tag>
<suite>
<stat name="Scheduler" id="s1" pass="0" fail="6" skip="0">Scheduler</stat>
</suite>
</statistics>
<errors>
</errors>
</robot>