@@ -813,13 +813,12 @@ def activate_jquery(self):
813813 def __activate_bootstrap (self ):
814814 """ Allows you to use Bootstrap Tours with SeleniumBase
815815 http://bootstraptour.com/
816- (Currently, SeleniumBase methods only use Shepherd Tours.)
817816 """
818817 bootstrap_tour_css = constants .BootstrapTour .MIN_CSS
819818 bootstrap_tour_js = constants .BootstrapTour .MIN_JS
820819
821820 verify_script = ("""// Instance the tour
822- var tour = new Tour({
821+ var tour2 = new Tour({
823822 });""" )
824823
825824 for x in range (4 ):
@@ -844,7 +843,7 @@ def __activate_bootstrap(self):
844843
845844 def __is_bootstrap_activated (self ):
846845 verify_script = ("""// Instance the tour
847- var tour = new Tour({
846+ var tour2 = new Tour({
848847 });""" )
849848 try :
850849 self .execute_script (verify_script )
@@ -873,6 +872,8 @@ def __activate_shepherd(self):
873872
874873 self .__activate_bootstrap ()
875874 self .wait_for_ready_state_complete ()
875+ self .add_css_style (backdrop_style )
876+ self .wait_for_ready_state_complete ()
876877 for x in range (4 ):
877878 # self.activate_jquery() # Included with __activate_bootstrap()
878879 self .add_css_link (spinner_css )
@@ -886,8 +887,6 @@ def __activate_shepherd(self):
886887 self .add_js_link (underscore_js )
887888 self .add_js_link (backbone_js )
888889 self .add_js_link (shepherd_js )
889- time .sleep (0.01 )
890- self .add_css_style (backdrop_style )
891890 time .sleep (0.1 )
892891
893892 for x in range (int (settings .MINI_TIMEOUT * 2.0 )):
@@ -896,6 +895,7 @@ def __activate_shepherd(self):
896895 self .execute_script (sh_style ) # Verify Shepherd has loaded
897896 self .wait_for_ready_state_complete ()
898897 self .execute_script (sh_style ) # Need it twice for ordering
898+ self .wait_for_ready_state_complete ()
899899 time .sleep (0.05 )
900900 return
901901 except Exception :
@@ -928,7 +928,10 @@ def create_tour(self, name=None, theme=None):
928928
929929 shepherd_theme = "shepherd-theme-arrows"
930930 if theme :
931- if theme == "default" :
931+ if theme .lower () == "bootstrap" :
932+ self .create_bootstrap_tour (name )
933+ return
934+ elif theme == "default" :
932935 shepherd_theme = "shepherd-theme-default"
933936 elif theme == "dark" :
934937 shepherd_theme = "shepherd-theme-dark"
@@ -939,29 +942,53 @@ def create_tour(self, name=None, theme=None):
939942 elif theme == "square-dark" :
940943 shepherd_theme = "shepherd-theme-square-dark"
941944
942- new_tour = ("""let tour = new Shepherd.Tour({
945+ new_tour = ("""
946+ // Shepherd Tour
947+ let tour = new Shepherd.Tour({
943948 defaults: {
944949 classes: '%s',
945950 scrollTo: true
946951 }
947- });""" % shepherd_theme )
952+ });
953+ """ % shepherd_theme )
954+
955+ self ._tour_steps [name ] = []
956+ self ._tour_steps [name ].append (new_tour )
957+
958+ def create_bootstrap_tour (self , name = None ):
959+ """ Creates a Bootstrap tour for a website.
960+ @Params
961+ name - If creating multiple tours, use this to select the
962+ tour you wish to add steps to.
963+ """
964+ if not name :
965+ name = "default"
966+
967+ new_tour = ("""
968+ // Bootstrap Tour
969+ var tour = new Tour({
970+ steps: [
971+ """ )
948972
949973 self ._tour_steps [name ] = []
950974 self ._tour_steps [name ].append (new_tour )
951975
952976 def add_tour_step (self , message , selector = None , name = None ,
953- title = None , theme = None , alignment = None ):
977+ title = None , theme = None , alignment = None , duration = None ):
954978 """ Allows the user to add tour steps for a website.
955979 @Params
956980 message - The message to display.
957981 selector - The CSS Selector of the Element to attach to.
958982 name - If creating multiple tours, use this to select the
959983 tour you wish to add steps to.
960984 title - Additional header text that appears above the message.
961- theme - Choose from "arrows", "dark", "default", "square", and
985+ theme - (NON-Bootstrap Tours ONLY) The styling of the tour step.
986+ Choose from "arrows", "dark", "default", "square", and
962987 "square-dark". ("arrows" is used if None is selected.)
963988 alignment - Choose from "top", "bottom", "left", and "right".
964989 ("top" is the default alignment).
990+ duration - (Bootstrap Tours ONLY) The amount of time, in seconds,
991+ before automatically advancing to the next tour step.
965992 """
966993 if not selector :
967994 selector = "html"
@@ -970,7 +997,8 @@ def add_tour_step(self, message, selector=None, name=None,
970997 if not name :
971998 name = "default"
972999 if name not in self ._tour_steps :
973- self .create_tour (name = name )
1000+ # By default, will create a Bootstrap tour if no tours exist
1001+ self .create_tour (name = name , theme = "bootstrap" )
9741002
9751003 if not title :
9761004 title = ""
@@ -981,6 +1009,34 @@ def add_tour_step(self, message, selector=None, name=None,
9811009 else :
9821010 message = ""
9831011
1012+ if not alignment or (
1013+ alignment not in ["top" , "bottom" , "left" , "right" ]):
1014+ alignment = "top"
1015+
1016+ if "Bootstrap" in self ._tour_steps [name ][0 ]:
1017+ self .__add_bootstrap_tour_step (
1018+ message , selector = selector , name = name , title = title ,
1019+ alignment = alignment , duration = duration )
1020+ else :
1021+ self .__add_shepherd_tour_step (
1022+ message , selector = selector , name = name , title = title ,
1023+ theme = theme , alignment = alignment )
1024+
1025+ def __add_shepherd_tour_step (self , message , selector = None , name = None ,
1026+ title = None , theme = None , alignment = None ):
1027+ """ Allows the user to add tour steps for a website.
1028+ @Params
1029+ message - The message to display.
1030+ selector - The CSS Selector of the Element to attach to.
1031+ name - If creating multiple tours, use this to select the
1032+ tour you wish to add steps to.
1033+ title - Additional header text that appears above the message.
1034+ theme - (NON-Bootstrap Tours ONLY) The styling of the tour step.
1035+ Choose from "arrows", "dark", "default", "square", and
1036+ "square-dark". ("arrows" is used if None is selected.)
1037+ alignment - Choose from "top", "bottom", "left", and "right".
1038+ ("top" is the default alignment).
1039+ """
9841040 if theme == "default" :
9851041 shepherd_theme = "shepherd-theme-default"
9861042 elif theme == "dark" :
@@ -997,10 +1053,6 @@ def add_tour_step(self, message, selector=None, name=None,
9971053 self ._tour_steps [name ][0 ]).group (1 )
9981054 shepherd_theme = shepherd_base_theme
9991055
1000- if not alignment or (
1001- alignment not in ["top" , "bottom" , "left" , "right" ]):
1002- alignment = "top"
1003-
10041056 shepherd_classes = shepherd_theme
10051057 if selector == "html" :
10061058 shepherd_classes += " shepherd-orphan"
@@ -1016,6 +1068,41 @@ def add_tour_step(self, message, selector=None, name=None,
10161068
10171069 self ._tour_steps [name ].append (step )
10181070
1071+ def __add_bootstrap_tour_step (self , message , selector = None , name = None ,
1072+ title = None , alignment = None , duration = None ):
1073+ """ Allows the user to add tour steps for a website.
1074+ @Params
1075+ message - The message to display.
1076+ selector - The CSS Selector of the Element to attach to.
1077+ name - If creating multiple tours, use this to select the
1078+ tour you wish to add steps to.
1079+ title - Additional header text that appears above the message.
1080+ alignment - Choose from "top", "bottom", "left", and "right".
1081+ ("top" is the default alignment).
1082+ duration - (Bootstrap Tours ONLY) The amount of time, in seconds,
1083+ before automatically advancing to the next tour step.
1084+ """
1085+ if selector != "html" :
1086+ element_row = "element: '%s'," % selector
1087+ else :
1088+ element_row = ""
1089+ if not duration :
1090+ duration = "0"
1091+ else :
1092+ duration = str (float (duration ) * 1000.0 )
1093+
1094+ step = ("""{
1095+ %s
1096+ title: '%s',
1097+ content: '%s',
1098+ orphan: true,
1099+ placement: 'auto %s',
1100+ smartPlacement: true,
1101+ duration: %s,
1102+ },""" % (element_row , title , message , alignment , duration ))
1103+
1104+ self ._tour_steps [name ].append (step )
1105+
10191106 def play_tour (self , name = None , interval = 0 ):
10201107 """ Plays a tour on the current website.
10211108 @Params
@@ -1027,23 +1114,36 @@ def play_tour(self, name=None, interval=0):
10271114 if self .headless :
10281115 return # Tours should not run in headless mode.
10291116
1030- autoplay = False
1031- if interval and interval > 0 :
1032- autoplay = True
1033- interval = float (interval )
1034- if interval < 0.5 :
1035- interval = 0.5
1036-
10371117 if not name :
10381118 name = "default"
10391119 if name not in self ._tour_steps :
10401120 raise Exception ("Tour {%s} does not exist!" % name )
10411121
1122+ if "Bootstrap" in self ._tour_steps [name ][0 ]:
1123+ self .__play_bootstrap_tour (name = name , interval = interval )
1124+ else :
1125+ self .__play_shepherd_tour (name = name , interval = interval )
1126+
1127+ def __play_shepherd_tour (self , name = None , interval = 0 ):
1128+ """ Plays a tour on the current website.
1129+ @Params
1130+ name - If creating multiple tours, use this to select the
1131+ tour you wish to play.
1132+ interval - The delay time between autoplaying tour steps.
1133+ If set to 0 (default), the tour is fully manual control.
1134+ """
10421135 instructions = ""
10431136 for tour_step in self ._tour_steps [name ]:
10441137 instructions += tour_step
10451138 instructions += "tour.start();"
10461139
1140+ autoplay = False
1141+ if interval and interval > 0 :
1142+ autoplay = True
1143+ interval = float (interval )
1144+ if interval < 0.5 :
1145+ interval = 0.5
1146+
10471147 if not self .__is_shepherd_activated ():
10481148 self .__activate_shepherd ()
10491149
@@ -1134,6 +1234,86 @@ def play_tour(self, name=None, interval=0):
11341234 tour_on = False
11351235 time .sleep (0.1 )
11361236
1237+ def __play_bootstrap_tour (self , name = None , interval = 0 ):
1238+ """ Plays a tour on the current website.
1239+ @Params
1240+ name - If creating multiple tours, use this to select the
1241+ tour you wish to play.
1242+ interval - The delay time between autoplaying tour steps.
1243+ If set to 0 (default), the tour is fully manual control.
1244+ """
1245+ instructions = ""
1246+ for tour_step in self ._tour_steps [name ]:
1247+ instructions += tour_step
1248+ instructions += (
1249+ """]});
1250+
1251+ // Initialize the tour
1252+ tour.init();
1253+
1254+ // Start the tour
1255+ tour.start();
1256+
1257+ $tour = tour;
1258+ $tour.restart();""" )
1259+
1260+ if interval and interval > 0 :
1261+ if interval < 1 :
1262+ interval = 1
1263+ interval = str (float (interval ) * 1000.0 )
1264+ instructions = instructions .replace (
1265+ 'duration: 0,' , 'duration: %s,' % interval )
1266+
1267+ if not self .__is_bootstrap_activated ():
1268+ self .__activate_bootstrap ()
1269+
1270+ if len (self ._tour_steps [name ]) > 1 :
1271+ try :
1272+ if "element: " in self ._tour_steps [name ][1 ]:
1273+ selector = re .search (
1274+ "[\S\s]+element: '([\S\s]+)',[\S\s]+title: '" ,
1275+ self ._tour_steps [name ][1 ]).group (1 )
1276+ selector = selector .replace ('\\ ' , '' )
1277+ self .wait_for_element_present (
1278+ selector , timeout = (settings .SMALL_TIMEOUT ))
1279+ else :
1280+ selector = "html"
1281+ except Exception :
1282+ self .__post_messenger_error_message (
1283+ "Tour Error: {'%s'} was not found!"
1284+ "" % selector ,
1285+ duration = settings .SMALL_TIMEOUT )
1286+ raise Exception (
1287+ "Tour Error: {'%s'} was not found! "
1288+ "Exiting due to failure on first tour step!"
1289+ "" % selector )
1290+
1291+ self .execute_script (instructions )
1292+ tour_on = True
1293+ while tour_on :
1294+ try :
1295+ time .sleep (0.01 )
1296+ result = self .execute_script (
1297+ "return $tour.ended()" )
1298+ except Exception :
1299+ tour_on = False
1300+ result = None
1301+ if result is False :
1302+ tour_on = True
1303+ else :
1304+ try :
1305+ time .sleep (0.01 )
1306+ result = self .execute_script (
1307+ "return $tour.ended()" )
1308+ if result is False :
1309+ time .sleep (0.1 )
1310+ continue
1311+ else :
1312+ return
1313+ except Exception :
1314+ tour_on = False
1315+ time .sleep (0.1 )
1316+
11371317 def __wait_for_css_query_selector (
11381318 self , selector , timeout = settings .SMALL_TIMEOUT ):
11391319 element = None
0 commit comments