From 0a5f5b466d008c935c0ce7ff88433ee2db4cd6a7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 14:28:06 -0400 Subject: [PATCH 01/10] Update a default value for highlight actions. --- seleniumbase/fixtures/base_case.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index a3ca57563d0..e89819fb9b5 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -1320,12 +1320,12 @@ def bring_to_front(self, selector, by=By.CSS_SELECTOR): self.execute_script(script) def highlight_click(self, selector, by=By.CSS_SELECTOR, - loops=2, scroll=True): + loops=3, scroll=True): self.highlight(selector, by=by, loops=loops, scroll=scroll) self.click(selector, by=by) def highlight_update_text(self, selector, new_value, by=By.CSS_SELECTOR, - loops=2, scroll=True): + loops=3, scroll=True): self.highlight(selector, by=by, loops=loops, scroll=scroll) self.update_text(selector, new_value, by=by) From d58348a531b3d25dc5cdfd05692c60ac5b82af7a Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 14:39:36 -0400 Subject: [PATCH 02/10] Don't duplicate the highlight animations with Demo Mode --- seleniumbase/fixtures/base_case.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index e89819fb9b5..3eca6e9c512 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -1321,12 +1321,14 @@ def bring_to_front(self, selector, by=By.CSS_SELECTOR): def highlight_click(self, selector, by=By.CSS_SELECTOR, loops=3, scroll=True): - self.highlight(selector, by=by, loops=loops, scroll=scroll) + if not self.demo_mode: + self.highlight(selector, by=by, loops=loops, scroll=scroll) self.click(selector, by=by) def highlight_update_text(self, selector, new_value, by=By.CSS_SELECTOR, loops=3, scroll=True): - self.highlight(selector, by=by, loops=loops, scroll=scroll) + if not self.demo_mode: + self.highlight(selector, by=by, loops=loops, scroll=scroll) self.update_text(selector, new_value, by=by) def highlight(self, selector, by=By.CSS_SELECTOR, From 068eb5aa8bb2db905c696428decc50c2868be241 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 14:41:02 -0400 Subject: [PATCH 03/10] Add feature to autoplay steps of walkthrough tours. --- seleniumbase/fixtures/base_case.py | 46 +++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 3eca6e9c512..d6183768d23 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -1030,15 +1030,24 @@ def add_tour_step(self, message, selector=None, name=None, self._tour_steps[name].append(step) - def play_tour(self, name=None): + def play_tour(self, name=None, interval=0): """ Plays a tour on the current website. @Params name - If creating multiple tours, use this to select the tour you wish to play. + interval - The delay time between autoplaying tour steps. + If set to 0 (default), the tour is fully manual control. """ if self.headless: return # Tours should not run in headless mode. + autoplay = False + if interval and interval > 0: + autoplay = True + interval = float(interval) + if interval < 0.5: + interval = 0.5 + if not name: name = "default" if name not in self._tour_steps: @@ -1070,6 +1079,11 @@ def play_tour(self, name=None): self.execute_script(instructions) tour_on = True + if autoplay: + start_ms = time.time() * 1000.0 + stop_ms = start_ms + (interval * 1000.0) + latest_element = None + latest_text = None while tour_on: try: time.sleep(0.01) @@ -1080,6 +1094,33 @@ def play_tour(self, name=None): result = None if result: tour_on = True + if autoplay: + try: + element = self.execute_script( + "Shepherd.activeTour.currentStep" + ".options.attachTo.element") + shep_text = self.execute_script( + "Shepherd.activeTour.currentStep.options.text") + except Exception: + continue + now_ms = time.time() * 1000.0 + if now_ms >= stop_ms: + if ((element == latest_element) and + (shep_text == latest_text)): + self.execute_script("Shepherd.activeTour.next()") + try: + latest_element = self.execute_script( + "Shepherd.activeTour.currentStep" + ".options.attachTo.element") + latest_text = self.execute_script( + "Shepherd.activeTour.currentStep" + ".options.text") + start_ms = time.time() * 1000.0 + stop_ms = start_ms + (interval * 1000.0) + except Exception: + pass + continue + else: try: time.sleep(0.01) @@ -1097,6 +1138,9 @@ def play_tour(self, name=None): duration=settings.SMALL_TIMEOUT) time.sleep(0.1) self.execute_script("Shepherd.activeTour.next()") + if autoplay: + start_ms = time.time() * 1000.0 + stop_ms = start_ms + (interval * 1000.0) tour_on = True except Exception: tour_on = False From 1e4e75f1b98f9fbefd220a7bf25f1fa6e5e9ea92 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 14:41:46 -0400 Subject: [PATCH 04/10] Update walkthrough tour ReadMe --- examples/tour_examples/ReadMe.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/tour_examples/ReadMe.md b/examples/tour_examples/ReadMe.md index cdbb82d9690..9083d4da58b 100755 --- a/examples/tour_examples/ReadMe.md +++ b/examples/tour_examples/ReadMe.md @@ -2,7 +2,7 @@ ![](https://cdn2.hubspot.net/hubfs/100006/images/google_tour.gif "SeleniumBase Tours")
-SeleniumBase Tours utilize the [HubSpot Shepherd Library](http://github.hubspot.com/shepherd/docs/welcome/) for creating and running tours on any website. +SeleniumBase Tours utilize the [HubSpot Shepherd Library](http://github.hubspot.com/shepherd/docs/welcome/) for creating and running tours, demos, and walkthroughs on any website. To utilize tours, there are three methods that you need to know at the basic level (which contain optional arguments): @@ -10,13 +10,13 @@ To utilize tours, there are three methods that you need to know at the basic lev ``self.add_tour_step(message, css_selector, title, alignment, theme)`` -``self.play_tour()`` +``self.play_tour(interval)`` With the ``create_tour()`` method, you can pass a default theme to change the look & feel of the tour steps. Valid themes are ``dark``, ``default``, ``arrows``, ``square``, and ``square-dark``. -With the ``self.add_tour_step()`` method, at minimum you must pass a message to display. Then you can specify a web element to attach to (by CSS selector). If no element is specified, the tour step will tether to the top of the screen by default. You can add an optional title above the message to display with the tour step. You can also change the theme for that step, as well as specifiy the alignment (which is the side of the element that you want the tour message to tether to). +With the ``self.add_tour_step()`` method, at minimum you must pass a message to display. Then you can specify a web element to attach to (by CSS selector). If no element is specified, the tour step will tether to the top of the screen by default. You can also add an optional title above the message to display with the tour step, as well as change the theme for that step, and even specify the alignment (which is the side of the element that you want the tour message to tether to). -Finally, you can play a tour you created by calling the ``self.play_tour()`` method. +Finally, you can play a tour you created by calling the ``self.play_tour()`` method. If you specify an interval, the tour will automatically walk through each step after that many seconds have passed. ### Here's an example of using SeleniumBase Tours: From db75cb41aa6729296192b18a7b61bf89acec7196 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 14:42:12 -0400 Subject: [PATCH 05/10] Update proxy_test --- examples/proxy_test.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/proxy_test.py b/examples/proxy_test.py index 83809c816a5..956804cdbfc 100755 --- a/examples/proxy_test.py +++ b/examples/proxy_test.py @@ -6,10 +6,9 @@ class MyTestClass(BaseCase): def test_proxy(self): self.open('https://ipinfo.io/') - ip_address = self.get_page_title().split(' ')[0] + ip_address = self.get_text("div.home-ip-details span.value")[1:-1] + self.open('https://ipinfo.io/%s' % ip_address) print("\n\nIP Address = %s\n" % ip_address) - href = '/%s' % ip_address - self.click('[href="%s"]' % href) print("Displaying Host Info:") print(self.get_text('table.table')) print("\nThe browser will close automatically in 7 seconds...") From a5360040f6ecacd70acf79245b9567e2c45930e6 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 23:33:08 -0400 Subject: [PATCH 06/10] Update spelling --- seleniumbase/fixtures/base_case.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index d6183768d23..ea982d1432e 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -1194,9 +1194,9 @@ def activate_messenger(self): "/messenger/1.5.0/css/messenger.css") msgr_theme_flat_css = ("https://cdnjs.cloudflare.com/ajax/libs" "/messenger/1.5.0/css/messenger-theme-flat.css") - msgr_theme_futur_css = ("https://cdnjs.cloudflare.com/ajax/libs" - "/messenger/1.5.0/css/" - "messenger-theme-future.css") + msgr_theme_future_css = ("https://cdnjs.cloudflare.com/ajax/libs" + "/messenger/1.5.0/css/" + "messenger-theme-future.css") msgr_theme_block_css = ("https://cdnjs.cloudflare.com/ajax/libs" "/messenger/1.5.0/css/" "messenger-theme-block.css") @@ -1213,7 +1213,7 @@ def activate_messenger(self): self.add_js_link(jquery_js) self.add_css_link(messenger_css) self.add_css_link(msgr_theme_flat_css) - self.add_css_link(msgr_theme_futur_css) + self.add_css_link(msgr_theme_future_css) self.add_css_link(msgr_theme_block_css) self.add_css_link(msgr_theme_air_css) self.add_css_link(msgr_theme_ice_css) From f9ee5dfa72dcd8df4c5cceca1cd66b28b45509d7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 23:35:02 -0400 Subject: [PATCH 07/10] Remove unused Messenger theme files --- seleniumbase/fixtures/base_case.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index ea982d1432e..59263417362 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -1178,12 +1178,6 @@ def activate_messenger(self): "/messenger/1.5.0/js/messenger-theme-flat.js") msg_theme_future_js = ("https://cdnjs.cloudflare.com/ajax/libs" "/messenger/1.5.0/js/messenger-theme-future.js") - msgr_theme_block_js = ("https://cdnjs.cloudflare.com/ajax/libs" - "/messenger/1.5.0/js/messenger-theme-block.js") - msgr_theme_air_js = ("https://cdnjs.cloudflare.com/ajax/libs" - "/messenger/1.5.0/js/messenger-theme-air.js") - msgr_theme_ice_js = ("https://cdnjs.cloudflare.com/ajax/libs" - "/messenger/1.5.0/js/messenger-theme-ice.js") underscore_js = ("https://cdnjs.cloudflare.com/ajax/libs" "/underscore.js/1.4.3/underscore-min.js") backbone_js = ("https://cdnjs.cloudflare.com/ajax/libs" @@ -1223,9 +1217,6 @@ def activate_messenger(self): self.add_js_link(messenger_js) self.add_js_link(msgr_theme_flat_js) self.add_js_link(msg_theme_future_js) - self.add_js_link(msgr_theme_block_js) - self.add_js_link(msgr_theme_air_js) - self.add_js_link(msgr_theme_ice_js) for x in range(int(settings.MINI_TIMEOUT * 10.0)): # Messenger needs a small amount of time to load & activate. From debc3179d476c0a465aae4d8933ce742856f46af Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sun, 17 Jun 2018 23:41:25 -0400 Subject: [PATCH 08/10] Add resources for offline usage. --- seleniumbase/resources/backbone-min.js | 42 ++ .../bootstrap-tour-standalone.min.css | 26 ++ .../bootstrap-tour-standalone.min.js | 22 + seleniumbase/resources/messenger-spinner.css | 165 +++++++ .../resources/messenger-theme-air.css | 359 +++++++++++++++ .../resources/messenger-theme-block.css | 96 ++++ .../resources/messenger-theme-flat.js | 33 ++ .../resources/messenger-theme-future.css | 412 ++++++++++++++++++ .../resources/messenger-theme-future.js | 33 ++ .../resources/messenger-theme-ice.css | 110 +++++ seleniumbase/resources/messenger.css | 105 +++++ seleniumbase/resources/messenger.min.js | 2 + .../resources/shepherd-theme-arrows-fix.css | 5 + .../resources/shepherd-theme-arrows.css | 229 ++++++++++ .../resources/shepherd-theme-dark.css | 246 +++++++++++ .../resources/shepherd-theme-default.css | 246 +++++++++++ .../resources/shepherd-theme-square-dark.css | 248 +++++++++++ .../resources/shepherd-theme-square.css | 248 +++++++++++ seleniumbase/resources/shepherd.min.js | 1 + seleniumbase/resources/tether.min.js | 1 + seleniumbase/resources/underscore-min.js | 1 + 21 files changed, 2630 insertions(+) create mode 100644 seleniumbase/resources/backbone-min.js create mode 100644 seleniumbase/resources/bootstrap-tour-standalone.min.css create mode 100644 seleniumbase/resources/bootstrap-tour-standalone.min.js create mode 100644 seleniumbase/resources/messenger-spinner.css create mode 100644 seleniumbase/resources/messenger-theme-air.css create mode 100644 seleniumbase/resources/messenger-theme-block.css create mode 100644 seleniumbase/resources/messenger-theme-flat.js create mode 100644 seleniumbase/resources/messenger-theme-future.css create mode 100644 seleniumbase/resources/messenger-theme-future.js create mode 100644 seleniumbase/resources/messenger-theme-ice.css create mode 100644 seleniumbase/resources/messenger.css create mode 100644 seleniumbase/resources/messenger.min.js create mode 100644 seleniumbase/resources/shepherd-theme-arrows-fix.css create mode 100644 seleniumbase/resources/shepherd-theme-arrows.css create mode 100644 seleniumbase/resources/shepherd-theme-dark.css create mode 100644 seleniumbase/resources/shepherd-theme-default.css create mode 100644 seleniumbase/resources/shepherd-theme-square-dark.css create mode 100644 seleniumbase/resources/shepherd-theme-square.css create mode 100644 seleniumbase/resources/shepherd.min.js create mode 100644 seleniumbase/resources/tether.min.js create mode 100644 seleniumbase/resources/underscore-min.js diff --git a/seleniumbase/resources/backbone-min.js b/seleniumbase/resources/backbone-min.js new file mode 100644 index 00000000000..d4b0314abe5 --- /dev/null +++ b/seleniumbase/resources/backbone-min.js @@ -0,0 +1,42 @@ +// Backbone.js 0.9.10 + +// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. +// Backbone may be freely distributed under the MIT license. +// For all details and documentation: +// http://backbonejs.org +(function(){var n=this,B=n.Backbone,h=[],C=h.push,u=h.slice,D=h.splice,g;g="undefined"!==typeof exports?exports:n.Backbone={};g.VERSION="0.9.10";var f=n._;!f&&"undefined"!==typeof require&&(f=require("underscore"));g.$=n.jQuery||n.Zepto||n.ender;g.noConflict=function(){n.Backbone=B;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var v=/\s+/,q=function(a,b,c,d){if(!c)return!0;if("object"===typeof c)for(var e in c)a[b].apply(a,[e,c[e]].concat(d));else if(v.test(c)){c=c.split(v);e=0;for(var f=c.length;e< +f;e++)a[b].apply(a,[c[e]].concat(d))}else return!0},w=function(a,b){var c,d=-1,e=a.length;switch(b.length){case 0:for(;++d=b);this.root=("/"+this.root+"/").replace(I,"/");b&&this._wantsHashChange&&(this.iframe=g.$('