Chapter 11Lesson 04~180 minutes

File Uploads, Downloads, Cookies, Storage, and Session State: Diagnostics, Failure Modes, and Production Practices

Diagnose browser-state failures by preserving the first evidence and identifying the owner boundary. The objective is not “make the file appear” but explain whether the runner, browser, AUT origin, profile, Grid node, or CI artifact layer owns the failure.

DiagnosticsInvalid cookie domainStale filesState leakagePrivacy

Learning objectives

  • Diagnose upload paths unavailable on a remote node and download files written outside the intended workspace.
  • Detect stale download artifacts before they can create false passes.
  • Interpret invalid cookie-domain failures and state leakage between tests.
  • Recognize privacy/security risks in profiles, downloads, screenshots, and logs.
  • Apply the chapter diagnostic sequence without blanket retries, broad deletion, or browser restarts.
  • Repair one intentionally broken cookie/download example while preserving original evidence.

1. Failure taxonomy by owner

The following table organizes the key choices and evidence for Failure taxonomy by owner. Use it together with the surrounding prose so the rows serve as a comparison aid rather than standalone rules.

Symptom Likely owner boundary First evidence
file input rejects/path not found on remote run runner ↔ Grid node transfer runner file existence, driver type/file detector, remote exception
download “missing” but browser showed success browser download manager/path/CI artifact collection configured directory, browser prefs/capabilities, directory listing
download test passes before click test filesystem contamination directory listing + timestamps/hashes before action
InvalidCookieDomainException cookie scope/current URL current_url + cookie domain requested
next test starts authenticated shared profile/cookie/storage/account state session/profile identity + cookie/storage keys before test
artifact contains secrets/PII evidence retention/profile/download boundary artifact manifest and redacted metadata—not secret contents in logs

2. Diagnostic sequence

  1. Preserve first-failure evidence: exception class/message, current URL, session/browser versions, path names (redacted if sensitive), directory manifest, cookie/storage key names.
  2. Confirm versions: Selenium binding, browser, driver/Grid.
  3. Confirm target/environment/test data: exact loopback/CI origin and generated-file provenance.
  4. Inspect session/capabilities/context: local vs RemoteWebDriver, download capability/preferences, current URL/window.
  5. Inspect element/state: file input type, selected filename/application result, cookie/storage scope.
  6. Inspect AUT/network/browser evidence: did the application expose the download; did server-side state change?
  7. Remote only: inspect Grid/node/queue and artifact-transfer boundary.
  8. Apply least destructive correction and rerun the smallest scenario.

3. Intentionally broken example: wrong-domain cookie

The following example makes the Intentionally broken example: wrong-domain cookie behavior concrete. Read it with the stated assumptions, then compare its observable output or state changes with the explanation that follows.

from selenium import webdriver
from selenium.common.exceptions import InvalidCookieDomainException

URL = "http://127.0.0.1:8776/"
driver = webdriver.Chrome()
try:
    driver.get(URL)
    try:
        driver.add_cookie({
            "name": "academy_mode",
            "value": "synthetic",
            "domain": "example.invalid",
        })
    except InvalidCookieDomainException as exc:
        print("FIRST_FAILURE", type(exc).__name__)
        print("current_url", driver.current_url)
        print("requested_domain", "example.invalid")
        print("existing_cookie_names", [c["name"] for c in driver.get_cookies()])
        raise
finally:
    driver.quit()

The exception is meaningful: the test tried to set a cookie outside the current browsing context's domain. Do not work around it by disabling security or changing DNS. Repair the test contract.

4. Least-destructive repair

The following example makes the Least-destructive repair behavior concrete. Read it with the stated assumptions, then compare its observable output or state changes with the explanation that follows.

driver.get("http://127.0.0.1:8776/")
# Host-only cookie: let the current origin define the host scope.
driver.add_cookie({"name": "academy_mode", "value": "synthetic", "sameSite": "Lax"})
cookie = driver.get_cookie("academy_mode")
assert cookie is not None
assert cookie["value"] == "synthetic"

If your business case truly requires a parent-domain cookie, navigate to a compatible host and assert the exact domain/path contract instead of copying a generic snippet.

5. Stale download false positive

A classic anti-pattern is:

The following example makes the Stale download false positive behavior concrete. Read it with the stated assumptions, then compare its observable output or state changes with the explanation that follows.

# BROKEN DESIGN: shared path may contain yesterday's file.
downloaded = Path.home() / "Downloads" / "report.csv"
driver.find_element(By.ID, "download").click()
assert downloaded.exists()

This assertion can pass even if the current click did nothing. The repair is architectural: create a new test-owned directory before session creation, assert it starts empty, use a deterministic expected filename/content, and retain before/after manifests.

6. Upload path unavailable on a remote node

If a RemoteWebDriver run reports a bad path, prove the runner file exists first. Then inspect the RemoteWebDriver/file detector rather than mounting random host directories into Grid. Python's current RemoteWebDriver defaults to LocalFileDetector, which is designed to recognize local file inputs and transfer them to the remote end.

from pathlib import Path
from selenium import webdriver

source = Path("synthetic.txt").resolve()
assert source.is_file(), source
options = webdriver.ChromeOptions()
driver = webdriver.Remote("http://127.0.0.1:4444", options=options)
try:
    print("driver_type", type(driver).__name__)
    print("file_detector", type(driver.file_detector).__name__)
    # Only after this evidence should the test send source to input[type=file].
finally:
    driver.quit()

7. Session leakage between tests

If test B begins authenticated, do not immediately delete cookies and rerun. Capture the initial cookie names, storage keys, profile path policy, session ID, and test-account identity. A reused profile can retain more than cookies; a reused server-side account can also retain state even with a fresh browser.

Fresh browser ≠ fresh account; deleted cookies ≠ empty profile. Browser state and server-side test data are separate cleanup domains.

8. Privacy and secrets

Do not upload real credentials, SSH keys, customer exports, or browser profile databases to “test” file handling. Avoid archiving entire profile directories. Prefer evidence such as filename, byte size, cryptographic hash, sanitized MIME type, and synthetic content identifiers. Download retention should follow the same least-data rule as CI logs.

9. Troubleshooting shortcuts to reject

  • Blanket retry: can turn state leakage into nondeterministic passes.
  • Giant timeout: cannot repair wrong filesystem ownership or cookie scope.
  • Browser/Grid restart: destroys evidence and may mask persistent setup defects.
  • TLS disablement: unrelated to local file/path or cookie-domain diagnosis.
  • Wildcard cleanup of shared directories: can delete unrelated files and still fail to prove test isolation.
  • Personal profile reuse: imports uncontrolled secrets and state.

10. Performance only where causal

Separate browser startup/profile creation, upload transfer time, AUT processing, browser download time, remote artifact transfer, and evidence hashing. A slow 100 MB Grid upload is not the same problem as a slow browser click. Keep Chapter 11 fixtures tiny so timing diagnoses architecture rather than bandwidth volume.

11. Summary and next step

File/state diagnosis begins with ownership. Preserve first evidence, prove the current origin/session/path, then correct the smallest boundary. Lesson 5 packages those habits into a teardown-focused checkpoint.

Knowledge check

What does InvalidCookieDomainException tell you?

Why is checking only report.csv.exists() unsafe in a shared Downloads folder?

What should you inspect first when a remote upload path fails?

Why can deleting cookies fail to restore isolation?

Why should first-failure artifacts avoid full profile copies?

Next lesson

Checkpoint Lab — File Uploads, Downloads, Cookies, Storage, and Session State

Continue with Checkpoint Lab — File Uploads, Downloads, Cookies, Storage, and Session State. It builds directly on the state, evidence, and operating assumptions established here, so carry those constraints forward rather than treating the next page as an isolated topic.

Official references and version notes

Version and compatibility note

Version-sensitive behavior was rechecked against current primary documentation on 2026-08-28. Mandatory examples pin Selenium Python 4.47.0, require Python 3.10+, use a supported locally installed Chromium-family browser with Selenium Manager for driver resolution, and target only 127.0.0.1. Chromium download preferences are intentionally labeled browser-specific. Remote/Grid file-transfer and downloadable-file APIs are optional extensions to the local path. JavaScript execution appears only for Web Storage access, where Selenium explicitly notes local/session storage are not W3C WebDriver commands. UI interactions remain native WebDriver interactions.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.