*** Settings *** Documentation Common shared resources for Aniworld Robot Framework tests. ... Provides keywords for server lifecycle, authentication, sessions, and cleanup. Library Process Library Browser Library RequestsLibrary Library JSONLibrary Library OperatingSystem Library String Library Collections Library DateTime *** Variables *** ${BASE_URL} http://127.0.0.1:8765 ${SERVER_HOST} 127.0.0.1 ${SERVER_PORT} 8765 ${SETUP_PASSWORD} TestPass123! ${BROWSER} chromium ${HEADLESS} True ${SERVER_PROCESS} ${EMPTY} *** Keywords *** # --------------------------------------------------------------------------- # Server Lifecycle # --------------------------------------------------------------------------- Start Aniworld Server [Documentation] Start the FastAPI uvicorn server as a background process. ${result}= Run Process conda run -n AniWorld python -m uvicorn src.server.fastapi_app:app ... --host ${SERVER_HOST} --port ${SERVER_PORT} ... --no-access-log ... cwd=/home/lukas/Volume/repo/Aniworld ... stdout=${CURDIR}/../fixtures/server_stdout.log ... stderr=${CURDIR}/../fixtures/server_stderr.log Set Suite Variable ${SERVER_PROCESS} ${result} Sleep 3s Stop Aniworld Server [Documentation] Terminate the uvicorn server process and clean up log files. Run Keyword And Ignore Error Terminate Process ${SERVER_PROCESS} Run Keyword And Ignore Error Remove File ${CURDIR}/../fixtures/server_stdout.log Run Keyword And Ignore Error Remove File ${CURDIR}/../fixtures/server_stderr.log Wait For Server [Documentation] Poll the health endpoint until the server responds with 200. ... Retries every 1 second for up to 30 seconds. FOR ${i} IN RANGE 30 ${resp}= Run Keyword And Ignore Error ... GET On Session anon /health expected_status=200 IF '${resp}[0]' == 'PASS' RETURN END Sleep 1s END Fail Server did not become healthy within 30 seconds Initialize Browser [Documentation] Initialize Browser library with the configured browser and headless mode. New Browser ${BROWSER} headless=${HEADLESS} New Context viewport={'width': 1280, 'height': 720} # --------------------------------------------------------------------------- # HTTP Session Management # --------------------------------------------------------------------------- Create Anonymous Session [Documentation] Create an unauthenticated HTTP session. Create Session anon ${BASE_URL} Create Authenticated Session [Documentation] Create an authenticated HTTP session. Performs setup if needed, then logs in. Create Anonymous Session ${configured}= Is Auth Configured IF not ${configured} Setup Master Password END ${token}= Login And Get Token Create Session auth ${BASE_URL} headers={'Authorization': 'Bearer ${token}'} # --------------------------------------------------------------------------- # Authentication Helpers # --------------------------------------------------------------------------- Is Auth Configured [Documentation] Check if the master password has already been configured. ${resp}= GET On Session anon /api/auth/status expected_status=200 ${json}= Convert String To Json ${resp.text} ${configured}= Get Value From Json ${json} $.configured RETURN ${configured}[0] Setup Master Password [Documentation] Configure the master password via the setup endpoint. ${payload}= Create Dictionary ... master_password=${SETUP_PASSWORD} ... anime_directory=/tmp/aniworld_test_anime ... name=AniworldTest ... data_dir=data ... scheduler_enabled=False ... logging_level=INFO ... backup_enabled=False ${resp}= POST On Session anon /api/auth/setup json=${payload} expected_status=201 Should Be Equal As Integers ${resp.status_code} 201 Login And Get Token [Documentation] Log in with the master password and return the JWT access token. ${payload}= Create Dictionary password=${SETUP_PASSWORD} ${resp}= POST On Session anon /api/auth/login json=${payload} expected_status=200 ${json}= Convert String To Json ${resp.text} ${token}= Get Value From Json ${json} $.access_token RETURN ${token}[0] # --------------------------------------------------------------------------- # State Reset # --------------------------------------------------------------------------- Reset Application State [Documentation] Reset auth, config, and database state for test isolation. ... Calls internal cleanup endpoints if available; otherwise warns. Run Keyword And Ignore Error POST On Session auth /api/admin/reset expected_status=200 # Fallback: clear local files Run Keyword And Ignore Error Remove Directory /tmp/aniworld_test_anime recursive=True Run Keyword And Ignore Error Create Directory /tmp/aniworld_test_anime # --------------------------------------------------------------------------- # Browser Navigation Helpers # --------------------------------------------------------------------------- Open Browser To Page [Arguments] ${path}=/ [Documentation] Open a new page at the given path relative to BASE_URL. New Page ${BASE_URL}${path} Close Browser [Documentation] Close all browser contexts and the browser itself. Browser.Close Browser ALL # --------------------------------------------------------------------------- # Assertion Helpers # --------------------------------------------------------------------------- Response Should Contain Key [Arguments] ${response} ${json_path} [Documentation] Assert that the JSON response contains the given JSONPath key. ${json}= Convert String To Json ${response.text} ${values}= Get Value From Json ${json} ${json_path} Should Not Be Empty ${values} Expected JSON path '${json_path}' not found in response Response Should Have Status [Arguments] ${response} ${expected_status} [Documentation] Assert that the response status code matches the expected value. Should Be Equal As Integers ${response.status_code} ${expected_status}