Add CAPTCHA automation beta flow
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
import csv
|
||||
import os
|
||||
import time
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
|
||||
from tests.browser import create_chrome_driver
|
||||
from tests.config_reader import load_config
|
||||
from tests.helpers import login, logout
|
||||
from tests.locators import Locator
|
||||
|
||||
|
||||
LOGIN_ATTEMPTS = 50
|
||||
MAX_CAPTCHA_RETRIES = 7
|
||||
|
||||
|
||||
@pytest.mark.captcha
|
||||
def test_captcha_login_stress():
|
||||
"""Run bounded EasyOCR login attempts and retain auditable CAPTCHA evidence."""
|
||||
config = load_config()
|
||||
output_dir = os.path.abspath(os.path.join("reports", "captcha_login_stress"))
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
started = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
csv_path = os.path.join(output_dir, f"captcha_login_{started}.csv")
|
||||
rows = []
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
def record(row):
|
||||
rows.append(row)
|
||||
|
||||
for login_number in range(1, LOGIN_ATTEMPTS + 1):
|
||||
login_started = datetime.now().isoformat(timespec="seconds")
|
||||
captcha_rows = []
|
||||
|
||||
driver = create_chrome_driver()
|
||||
try:
|
||||
driver.get(config["url"])
|
||||
|
||||
login_status = "FAILED"
|
||||
logout_status = "NOT_ATTEMPTED"
|
||||
error_text = ""
|
||||
captcha_metrics = {"captcha_attempts": []}
|
||||
try:
|
||||
login(
|
||||
driver,
|
||||
config["login"]["username"],
|
||||
config["login"]["password"],
|
||||
max_captcha_retries=MAX_CAPTCHA_RETRIES,
|
||||
captcha_metrics=captcha_metrics,
|
||||
max_login_duration_seconds=1200,
|
||||
)
|
||||
login_status = "PASSED"
|
||||
passed += 1
|
||||
except Exception as exc:
|
||||
failed += 1
|
||||
error_text = f"{type(exc).__name__}: {exc}"
|
||||
try:
|
||||
driver.save_screenshot(os.path.join(output_dir, f"login_{login_number:03d}_failure.png"))
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
# Explicitly log out after a successful authenticated flow,
|
||||
# then close the browser session.
|
||||
if login_status == "PASSED":
|
||||
try:
|
||||
logout_status = "PASSED" if logout(driver) else "FAILED"
|
||||
except Exception as exc:
|
||||
logout_status = "FAILED"
|
||||
print(f"Logout error: {type(exc).__name__}: {exc}")
|
||||
|
||||
try:
|
||||
driver.quit()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
captcha_rows = captcha_metrics.get("captcha_attempts", []) or [{
|
||||
"attempt": 0, "captcha_text": "", "variant": "",
|
||||
"status": "no_captcha_record", "screenshot": "", "error": error_text,
|
||||
}]
|
||||
for item in captcha_rows:
|
||||
record({
|
||||
"login_attempt": login_number,
|
||||
"started_at": login_started,
|
||||
"login_status": login_status,
|
||||
"logout_status": logout_status,
|
||||
"captcha_attempt": item["attempt"],
|
||||
"attempted_captcha": item["variant"],
|
||||
"ocr_captcha": item["captcha_text"],
|
||||
"screenshot_path": item["screenshot"],
|
||||
"captcha_status": item["status"],
|
||||
"captcha_entered_count": sum(
|
||||
1 for captcha_row in captcha_rows if captcha_row["variant"]
|
||||
),
|
||||
"error": item["error"] or error_text,
|
||||
"attempts_to_result": len(captcha_rows),
|
||||
"passed_count": passed,
|
||||
"failed_count": failed,
|
||||
})
|
||||
finally:
|
||||
# Clean up the driver after all attempts
|
||||
try:
|
||||
driver.quit()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
fieldnames = [
|
||||
"login_attempt", "started_at", "login_status", "captcha_attempt",
|
||||
"logout_status",
|
||||
"attempted_captcha", "ocr_captcha", "screenshot_path", "captcha_status",
|
||||
"captcha_entered_count", "error", "attempts_to_result", "passed_count",
|
||||
"failed_count",
|
||||
]
|
||||
with open(csv_path, "w", newline="", encoding="utf-8") as report:
|
||||
writer = csv.DictWriter(report, fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
writer.writerows(rows)
|
||||
|
||||
print(f"CAPTCHA stress report: {csv_path}")
|
||||
print(f"Passed: {passed}; Failed: {failed}; Total: {LOGIN_ATTEMPTS}")
|
||||
Reference in New Issue
Block a user