From f064468db0329d454be0cb33788cc147692b6e89 Mon Sep 17 00:00:00 2001 From: Ethan Stoner Date: Sat, 29 Aug 2026 14:36:08 -0700 Subject: [PATCH] match the unittest convention the selector tests introduced #50 landed a tests directory using stdlib unittest, discovered with python -m unittest discover -s tests. The multi-account checks were a standalone script with their own runner, so discovery would have walked straight past them. Same cases, rewritten as TestCases. The layer that starts Edge twice is behind REWARDS_BROWSER_TESTS rather than a --browser argument, since discovery does not pass arguments through. Claude-Session: https://claude.ai/code/session_019PWUtibJn81iDbxZ4hzeU3 --- tests/test_multi_account.py | 540 +++++++++++++++++------------------- 1 file changed, 262 insertions(+), 278 deletions(-) diff --git a/tests/test_multi_account.py b/tests/test_multi_account.py index bfbd569..fac6545 100644 --- a/tests/test_multi_account.py +++ b/tests/test_multi_account.py @@ -1,49 +1,51 @@ -"""Checks for REWARDS_ACCOUNTS. +"""Tests for running more than one account in a single run. -Five layers, cheapest first: +Names become directory names, so most of these are about refusing one that +would resolve somewhere other than where it reads: `..`, an absolute path, and +the trailing dot Win32 strips but Python's normalisation does not. The rest +cover the run loop, where one account failing used to end the batch and take +the remaining accounts with it. - 1. which accounts a configuration produces - 2. the flags each one hands Edge - 3. the run loop's ordering, skip-on-failure and exit codes - 4. one account failing every way it can, without ending the batch - 5. two real Edge profiles holding two independent, persistent identities +None of these need a browser. The last case does, and starts Edge twice to show +that two profiles hold two independent, persistent identities, so it is opt in: -Layers 1 to 4 are pure and need nothing installed. Layer 4 drives the real -run loop with a stand-in for the browser, so the code under test is the -shipped one and only selenium is replaced. Layer 5 starts Edge twice and -reaches bing.com, so it is opt in: - - python tests/test_multi_account.py # layers 1-4 - python tests/test_multi_account.py --browser # all five - -Layer 5 is the one that answers "does multi-account work". Two profiles must -end up with two different identities, and each must keep its own across a -restart, because that is what a per-account sign-in is made of. It uses -bing.com's own MUID cookie rather than an injected one: a cookie added through -webdriver is not written to the profile the way a Set-Cookie is, so it proves -nothing about a sign-in surviving. + python -m unittest discover -s tests + REWARDS_BROWSER_TESTS=1 python -m unittest discover -s tests """ import logging import os import shutil import sys +import unittest -sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "src")) +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) -FAILURES = [] +from selenium.common.exceptions import ( + NoSuchDriverException, + SessionNotCreatedException, + WebDriverException, +) +import accounts +import main +from constants import USER_DATA_DIR -def check(label, got, want): - if got == want: - print(f" ok {label}") - - return True - - print(f" FAIL {label}\n got {got!r}\n want {want!r}") - FAILURES.append(label) - - return False +# Names that have to be refused, with the reason each one is not simply a +# directory sitting under data-dir. +REFUSED_NAMES = [ + # relative traversal + "..", ".", "../escape", "..\\escape", "a/b", "a\\b", + # absolute, drive relative and UNC + "/etc", "\\", "/", "C:", "C:\\Windows", "\\\\server\\share", + # expanded by a shell somewhere else, not here + "~", "%TEMP%", "$HOME", + # Win32 strips a trailing dot from a path component and Python does not, so + # "personal." is the "personal" directory and "..." is data-dir itself + "...", "....", "personal.", "personal..", + # shell and filesystem metacharacters + "a b", "a:b", "a;b", "a|b", "a*b", "a?b", "a