fix: resolve TradingView authentication and screenshot automation

- Fixed authentication detection logic in checkLoginStatus method
- Resolved screenshot automation to properly capture TradingView charts
- Enhanced debugging output for authentication variable detection
- Improved session persistence and login flow
- Fixed weird screenshot issue - automation now properly navigates to charts

The automation now successfully:
- Authenticates with TradingView using proper session management
- Navigates to specific symbol charts correctly
- Captures clean screenshots instead of landing pages
- Maintains session persistence to avoid captchas
This commit is contained in:
mindesbunister
2025-07-18 09:49:04 +02:00
parent e77e06a5fe
commit 451e6c87b3
2 changed files with 135 additions and 102 deletions

View File

@@ -190,62 +190,89 @@ export class TradingViewAutomation {
}
async checkLoginStatus(): Promise<boolean> {
if (!this.page) throw new Error('Page not initialized')
console.log('CHECKING: Login status with 6 detection strategies...')
if (!this.page) return false
try {
// Strategy 1: Check JavaScript authentication variables (most reliable)
console.log('CHECKING: Strategy 1: Checking JavaScript authentication variables...')
console.log('🔍 CHECKING LOGIN STATUS - Starting comprehensive authentication detection...')
// Strategy 1: Check JavaScript authentication variables
console.log('CHECKING: Strategy 1: JavaScript authentication variables...')
const authStatus = await this.page.evaluate(() => {
// Check if window.is_authenticated exists and is true
const w = window as any
console.log('EVAL: Starting JavaScript authentication check...')
// Enhanced debugging - capture all relevant variables
const result = {
is_authenticated: w.is_authenticated,
user: w.user,
hasUser: typeof w.user === 'object' && w.user !== null,
authType: typeof w.is_authenticated,
userType: typeof w.user
// Check window.is_authenticated
console.log('EVAL: Checking window.is_authenticated...')
const isAuthVar = (window as any).is_authenticated
console.log('EVAL: window.is_authenticated =', isAuthVar, typeof isAuthVar)
// Check window.user
console.log('EVAL: Checking window.user...')
const userVar = (window as any).user
console.log('EVAL: window.user =', userVar, typeof userVar)
// Check if user object has meaningful data
if (userVar && typeof userVar === 'object') {
console.log('EVAL: User object keys:', Object.keys(userVar))
console.log('EVAL: User object values preview:', JSON.stringify(userVar).substring(0, 200))
}
console.log('🔍 JavaScript auth detection:', {
is_authenticated: result.is_authenticated,
authType: result.authType,
hasUser: result.hasUser,
userType: result.userType,
userExists: !!w.user,
username: w.user?.username || 'N/A'
})
if (typeof w.is_authenticated === 'boolean') {
return {
isAuthenticated: w.is_authenticated,
hasUser: typeof w.user === 'object' && w.user !== null,
username: w.user?.username || null
}
}
return null
// Return authentication status
const result = isAuthVar === true || (userVar && typeof userVar === 'object' && Object.keys(userVar).length > 0)
console.log('EVAL: Final Strategy 1 result:', result)
return result
})
console.log('🔍 Auth status result:', authStatus)
console.log('CHECKING: Strategy 1 JavaScript result:', authStatus)
if (authStatus) {
if (authStatus.isAuthenticated && authStatus.hasUser) {
console.log(`SUCCESS: JavaScript indicates user is authenticated as "${authStatus.username}"`)
return true
} else {
console.log('INFO: JavaScript indicates user is not authenticated')
console.log('🔍 Auth details:', {
isAuthenticated: authStatus.isAuthenticated,
hasUser: authStatus.hasUser,
username: authStatus.username
})
return false
}
} else {
console.log('INFO: No JavaScript authentication variables found')
console.log('✅ Strategy 1: Authenticated via JavaScript variables')
return true
}
// Strategy 1.5: Check for user avatar/profile elements (indicates logged in state)
console.log('CHECKING: Strategy 1.5: User interface elements...')
const userElements = await this.page.$$eval('[data-testid="header-user-menu"], .tv-header__user-menu, [class*="user-menu"], [class*="avatar"], [data-name="header-user-menu"]', elements => {
console.log('EVAL: Found', elements.length, 'potential user elements')
return elements.length > 0
}).catch(() => false)
if (userElements) {
console.log('Strategy 1.5: Found user interface elements - likely authenticated')
return true
}
// Strategy 2: Check for absence of login forms (indicates already logged in)
console.log('CHECKING: Strategy 2: Absence of login forms...')
const pageUrl = this.page.url()
console.log('CHECKING: Current URL:', pageUrl)
// If we're not on a login page and no login forms exist, we're likely logged in
const hasLoginForms = await this.page.$('input[type="email"], input[name="username"], input[name="email"], input[type="password"]').then(el => !!el).catch(() => false)
const isOnLoginPage = pageUrl.includes('/signin') || pageUrl.includes('/login') || pageUrl.includes('/accounts/signin')
console.log('CHECKING: Has login forms:', hasLoginForms)
console.log('CHECKING: Is on login page:', isOnLoginPage)
if (!hasLoginForms && !isOnLoginPage) {
console.log('Strategy 2: No login forms and not on login page - likely authenticated')
return true
}
// Strategy 3: Check for "Sign In" vs "User Menu" buttons
console.log('CHECKING: Strategy 3: Page action buttons...')
const hasSignInButton = await this.page.$('[data-testid="header-signin-button"], a[href*="signin"], button:has-text("Sign in")').then(el => !!el).catch(() => false)
const hasUserMenu = await this.page.$('[data-testid="header-user-menu"], .tv-header__user-menu, [class*="user-menu"]').then(el => !!el).catch(() => false)
console.log('CHECKING: Has sign in button:', hasSignInButton)
console.log('CHECKING: Has user menu:', hasUserMenu)
if (!hasSignInButton && hasUserMenu) {
console.log('Strategy 3: User menu present, no sign in button - authenticated')
return true
}
if (!hasSignInButton && !isOnLoginPage) {
console.log('Strategy 3: No sign in button and not on login page - likely authenticated')
return true
}
// Strategy 2: Check for user account indicators (positive indicators)
@@ -300,8 +327,8 @@ export class TradingViewAutomation {
// Strategy 4: Check URL patterns
console.log('CHECKING: Strategy 4: Checking URL patterns...')
const currentUrl = this.page.url()
if (currentUrl.includes('/signin') || currentUrl.includes('/login')) {
const urlCheck = this.page.url()
if (urlCheck.includes('/signin') || urlCheck.includes('/login')) {
console.log('ERROR: On login page - not logged in')
return false
}
@@ -338,6 +365,20 @@ export class TradingViewAutomation {
}
}
// Strategy 7: Check for absence of login interface (final check)
console.log('CHECKING: Strategy 7: Final absence of login interface check...')
const finalUrlCheck = this.page.url()
const hasAnyLoginElements = await this.page.$('input[type="email"], input[name="username"], input[name="email"], input[type="password"], [href*="signin"], [href*="login"], button:has-text("Sign in")').then(el => !!el).catch(() => false)
const isOnMainTradingViewDomain = finalUrlCheck.includes('tradingview.com') && !finalUrlCheck.includes('/signin') && !finalUrlCheck.includes('/login')
console.log('CHECKING: Has any login elements:', hasAnyLoginElements)
console.log('CHECKING: Is on main TradingView domain (not login page):', isOnMainTradingViewDomain)
if (isOnMainTradingViewDomain && !hasAnyLoginElements) {
console.log('✅ Strategy 7: On main TradingView domain with no login elements - authenticated')
return true
}
// If we can't determine status clearly, assume not logged in to be safe
console.log('WARNING: Could not determine login status clearly, assuming not logged in')
return false
@@ -405,9 +446,7 @@ export class TradingViewAutomation {
const elem = el as HTMLElement
return elem.textContent || elem.getAttribute('title') || elem.getAttribute('href') || ''
})
console.log(`🎯 Found signin element: ${selector} with text: "${text}"`)
// Check if this looks like a sign in button
console.log(`Found signin element: ${selector} with text: "${text}"`) // Check if this looks like a sign in button
const lowerText = text.toLowerCase()
if (lowerText.includes('sign in') || lowerText.includes('login') ||
lowerText.includes('signin') || selector.includes('signin') ||
@@ -910,6 +949,38 @@ export class TradingViewAutomation {
}
}
async navigateToLayout(layoutId: string, symbol: string, timeframe?: string): Promise<boolean> {
if (!this.page) throw new Error('Page not initialized')
try {
console.log(`🎯 Navigating to layout ${layoutId} with symbol: ${symbol}`)
// Construct direct layout URL - this bypasses the generic chart URL issue
const directUrl = `https://www.tradingview.com/chart/${layoutId}/?symbol=${symbol}${timeframe ? `&interval=${timeframe}` : ''}`
console.log(`📍 Direct layout navigation to: ${directUrl}`)
await this.page.goto(directUrl, {
waitUntil: 'domcontentloaded',
timeout: 30000
})
// Wait for chart to load
await sleep(5000)
// Wait for chart container
await this.page.waitForSelector('.chart-container, #chart-container, [data-name="chart"]', {
timeout: 30000
})
console.log(`✅ Successfully navigated to layout ${layoutId}`)
return true
} catch (error) {
console.error(`❌ Failed to navigate to layout ${layoutId}:`, error)
return false
}
}
async navigateToSymbol(symbol: string, timeframe?: string): Promise<boolean> {
if (!this.page) throw new Error('Page not initialized')