backup
This commit is contained in:
306
tests/robot/resources/api_keywords.resource
Normal file
306
tests/robot/resources/api_keywords.resource
Normal file
@@ -0,0 +1,306 @@
|
||||
*** Settings ***
|
||||
Documentation API-specific keywords for Aniworld Robot Framework tests.
|
||||
... Wraps common HTTP patterns and JSON assertions for REST API testing.
|
||||
|
||||
Resource ${CURDIR}/common.resource
|
||||
|
||||
*** Keywords ***
|
||||
# ---------------------------------------------------------------------------
|
||||
# Generic API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
GET API
|
||||
[Arguments] ${endpoint} ${expected_status}=200 ${session}=auth
|
||||
[Documentation] Perform an authenticated GET request and return the response.
|
||||
${resp}= GET On Session ${session} ${endpoint} expected_status=${expected_status}
|
||||
RETURN ${resp}
|
||||
|
||||
POST API
|
||||
[Arguments] ${endpoint} ${payload}=${EMPTY} ${expected_status}=200 ${session}=auth
|
||||
[Documentation] Perform an authenticated POST request with optional JSON payload.
|
||||
IF '${payload}' == '${EMPTY}'
|
||||
${resp}= POST On Session ${session} ${endpoint} expected_status=${expected_status}
|
||||
ELSE
|
||||
${resp}= POST On Session ${session} ${endpoint} json=${payload} expected_status=${expected_status}
|
||||
END
|
||||
RETURN ${resp}
|
||||
|
||||
PUT API
|
||||
[Arguments] ${endpoint} ${payload} ${expected_status}=200 ${session}=auth
|
||||
[Documentation] Perform an authenticated PUT request with JSON payload.
|
||||
${resp}= PUT On Session ${session} ${endpoint} json=${payload} expected_status=${expected_status}
|
||||
RETURN ${resp}
|
||||
|
||||
DELETE API
|
||||
[Arguments] ${endpoint} ${expected_status}=200 ${session}=auth
|
||||
[Documentation] Perform an authenticated DELETE request.
|
||||
${resp}= DELETE On Session ${session} ${endpoint} expected_status=${expected_status}
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# JSON Response Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get JSON Value
|
||||
[Arguments] ${response} ${json_path}
|
||||
[Documentation] Extract a value from a JSON response using JSONPath.
|
||||
${json}= Convert String To Json ${response.text}
|
||||
${values}= Get Value From Json ${json} ${json_path}
|
||||
RETURN ${values}[0]
|
||||
|
||||
Response Should Contain Keys
|
||||
[Arguments] ${response} @{keys}
|
||||
[Documentation] Assert that the JSON response contains all the specified top-level keys.
|
||||
${json}= Convert String To Json ${response.text}
|
||||
FOR ${key} IN @{keys}
|
||||
Dictionary Should Contain Key ${json} ${key}
|
||||
END
|
||||
|
||||
Response Should Be Valid JSON
|
||||
[Arguments] ${response}
|
||||
[Documentation] Assert that the response body is valid JSON.
|
||||
${json}= Convert String To Json ${response.text}
|
||||
Should Not Be Empty ${json}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Auth-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
POST Auth Setup
|
||||
[Arguments] ${password} ${expected_status}=201
|
||||
[Documentation] POST to /api/auth/setup with the given password.
|
||||
${payload}= Create Dictionary master_password=${password}
|
||||
${resp}= POST On Session anon /api/auth/setup json=${payload} expected_status=${expected_status}
|
||||
RETURN ${resp}
|
||||
|
||||
POST Auth Login
|
||||
[Arguments] ${password} ${expected_status}=200
|
||||
[Documentation] POST to /api/auth/login with the given password.
|
||||
${payload}= Create Dictionary password=${password}
|
||||
${resp}= POST On Session anon /api/auth/login json=${payload} expected_status=${expected_status}
|
||||
RETURN ${resp}
|
||||
|
||||
GET Auth Status
|
||||
[Arguments] ${expected_status}=200
|
||||
[Documentation] GET /api/auth/status.
|
||||
${resp}= GET On Session anon /api/auth/status expected_status=${expected_status}
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Config-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get Current Config
|
||||
[Documentation] GET /api/config and return the parsed JSON.
|
||||
${resp}= GET API /api/config
|
||||
${json}= Convert String To Json ${resp.text}
|
||||
RETURN ${json}
|
||||
|
||||
Update Config
|
||||
[Arguments] ${payload}
|
||||
[Documentation] PUT /api/config with the given payload.
|
||||
${resp}= PUT API /api/config ${payload}
|
||||
RETURN ${resp}
|
||||
|
||||
Validate Config
|
||||
[Arguments] ${payload} ${expected_status}=200
|
||||
[Documentation] POST /api/config/validate with the given payload.
|
||||
${resp}= POST API /api/config/validate ${payload} ${expected_status}
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Queue-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get Queue Status
|
||||
[Documentation] GET /api/queue/status and return the response.
|
||||
${resp}= GET API /api/queue/status
|
||||
RETURN ${resp}
|
||||
|
||||
Add To Queue
|
||||
[Arguments] ${payload}
|
||||
[Documentation] POST /api/queue/add with the given payload.
|
||||
${resp}= POST API /api/queue/add ${payload} 201
|
||||
RETURN ${resp}
|
||||
|
||||
Start Queue
|
||||
[Documentation] POST /api/queue/start.
|
||||
${resp}= POST API /api/queue/start
|
||||
RETURN ${resp}
|
||||
|
||||
Stop Queue
|
||||
[Documentation] POST /api/queue/stop.
|
||||
${resp}= POST API /api/queue/stop
|
||||
RETURN ${resp}
|
||||
|
||||
Pause Queue
|
||||
[Documentation] POST /api/queue/pause.
|
||||
${resp}= POST API /api/queue/pause
|
||||
RETURN ${resp}
|
||||
|
||||
Resume Queue
|
||||
[Documentation] POST /api/queue/resume.
|
||||
${resp}= POST API /api/queue/resume
|
||||
RETURN ${resp}
|
||||
|
||||
Clear Completed
|
||||
[Documentation] DELETE /api/queue/completed.
|
||||
${resp}= DELETE API /api/queue/completed
|
||||
RETURN ${resp}
|
||||
|
||||
Clear Failed
|
||||
[Documentation] DELETE /api/queue/failed.
|
||||
${resp}= DELETE API /api/queue/failed
|
||||
RETURN ${resp}
|
||||
|
||||
Clear Pending
|
||||
[Documentation] DELETE /api/queue/pending.
|
||||
${resp}= DELETE API /api/queue/pending
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Anime-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get Anime Status
|
||||
[Documentation] GET /api/anime/status.
|
||||
${resp}= GET API /api/anime/status
|
||||
RETURN ${resp}
|
||||
|
||||
Rescan Library
|
||||
[Documentation] POST /api/anime/rescan.
|
||||
${resp}= POST API /api/anime/rescan
|
||||
RETURN ${resp}
|
||||
|
||||
Get Scan Status
|
||||
[Documentation] GET /api/anime/scan/status.
|
||||
${resp}= GET API /api/anime/scan/status
|
||||
RETURN ${resp}
|
||||
|
||||
Search Anime
|
||||
[Arguments] ${query}
|
||||
[Documentation] GET /api/anime/search?q={query}.
|
||||
${resp}= GET API /api/anime/search?q=${query}
|
||||
RETURN ${resp}
|
||||
|
||||
Add Series
|
||||
[Arguments] ${link} ${name} ${year}=${EMPTY}
|
||||
[Documentation] POST /api/anime/add with series details.
|
||||
${payload}= Create Dictionary link=${link} name=${name}
|
||||
IF '${year}' != '${EMPTY}'
|
||||
Set To Dictionary ${payload} year=${year}
|
||||
END
|
||||
${resp}= POST API /api/anime/add ${payload} 201
|
||||
RETURN ${resp}
|
||||
|
||||
Get Series Details
|
||||
[Arguments] ${key}
|
||||
[Documentation] GET /api/anime/{key}.
|
||||
${resp}= GET API /api/anime/${key}
|
||||
RETURN ${resp}
|
||||
|
||||
Delete Series
|
||||
[Arguments] ${key}
|
||||
[Documentation] DELETE /api/anime/{key}.
|
||||
${resp}= DELETE API /api/anime/${key}
|
||||
RETURN ${resp}
|
||||
|
||||
Get Series Episodes
|
||||
[Arguments] ${key}
|
||||
[Documentation] GET /api/anime/{key}/episodes.
|
||||
${resp}= GET API /api/anime/${key}/episodes
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Scheduler-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get Scheduler Config
|
||||
[Documentation] GET /api/scheduler/config.
|
||||
${resp}= GET API /api/scheduler/config
|
||||
RETURN ${resp}
|
||||
|
||||
Update Scheduler Config
|
||||
[Arguments] ${payload}
|
||||
[Documentation] POST /api/scheduler/config.
|
||||
${resp}= POST API /api/scheduler/config ${payload}
|
||||
RETURN ${resp}
|
||||
|
||||
Trigger Rescan
|
||||
[Documentation] POST /api/scheduler/trigger-rescan.
|
||||
${resp}= POST API /api/scheduler/trigger-rescan
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# NFO-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get Nfo Diagnostics
|
||||
[Arguments] ${key}
|
||||
[Documentation] GET /api/nfo/{key}/diagnostics.
|
||||
${resp}= GET API /api/nfo/${key}/diagnostics
|
||||
RETURN ${resp}
|
||||
|
||||
Repair Nfo
|
||||
[Arguments] ${key}
|
||||
[Documentation] POST /api/nfo/{key}/repair.
|
||||
${resp}= POST API /api/nfo/${key}/repair
|
||||
RETURN ${resp}
|
||||
|
||||
Get Needs Repair
|
||||
[Documentation] GET /api/nfo/needs-repair.
|
||||
${resp}= GET API /api/nfo/needs-repair
|
||||
RETURN ${resp}
|
||||
|
||||
Scan Nfo
|
||||
[Documentation] POST /api/nfo/scan.
|
||||
${resp}= POST API /api/nfo/scan
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Logging-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get Logging Config
|
||||
[Documentation] GET /api/logging/config.
|
||||
${resp}= GET API /api/logging/config
|
||||
RETURN ${resp}
|
||||
|
||||
List Log Files
|
||||
[Documentation] GET /api/logging/files.
|
||||
${resp}= GET API /api/logging/files
|
||||
RETURN ${resp}
|
||||
|
||||
Tail Log File
|
||||
[Arguments] ${filename}
|
||||
[Documentation] GET /api/logging/files/{filename}/tail.
|
||||
${resp}= GET API /api/logging/files/${filename}/tail
|
||||
RETURN ${resp}
|
||||
|
||||
Download Log File
|
||||
[Arguments] ${filename}
|
||||
[Documentation] GET /api/logging/files/{filename}/download.
|
||||
${resp}= GET API /api/logging/files/${filename}/download
|
||||
RETURN ${resp}
|
||||
|
||||
Write Test Logs
|
||||
[Documentation] POST /api/logging/test.
|
||||
${resp}= POST API /api/logging/test
|
||||
RETURN ${resp}
|
||||
|
||||
Cleanup Logs
|
||||
[Documentation] POST /api/logging/cleanup.
|
||||
${resp}= POST API /api/logging/cleanup
|
||||
RETURN ${resp}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Setup-Specific API Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Get Unresolved Folders
|
||||
[Documentation] GET /api/setup/unresolved.
|
||||
${resp}= GET API /api/setup/unresolved
|
||||
RETURN ${resp}
|
||||
|
||||
Get Unresolved Folder Details
|
||||
[Arguments] ${folder_name}
|
||||
[Documentation] GET /api/setup/unresolved/{folder_name}.
|
||||
${resp}= GET API /api/setup/unresolved/${folder_name}
|
||||
RETURN ${resp}
|
||||
|
||||
Resolve Folder
|
||||
[Arguments] ${folder_name} ${provider_key}
|
||||
[Documentation] POST /api/setup/unresolved/{folder_name}/resolve.
|
||||
${payload}= Create Dictionary provider_key=${provider_key}
|
||||
${resp}= POST API /api/setup/unresolved/${folder_name}/resolve ${payload}
|
||||
RETURN ${resp}
|
||||
146
tests/robot/resources/common.resource
Normal file
146
tests/robot/resources/common.resource
Normal file
@@ -0,0 +1,146 @@
|
||||
*** 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}
|
||||
204
tests/robot/resources/ui_keywords.resource
Normal file
204
tests/robot/resources/ui_keywords.resource
Normal file
@@ -0,0 +1,204 @@
|
||||
*** Settings ***
|
||||
Documentation UI-specific keywords for Aniworld Robot Framework tests.
|
||||
... Wraps Browser library interactions for page navigation, form filling,
|
||||
... and common UI assertions.
|
||||
|
||||
Resource ${CURDIR}/common.resource
|
||||
|
||||
*** Keywords ***
|
||||
# ---------------------------------------------------------------------------
|
||||
# Navigation
|
||||
# ---------------------------------------------------------------------------
|
||||
Navigate To
|
||||
[Arguments] ${path}
|
||||
[Documentation] Navigate the browser to the given path relative to BASE_URL.
|
||||
Go To ${BASE_URL}${path}
|
||||
|
||||
Reload Page
|
||||
[Documentation] Reload the current page.
|
||||
Reload
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Authentication UI Flows
|
||||
# ---------------------------------------------------------------------------
|
||||
Perform Login
|
||||
[Arguments] ${password}=${SETUP_PASSWORD}
|
||||
[Documentation] Fill the login form and submit it.
|
||||
Fill Text id=password-input ${password}
|
||||
Click id=login-submit-btn
|
||||
Wait For Elements State id=search-input visible timeout=5s
|
||||
|
||||
Perform Logout
|
||||
[Documentation] Click the logout button and wait for redirect to login.
|
||||
Click id=logout-btn
|
||||
Wait For Elements State id=password-input visible timeout=5s
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Setup UI Flow
|
||||
# ---------------------------------------------------------------------------
|
||||
Complete Setup Flow
|
||||
[Arguments] ${password}=${SETUP_PASSWORD}
|
||||
... ${anime_dir}=/tmp/aniworld_test_anime
|
||||
... ${app_name}=AniworldTest
|
||||
[Documentation] Fill the entire setup form and submit it.
|
||||
# General section
|
||||
Fill Text id=app-name-input ${app_name}
|
||||
Fill Text id=data-dir-input data
|
||||
Fill Text id=anime-directory-input ${anime_dir}
|
||||
# Security section
|
||||
Fill Text id=master-password-input ${password}
|
||||
Fill Text id=confirm-password-input ${password}
|
||||
# Scheduler section
|
||||
Uncheck Checkbox id=scheduler-enabled
|
||||
# Submit
|
||||
Click id=setup-submit-btn
|
||||
Wait For Elements State id=search-input visible timeout=10s
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Settings Modal
|
||||
# ---------------------------------------------------------------------------
|
||||
Open Settings Modal
|
||||
[Documentation] Click the config button and wait for the modal to appear.
|
||||
Click id=config-btn
|
||||
Wait For Elements State id=config-modal visible timeout=5s
|
||||
|
||||
Close Settings Modal
|
||||
[Documentation] Click the close button and wait for the modal to disappear.
|
||||
Click id=close-config
|
||||
Wait For Elements State id=config-modal hidden timeout=5s
|
||||
|
||||
Save Settings
|
||||
[Documentation] Click the save button inside the settings modal.
|
||||
Click id=save-main-config
|
||||
Wait For Elements State .toast, .notification visible timeout=5s
|
||||
|
||||
Fill General Settings
|
||||
[Arguments] ${app_name} ${data_dir} ${anime_dir}
|
||||
[Documentation] Fill the general settings section in the modal.
|
||||
Fill Text id=app-name-input ${app_name}
|
||||
Fill Text id=data-dir-input ${data_dir}
|
||||
Fill Text id=anime-directory-input ${anime_dir}
|
||||
|
||||
Fill Scheduler Settings
|
||||
[Arguments] ${enabled}=False ${time}=03:00 @{days}
|
||||
[Documentation] Fill the scheduler settings section.
|
||||
IF ${enabled}
|
||||
Check Checkbox id=scheduled-rescan-enabled
|
||||
ELSE
|
||||
Uncheck Checkbox id=scheduled-rescan-enabled
|
||||
END
|
||||
Fill Text id=scheduler-time-input ${time}
|
||||
# Days selection would be handled by multi-select UI elements
|
||||
|
||||
Fill NFO Settings
|
||||
[Arguments] ${tmdb_key}=${EMPTY} ${auto_create}=False
|
||||
[Documentation] Fill the NFO settings section.
|
||||
Fill Text id=tmdb-api-key-input ${tmdb_key}
|
||||
IF ${auto_create}
|
||||
Check Checkbox id=nfo-auto-create
|
||||
ELSE
|
||||
Uncheck Checkbox id=nfo-auto-create
|
||||
END
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Search
|
||||
# ---------------------------------------------------------------------------
|
||||
Search For Anime
|
||||
[Arguments] ${query}
|
||||
[Documentation] Type a query into the search box and submit.
|
||||
Fill Text id=search-input ${query}
|
||||
Click id=search-btn
|
||||
Wait For Elements State id=search-results visible timeout=5s
|
||||
|
||||
Clear Search
|
||||
[Documentation] Click the clear search button.
|
||||
Click id=clear-search
|
||||
Wait For Elements State id=search-results hidden timeout=3s
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Theme
|
||||
# ---------------------------------------------------------------------------
|
||||
Toggle Theme
|
||||
[Documentation] Click the theme toggle button.
|
||||
Click id=theme-toggle
|
||||
|
||||
Get Current Theme
|
||||
[Documentation] Return the current theme attribute from the HTML element.
|
||||
${theme}= Get Attribute html data-theme
|
||||
RETURN ${theme}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Queue Page
|
||||
# ---------------------------------------------------------------------------
|
||||
Navigate To Queue Page
|
||||
[Documentation] Navigate to the download queue page.
|
||||
Navigate To /queue
|
||||
Wait For Elements State id=pending-queue visible timeout=5s
|
||||
|
||||
Start Queue From UI
|
||||
[Documentation] Click the start queue button on the queue page.
|
||||
Click id=start-queue-btn
|
||||
|
||||
Stop Queue From UI
|
||||
[Documentation] Click the stop queue button on the queue page.
|
||||
Click id=stop-queue-btn
|
||||
|
||||
Clear Completed From UI
|
||||
[Documentation] Click clear completed and confirm the modal.
|
||||
Click id=clear-completed-btn
|
||||
Wait For Elements State id=confirm-modal visible timeout=3s
|
||||
Click id=confirm-ok
|
||||
Wait For Elements State id=confirm-modal hidden timeout=3s
|
||||
|
||||
Clear Failed From UI
|
||||
[Documentation] Click clear failed and confirm the modal.
|
||||
Click id=clear-failed-btn
|
||||
Wait For Elements State id=confirm-modal visible timeout=3s
|
||||
Click id=confirm-ok
|
||||
Wait For Elements State id=confirm-modal hidden timeout=3s
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Common UI Assertions
|
||||
# ---------------------------------------------------------------------------
|
||||
Page Title Should Contain
|
||||
[Arguments] ${text}
|
||||
[Documentation] Assert that the page title contains the given text.
|
||||
${title}= Get Title
|
||||
Should Contain ${title} ${text}
|
||||
|
||||
Element Should Be Visible
|
||||
[Arguments] ${selector}
|
||||
[Documentation] Assert that the element matching the selector is visible.
|
||||
Wait For Elements State ${selector} visible timeout=5s
|
||||
|
||||
Element Should Be Hidden
|
||||
[Arguments] ${selector}
|
||||
[Documentation] Assert that the element matching the selector is hidden.
|
||||
Wait For Elements State ${selector} hidden timeout=5s
|
||||
|
||||
Element Text Should Contain
|
||||
[Arguments] ${selector} ${text}
|
||||
[Documentation] Assert that the element's text contains the given substring.
|
||||
${element_text}= Get Text ${selector}
|
||||
Should Contain ${element_text} ${text}
|
||||
|
||||
Toast Should Contain
|
||||
[Arguments] ${text}
|
||||
[Documentation] Assert that a toast/notification contains the given text.
|
||||
${toast}= Get Text .toast, .notification
|
||||
Should Contain ${toast} ${text}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Responsive Helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
Set Mobile Viewport
|
||||
[Documentation] Resize the browser viewport to mobile dimensions.
|
||||
Set Viewport Size 375 667
|
||||
|
||||
Set Tablet Viewport
|
||||
[Documentation] Resize the browser viewport to tablet dimensions.
|
||||
Set Viewport Size 768 1024
|
||||
|
||||
Set Desktop Viewport
|
||||
[Documentation] Resize the browser viewport to desktop dimensions.
|
||||
Set Viewport Size 1280 720
|
||||
Reference in New Issue
Block a user