Raymond Weitekamp commited on
Commit
fcd4d8a
·
1 Parent(s): 9dbf2cc

feat: add HF authentication setup and testing infrastructure - Add save_hf_storage_state.py for auth state management - Add check_hf_login.py for login verification - Update test_local.sh with Playwright setup - Add .cursor rules for test-first development - Update requirements.txt with new dependencies

Browse files
.cursor/rules/test-first.mdc ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ description: test before commiting.
3
+ globs:
4
+ ---
5
+
6
+ # YOU MUST RUN THE LOCAL TESTS BEFORE PUSHING
7
+
8
+ [test_local.sh](mdc:test_local.sh)
.gitignore CHANGED
@@ -27,4 +27,6 @@ Thumbs.db
27
 
28
  test-image.png
29
 
30
- /chrome_profile/
 
 
 
27
 
28
  test-image.png
29
 
30
+ /chrome_profile/
31
+
32
+ auth_state.json
check_hf_login.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from playwright.sync_api import sync_playwright
3
+
4
+ def check_huggingface_login():
5
+ # This assumes your copied Chrome profile is in "./chrome_profile"
6
+ user_data_dir = os.path.join(os.getcwd(), "chrome_profile")
7
+
8
+ with sync_playwright() as p:
9
+ # Launch a persistent context using your Chrome profile
10
+ context = p.chromium.launch_persistent_context(
11
+ user_data_dir=user_data_dir,
12
+ headless=False # Launch in non-headless mode so you can visually inspect the page
13
+ )
14
+ page = context.new_page()
15
+
16
+ # Navigate to Hugging Face homepage
17
+ page.goto("https://huggingface.co")
18
+ page.wait_for_load_state("networkidle")
19
+
20
+ print("Browser opened. Please inspect the page to verify that you are logged in (e.g., look for your profile avatar or username).")
21
+ input("Press Enter to close the browser once you've confirmed the login status...")
22
+
23
+ context.close()
24
+
25
+ if __name__ == "__main__":
26
+ check_huggingface_login()
requirements.txt CHANGED
@@ -3,4 +3,5 @@ huggingface-hub>=0.19.0
3
  Pillow>=10.0.0
4
  pytest>=7.0.0
5
  pytest-playwright>=0.4.0
 
6
  playwright>=1.40.0
 
3
  Pillow>=10.0.0
4
  pytest>=7.0.0
5
  pytest-playwright>=0.4.0
6
+ pytest-asyncio>=0.23.0
7
  playwright>=1.40.0
save_hf_storage_state.py ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import os
3
+ import sys
4
+ from playwright.async_api import async_playwright
5
+
6
+ async def wait_for_enter():
7
+ # Print the prompt and flush immediately so it's visible.
8
+ print("Press Enter to exit...", flush=True)
9
+ loop = asyncio.get_event_loop()
10
+ # Run sys.stdin.readline in the default executor so we don't block the event loop.
11
+ await loop.run_in_executor(None, sys.stdin.readline)
12
+
13
+ async def save_storage_state():
14
+ auth_state_path = "auth_state.json"
15
+ print("\n=== Starting Authentication State Check ===")
16
+
17
+ # Check if auth state exists and print the result
18
+ has_auth_state = os.path.exists(auth_state_path)
19
+ if has_auth_state:
20
+ print(f"✓ Found existing auth_state.json at: {os.path.abspath(auth_state_path)}")
21
+ else:
22
+ print("✗ No existing auth_state.json found. Will create new authentication state.")
23
+
24
+ print("\n=== Launching Browser ===")
25
+ async with async_playwright() as playwright:
26
+ print("• Launching Chromium...")
27
+ browser = await playwright.chromium.launch(headless=False)
28
+
29
+ if has_auth_state:
30
+ print("• Loading stored authentication state...")
31
+ context = await browser.new_context(storage_state=auth_state_path)
32
+ else:
33
+ print("• Starting fresh browser context...")
34
+ context = await browser.new_context()
35
+
36
+ print("• Opening new page...")
37
+ page = await context.new_page()
38
+ print("• Navigating to Hugging Face...")
39
+ await page.goto("https://huggingface.co")
40
+ await page.wait_for_load_state("networkidle")
41
+
42
+ print("\n=== Instructions ===")
43
+ print("1. Please check if you're logged in.")
44
+ print("2. If not, log in manually in the browser window.")
45
+ print("3. When ready to exit and save the current state, hit Enter below.\n")
46
+
47
+ # Await the blocking call to wait for the user to press Enter.
48
+ await wait_for_enter()
49
+
50
+ print("\n=== Saving State ===")
51
+ await context.storage_state(path=auth_state_path)
52
+ print(f"✓ Authentication state saved to: {os.path.abspath(auth_state_path)}")
53
+
54
+ print("\n=== Cleaning Up ===")
55
+ print("• Closing browser...")
56
+ await browser.close()
57
+ print("✓ Done!")
58
+
59
+ if __name__ == "__main__":
60
+ asyncio.run(save_storage_state())
test_local.sh CHANGED
@@ -54,8 +54,8 @@ if [ $? -eq 0 ]; then
54
  kill $GRADIO_PID
55
 
56
  if [ $E2E_STATUS -eq 0 ]; then
57
- echo "All tests passed! Starting Gradio app for development..."
58
- python app.py
59
  else
60
  echo "E2E tests failed! Please fix the issues before running the app."
61
  exit 1
 
54
  kill $GRADIO_PID
55
 
56
  if [ $E2E_STATUS -eq 0 ]; then
57
+ echo "All tests passed!"
58
+ exit 0
59
  else
60
  echo "E2E tests failed! Please fix the issues before running the app."
61
  exit 1