mirror of
				https://github.com/dgtlmoon/changedetection.io.git
				synced 2025-10-31 06:37:41 +00:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			browserles
			...
			browserste
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | f87c96d295 | ||
|   | 9f56b45bd9 | ||
|   | 98c0220e13 | ||
|   | cf385b5726 | ||
|   | 6d0d7df8cb | ||
|   | 656e8f6f34 | ||
|   | 592677b6b3 | 
| @@ -131,21 +131,11 @@ def construct_blueprint(datastore: ChangeDetectionStore): | ||||
|                 this_session.call_action(action_name=step_operation, | ||||
|                                          selector=step_selector, | ||||
|                                          optional_value=step_optional_value) | ||||
|             except playwright._impl._api_types.TimeoutError as e: | ||||
|                 print("Element wasnt found :-(", step_operation) | ||||
|                 return make_response("Element was not found on page", 401) | ||||
|  | ||||
|             except playwright._impl._api_types.Error as e: | ||||
|                 # Browser/playwright level error | ||||
|                 print("Browser error - got playwright._impl._api_types.Error, try reloading the session/browser") | ||||
|                 print (str(e)) | ||||
|  | ||||
|             except Exception as e: | ||||
|                 print("Exception when calling step operation", step_operation, str(e)) | ||||
|                 # Try to find something of value to give back to the user | ||||
|                 for l in str(e).splitlines(): | ||||
|                     if 'DOMException' in l: | ||||
|                         return make_response(l, 401) | ||||
|  | ||||
|                 return make_response('Browser session ran out of time :( Please reload this page.', 401) | ||||
|                 return make_response(str(e).splitlines()[0], 401) | ||||
|  | ||||
|             # Get visual selector ready/update its data (also use the current filter info from the page?) | ||||
|             # When the last 'apply' button was pressed | ||||
| @@ -205,6 +195,10 @@ def construct_blueprint(datastore: ChangeDetectionStore): | ||||
|             cleanup_playwright_session() | ||||
|             return make_response('Browser session ran out of time :( Please reload this page.', 401) | ||||
|  | ||||
|         response = None | ||||
|  | ||||
|         if request.method == 'POST': | ||||
|             # Screenshots and other info only needed on requesting a step (POST) | ||||
|             try: | ||||
|                 state = this_session.get_current_state() | ||||
|             except playwright._impl._api_types.Error as e: | ||||
| @@ -232,6 +226,13 @@ def construct_blueprint(datastore: ChangeDetectionStore): | ||||
|             # No longer needed | ||||
|             os.unlink(tmp_file) | ||||
|  | ||||
|         elif request.method == 'GET': | ||||
|             # Just enough to get the session rolling, it will call for goto-site via POST next | ||||
|             response = make_response({ | ||||
|                 'session_age_start': this_session.age_start, | ||||
|                 'browser_time_remaining': round(remaining) | ||||
|             }) | ||||
|  | ||||
|         return response | ||||
|  | ||||
|     return browser_steps_blueprint | ||||
|   | ||||
| @@ -90,7 +90,7 @@ class steppable_browser_interface(): | ||||
|             return | ||||
|         elem = self.page.get_by_text(value) | ||||
|         if elem.count(): | ||||
|             elem.first.click(delay=randint(200, 500)) | ||||
|             elem.first.click(delay=randint(200, 500), timeout=3000) | ||||
|  | ||||
|     def action_enter_text_in_field(self, selector, value): | ||||
|         if not len(selector.strip()): | ||||
| @@ -146,10 +146,10 @@ class steppable_browser_interface(): | ||||
|         self.page.keyboard.press("PageDown", delay=randint(200, 500)) | ||||
|  | ||||
|     def action_check_checkbox(self, selector, value): | ||||
|         self.page.locator(selector).check() | ||||
|         self.page.locator(selector).check(timeout=1000) | ||||
|  | ||||
|     def action_uncheck_checkbox(self, selector, value): | ||||
|         self.page.locator(selector).uncheck() | ||||
|         self.page.locator(selector, timeout=1000).uncheck(timeout=1000) | ||||
|  | ||||
|  | ||||
| # Responsible for maintaining a live 'context' with browserless | ||||
| @@ -211,7 +211,7 @@ class browsersteps_live_ui(steppable_browser_interface): | ||||
|         # Listen for all console events and handle errors | ||||
|         self.page.on("console", lambda msg: print(f"Browser steps console - {msg.type}: {msg.text} {msg.args}")) | ||||
|  | ||||
|         print("time to browser setup", time.time() - now) | ||||
|         print("Time to browser setup", time.time() - now) | ||||
|         self.page.wait_for_timeout(1 * 1000) | ||||
|  | ||||
|     def mark_as_closed(self): | ||||
|   | ||||
| @@ -13,7 +13,7 @@ $(document).ready(function () { | ||||
|     var browserless_seconds_remaining = 0; | ||||
|     var apply_buttons_disabled = false; | ||||
|     var include_text_elements = $("#include_text_elements"); | ||||
|     var xpath_data; | ||||
|     var xpath_data = false; | ||||
|     var current_selected_i; | ||||
|     var state_clicked = false; | ||||
|     var c; | ||||
| @@ -25,11 +25,42 @@ $(document).ready(function () { | ||||
|     $(window).resize(function () { | ||||
|         set_scale(); | ||||
|     }); | ||||
|     // Should always be disabled | ||||
|     $('#browser_steps >li:first-child select').val('Goto site').attr('disabled', 'disabled'); | ||||
|  | ||||
|     $('a#browsersteps-tab').click(function () { | ||||
|     $('#browsersteps-click-start').click(function () { | ||||
|         $("#browsersteps-click-start").fadeOut(); | ||||
|         $("#browsersteps-selector-wrapper .spinner").fadeIn(); | ||||
|         start(); | ||||
|     }); | ||||
|  | ||||
|     $('a#browsersteps-tab').click(function () { | ||||
|         reset(); | ||||
|     }); | ||||
|  | ||||
|     window.addEventListener('hashchange', function () { | ||||
|         if (window.location.hash == '#browser-steps') { | ||||
|             reset(); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     function reset() { | ||||
|         xpath_data = false; | ||||
|         $('#browsersteps-img').removeAttr('src'); | ||||
|         $("#browsersteps-click-start").show(); | ||||
|         $("#browsersteps-selector-wrapper .spinner").hide(); | ||||
|         browserless_seconds_remaining = 0; | ||||
|         browsersteps_session_id = false; | ||||
|         apply_buttons_disabled = false; | ||||
|         ctx.clearRect(0, 0, c.width, c.height); | ||||
|         set_first_gotosite_disabled(); | ||||
|     } | ||||
|  | ||||
|     function set_first_gotosite_disabled() { | ||||
|         $('#browser_steps >li:first-child select').val('Goto site').attr('disabled', 'disabled'); | ||||
|         $('#browser_steps >li:first-child').css('opacity', '0.5'); | ||||
|     } | ||||
|  | ||||
|     // Show seconds remaining until playwright/browserless needs to restart the session | ||||
|     // (See comment at the top of changedetectionio/blueprint/browser_steps/__init__.py ) | ||||
|     setInterval(() => { | ||||
| @@ -40,21 +71,6 @@ $(document).ready(function () { | ||||
|     }, "1000") | ||||
|  | ||||
|  | ||||
|     if (window.location.hash == '#browser-steps') { | ||||
|         start(); | ||||
|     } | ||||
|  | ||||
|     window.addEventListener('hashchange', function () { | ||||
|         if (window.location.hash == '#browser-steps') { | ||||
|             start(); | ||||
|         } | ||||
|         // For when the page loads | ||||
|         if (!window.location.hash || window.location.hash != '#browser-steps') { | ||||
|             $("img#browsersteps-img").attr('src', ''); | ||||
|             return; | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     function set_scale() { | ||||
|  | ||||
|         // some things to check if the scaling doesnt work | ||||
| @@ -87,7 +103,6 @@ $(document).ready(function () { | ||||
|         // @todo is click better? | ||||
|         $('#browsersteps-selector-canvas').off("mousemove mousedown click"); | ||||
|         // Undo disable_browsersteps_ui | ||||
|         $("#browser_steps select,input").removeAttr('disabled').css('opacity', '1.0'); | ||||
|         $("#browser-steps-ui").css('opacity', '1.0'); | ||||
|  | ||||
|         // init | ||||
| @@ -118,6 +133,10 @@ $(document).ready(function () { | ||||
|         }); | ||||
|  | ||||
|         $('#browsersteps-selector-canvas').bind('mousemove', function (e) { | ||||
|             if (!xpath_data) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             // checkbox if find elements is enabled | ||||
|             ctx.clearRect(0, 0, c.width, c.height); | ||||
|             ctx.fillStyle = 'rgba(255,0,0, 0.1)'; | ||||
| @@ -175,7 +194,6 @@ $(document).ready(function () { | ||||
|     // }); | ||||
|  | ||||
|  | ||||
|  | ||||
|     // callback for clicking on an xpath on the canvas | ||||
|     function process_selected(xpath_data_index) { | ||||
|         found_something = false; | ||||
| @@ -233,8 +251,8 @@ $(document).ready(function () { | ||||
|         browsersteps_session_id = Date.now(); | ||||
|         // @todo This setting of the first one should be done at the datalayer but wtforms doesnt wanna play nice | ||||
|         $('#browser_steps >li:first-child').removeClass('empty'); | ||||
|         $('#browser_steps >li:first-child select').val('Goto site').attr('disabled', 'disabled'); | ||||
|         $('#browser-steps-ui .loader').show(); | ||||
|         set_first_gotosite_disabled(); | ||||
|         $('#browser-steps-ui .loader .spinner').show(); | ||||
|         $('.clear,.remove', $('#browser_steps >li:first-child')).hide(); | ||||
|         $.ajax({ | ||||
|             type: "GET", | ||||
| @@ -247,11 +265,12 @@ $(document).ready(function () { | ||||
|             } | ||||
|         }).done(function (data) { | ||||
|             xpath_data = data.xpath_data; | ||||
|             $('#browsersteps-img').attr('src', data.screenshot); | ||||
|             $("#loading-status-text").fadeIn(); | ||||
|             // This should trigger 'Goto site' | ||||
|             console.log("Got startup response, requesting Goto-Site (first) step fake click"); | ||||
|             $('#browser_steps >li:first-child .apply').click(); | ||||
|             browserless_seconds_remaining = data.browser_time_remaining; | ||||
|             set_first_gotosite_disabled(); | ||||
|         }).fail(function (data) { | ||||
|             console.log(data); | ||||
|             alert('There was an error communicating with the server.'); | ||||
| @@ -260,7 +279,7 @@ $(document).ready(function () { | ||||
|     } | ||||
|  | ||||
|     function disable_browsersteps_ui() { | ||||
|         $("#browser_steps select,input").attr('disabled', 'disabled').css('opacity', '0.5'); | ||||
|         set_first_gotosite_disabled(); | ||||
|         $("#browser-steps-ui").css('opacity', '0.3'); | ||||
|         $('#browsersteps-selector-canvas').off("mousemove mousedown click"); | ||||
|     } | ||||
| @@ -307,11 +326,14 @@ $(document).ready(function () { | ||||
|  | ||||
|     // Add the extra buttons to the steps | ||||
|     $('ul#browser_steps li').each(function (i) { | ||||
|             $(this).append('<div class="control">' + | ||||
|                 '<a data-step-index=' + i + ' class="pure-button button-secondary button-green button-xsmall apply" >Apply</a> ' + | ||||
|                 '<a data-step-index=' + i + ' class="pure-button button-secondary button-xsmall clear" >Clear</a> ' + | ||||
|                 '<a data-step-index=' + i + ' class="pure-button button-secondary button-red button-xsmall remove" >Remove</a>' + | ||||
|                 '</div>') | ||||
|             var s = '<div class="control">' + '<a data-step-index=' + i + ' class="pure-button button-secondary button-green button-xsmall apply" >Apply</a> '; | ||||
|             if (i > 0) { | ||||
|                 // The first step never gets these (Goto-site) | ||||
|                 s += '<a data-step-index=' + i + ' class="pure-button button-secondary button-xsmall clear" >Clear</a> ' + | ||||
|                     '<a data-step-index=' + i + ' class="pure-button button-secondary button-red button-xsmall remove" >Remove</a>'; | ||||
|             } | ||||
|             s += '</div>'; | ||||
|             $(this).append(s) | ||||
|         } | ||||
|     ); | ||||
|  | ||||
| @@ -353,7 +375,7 @@ $(document).ready(function () { | ||||
|         } | ||||
|  | ||||
|         var current_data = $(event.currentTarget).closest('li'); | ||||
|         $('#browser-steps-ui .loader').fadeIn(); | ||||
|         $('#browser-steps-ui .loader .spinner').fadeIn(); | ||||
|         apply_buttons_disabled = true; | ||||
|         $('ul#browser_steps li .control .apply').css('opacity', 0.5); | ||||
|         $("#browsersteps-img").css('opacity', 0.65); | ||||
| @@ -374,7 +396,7 @@ $(document).ready(function () { | ||||
|             is_last_step = false; | ||||
|         } | ||||
|  | ||||
|  | ||||
|         console.log("Requesting step via POST " + $("select[id$='operation']", current_data).first().val()); | ||||
|         // POST the currently clicked step form widget back and await response, redraw | ||||
|         $.ajax({ | ||||
|             method: "POST", | ||||
| @@ -391,18 +413,26 @@ $(document).ready(function () { | ||||
|                     // More than likely the CSRF token was lost when the server restarted | ||||
|                     alert("There was a problem processing the request, please reload the page."); | ||||
|                     $("#loading-status-text").hide(); | ||||
|                     $('#browser-steps-ui .loader .spinner').fadeOut(); | ||||
|                 }, | ||||
|                 401: function (data) { | ||||
|                     // More than likely the CSRF token was lost when the server restarted | ||||
|                     alert(data.responseText); | ||||
|                     $("#loading-status-text").hide(); | ||||
|                     $('#browser-steps-ui .loader .spinner').fadeOut(); | ||||
|                 } | ||||
|             } | ||||
|         }).done(function (data) { | ||||
|             // it should return the new state (selectors available and screenshot) | ||||
|             xpath_data = data.xpath_data; | ||||
|             $('#browsersteps-img').attr('src', data.screenshot); | ||||
|             $('#browser-steps-ui .loader').fadeOut(); | ||||
|             $('#browser-steps-ui .loader .spinner').fadeOut(); | ||||
|             apply_buttons_disabled = false; | ||||
|             $("#browsersteps-img").css('opacity', 1); | ||||
|             $('ul#browser_steps li .control .apply').css('opacity', 1); | ||||
|             browserless_seconds_remaining = data.browser_time_remaining; | ||||
|             $("#loading-status-text").hide(); | ||||
|             set_first_gotosite_disabled(); | ||||
|         }).fail(function (data) { | ||||
|             console.log(data); | ||||
|             if (data.responseText.includes("Browser session expired")) { | ||||
| @@ -412,7 +442,6 @@ $(document).ready(function () { | ||||
|             $("#loading-status-text").hide(); | ||||
|             $('ul#browser_steps li .control .apply').css('opacity', 1); | ||||
|             $("#browsersteps-img").css('opacity', 1); | ||||
|             //$('#browsersteps-selector-wrapper .loader').fadeOut(2500); | ||||
|         }); | ||||
|  | ||||
|     }); | ||||
|   | ||||
| @@ -6,6 +6,11 @@ | ||||
|   } | ||||
|  | ||||
|   li { | ||||
|     &:not(:first-child) { | ||||
|       &:hover { | ||||
|         opacity: 1.0; | ||||
|       } | ||||
|     } | ||||
|     list-style: decimal; | ||||
|     padding: 5px; | ||||
|     .control { | ||||
| @@ -70,6 +75,8 @@ | ||||
|     transform: translate(-50%, -50%); | ||||
|     margin-left: -40px; | ||||
|     z-index: 100; | ||||
|     max-width: 350px; | ||||
|     text-align: center; | ||||
|   } | ||||
|  | ||||
|   /* nice tall skinny one */ | ||||
| @@ -78,4 +85,10 @@ | ||||
|     height: 80px; | ||||
|     font-size: 3px; | ||||
|   } | ||||
|  | ||||
|   #browsersteps-click-start { | ||||
|     &:hover { | ||||
|       cursor: pointer; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -50,6 +50,8 @@ nvm use v14.18.1 && npm install && npm run build | ||||
|   #browser_steps li { | ||||
|     list-style: decimal; | ||||
|     padding: 5px; } | ||||
|     #browser_steps li:not(:first-child):hover { | ||||
|       opacity: 1.0; } | ||||
|     #browser_steps li .control { | ||||
|       padding-left: 5px; | ||||
|       padding-right: 5px; } | ||||
| @@ -96,11 +98,15 @@ nvm use v14.18.1 && npm install && npm run build | ||||
|     top: 50%; | ||||
|     transform: translate(-50%, -50%); | ||||
|     margin-left: -40px; | ||||
|     z-index: 100; } | ||||
|     z-index: 100; | ||||
|     max-width: 350px; | ||||
|     text-align: center; } | ||||
|   #browsersteps-selector-wrapper .spinner, #browsersteps-selector-wrapper .spinner:after { | ||||
|     width: 80px; | ||||
|     height: 80px; | ||||
|     font-size: 3px; } | ||||
|   #browsersteps-selector-wrapper #browsersteps-click-start:hover { | ||||
|     cursor: pointer; } | ||||
|  | ||||
| .arrow { | ||||
|   border: solid #1b98f8; | ||||
|   | ||||
| @@ -167,7 +167,11 @@ User-Agent: wonderbra 1.0") }} | ||||
|  | ||||
|                                 <div class="noselect"  id="browsersteps-selector-wrapper" style="width: 100%"> | ||||
|                                     <span class="loader" > | ||||
|                                         <div class="spinner"></div> | ||||
|                                         <span id="browsersteps-click-start"> | ||||
|                                             <h2 >Click here to Start</h2> | ||||
|                                             Please allow 10-15 seconds for the browser to connect. | ||||
|                                         </span> | ||||
|                                         <div class="spinner"  style="display: none;"></div> | ||||
|                                     </span> | ||||
|                                     <img  class="noselect" id="browsersteps-img" src="" style="max-width: 100%; width: 100%;" /> | ||||
|                                     <canvas  class="noselect" id="browsersteps-selector-canvas" style="max-width: 100%; width: 100%;"></canvas> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user