114 lines
3.5 KiB
Python
114 lines
3.5 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Test #2: Twitter/X Lazy Loading Scroll
|
|
|
|
Symptom: Infinite scroll doesn't load new content
|
|
Root Cause: Lazy loading requires content to be visible before loading more
|
|
Fix: Add wait_for_selector between scroll calls
|
|
"""
|
|
|
|
import asyncio
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "tools" / "src"))
|
|
|
|
from gcu.browser.bridge import BeelineBridge
|
|
|
|
BRIDGE_PORT = 9229
|
|
CONTEXT_NAME = "twitter-scroll-test"
|
|
|
|
|
|
async def test_twitter_lazy_scroll():
|
|
"""Test that repeated scrolls with waits load new content."""
|
|
print("=" * 70)
|
|
print("TEST #2: Twitter/X Lazy Loading Scroll")
|
|
print("=" * 70)
|
|
|
|
bridge = BeelineBridge()
|
|
|
|
try:
|
|
await bridge.start()
|
|
|
|
for i in range(10):
|
|
await asyncio.sleep(1)
|
|
if bridge.is_connected:
|
|
print("✓ Extension connected!")
|
|
break
|
|
print(f"Waiting for extension... ({i + 1}/10)")
|
|
else:
|
|
print("✗ Extension not connected")
|
|
return
|
|
|
|
context = await bridge.create_context(CONTEXT_NAME)
|
|
tab_id = context.get("tabId")
|
|
group_id = context.get("groupId")
|
|
print(f"✓ Created tab: {tab_id}")
|
|
|
|
# Navigate to Twitter/X
|
|
print("\n--- Navigating to X.com ---")
|
|
await bridge.navigate(tab_id, "https://x.com", wait_until="networkidle", timeout_ms=30000)
|
|
print("✓ Page loaded")
|
|
|
|
# Wait for tweets to appear
|
|
print("\n--- Waiting for tweets ---")
|
|
await bridge.wait_for_selector(tab_id, '[data-testid="tweet"]', timeout_ms=10000)
|
|
|
|
# Count initial tweets
|
|
initial_count = await bridge.evaluate(
|
|
tab_id,
|
|
"(function() { return document.querySelectorAll("
|
|
"'[data-testid=\"tweet\"]').length; })()",
|
|
)
|
|
print(f"Initial tweet count: {initial_count.get('result', 0)}")
|
|
|
|
# Take screenshot of initial state
|
|
screenshot = await bridge.screenshot(tab_id)
|
|
print(f"Screenshot: {len(screenshot.get('data', ''))} bytes")
|
|
|
|
# Scroll multiple times with waits
|
|
print("\n--- Scrolling with waits ---")
|
|
for i in range(3):
|
|
result = await bridge.scroll(tab_id, "down", 500)
|
|
print(f" Scroll {i + 1}: {result.get('method', 'unknown')} method")
|
|
|
|
# Wait for new content to load
|
|
await asyncio.sleep(2)
|
|
|
|
# Count tweets after scroll
|
|
count_result = await bridge.evaluate(
|
|
tab_id,
|
|
"(function() { return document.querySelectorAll("
|
|
"'[data-testid=\"tweet\"]').length; })()",
|
|
)
|
|
count = count_result.get("result", 0)
|
|
print(f" Tweet count after scroll: {count}")
|
|
|
|
# Final count
|
|
final_count = await bridge.evaluate(
|
|
tab_id,
|
|
"(function() { return document.querySelectorAll("
|
|
"'[data-testid=\"tweet\"]').length; })()",
|
|
)
|
|
final = final_count.get("result", 0)
|
|
initial = initial_count.get("result", 0)
|
|
|
|
print("\n--- Results ---")
|
|
print(f"Initial tweets: {initial}")
|
|
print(f"Final tweets: {final}")
|
|
|
|
if final > initial:
|
|
print(f"✓ PASS: Loaded {final - initial} new tweets")
|
|
else:
|
|
print("✗ FAIL: No new tweets loaded (may need login)")
|
|
|
|
await bridge.destroy_context(group_id)
|
|
print("\n✓ Context destroyed")
|
|
|
|
finally:
|
|
await bridge.stop()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(test_twitter_lazy_scroll())
|