Files
Aniworld/robot_output/output.xml
Lukas 6c502e2014 fix: scan episodes synchronously and disable test mode rate limiting
- Always scan missing episodes sync in add_series to avoid race condition
- Add db fallback in get_anime when in-memory episodeDict empty
- Add with_episodes param to AnimeSeriesService.get_by_key
- Disable auth rate limiting and lockout in test mode (ANIWORLD_TESTING=1)
- Simplify responsive.robot tests: fix setup, remove fragile width checks
2026-06-27 13:42:09 +02:00

1229 lines
56 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<robot generator="Robot 7.4.2 (Python 3.13.5 on linux)" generated="2026-06-27T00:11:00.220989" rpa="false" schemaversion="5">
<suite id="s1" name="Responsive" source="/home/lukas/Volume/repo/Aniworld/tests/robot/ui/responsive.robot">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Start Aniworld Server" owner="common">
<kw name="Start Process" owner="Process">
<msg time="2026-06-27T00:11:00.467699" level="INFO">Starting process:
bash /home/lukas/Volume/repo/Aniworld/tests/robot/start_server.sh</msg>
<msg time="2026-06-27T00:11:00.468334" level="INFO">${handle} = &lt;Popen: returncode: None args: ['bash', '/home/lukas/Volume/repo/Aniworld/te...&gt;</msg>
<var>${handle}</var>
<arg>bash</arg>
<arg>/home/lukas/Volume/repo/Aniworld/tests/robot/start_server.sh</arg>
<arg>cwd=/home/lukas/Volume/repo/Aniworld</arg>
<arg>stdout=/home/lukas/Volume/repo/Aniworld/tests/robot/resources/../fixtures/server_stdout.log</arg>
<arg>stderr=/home/lukas/Volume/repo/Aniworld/tests/robot/resources/../fixtures/server_stderr.log</arg>
<doc>Starts a new process on background.</doc>
<status status="PASS" start="2026-06-27T00:11:00.466976" elapsed="0.001392"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<msg time="2026-06-27T00:11:00.468853" level="INFO">${SERVER_PROCESS} = &lt;Popen: returncode: None args: ['bash', '/home/lukas/Volume/repo/Aniworld/te...&gt;</msg>
<arg>${SERVER_PROCESS}</arg>
<arg>${handle}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="PASS" start="2026-06-27T00:11:00.468516" elapsed="0.000398"/>
</kw>
<kw name="Sleep" owner="BuiltIn">
<msg time="2026-06-27T00:11:05.469435" level="INFO">Slept 5 seconds.</msg>
<arg>5s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="PASS" start="2026-06-27T00:11:00.469041" elapsed="5.000550"/>
</kw>
<doc>Start the FastAPI uvicorn server as a background process.</doc>
<status status="PASS" start="2026-06-27T00:11:00.466711" elapsed="5.003048"/>
</kw>
<kw name="Create Anonymous Session" owner="common">
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T00:11:05.471006" 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-27T00:11:05.470673" elapsed="0.000561"/>
</kw>
<doc>Create an unauthenticated HTTP session.</doc>
<status status="PASS" start="2026-06-27T00:11:05.470050" elapsed="0.001309"/>
</kw>
<kw name="Wait For Server" owner="common">
<for flavor="IN RANGE">
<iter>
<kw name="Run Keyword And Ignore Error" owner="BuiltIn">
<kw name="GET On Session" owner="RequestsLibrary">
<msg time="2026-06-27T00:11:05.476546" level="INFO">GET Request : url=http://127.0.0.1:8765/health
path_url=/health
headers={'User-Agent': 'python-requests/2.33.1', 'Accept-Encoding': 'gzip, deflate, br', 'Accept': '*/*', 'Connection': 'keep-alive'}
body=None
</msg>
<msg time="2026-06-27T00:11:05.476678" level="INFO">GET Response : url=http://127.0.0.1:8765/health
status=200, reason=OK
headers={'date': 'Fri, 26 Jun 2026 22:11:05 GMT', 'server': 'uvicorn', 'content-length': '583', 'content-type': 'application/json'}
body={"status":"healthy","timestamp":"2026-06-27T00:11:05.475722","version":"v1.4.17","service":"aniworld-api","series_app_initialized":true,"anime_directory_configured":true,"scheduler_next_run":"2026-06-27T03:00:00+02:00","scheduler_last_run":null,"checks":{"ffmpeg":{"status":"ok","message":"Found at /usr/bin/ffmpeg"},"dns_aniworld":{"status":"ok","message":"Resolved successfully"},"dns_tmdb":{"status":"ok","message":"Resolved successfully"},"anime_directory":{"status":"ok","message":"Directory exists and is writable: /tmp/aniworld_test_anime","path":"/tmp/aniworld_test_anime"}}}
</msg>
<arg>anon</arg>
<arg>/health</arg>
<arg>expected_status=any</arg>
<doc>Sends a GET request on a previously created HTTP Session.</doc>
<status status="PASS" start="2026-06-27T00:11:05.473011" elapsed="0.003759"/>
</kw>
<msg time="2026-06-27T00:11:05.476966" level="INFO">${resp} = ('PASS', &lt;Response [200]&gt;)</msg>
<var>${resp}</var>
<arg>GET On Session</arg>
<arg>anon</arg>
<arg>/health</arg>
<arg>expected_status=any</arg>
<doc>Runs the given keyword with the given arguments and ignores possible error.</doc>
<status status="PASS" start="2026-06-27T00:11:05.472576" elapsed="0.004416"/>
</kw>
<if>
<branch type="IF" condition="'${resp}[0]' == 'PASS'">
<kw name="Evaluate" owner="BuiltIn">
<msg time="2026-06-27T00:11:05.478333" level="INFO">${status_code} = 200</msg>
<var>${status_code}</var>
<arg>$resp[1].status_code</arg>
<doc>Evaluates the given expression in Python and returns the result.</doc>
<status status="PASS" start="2026-06-27T00:11:05.477646" elapsed="0.000735"/>
</kw>
<if>
<branch type="IF" condition="$status_code == 200 or $status_code == 503">
<return>
<status status="PASS" start="2026-06-27T00:11:05.478970" elapsed="0.000151"/>
</return>
<status status="PASS" start="2026-06-27T00:11:05.478552" elapsed="0.000633"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.478511" elapsed="0.000719"/>
</if>
<status status="PASS" start="2026-06-27T00:11:05.477113" elapsed="0.002150"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.477078" elapsed="0.002220"/>
</if>
<kw name="Sleep" owner="BuiltIn">
<arg>1s</arg>
<doc>Pauses the test executed for the given time.</doc>
<status status="NOT RUN" start="2026-06-27T00:11:05.479413" elapsed="0.000104"/>
</kw>
<var name="${i}">0</var>
<status status="PASS" start="2026-06-27T00:11:05.472351" elapsed="0.007217"/>
</iter>
<var>${i}</var>
<value>30</value>
<status status="PASS" start="2026-06-27T00:11:05.471926" elapsed="0.007707"/>
</for>
<kw name="Fail" owner="BuiltIn">
<arg>Server did not become healthy within 30 seconds</arg>
<doc>Fails the test with the given message and optionally alters its tags.</doc>
<status status="NOT RUN" start="2026-06-27T00:11:05.479814" elapsed="0.000065"/>
</kw>
<doc>Poll the health endpoint until the server responds.
Accepts 200 or 503 (not configured yet) as valid responses.
Retries every 1 second for up to 30 seconds.</doc>
<status status="PASS" start="2026-06-27T00:11:05.471672" elapsed="0.008286"/>
</kw>
<kw name="Setup Master Password" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T00:11:05.481529" 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-27T00:11:05.480940" elapsed="0.000623"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T00:11:05.484154" 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-27T00:11:05.484230" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/setup
status=400, reason=Bad Request
headers={'date': 'Fri, 26 Jun 2026 22:11:05 GMT', 'server': 'uvicorn', 'content-length': '47', 'content-type': 'application/json'}
body={"detail":"Master password already configured"}
</msg>
<msg time="2026-06-27T00:11:05.484639" 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-27T00:11:05.481710" elapsed="0.002963"/>
</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-27T00:11:05.485515" elapsed="0.000075"/>
</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-27T00:11:05.485716" elapsed="0.000126"/>
</kw>
<status status="NOT RUN" start="2026-06-27T00:11:05.484825" elapsed="0.001069"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.484799" elapsed="0.001138"/>
</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-27T00:11:05.486482" elapsed="0.000063"/>
</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-27T00:11:05.486644" elapsed="0.000062"/>
</kw>
<status status="NOT RUN" start="2026-06-27T00:11:05.486000" elapsed="0.000753"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.485983" elapsed="0.000807"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' == '400'">
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T00:11:05.487706" 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-27T00:11:05.487270" elapsed="0.000479"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T00:11:05.508095" 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-27T00:11:05.487868" elapsed="0.020282"/>
</kw>
<if>
<branch type="IF" condition="'${detail}[0]' == 'Master password already configured'">
<return>
<status status="PASS" start="2026-06-27T00:11:05.508708" elapsed="0.000162"/>
</return>
<status status="PASS" start="2026-06-27T00:11:05.508300" elapsed="0.000629"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.508271" elapsed="0.000698"/>
</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-27T00:11:05.509108" elapsed="0.000161"/>
</kw>
<status status="PASS" start="2026-06-27T00:11:05.486845" elapsed="0.022470"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.486832" elapsed="0.022522"/>
</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-27T00:11:05.509570" elapsed="0.000056"/>
</kw>
<return>
<status status="NOT RUN" start="2026-06-27T00:11:05.509678" elapsed="0.000120"/>
</return>
<status status="NOT RUN" start="2026-06-27T00:11:05.509414" elapsed="0.000421"/>
</branch>
<status status="NOT RUN" start="2026-06-27T00:11:05.509398" elapsed="0.000475"/>
</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-27T00:11:05.510055" elapsed="0.000214"/>
</kw>
<doc>Configure the master password via the setup endpoint.</doc>
<status status="PASS" start="2026-06-27T00:11:05.480658" elapsed="0.029760"/>
</kw>
<kw name="Login And Get Token" owner="common">
<kw name="Create Dictionary" owner="BuiltIn">
<msg time="2026-06-27T00:11:05.511663" 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-27T00:11:05.511179" elapsed="0.000529"/>
</kw>
<kw name="POST On Session" owner="RequestsLibrary">
<msg time="2026-06-27T00:11:05.522829" 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-27T00:11:05.522936" level="INFO">POST Response : url=http://127.0.0.1:8765/api/auth/login
status=200, reason=OK
headers={'date': 'Fri, 26 Jun 2026 22:11:05 GMT', 'server': 'uvicorn', 'content-length': '232', 'content-type': 'application/json'}
body={"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYXN0ZXIiLCJleHAiOjE3ODI1OTgyNjUsImlhdCI6MTc4MjUxMTg2NX0.oQ307cnSsVWuTlBbwlWWrNTrbSD4kK2o9uqnC2s1KFY","token_type":"bearer","expires_at":"2026-06-27T22:11:05.521518Z"}
</msg>
<msg time="2026-06-27T00:11:05.523091" level="INFO">${resp} = &lt;Response [200]&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-27T00:11:05.511854" elapsed="0.011283"/>
</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-27T00:11:05.524288" elapsed="0.000189"/>
</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-27T00:11:05.524640" elapsed="0.000164"/>
</kw>
<status status="NOT RUN" start="2026-06-27T00:11:05.523295" elapsed="0.001568"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.523262" elapsed="0.001650"/>
</if>
<if>
<branch type="IF" condition="'${resp.status_code}' != '200'">
<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-27T00:11:05.525607" elapsed="0.000074"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<var>${detail}</var>
<arg>${json}</arg>
<arg>$.detail</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="NOT RUN" start="2026-06-27T00:11:05.525820" elapsed="0.000072"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<var>${detail_val}</var>
<arg>${detail}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="NOT RUN" start="2026-06-27T00:11:05.526007" elapsed="0.000077"/>
</kw>
<kw name="Fail" owner="BuiltIn">
<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="NOT RUN" start="2026-06-27T00:11:05.526192" elapsed="0.000061"/>
</kw>
<status status="NOT RUN" start="2026-06-27T00:11:05.524992" elapsed="0.001303"/>
</branch>
<status status="PASS" start="2026-06-27T00:11:05.524970" elapsed="0.001367"/>
</if>
<kw name="Convert String To Json" owner="JSONLibrary">
<msg time="2026-06-27T00:11:05.527193" level="INFO">${json} = {'access_token': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYXN0ZXIiLCJleHAiOjE3ODI1OTgyNjUsImlhdCI6MTc4MjUxMTg2NX0.oQ307cnSsVWuTlBbwlWWrNTrbSD4kK2o9uqnC2s1KFY', 'token_type': 'bearer', 'expire...</msg>
<var>${json}</var>
<arg>${resp.text}</arg>
<doc>Convert String to JSON object</doc>
<status status="PASS" start="2026-06-27T00:11:05.526429" elapsed="0.000798"/>
</kw>
<kw name="Get Value From Json" owner="JSONLibrary">
<msg time="2026-06-27T00:11:05.545391" level="INFO">${token} = ['eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYXN0ZXIiLCJleHAiOjE3ODI1OTgyNjUsImlhdCI6MTc4MjUxMTg2NX0.oQ307cnSsVWuTlBbwlWWrNTrbSD4kK2o9uqnC2s1KFY']</msg>
<var>${token}</var>
<arg>${json}</arg>
<arg>$.access_token</arg>
<doc>Get Value From JSON using JSONPath</doc>
<status status="PASS" start="2026-06-27T00:11:05.527348" elapsed="0.018096"/>
</kw>
<kw name="Set Variable" owner="BuiltIn">
<msg time="2026-06-27T00:11:05.546204" level="INFO">${token_str} = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYXN0ZXIiLCJleHAiOjE3ODI1OTgyNjUsImlhdCI6MTc4MjUxMTg2NX0.oQ307cnSsVWuTlBbwlWWrNTrbSD4kK2o9uqnC2s1KFY</msg>
<var>${token_str}</var>
<arg>${token}[0]</arg>
<doc>Returns the given values which can then be assigned to a variables.</doc>
<status status="PASS" start="2026-06-27T00:11:05.545644" elapsed="0.000596"/>
</kw>
<kw name="Set Suite Variable" owner="BuiltIn">
<msg time="2026-06-27T00:11:05.546881" level="INFO">${TOKEN} = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYXN0ZXIiLCJleHAiOjE3ODI1OTgyNjUsImlhdCI6MTc4MjUxMTg2NX0.oQ307cnSsVWuTlBbwlWWrNTrbSD4kK2o9uqnC2s1KFY</msg>
<arg>${TOKEN}</arg>
<arg>${token_str}</arg>
<doc>Makes a variable available everywhere within the scope of the current suite.</doc>
<status status="PASS" start="2026-06-27T00:11:05.546404" elapsed="0.000521"/>
</kw>
<return>
<value>${token_str}</value>
<status status="PASS" start="2026-06-27T00:11:05.546990" elapsed="0.000187"/>
</return>
<doc>Log in with the master password and return the JWT access token.</doc>
<status status="PASS" start="2026-06-27T00:11:05.510887" elapsed="0.036407"/>
</kw>
<kw name="Create Session" owner="RequestsLibrary">
<msg time="2026-06-27T00:11:05.547765" level="INFO">Creating Session using : alias=auth, url=http://127.0.0.1:8765, headers={'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJtYXN0ZXIiLCJleHAiOjE3ODI1OTgyNjUsImlhdCI6MTc4MjUxMTg2NX0.oQ307cnSsVWuTlBbwlWWrNTrbSD4kK2o9uqnC2s1KFY'}, cookies={}, auth=None, timeout=None, proxies=None, verify=False, debug=0 </msg>
<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="PASS" start="2026-06-27T00:11:05.547428" elapsed="0.000495"/>
</kw>
<kw name="Initialize Browser" owner="common">
<kw name="New Browser" owner="Browser">
<msg time="2026-06-27T00:11:05.549085" level="INFO">{"browser": "chromium", "headless": true, "chromiumSandbox": false, "devtools": false, "handleSIGHUP": true, "handleSIGINT": true, "handleSIGTERM": true, "slowMo": 0.0, "timeout": 30000.0, "tracesDir": "/home/lukas/Volume/repo/Aniworld/robot_output/browser/traces/temp/f808209d-8694-49b8-8298-841cb668b8c1"}</msg>
<msg time="2026-06-27T00:11:05.554197" level="INFO">Starting Browser process /home/lukas/miniconda3/lib/python3.13/site-packages/Browser/wrapper/index.js using at 127.0.0.1:48397</msg>
<msg time="2026-06-27T00:11:06.039010" level="INFO">Successfully created browser with options: {"browser":"chromium","headless":true,"chromiumSandbox":false,"devtools":false,"handleSIGHUP":true,"handleSIGINT":true,"handleSIGTERM":true,"slowMo":0,"timeout":30000,"tracesDir":"/home/lukas/Volume/repo/Aniworld/robot_output/browser/traces/temp/f808209d-8694-49b8-8298-841cb668b8c1"}</msg>
<arg>${BROWSER}</arg>
<arg>headless=${HEADLESS}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new playwright Browser with specified options.</doc>
<status status="PASS" start="2026-06-27T00:11:05.548415" elapsed="0.490914"/>
</kw>
<kw name="New Context" owner="Browser">
<msg time="2026-06-27T00:11:06.041037" level="INFO">{
"acceptDownloads": true,
"bypassCSP": false,
"forcedColors": "none",
"ignoreHTTPSErrors": false,
"javaScriptEnabled": true,
"offline": false,
"reducedMotion": "no-preference",
"serviceWorkers": "allow",
"viewport": {
"width": 1280,
"height": 720
}
}</msg>
<msg time="2026-06-27T00:11:06.052337" level="INFO">Successfully created context. </msg>
<msg time="2026-06-27T00:11:06.052421" level="INFO">{'acceptDownloads': True, 'bypassCSP': False, 'forcedColors': 'none', 'ignoreHTTPSErrors': False, 'javaScriptEnabled': True, 'offline': False, 'reducedMotion': 'no-preference', 'serviceWorkers': 'allow', 'viewport': {'width': 1280, 'height': 720}}</msg>
<arg>viewport={'width': 1280, 'height': 720}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Create a new BrowserContext with specified options.</doc>
<status status="PASS" start="2026-06-27T00:11:06.039595" elapsed="0.012901"/>
</kw>
<doc>Initialize Browser library with the configured browser and headless mode.</doc>
<status status="PASS" start="2026-06-27T00:11:05.548090" elapsed="0.504508"/>
</kw>
<arg>Start Aniworld Server</arg>
<arg>AND</arg>
<arg>Create Anonymous Session</arg>
<arg>AND</arg>
<arg>Wait For Server</arg>
<arg>AND</arg>
<arg>Setup Master Password</arg>
<arg>AND</arg>
<arg>Login And Get Token</arg>
<arg>AND</arg>
<arg>Create Session</arg>
<arg>auth</arg>
<arg>${BASE_URL}</arg>
<arg>headers={'Authorization': 'Bearer ${TOKEN}'}</arg>
<arg>AND</arg>
<arg>Initialize Browser</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="PASS" start="2026-06-27T00:11:00.465971" elapsed="5.586675"/>
</kw>
<test id="s1-t1" name="Mobile Viewport Layout" line="28">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Open Browser To Page" owner="common">
<kw name="New Page" owner="Browser">
<msg time="2026-06-27T00:11:06.380386" level="INFO">Successfully initialized new page object and opened url: http://127.0.0.1:8765/login</msg>
<arg>${BASE_URL}${path}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Open a new Page.</doc>
<status status="PASS" start="2026-06-27T00:11:06.059385" elapsed="0.321183"/>
</kw>
<arg>/login</arg>
<doc>Open a new page at the given path relative to BASE_URL.</doc>
<status status="PASS" start="2026-06-27T00:11:06.059089" elapsed="0.321576"/>
</kw>
<kw name="Perform Login" owner="ui_keywords">
<kw name="Fill Text" owner="Browser">
<msg time="2026-06-27T00:11:06.381741" level="INFO">Fills the text 'TestPass123!' in the given field.</msg>
<arg>id=password-input</arg>
<arg>${password}</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Clears and fills the given ``txt`` into the text field found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:06.381283" elapsed="0.037092"/>
</kw>
<kw name="Click" owner="Browser">
<msg time="2026-06-27T00:11:06.419114" level="INFO">Clicks the element 'id=login-submit-btn'.</msg>
<arg>id=login-submit-btn</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Simulates mouse click on the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:06.418596" elapsed="0.045128"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:07.768613" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:06.464038" elapsed="1.304740"/>
</kw>
<doc>Fill the login form and submit it.</doc>
<status status="PASS" start="2026-06-27T00:11:06.380868" elapsed="1.388006"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:07.776638" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:07.769033" elapsed="0.007755"/>
</kw>
<arg>Open Browser To Page</arg>
<arg>/login</arg>
<arg>AND</arg>
<arg>Perform Login</arg>
<arg>AND</arg>
<arg>Wait For Elements State</arg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="PASS" start="2026-06-27T00:11:06.058551" elapsed="1.718506"/>
</kw>
<kw name="Set Mobile Viewport" owner="ui_keywords">
<kw name="Set Viewport Size" owner="Browser">
<msg time="2026-06-27T00:11:07.785457" level="INFO">Set viewport size to: {"width":375,"height":667}</msg>
<arg>375</arg>
<arg>667</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Sets current Pages viewport size to specified dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:07.777524" elapsed="0.008155"/>
</kw>
<doc>Resize the browser viewport to mobile dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:07.777243" elapsed="0.008556"/>
</kw>
<kw name="Reload Page" owner="ui_keywords">
<kw name="Reload" owner="Browser">
<msg time="2026-06-27T00:11:07.814801" level="INFO">Reloaded page with options: {"waitUntil": "load"}</msg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Reloads current active page.</doc>
<status status="PASS" start="2026-06-27T00:11:07.786344" elapsed="0.028658"/>
</kw>
<doc>Reload the current page.</doc>
<status status="PASS" start="2026-06-27T00:11:07.785950" elapsed="0.029186"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:07.835438" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:07.815297" elapsed="0.020320"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:07.840817" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:07.836356" elapsed="0.004602"/>
</kw>
<arg>id=search-input</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:07.835980" elapsed="0.005073"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:07.846029" level="INFO">Waited for Element with selector id=theme-toggle at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:07.841553" elapsed="0.004617"/>
</kw>
<arg>id=theme-toggle</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:07.841206" elapsed="0.005056"/>
</kw>
<kw name="Close Browser" owner="common" type="TEARDOWN">
<kw name="Close Browser" owner="Browser">
<msg time="2026-06-27T00:11:07.871959" level="INFO">Closed all browsers</msg>
<arg>ALL</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="PASS" start="2026-06-27T00:11:07.846816" elapsed="0.025287"/>
</kw>
<doc>Close all browser contexts and the browser itself.</doc>
<status status="PASS" start="2026-06-27T00:11:07.846473" elapsed="0.025723"/>
</kw>
<doc>Resize to mobile and verify layout adapts.</doc>
<status status="PASS" start="2026-06-27T00:11:06.052754" elapsed="1.819488"/>
</test>
<test id="s1-t2" name="Mobile Menu Accessible" line="36">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Open Browser To Page" owner="common">
<kw name="New Page" owner="Browser">
<msg time="2026-06-27T00:11:08.268293" level="INFO">Successfully initialized new page object and opened url: http://127.0.0.1:8765/login</msg>
<msg time="2026-06-27T00:11:08.268390" level="INFO">No browser and context was open. New browser and context was automatically opened when page is created.</msg>
<arg>${BASE_URL}${path}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Open a new Page.</doc>
<status status="PASS" start="2026-06-27T00:11:07.880942" elapsed="0.387623"/>
</kw>
<arg>/login</arg>
<doc>Open a new page at the given path relative to BASE_URL.</doc>
<status status="PASS" start="2026-06-27T00:11:07.880651" elapsed="0.388054"/>
</kw>
<kw name="Perform Login" owner="ui_keywords">
<kw name="Fill Text" owner="Browser">
<msg time="2026-06-27T00:11:08.271099" level="INFO">Fills the text 'TestPass123!' in the given field.</msg>
<arg>id=password-input</arg>
<arg>${password}</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Clears and fills the given ``txt`` into the text field found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:08.270411" elapsed="0.026025"/>
</kw>
<kw name="Click" owner="Browser">
<msg time="2026-06-27T00:11:08.297150" level="INFO">Clicks the element 'id=login-submit-btn'.</msg>
<arg>id=login-submit-btn</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Simulates mouse click on the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:08.296634" elapsed="0.043649"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:09.646331" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:08.340489" elapsed="1.306280"/>
</kw>
<doc>Fill the login form and submit it.</doc>
<status status="PASS" start="2026-06-27T00:11:08.268927" elapsed="1.378065"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:09.655733" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:09.647417" elapsed="0.008527"/>
</kw>
<arg>Open Browser To Page</arg>
<arg>/login</arg>
<arg>AND</arg>
<arg>Perform Login</arg>
<arg>AND</arg>
<arg>Wait For Elements State</arg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="PASS" start="2026-06-27T00:11:07.880073" elapsed="1.775993"/>
</kw>
<kw name="Set Mobile Viewport" owner="ui_keywords">
<kw name="Set Viewport Size" owner="Browser">
<msg time="2026-06-27T00:11:09.671132" level="INFO">Set viewport size to: {"width":375,"height":667}</msg>
<arg>375</arg>
<arg>667</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Sets current Pages viewport size to specified dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:09.656945" elapsed="0.014533"/>
</kw>
<doc>Resize the browser viewport to mobile dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:09.656297" elapsed="0.015341"/>
</kw>
<kw name="Reload Page" owner="ui_keywords">
<kw name="Reload" owner="Browser">
<msg time="2026-06-27T00:11:09.729193" level="INFO">Reloaded page with options: {"waitUntil": "load"}</msg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Reloads current active page.</doc>
<status status="PASS" start="2026-06-27T00:11:09.673530" elapsed="0.055893"/>
</kw>
<doc>Reload the current page.</doc>
<status status="PASS" start="2026-06-27T00:11:09.672367" elapsed="0.057187"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:09.781081" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:09.729765" elapsed="0.051738"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:09.797535" level="INFO">Waited for Element with selector id=theme-toggle at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:09.782638" elapsed="0.015213"/>
</kw>
<arg>id=theme-toggle</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:09.781956" elapsed="0.016087"/>
</kw>
<kw name="Close Browser" owner="common" type="TEARDOWN">
<kw name="Close Browser" owner="Browser">
<msg time="2026-06-27T00:11:09.854804" level="INFO">Closed all browsers</msg>
<arg>ALL</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="PASS" start="2026-06-27T00:11:09.799163" elapsed="0.055883"/>
</kw>
<doc>Close all browser contexts and the browser itself.</doc>
<status status="PASS" start="2026-06-27T00:11:09.798428" elapsed="0.056757"/>
</kw>
<doc>Verify compact header on mobile.</doc>
<status status="PASS" start="2026-06-27T00:11:07.877238" elapsed="1.978013"/>
</test>
<test id="s1-t3" name="Tablet Viewport Layout" line="47">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Open Browser To Page" owner="common">
<kw name="New Page" owner="Browser">
<msg time="2026-06-27T00:11:10.278738" level="INFO">Successfully initialized new page object and opened url: http://127.0.0.1:8765/login</msg>
<msg time="2026-06-27T00:11:10.278825" level="INFO">No browser and context was open. New browser and context was automatically opened when page is created.</msg>
<arg>${BASE_URL}${path}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Open a new Page.</doc>
<status status="PASS" start="2026-06-27T00:11:09.888186" elapsed="0.390796"/>
</kw>
<arg>/login</arg>
<doc>Open a new page at the given path relative to BASE_URL.</doc>
<status status="PASS" start="2026-06-27T00:11:09.887750" elapsed="0.391355"/>
</kw>
<kw name="Perform Login" owner="ui_keywords">
<kw name="Fill Text" owner="Browser">
<msg time="2026-06-27T00:11:10.280741" level="INFO">Fills the text 'TestPass123!' in the given field.</msg>
<arg>id=password-input</arg>
<arg>${password}</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Clears and fills the given ``txt`` into the text field found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:10.279910" elapsed="0.032976"/>
</kw>
<kw name="Click" owner="Browser">
<msg time="2026-06-27T00:11:10.313898" level="INFO">Clicks the element 'id=login-submit-btn'.</msg>
<arg>id=login-submit-btn</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Simulates mouse click on the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:10.313162" elapsed="0.046384"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:11.664590" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:10.359807" elapsed="1.304957"/>
</kw>
<doc>Fill the login form and submit it.</doc>
<status status="PASS" start="2026-06-27T00:11:10.279371" elapsed="1.385505"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:11.670721" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:11.665045" elapsed="0.005886"/>
</kw>
<arg>Open Browser To Page</arg>
<arg>/login</arg>
<arg>AND</arg>
<arg>Perform Login</arg>
<arg>AND</arg>
<arg>Wait For Elements State</arg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="PASS" start="2026-06-27T00:11:09.886898" elapsed="1.784154"/>
</kw>
<kw name="Set Tablet Viewport" owner="ui_keywords">
<kw name="Set Viewport Size" owner="Browser">
<msg time="2026-06-27T00:11:11.680923" level="INFO">Set viewport size to: {"width":768,"height":1024}</msg>
<arg>768</arg>
<arg>1024</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Sets current Pages viewport size to specified dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:11.671774" elapsed="0.009299"/>
</kw>
<doc>Resize the browser viewport to tablet dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:11.671323" elapsed="0.009849"/>
</kw>
<kw name="Reload Page" owner="ui_keywords">
<kw name="Reload" owner="Browser">
<msg time="2026-06-27T00:11:11.713585" level="INFO">Reloaded page with options: {"waitUntil": "load"}</msg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Reloads current active page.</doc>
<status status="PASS" start="2026-06-27T00:11:11.681645" elapsed="0.032177"/>
</kw>
<doc>Reload the current page.</doc>
<status status="PASS" start="2026-06-27T00:11:11.681334" elapsed="0.032635"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:11.739275" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:11.714185" elapsed="0.025356"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:11.747239" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:11.740466" elapsed="0.006999"/>
</kw>
<arg>id=search-input</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:11.739892" elapsed="0.007712"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:11.753577" level="INFO">Waited for Element with selector id=rescan-btn at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:11.748334" elapsed="0.005465"/>
</kw>
<arg>id=rescan-btn</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:11.747852" elapsed="0.006076"/>
</kw>
<kw name="Close Browser" owner="common" type="TEARDOWN">
<kw name="Close Browser" owner="Browser">
<msg time="2026-06-27T00:11:11.780875" level="INFO">Closed all browsers</msg>
<arg>ALL</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="PASS" start="2026-06-27T00:11:11.754571" elapsed="0.026510"/>
</kw>
<doc>Close all browser contexts and the browser itself.</doc>
<status status="PASS" start="2026-06-27T00:11:11.754200" elapsed="0.027017"/>
</kw>
<doc>Resize to tablet and verify layout adapts.</doc>
<status status="PASS" start="2026-06-27T00:11:09.880881" elapsed="1.900400"/>
</test>
<test id="s1-t4" name="Touch Buttons Clickable" line="58">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Open Browser To Page" owner="common">
<kw name="New Page" owner="Browser">
<msg time="2026-06-27T00:11:12.267059" level="INFO">Successfully initialized new page object and opened url: http://127.0.0.1:8765/login</msg>
<msg time="2026-06-27T00:11:12.267180" level="INFO">No browser and context was open. New browser and context was automatically opened when page is created.</msg>
<arg>${BASE_URL}${path}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Open a new Page.</doc>
<status status="PASS" start="2026-06-27T00:11:11.794660" elapsed="0.472663"/>
</kw>
<arg>/login</arg>
<doc>Open a new page at the given path relative to BASE_URL.</doc>
<status status="PASS" start="2026-06-27T00:11:11.794250" elapsed="0.473175"/>
</kw>
<kw name="Perform Login" owner="ui_keywords">
<kw name="Fill Text" owner="Browser">
<msg time="2026-06-27T00:11:12.268919" level="INFO">Fills the text 'TestPass123!' in the given field.</msg>
<arg>id=password-input</arg>
<arg>${password}</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Clears and fills the given ``txt`` into the text field found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:12.268220" elapsed="0.028582"/>
</kw>
<kw name="Click" owner="Browser">
<msg time="2026-06-27T00:11:12.297581" level="INFO">Clicks the element 'id=login-submit-btn'.</msg>
<arg>id=login-submit-btn</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Simulates mouse click on the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:12.297037" elapsed="0.045981"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:13.643013" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:12.343211" elapsed="1.300006"/>
</kw>
<doc>Fill the login form and submit it.</doc>
<status status="PASS" start="2026-06-27T00:11:12.267618" elapsed="1.375731"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:13.649334" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:13.643565" elapsed="0.006028"/>
</kw>
<arg>Open Browser To Page</arg>
<arg>/login</arg>
<arg>AND</arg>
<arg>Perform Login</arg>
<arg>AND</arg>
<arg>Wait For Elements State</arg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="PASS" start="2026-06-27T00:11:11.793546" elapsed="1.856215"/>
</kw>
<kw name="Set Mobile Viewport" owner="ui_keywords">
<kw name="Set Viewport Size" owner="Browser">
<msg time="2026-06-27T00:11:13.659142" level="INFO">Set viewport size to: {"width":375,"height":667}</msg>
<arg>375</arg>
<arg>667</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Sets current Pages viewport size to specified dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:13.650519" elapsed="0.008859"/>
</kw>
<doc>Resize the browser viewport to mobile dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:13.650047" elapsed="0.009483"/>
</kw>
<kw name="Reload Page" owner="ui_keywords">
<kw name="Reload" owner="Browser">
<msg time="2026-06-27T00:11:13.688830" level="INFO">Reloaded page with options: {"waitUntil": "load"}</msg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Reloads current active page.</doc>
<status status="PASS" start="2026-06-27T00:11:13.660230" elapsed="0.029061"/>
</kw>
<doc>Reload the current page.</doc>
<status status="PASS" start="2026-06-27T00:11:13.659772" elapsed="0.029692"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:13.723409" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:13.689744" elapsed="0.033890"/>
</kw>
<kw name="Click" owner="Browser">
<msg time="2026-06-27T00:11:13.724677" level="INFO">Clicks the element 'id=theme-toggle'.</msg>
<arg>id=theme-toggle</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Simulates mouse click on the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:13.723984" elapsed="0.036352"/>
</kw>
<kw name="Get Current Theme" owner="ui_keywords">
<kw name="Get Attribute" owner="Browser">
<msg time="2026-06-27T00:11:13.793717" level="INFO">Attribute is: 'dark'</msg>
<msg time="2026-06-27T00:11:13.793859" level="INFO">${theme} = dark</msg>
<var>${theme}</var>
<arg>html</arg>
<arg>data-theme</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns the HTML ``attribute`` of the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:13.760971" elapsed="0.032911"/>
</kw>
<return>
<value>${theme}</value>
<status status="PASS" start="2026-06-27T00:11:13.793972" elapsed="0.000151"/>
</return>
<msg time="2026-06-27T00:11:13.794274" level="INFO">${theme} = dark</msg>
<var>${theme}</var>
<doc>Return the current theme attribute from the HTML element.</doc>
<status status="PASS" start="2026-06-27T00:11:13.760578" elapsed="0.033716"/>
</kw>
<kw name="Should Be Equal As Strings" owner="BuiltIn">
<arg>${theme}</arg>
<arg>dark</arg>
<doc>Fails if objects are unequal after converting them to strings.</doc>
<status status="PASS" start="2026-06-27T00:11:13.794422" elapsed="0.000370"/>
</kw>
<kw name="Click" owner="Browser">
<msg time="2026-06-27T00:11:13.795264" level="INFO">Clicks the element 'id=theme-toggle'.</msg>
<arg>id=theme-toggle</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Simulates mouse click on the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:13.794910" elapsed="0.053086"/>
</kw>
<kw name="Get Current Theme" owner="ui_keywords">
<kw name="Get Attribute" owner="Browser">
<msg time="2026-06-27T00:11:13.860361" level="INFO">Attribute is: 'light'</msg>
<msg time="2026-06-27T00:11:13.860577" level="INFO">${theme} = light</msg>
<var>${theme}</var>
<arg>html</arg>
<arg>data-theme</arg>
<tag>Assertion</tag>
<tag>Getter</tag>
<tag>PageContent</tag>
<doc>Returns the HTML ``attribute`` of the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:13.848834" elapsed="0.011781"/>
</kw>
<return>
<value>${theme}</value>
<status status="PASS" start="2026-06-27T00:11:13.860767" elapsed="0.000227"/>
</return>
<msg time="2026-06-27T00:11:13.861226" level="INFO">${theme} = light</msg>
<var>${theme}</var>
<doc>Return the current theme attribute from the HTML element.</doc>
<status status="PASS" start="2026-06-27T00:11:13.848328" elapsed="0.012931"/>
</kw>
<kw name="Should Be Equal As Strings" owner="BuiltIn">
<arg>${theme}</arg>
<arg>light</arg>
<doc>Fails if objects are unequal after converting them to strings.</doc>
<status status="PASS" start="2026-06-27T00:11:13.861462" elapsed="0.000581"/>
</kw>
<kw name="Close Browser" owner="common" type="TEARDOWN">
<kw name="Close Browser" owner="Browser">
<msg time="2026-06-27T00:11:13.891205" level="INFO">Closed all browsers</msg>
<arg>ALL</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="PASS" start="2026-06-27T00:11:13.862958" elapsed="0.028395"/>
</kw>
<doc>Close all browser contexts and the browser itself.</doc>
<status status="PASS" start="2026-06-27T00:11:13.862392" elapsed="0.029062"/>
</kw>
<doc>Verify buttons remain clickable on touch-sized viewport.</doc>
<status status="PASS" start="2026-06-27T00:11:11.789449" elapsed="2.102049"/>
</test>
<test id="s1-t5" name="Desktop Viewport Reset" line="75">
<kw name="Run Keywords" owner="BuiltIn" type="SETUP">
<kw name="Open Browser To Page" owner="common">
<kw name="New Page" owner="Browser">
<msg time="2026-06-27T00:11:14.327925" level="INFO">Successfully initialized new page object and opened url: http://127.0.0.1:8765/login</msg>
<msg time="2026-06-27T00:11:14.328025" level="INFO">No browser and context was open. New browser and context was automatically opened when page is created.</msg>
<arg>${BASE_URL}${path}</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Open a new Page.</doc>
<status status="PASS" start="2026-06-27T00:11:13.905103" elapsed="0.423116"/>
</kw>
<arg>/login</arg>
<doc>Open a new page at the given path relative to BASE_URL.</doc>
<status status="PASS" start="2026-06-27T00:11:13.904781" elapsed="0.423583"/>
</kw>
<kw name="Perform Login" owner="ui_keywords">
<kw name="Fill Text" owner="Browser">
<msg time="2026-06-27T00:11:14.329993" level="INFO">Fills the text 'TestPass123!' in the given field.</msg>
<arg>id=password-input</arg>
<arg>${password}</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Clears and fills the given ``txt`` into the text field found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:14.329313" elapsed="0.038251"/>
</kw>
<kw name="Click" owner="Browser">
<msg time="2026-06-27T00:11:14.368626" level="INFO">Clicks the element 'id=login-submit-btn'.</msg>
<arg>id=login-submit-btn</arg>
<tag>PageContent</tag>
<tag>Setter</tag>
<doc>Simulates mouse click on the element found by ``selector``.</doc>
<status status="PASS" start="2026-06-27T00:11:14.367890" elapsed="0.044293"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:15.726340" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:14.412480" elapsed="1.314003"/>
</kw>
<doc>Fill the login form and submit it.</doc>
<status status="PASS" start="2026-06-27T00:11:14.328657" elapsed="1.397918"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:15.731079" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:15.726730" elapsed="0.004561"/>
</kw>
<arg>Open Browser To Page</arg>
<arg>/login</arg>
<arg>AND</arg>
<arg>Perform Login</arg>
<arg>AND</arg>
<arg>Wait For Elements State</arg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<doc>Executes all the given keywords in a sequence.</doc>
<status status="PASS" start="2026-06-27T00:11:13.904168" elapsed="1.827232"/>
</kw>
<kw name="Set Desktop Viewport" owner="ui_keywords">
<kw name="Set Viewport Size" owner="Browser">
<msg time="2026-06-27T00:11:15.735704" level="INFO">Set viewport size to: {"width":1280,"height":720}</msg>
<arg>1280</arg>
<arg>720</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Sets current Pages viewport size to specified dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:15.732034" elapsed="0.003826"/>
</kw>
<doc>Resize the browser viewport to desktop dimensions.</doc>
<status status="PASS" start="2026-06-27T00:11:15.731617" elapsed="0.004345"/>
</kw>
<kw name="Reload Page" owner="ui_keywords">
<kw name="Reload" owner="Browser">
<msg time="2026-06-27T00:11:15.760176" level="INFO">Reloaded page with options: {"waitUntil": "load"}</msg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Reloads current active page.</doc>
<status status="PASS" start="2026-06-27T00:11:15.736471" elapsed="0.023992"/>
</kw>
<doc>Reload the current page.</doc>
<status status="PASS" start="2026-06-27T00:11:15.736121" elapsed="0.024489"/>
</kw>
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:15.781568" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>id=search-input</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:15.760872" elapsed="0.020856"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:15.787998" level="INFO">Waited for Element with selector id=search-input at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:15.782343" elapsed="0.005791"/>
</kw>
<arg>id=search-input</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:15.781949" elapsed="0.006282"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:15.793088" level="INFO">Waited for Element with selector id=rescan-btn at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:15.788762" elapsed="0.004433"/>
</kw>
<arg>id=rescan-btn</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:15.788411" elapsed="0.004868"/>
</kw>
<kw name="Element Should Be Visible" owner="ui_keywords">
<kw name="Wait For Elements State" owner="Browser">
<msg time="2026-06-27T00:11:15.798708" level="INFO">Waited for Element with selector id=config-btn at state visible</msg>
<arg>${selector}</arg>
<arg>visible</arg>
<arg>timeout=5s</arg>
<tag>PageContent</tag>
<tag>Wait</tag>
<doc>Waits for the element found by ``selector`` to satisfy state option.</doc>
<status status="PASS" start="2026-06-27T00:11:15.793752" elapsed="0.005165"/>
</kw>
<arg>id=config-btn</arg>
<doc>Assert that the element matching the selector is visible.</doc>
<status status="PASS" start="2026-06-27T00:11:15.793425" elapsed="0.005611"/>
</kw>
<kw name="Close Browser" owner="common" type="TEARDOWN">
<kw name="Close Browser" owner="Browser">
<msg time="2026-06-27T00:11:15.823281" level="INFO">Closed all browsers</msg>
<arg>ALL</arg>
<tag>BrowserControl</tag>
<tag>Setter</tag>
<doc>Closes the current browser.</doc>
<status status="PASS" start="2026-06-27T00:11:15.799817" elapsed="0.023671"/>
</kw>
<doc>Close all browser contexts and the browser itself.</doc>
<status status="PASS" start="2026-06-27T00:11:15.799308" elapsed="0.024304"/>
</kw>
<doc>Resize back to desktop and verify normal layout.</doc>
<status status="PASS" start="2026-06-27T00:11:13.897314" elapsed="1.926347"/>
</test>
<doc>Responsive design UI tests for Aniworld.
Covers mobile and tablet viewport layouts and touch interactions.</doc>
<status status="PASS" start="2026-06-27T00:11:00.221899" elapsed="15.607008"/>
</suite>
<statistics>
<total>
<stat pass="5" fail="0" skip="0">All Tests</stat>
</total>
<tag>
</tag>
<suite>
<stat name="Responsive" id="s1" pass="5" fail="0" skip="0">Responsive</stat>
</suite>
</statistics>
<errors>
</errors>
</robot>