44and definitions responsible for making HTTP requests to find servers
55the user might want to shill into.
66"""
7- from typing import Dict , Tuple , Callable , List , Optional , Any
7+ from typing import Callable , Optional , Any
88from contextlib import suppress
99from enum import auto , Enum
1010
11- from datetime import datetime , timedelta
11+ from datetime import timedelta
1212from typeguard import typechecked
1313
1414from . import misc
@@ -38,7 +38,7 @@ class GLOBALS:
3838 from selenium .webdriver .support .expected_conditions import (
3939 presence_of_element_located ,
4040 url_contains ,
41- url_changes
41+ url_changes ,
4242 )
4343 from selenium .common .exceptions import (
4444 NoSuchElementException ,
@@ -62,6 +62,7 @@ class GLOBALS:
6262
6363WD_TIMEOUT_SHORT = 5
6464WD_TIMEOUT_MED = 15
65+ WD_TIMEOUT_30 = 30
6566WD_TIMEOUT_LONG = 90
6667WD_RD_CLICK_UPPER_N = 5
6768WD_RD_CLICK_LOWER_N = 2
@@ -124,6 +125,42 @@ def __init__(self,
124125 self .driver = None
125126 self ._token = None
126127
128+ async def initialize (self ) -> None :
129+ """
130+ Starts the webdriver whenever the framework is started.
131+
132+ Raises
133+ ----------
134+ Any
135+ Raised in :py:meth:`~SeleniumCLIENT.login` method.
136+ """
137+ WD_OUTPUT_PATH .mkdir (exist_ok = True , parents = True )
138+ web_data_path = pathlib .Path (WD_PROFILES_PATH , self ._username )
139+
140+ opts = Options ()
141+ opts .add_argument (f"--user-data-dir={ web_data_path .absolute ()} " )
142+ opts .add_argument ("--profile-directory=Profile 1" )
143+ opts .add_argument ("--no-sandbox" )
144+ opts .add_argument ("--mute-audio" )
145+ opts .add_argument ("--no-first-run" )
146+ opts .add_argument ("--disable-background-networking" )
147+ opts .add_argument ("--disable-sync" )
148+
149+ if self ._proxy is not None :
150+ proxy = self ._proxy .split ("://" ) # protocol, url
151+ if '@' in proxy [1 ]: # Username and password also provided
152+ trace ("Proxy with username and password provided. Enter manually." , TraceLEVELS .WARNING )
153+ proxy [1 ] = proxy [1 ][proxy [1 ].find ('@' ) + 1 :]
154+
155+ proxy = f"{ proxy [0 ]} ://{ proxy [1 ]} "
156+ opts .add_argument (f"--proxy-server={ proxy } " )
157+
158+ driver = Chrome (options = opts )
159+ driver .maximize_window ()
160+ self .driver = driver
161+
162+ return await self .login ()
163+
127164 def __str__ (self ) -> str :
128165 return f"{ type (self ).__name__ } (username={ self ._username } )"
129166
@@ -258,10 +295,10 @@ async def fetch_invite_link(self, url: str):
258295 main_window_handle = driver .current_window_handle
259296 driver .switch_to .new_window ("tab" )
260297 await self .async_execute (driver .get , url )
261- await self . random_sleep ( 0.5 , 1 )
298+ await asyncio . sleep ( 1 )
262299 try :
263300 await self .async_execute (
264- WebDriverWait (driver , WD_TIMEOUT_MED ).until ,
301+ WebDriverWait (driver , WD_TIMEOUT_LONG ).until ,
265302 url_contains ("discord.com" )
266303 )
267304 await self .await_load ()
@@ -340,8 +377,8 @@ async def await_load(self):
340377 TimeoutError
341378 The page loading timed-out.
342379 """
343- await self .random_sleep (2 , 3 )
344380 trace ("Awaiting Discord load" , TraceLEVELS .DEBUG )
381+ await asyncio .sleep (3 )
345382 try :
346383 await self .async_execute (
347384 WebDriverWait (self .driver , WD_TIMEOUT_LONG ).until_not ,
@@ -426,37 +463,6 @@ async def await_captcha(self):
426463 except TimeoutException as exc :
427464 raise TimeoutError ("CAPTCHA was not solved by the user" ) from exc
428465
429- async def initialize (self ) -> None :
430- """
431- Starts the webdriver whenever the framework is started.
432-
433- Raises
434- ----------
435- Any
436- Raised in :py:meth:`~SeleniumCLIENT.login` method.
437- """
438- WD_OUTPUT_PATH .mkdir (exist_ok = True , parents = True )
439- web_data_path = pathlib .Path (WD_PROFILES_PATH , self ._username )
440-
441- opts = Options ()
442- opts .add_argument (f"--user-data-dir={ web_data_path .absolute ()} " )
443- opts .add_argument ("--profile-directory=Profile 1" )
444- opts .add_argument ("--no-sandbox" )
445- opts .add_argument ("--mute-audio" )
446-
447- if self ._proxy is not None :
448- proxy = self ._proxy .split ("://" ) # protocol, url
449- if '@' in proxy [1 ]:
450- proxy [1 ] = proxy [1 ][proxy [1 ].find ('@' ) + 1 :]
451-
452- proxy = f"{ proxy [0 ]} ://{ proxy [1 ]} "
453- opts .add_argument (f"--proxy-server={ proxy } " )
454-
455- driver = Chrome (options = opts )
456- driver .maximize_window ()
457- self .driver = driver
458- return await self .login ()
459-
460466 async def login (self ) -> str :
461467 """
462468 Logins to Discord using the webdriver
@@ -479,6 +485,7 @@ async def login(self) -> str:
479485 driver .get (DISCORD_LOGIN_URL )
480486 await self .await_load ()
481487 await self .random_sleep (2 , 3 )
488+
482489 # Check if already logged in
483490 if driver .current_url == DISCORD_LOGIN_URL :
484491 # Check previous accounts
@@ -490,6 +497,13 @@ async def login(self) -> str:
490497 )
491498 await self .hover_click (login_bnt )
492499
500+ await self .async_execute (
501+ WebDriverWait (driver , WD_TIMEOUT_LONG ).until ,
502+ presence_of_element_located (
503+ (By .XPATH , "//input[@name='email']" )
504+ )
505+ )
506+
493507 # Not logged in
494508 email_entry = driver .find_element (
495509 By .XPATH ,
@@ -507,8 +521,8 @@ async def login(self) -> str:
507521 ActionChains (driver ).send_keys (Keys .ENTER ).perform ()
508522
509523 await self .await_url_change ()
510- await self .await_load ()
511524
525+ await self .await_load ()
512526 return self .update_token_file ()
513527 except (WebDriverException , OSError ) as exc :
514528 raise RuntimeError (
@@ -584,7 +598,7 @@ async def join_guild(self, invite: str) -> None:
584598
585599 join_bnt = driver .find_element (
586600 By .XPATH ,
587- "//button[@type='button']/div[contains(text(), 'Join')]"
601+ "//button[@type='button']/div[contains(text(), 'Join Server ')]"
588602 )
589603 await self .hover_click (join_bnt )
590604 await self .random_sleep (3 , 5 ) # Wait for any CAPTCHA to appear
@@ -608,7 +622,7 @@ async def join_guild(self, invite: str) -> None:
608622 (
609623 By .XPATH ,
610624 "//button[@type='button']"
611- "/div[contains(text(), 'Join')]"
625+ "/div[contains(text(), 'Join Server ')]"
612626 )
613627 )
614628 )
0 commit comments