@@ -1024,6 +1024,9 @@ def evaluate(self, expression):
10241024 ).strip ()
10251025 return self .loop .run_until_complete (self .page .evaluate (expression ))
10261026
1027+ def execute_script (self , expression ):
1028+ return self .evaluate (expression )
1029+
10271030 def js_dumps (self , obj_name ):
10281031 """Similar to evaluate(), but for dictionary results."""
10291032 if obj_name .startswith ("return " ):
@@ -1407,6 +1410,64 @@ def enter_mfa_code(self, selector, totp_key=None, timeout=None):
14071410 mfa_code = self .get_mfa_code (totp_key )
14081411 self .type (selector , mfa_code + "\n " , timeout = timeout )
14091412
1413+ def activate_messenger (self ):
1414+ js_utils .activate_messenger (self )
1415+ self .__add_light_pause ()
1416+
1417+ def set_messenger_theme (
1418+ self , theme = "default" , location = "default" , max_messages = "default"
1419+ ):
1420+ """Sets a theme for posting messages.
1421+ Themes: ["flat", "future", "block", "air", "ice"]
1422+ Locations: ["top_left", "top_center", "top_right",
1423+ "bottom_left", "bottom_center", "bottom_right"]
1424+ max_messages: The limit of concurrent messages to display."""
1425+ if not theme :
1426+ theme = "default" # "flat"
1427+ if not location :
1428+ location = "default" # "bottom_right"
1429+ if not max_messages :
1430+ max_messages = "default" # "8"
1431+ else :
1432+ max_messages = str (max_messages ) # Value must be in string format
1433+ js_utils .set_messenger_theme (
1434+ self ,
1435+ theme = theme ,
1436+ location = location ,
1437+ max_messages = max_messages ,
1438+ )
1439+ self .__add_light_pause ()
1440+
1441+ def post_message (self , message , duration = None , pause = True , style = "info" ):
1442+ """Post a message on the screen with Messenger.
1443+ Arguments:
1444+ message: The message to display.
1445+ duration: The time until the message vanishes. (Default: 2.55s)
1446+ pause: If True, the program waits until the message completes.
1447+ style: "info", "success", or "error"."""
1448+ driver = self .driver
1449+ if hasattr (driver , "cdp_base" ):
1450+ driver = driver .cdp_base
1451+ if style not in ["info" , "success" , "error" ]:
1452+ style = "info"
1453+ if not duration :
1454+ duration = settings .DEFAULT_MESSAGE_DURATION
1455+ if (
1456+ (
1457+ driver .config .headless
1458+ or (hasattr (sb_config , "xvfb" ) and sb_config .xvfb )
1459+ )
1460+ and float (duration ) > 0.75
1461+ ):
1462+ duration = 0.75
1463+ try :
1464+ js_utils .post_message (self , message , duration , style = style )
1465+ except Exception :
1466+ print (" * %s message: %s" % (style .upper (), message ))
1467+ if pause :
1468+ duration = float (duration ) + 0.15
1469+ time .sleep (float (duration ))
1470+
14101471 def set_locale (self , locale ):
14111472 """(Settings will take effect on the next page load)"""
14121473 self .loop .run_until_complete (self .page .set_locale (locale ))
@@ -1510,7 +1571,10 @@ def __install_pyautogui_if_missing(self):
15101571 except Exception :
15111572 if (
15121573 shared_utils .is_linux ()
1513- and (not sb_config .headed or sb_config .xvfb )
1574+ and (
1575+ not sb_config .headed
1576+ or (hasattr (sb_config , "xvfb" ) and sb_config .xvfb )
1577+ )
15141578 and not driver .config .headless
15151579 and (
15161580 not hasattr (sb_config , "_virtual_display" )
@@ -2611,6 +2675,40 @@ def scroll_down(self, amount=25):
26112675 self .loop .run_until_complete (self .page .scroll_down (amount ))
26122676 self .loop .run_until_complete (self .page .wait ())
26132677
2678+ def save_page_source (self , name , folder = None ):
2679+ import codecs
2680+ from seleniumbase .core import log_helper
2681+ if not name .endswith (".html" ):
2682+ name = name + ".html"
2683+ if folder :
2684+ abs_path = os .path .abspath ("." )
2685+ file_path = os .path .join (abs_path , folder )
2686+ if not os .path .exists (file_path ):
2687+ os .makedirs (file_path )
2688+ html_file_path = os .path .join (file_path , name )
2689+ else :
2690+ html_file_path = name
2691+ page_source = self .get_page_source ()
2692+ last_page = self .get_current_url ()
2693+ meta_charset = '<meta charset="utf-8">'
2694+ rendered_source = ""
2695+ if "://" in last_page :
2696+ base_href_html = log_helper .get_base_href_html (last_page )
2697+ if ' charset="' not in page_source :
2698+ rendered_source = "%s\n %s\n %s" % (
2699+ base_href_html , meta_charset , page_source
2700+ )
2701+ else :
2702+ rendered_source = "%s\n %s" % (base_href_html , page_source )
2703+ else :
2704+ rendered_source = page_source
2705+ html_file = codecs .open (html_file_path , "w+" , "utf-8" )
2706+ html_file .write (rendered_source )
2707+ html_file .close ()
2708+
2709+ def save_as_html (self , * args , ** kwargs ):
2710+ self .save_page_source (* args , ** kwargs )
2711+
26142712 def save_screenshot (self , name , folder = None , selector = None ):
26152713 filename = name
26162714 if folder :
0 commit comments