211 lines
7.3 KiB
Python
211 lines
7.3 KiB
Python
"""
|
|
Randomized Wait Utility for Realistic Test Behavior
|
|
|
|
World-class utility to simulate realistic human behavior with randomized waits.
|
|
Instead of hardcoded waits, uses intelligent random delays based on context.
|
|
"""
|
|
import random
|
|
import time
|
|
from typing import Optional
|
|
|
|
|
|
class RandomizedWait:
|
|
"""Utility class for randomized, realistic waits"""
|
|
|
|
# Wait ranges (in seconds) for different contexts
|
|
WAIT_RANGES = {
|
|
# Question answering - varies by question type
|
|
'question_answer': {
|
|
'rating_scale': (1, 4), # Quick selection: 1-4 seconds
|
|
'multiple_choice': (2, 6), # Reading options: 2-6 seconds
|
|
'true_false': (1, 3), # Binary choice: 1-3 seconds
|
|
'open_ended': (5, 15), # Typing response: 5-15 seconds
|
|
'matrix': (3, 8), # Multiple selections: 3-8 seconds
|
|
'default': (2, 5) # Default: 2-5 seconds
|
|
},
|
|
|
|
# Navigation between questions
|
|
'question_navigation': {
|
|
'next': (1, 3), # Clicking next: 1-3 seconds
|
|
'previous': (1, 2), # Going back: 1-2 seconds
|
|
'default': (1, 2) # Default navigation: 1-2 seconds
|
|
},
|
|
|
|
# Page/UI loading
|
|
'page_load': {
|
|
'initial': (2, 4), # Initial page load: 2-4 seconds
|
|
'navigation': (1, 3), # Navigation load: 1-3 seconds
|
|
'modal': (0.5, 1.5), # Modal appearance: 0.5-1.5 seconds
|
|
'default': (1, 2) # Default load: 1-2 seconds
|
|
},
|
|
|
|
# Form interactions
|
|
'form_interaction': {
|
|
'input': (0.5, 1.5), # Text input: 0.5-1.5 seconds
|
|
'click': (0.3, 1), # Button click: 0.3-1 second
|
|
'select': (1, 2), # Dropdown select: 1-2 seconds
|
|
'default': (0.5, 1) # Default: 0.5-1 second
|
|
},
|
|
|
|
# Submission and confirmation
|
|
'submission': {
|
|
'submit': (2, 4), # Submit action: 2-4 seconds
|
|
'confirm': (1, 2), # Confirmation: 1-2 seconds
|
|
'feedback': (3, 8), # Writing feedback: 3-8 seconds
|
|
'default': (1, 3) # Default: 1-3 seconds
|
|
},
|
|
|
|
# Error recovery
|
|
'error_recovery': {
|
|
'retry': (1, 2), # Retry after error: 1-2 seconds
|
|
'wait': (2, 4), # Wait for state change: 2-4 seconds
|
|
'default': (1, 3) # Default: 1-3 seconds
|
|
}
|
|
}
|
|
|
|
@staticmethod
|
|
def wait_for_question_answer(question_type: str = 'default') -> float:
|
|
"""
|
|
Wait after answering a question (realistic thinking time)
|
|
|
|
Args:
|
|
question_type: Type of question (rating_scale, multiple_choice, etc.)
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
ranges = RandomizedWait.WAIT_RANGES['question_answer']
|
|
min_wait, max_wait = ranges.get(question_type, ranges['default'])
|
|
wait_time = random.uniform(min_wait, max_wait)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
@staticmethod
|
|
def wait_for_navigation(action: str = 'next') -> float:
|
|
"""
|
|
Wait after navigation action (page load time)
|
|
|
|
Args:
|
|
action: Navigation action (next, previous, etc.)
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
ranges = RandomizedWait.WAIT_RANGES['question_navigation']
|
|
min_wait, max_wait = ranges.get(action, ranges['default'])
|
|
wait_time = random.uniform(min_wait, max_wait)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
@staticmethod
|
|
def wait_for_page_load(load_type: str = 'default') -> float:
|
|
"""
|
|
Wait for page/UI to load
|
|
|
|
Args:
|
|
load_type: Type of load (initial, navigation, modal, etc.)
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
ranges = RandomizedWait.WAIT_RANGES['page_load']
|
|
min_wait, max_wait = ranges.get(load_type, ranges['default'])
|
|
wait_time = random.uniform(min_wait, max_wait)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
@staticmethod
|
|
def wait_for_form_interaction(interaction_type: str = 'default') -> float:
|
|
"""
|
|
Wait for form interaction (click, input, select)
|
|
|
|
Args:
|
|
interaction_type: Type of interaction (input, click, select, etc.)
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
ranges = RandomizedWait.WAIT_RANGES['form_interaction']
|
|
min_wait, max_wait = ranges.get(interaction_type, ranges['default'])
|
|
wait_time = random.uniform(min_wait, max_wait)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
@staticmethod
|
|
def wait_for_submission(action: str = 'default') -> float:
|
|
"""
|
|
Wait for submission-related actions
|
|
|
|
Args:
|
|
action: Submission action (submit, confirm, feedback, etc.)
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
ranges = RandomizedWait.WAIT_RANGES['submission']
|
|
min_wait, max_wait = ranges.get(action, ranges['default'])
|
|
wait_time = random.uniform(min_wait, max_wait)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
@staticmethod
|
|
def wait_for_error_recovery(recovery_type: str = 'default') -> float:
|
|
"""
|
|
Wait for error recovery
|
|
|
|
Args:
|
|
recovery_type: Type of recovery (retry, wait, etc.)
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
ranges = RandomizedWait.WAIT_RANGES['error_recovery']
|
|
min_wait, max_wait = ranges.get(recovery_type, ranges['default'])
|
|
wait_time = random.uniform(min_wait, max_wait)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
@staticmethod
|
|
def random_wait(min_seconds: float, max_seconds: float) -> float:
|
|
"""
|
|
Generic random wait between min and max seconds
|
|
|
|
Args:
|
|
min_seconds: Minimum wait time
|
|
max_seconds: Maximum wait time
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
wait_time = random.uniform(min_seconds, max_seconds)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
@staticmethod
|
|
def smart_wait(context: str, sub_context: Optional[str] = None) -> float:
|
|
"""
|
|
Smart wait that automatically selects appropriate wait range based on context
|
|
|
|
Args:
|
|
context: Main context (question_answer, navigation, page_load, etc.)
|
|
sub_context: Sub-context (question_type, action_type, etc.)
|
|
|
|
Returns:
|
|
float: Actual wait time used
|
|
"""
|
|
if context not in RandomizedWait.WAIT_RANGES:
|
|
context = 'page_load' # Default fallback
|
|
|
|
ranges = RandomizedWait.WAIT_RANGES[context]
|
|
|
|
if sub_context and sub_context in ranges:
|
|
min_wait, max_wait = ranges[sub_context]
|
|
else:
|
|
min_wait, max_wait = ranges['default']
|
|
|
|
wait_time = random.uniform(min_wait, max_wait)
|
|
time.sleep(wait_time)
|
|
return wait_time
|
|
|
|
|