kopia lustrzana https://github.com/dgtlmoon/changedetection.io
BrowserSteps - Make the UI require an extra step so it doesnt slow down the experience when clicking through the tabs (#1175)
rodzic
0b8c3add34
commit
b4d79839bf
|
@ -131,21 +131,11 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||||
this_session.call_action(action_name=step_operation,
|
this_session.call_action(action_name=step_operation,
|
||||||
selector=step_selector,
|
selector=step_selector,
|
||||||
optional_value=step_optional_value)
|
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
|
# Try to find something of value to give back to the user
|
||||||
for l in str(e).splitlines():
|
return make_response(str(e).splitlines()[0], 401)
|
||||||
if 'DOMException' in l:
|
|
||||||
return make_response(l, 401)
|
|
||||||
|
|
||||||
return make_response('Browser session ran out of time :( Please reload this page.', 401)
|
|
||||||
|
|
||||||
# Get visual selector ready/update its data (also use the current filter info from the page?)
|
# Get visual selector ready/update its data (also use the current filter info from the page?)
|
||||||
# When the last 'apply' button was pressed
|
# When the last 'apply' button was pressed
|
||||||
|
@ -205,32 +195,43 @@ def construct_blueprint(datastore: ChangeDetectionStore):
|
||||||
cleanup_playwright_session()
|
cleanup_playwright_session()
|
||||||
return make_response('Browser session ran out of time :( Please reload this page.', 401)
|
return make_response('Browser session ran out of time :( Please reload this page.', 401)
|
||||||
|
|
||||||
try:
|
response = None
|
||||||
state = this_session.get_current_state()
|
|
||||||
except playwright._impl._api_types.Error as e:
|
|
||||||
return make_response("Browser session ran out of time :( Please reload this page."+str(e), 401)
|
|
||||||
|
|
||||||
# Use send_file() which is way faster than read/write loop on bytes
|
if request.method == 'POST':
|
||||||
import json
|
# Screenshots and other info only needed on requesting a step (POST)
|
||||||
from tempfile import mkstemp
|
try:
|
||||||
from flask import send_file
|
state = this_session.get_current_state()
|
||||||
tmp_fd, tmp_file = mkstemp(text=True, suffix=".json", prefix="changedetectionio-")
|
except playwright._impl._api_types.Error as e:
|
||||||
|
return make_response("Browser session ran out of time :( Please reload this page."+str(e), 401)
|
||||||
|
|
||||||
output = json.dumps({'screenshot': "data:image/jpeg;base64,{}".format(
|
# Use send_file() which is way faster than read/write loop on bytes
|
||||||
base64.b64encode(state[0]).decode('ascii')),
|
import json
|
||||||
'xpath_data': state[1],
|
from tempfile import mkstemp
|
||||||
'session_age_start': this_session.age_start,
|
from flask import send_file
|
||||||
'browser_time_remaining': round(remaining)
|
tmp_fd, tmp_file = mkstemp(text=True, suffix=".json", prefix="changedetectionio-")
|
||||||
})
|
|
||||||
|
|
||||||
with os.fdopen(tmp_fd, 'w') as f:
|
output = json.dumps({'screenshot': "data:image/jpeg;base64,{}".format(
|
||||||
f.write(output)
|
base64.b64encode(state[0]).decode('ascii')),
|
||||||
|
'xpath_data': state[1],
|
||||||
|
'session_age_start': this_session.age_start,
|
||||||
|
'browser_time_remaining': round(remaining)
|
||||||
|
})
|
||||||
|
|
||||||
response = make_response(send_file(path_or_file=tmp_file,
|
with os.fdopen(tmp_fd, 'w') as f:
|
||||||
mimetype='application/json; charset=UTF-8',
|
f.write(output)
|
||||||
etag=True))
|
|
||||||
# No longer needed
|
response = make_response(send_file(path_or_file=tmp_file,
|
||||||
os.unlink(tmp_file)
|
mimetype='application/json; charset=UTF-8',
|
||||||
|
etag=True))
|
||||||
|
# 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 response
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ class steppable_browser_interface():
|
||||||
return
|
return
|
||||||
elem = self.page.get_by_text(value)
|
elem = self.page.get_by_text(value)
|
||||||
if elem.count():
|
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):
|
def action_enter_text_in_field(self, selector, value):
|
||||||
if not len(selector.strip()):
|
if not len(selector.strip()):
|
||||||
|
@ -146,10 +146,10 @@ class steppable_browser_interface():
|
||||||
self.page.keyboard.press("PageDown", delay=randint(200, 500))
|
self.page.keyboard.press("PageDown", delay=randint(200, 500))
|
||||||
|
|
||||||
def action_check_checkbox(self, selector, value):
|
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):
|
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
|
# 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
|
# 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}"))
|
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)
|
self.page.wait_for_timeout(1 * 1000)
|
||||||
|
|
||||||
def mark_as_closed(self):
|
def mark_as_closed(self):
|
||||||
|
|
|
@ -10,10 +10,10 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var browsersteps_session_id;
|
var browsersteps_session_id;
|
||||||
var browserless_seconds_remaining=0;
|
var browserless_seconds_remaining = 0;
|
||||||
var apply_buttons_disabled = false;
|
var apply_buttons_disabled = false;
|
||||||
var include_text_elements = $("#include_text_elements");
|
var include_text_elements = $("#include_text_elements");
|
||||||
var xpath_data;
|
var xpath_data = false;
|
||||||
var current_selected_i;
|
var current_selected_i;
|
||||||
var state_clicked = false;
|
var state_clicked = false;
|
||||||
var c;
|
var c;
|
||||||
|
@ -25,11 +25,42 @@ $(document).ready(function () {
|
||||||
$(window).resize(function () {
|
$(window).resize(function () {
|
||||||
set_scale();
|
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();
|
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
|
// Show seconds remaining until playwright/browserless needs to restart the session
|
||||||
// (See comment at the top of changedetectionio/blueprint/browser_steps/__init__.py )
|
// (See comment at the top of changedetectionio/blueprint/browser_steps/__init__.py )
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
|
@ -40,21 +71,6 @@ $(document).ready(function () {
|
||||||
}, "1000")
|
}, "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() {
|
function set_scale() {
|
||||||
|
|
||||||
// some things to check if the scaling doesnt work
|
// some things to check if the scaling doesnt work
|
||||||
|
@ -87,7 +103,6 @@ $(document).ready(function () {
|
||||||
// @todo is click better?
|
// @todo is click better?
|
||||||
$('#browsersteps-selector-canvas').off("mousemove mousedown click");
|
$('#browsersteps-selector-canvas').off("mousemove mousedown click");
|
||||||
// Undo disable_browsersteps_ui
|
// Undo disable_browsersteps_ui
|
||||||
$("#browser_steps select,input").removeAttr('disabled').css('opacity', '1.0');
|
|
||||||
$("#browser-steps-ui").css('opacity', '1.0');
|
$("#browser-steps-ui").css('opacity', '1.0');
|
||||||
|
|
||||||
// init
|
// init
|
||||||
|
@ -103,7 +118,7 @@ $(document).ready(function () {
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
console.log(e);
|
console.log(e);
|
||||||
console.log("current xpath in index is "+current_selected_i);
|
console.log("current xpath in index is " + current_selected_i);
|
||||||
last_click_xy = {'x': parseInt((1 / x_scale) * e.offsetX), 'y': parseInt((1 / y_scale) * e.offsetY)}
|
last_click_xy = {'x': parseInt((1 / x_scale) * e.offsetX), 'y': parseInt((1 / y_scale) * e.offsetY)}
|
||||||
process_selected(current_selected_i);
|
process_selected(current_selected_i);
|
||||||
current_selected_i = false;
|
current_selected_i = false;
|
||||||
|
@ -118,6 +133,10 @@ $(document).ready(function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#browsersteps-selector-canvas').bind('mousemove', function (e) {
|
$('#browsersteps-selector-canvas').bind('mousemove', function (e) {
|
||||||
|
if (!xpath_data) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// checkbox if find elements is enabled
|
// checkbox if find elements is enabled
|
||||||
ctx.clearRect(0, 0, c.width, c.height);
|
ctx.clearRect(0, 0, c.width, c.height);
|
||||||
ctx.fillStyle = 'rgba(255,0,0, 0.1)';
|
ctx.fillStyle = 'rgba(255,0,0, 0.1)';
|
||||||
|
@ -153,8 +172,8 @@ $(document).ready(function () {
|
||||||
// does it mean sort the xpath list by size (w*h) i think so!
|
// does it mean sort the xpath list by size (w*h) i think so!
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( include_text_elements[0].checked === true) {
|
if (include_text_elements[0].checked === true) {
|
||||||
// blue one with background instead?
|
// blue one with background instead?
|
||||||
ctx.fillStyle = 'rgba(0,0,255, 0.1)';
|
ctx.fillStyle = 'rgba(0,0,255, 0.1)';
|
||||||
ctx.strokeStyle = 'rgba(0,0,200, 0.7)';
|
ctx.strokeStyle = 'rgba(0,0,200, 0.7)';
|
||||||
$('#browsersteps-selector-canvas').css('cursor', 'grab');
|
$('#browsersteps-selector-canvas').css('cursor', 'grab');
|
||||||
|
@ -175,7 +194,6 @@ $(document).ready(function () {
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// callback for clicking on an xpath on the canvas
|
// callback for clicking on an xpath on the canvas
|
||||||
function process_selected(xpath_data_index) {
|
function process_selected(xpath_data_index) {
|
||||||
found_something = false;
|
found_something = false;
|
||||||
|
@ -190,23 +208,23 @@ $(document).ready(function () {
|
||||||
console.log(x);
|
console.log(x);
|
||||||
if (x && first_available.length) {
|
if (x && first_available.length) {
|
||||||
// @todo will it let you click shit that has a layer ontop? probably not.
|
// @todo will it let you click shit that has a layer ontop? probably not.
|
||||||
if (x['tagtype'] === 'text' || x['tagtype'] === 'email' || x['tagName'] === 'textarea' || x['tagtype'] === 'password' || x['tagtype'] === 'search' ) {
|
if (x['tagtype'] === 'text' || x['tagtype'] === 'email' || x['tagName'] === 'textarea' || x['tagtype'] === 'password' || x['tagtype'] === 'search') {
|
||||||
$('select', first_available).val('Enter text in field').change();
|
$('select', first_available).val('Enter text in field').change();
|
||||||
$('input[type=text]', first_available).first().val(x['xpath']);
|
$('input[type=text]', first_available).first().val(x['xpath']);
|
||||||
$('input[placeholder="Value"]', first_available).addClass('ok').click().focus();
|
$('input[placeholder="Value"]', first_available).addClass('ok').click().focus();
|
||||||
found_something = true;
|
found_something = true;
|
||||||
} else {
|
} else {
|
||||||
if (x['isClickable'] || x['tagName'].startsWith('h')|| x['tagName'] === 'a' || x['tagName'] === 'button' || x['tagtype'] === 'submit'|| x['tagtype'] === 'checkbox'|| x['tagtype'] === 'radio'|| x['tagtype'] === 'li') {
|
if (x['isClickable'] || x['tagName'].startsWith('h') || x['tagName'] === 'a' || x['tagName'] === 'button' || x['tagtype'] === 'submit' || x['tagtype'] === 'checkbox' || x['tagtype'] === 'radio' || x['tagtype'] === 'li') {
|
||||||
$('select', first_available).val('Click element').change();
|
$('select', first_available).val('Click element').change();
|
||||||
$('input[type=text]', first_available).first().val(x['xpath']);
|
$('input[type=text]', first_available).first().val(x['xpath']);
|
||||||
found_something = true;
|
found_something = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
first_available.xpath_data_index=xpath_data_index;
|
first_available.xpath_data_index = xpath_data_index;
|
||||||
|
|
||||||
if (!found_something) {
|
if (!found_something) {
|
||||||
if ( include_text_elements[0].checked === true) {
|
if (include_text_elements[0].checked === true) {
|
||||||
// Suggest that we use as filter?
|
// Suggest that we use as filter?
|
||||||
// @todo filters should always be in the last steps, nothing non-filter after it
|
// @todo filters should always be in the last steps, nothing non-filter after it
|
||||||
found_something = true;
|
found_something = true;
|
||||||
|
@ -230,15 +248,15 @@ $(document).ready(function () {
|
||||||
|
|
||||||
function start() {
|
function start() {
|
||||||
console.log("Starting browser-steps UI");
|
console.log("Starting browser-steps UI");
|
||||||
browsersteps_session_id=Date.now();
|
browsersteps_session_id = Date.now();
|
||||||
// @todo This setting of the first one should be done at the datalayer but wtforms doesnt wanna play nice
|
// @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').removeClass('empty');
|
||||||
$('#browser_steps >li:first-child select').val('Goto site').attr('disabled', 'disabled');
|
set_first_gotosite_disabled();
|
||||||
$('#browser-steps-ui .loader').show();
|
$('#browser-steps-ui .loader .spinner').show();
|
||||||
$('.clear,.remove', $('#browser_steps >li:first-child')).hide();
|
$('.clear,.remove', $('#browser_steps >li:first-child')).hide();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
url: browser_steps_sync_url+"&browsersteps_session_id="+browsersteps_session_id,
|
url: browser_steps_sync_url + "&browsersteps_session_id=" + browsersteps_session_id,
|
||||||
statusCode: {
|
statusCode: {
|
||||||
400: function () {
|
400: function () {
|
||||||
// More than likely the CSRF token was lost when the server restarted
|
// More than likely the CSRF token was lost when the server restarted
|
||||||
|
@ -247,11 +265,12 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
}).done(function (data) {
|
}).done(function (data) {
|
||||||
xpath_data = data.xpath_data;
|
xpath_data = data.xpath_data;
|
||||||
$('#browsersteps-img').attr('src', data.screenshot);
|
|
||||||
$("#loading-status-text").fadeIn();
|
$("#loading-status-text").fadeIn();
|
||||||
// This should trigger 'Goto site'
|
// This should trigger 'Goto site'
|
||||||
|
console.log("Got startup response, requesting Goto-Site (first) step fake click");
|
||||||
$('#browser_steps >li:first-child .apply').click();
|
$('#browser_steps >li:first-child .apply').click();
|
||||||
browserless_seconds_remaining = data.browser_time_remaining;
|
browserless_seconds_remaining = data.browser_time_remaining;
|
||||||
|
set_first_gotosite_disabled();
|
||||||
}).fail(function (data) {
|
}).fail(function (data) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
alert('There was an error communicating with the server.');
|
alert('There was an error communicating with the server.');
|
||||||
|
@ -260,7 +279,7 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
function disable_browsersteps_ui() {
|
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');
|
$("#browser-steps-ui").css('opacity', '0.3');
|
||||||
$('#browsersteps-selector-canvas').off("mousemove mousedown click");
|
$('#browsersteps-selector-canvas').off("mousemove mousedown click");
|
||||||
}
|
}
|
||||||
|
@ -307,11 +326,14 @@ $(document).ready(function () {
|
||||||
|
|
||||||
// Add the extra buttons to the steps
|
// Add the extra buttons to the steps
|
||||||
$('ul#browser_steps li').each(function (i) {
|
$('ul#browser_steps li').each(function (i) {
|
||||||
$(this).append('<div class="control">' +
|
var s = '<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-green button-xsmall apply" >Apply</a> ' +
|
if (i > 0) {
|
||||||
'<a data-step-index=' + i + ' class="pure-button button-secondary button-xsmall clear" >Clear</a> ' +
|
// The first step never gets these (Goto-site)
|
||||||
'<a data-step-index=' + i + ' class="pure-button button-secondary button-red button-xsmall remove" >Remove</a>' +
|
s += '<a data-step-index=' + i + ' class="pure-button button-secondary button-xsmall clear" >Clear</a> ' +
|
||||||
'</div>')
|
'<a data-step-index=' + i + ' class="pure-button button-secondary button-red button-xsmall remove" >Remove</a>';
|
||||||
|
}
|
||||||
|
s += '</div>';
|
||||||
|
$(this).append(s)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -348,15 +370,15 @@ $(document).ready(function () {
|
||||||
|
|
||||||
$('ul#browser_steps li .control .apply').click(function (event) {
|
$('ul#browser_steps li .control .apply').click(function (event) {
|
||||||
// sequential requests @todo refactor
|
// sequential requests @todo refactor
|
||||||
if(apply_buttons_disabled) {
|
if (apply_buttons_disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var current_data = $(event.currentTarget).closest('li');
|
var current_data = $(event.currentTarget).closest('li');
|
||||||
$('#browser-steps-ui .loader').fadeIn();
|
$('#browser-steps-ui .loader .spinner').fadeIn();
|
||||||
apply_buttons_disabled=true;
|
apply_buttons_disabled = true;
|
||||||
$('ul#browser_steps li .control .apply').css('opacity',0.5);
|
$('ul#browser_steps li .control .apply').css('opacity', 0.5);
|
||||||
$("#browsersteps-img").css('opacity',0.65);
|
$("#browsersteps-img").css('opacity', 0.65);
|
||||||
|
|
||||||
var is_last_step = 0;
|
var is_last_step = 0;
|
||||||
var step_n = $(event.currentTarget).data('step-index');
|
var step_n = $(event.currentTarget).data('step-index');
|
||||||
|
@ -368,17 +390,17 @@ $(document).ready(function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (is_last_step == (step_n+1)) {
|
if (is_last_step == (step_n + 1)) {
|
||||||
is_last_step = true;
|
is_last_step = true;
|
||||||
} else {
|
} else {
|
||||||
is_last_step = false;
|
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
|
// POST the currently clicked step form widget back and await response, redraw
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: browser_steps_sync_url+"&browsersteps_session_id="+browsersteps_session_id,
|
url: browser_steps_sync_url + "&browsersteps_session_id=" + browsersteps_session_id,
|
||||||
data: {
|
data: {
|
||||||
'operation': $("select[id$='operation']", current_data).first().val(),
|
'operation': $("select[id$='operation']", current_data).first().val(),
|
||||||
'selector': $("input[id$='selector']", current_data).first().val(),
|
'selector': $("input[id$='selector']", current_data).first().val(),
|
||||||
|
@ -391,28 +413,35 @@ $(document).ready(function () {
|
||||||
// More than likely the CSRF token was lost when the server restarted
|
// More than likely the CSRF token was lost when the server restarted
|
||||||
alert("There was a problem processing the request, please reload the page.");
|
alert("There was a problem processing the request, please reload the page.");
|
||||||
$("#loading-status-text").hide();
|
$("#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) {
|
}).done(function (data) {
|
||||||
// it should return the new state (selectors available and screenshot)
|
// it should return the new state (selectors available and screenshot)
|
||||||
xpath_data = data.xpath_data;
|
xpath_data = data.xpath_data;
|
||||||
$('#browsersteps-img').attr('src', data.screenshot);
|
$('#browsersteps-img').attr('src', data.screenshot);
|
||||||
$('#browser-steps-ui .loader').fadeOut();
|
$('#browser-steps-ui .loader .spinner').fadeOut();
|
||||||
apply_buttons_disabled=false;
|
apply_buttons_disabled = false;
|
||||||
$("#browsersteps-img").css('opacity',1);
|
$("#browsersteps-img").css('opacity', 1);
|
||||||
$('ul#browser_steps li .control .apply').css('opacity',1);
|
$('ul#browser_steps li .control .apply').css('opacity', 1);
|
||||||
browserless_seconds_remaining = data.browser_time_remaining;
|
browserless_seconds_remaining = data.browser_time_remaining;
|
||||||
$("#loading-status-text").hide();
|
$("#loading-status-text").hide();
|
||||||
|
set_first_gotosite_disabled();
|
||||||
}).fail(function (data) {
|
}).fail(function (data) {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
if (data.responseText.includes("Browser session expired")) {
|
if (data.responseText.includes("Browser session expired")) {
|
||||||
disable_browsersteps_ui();
|
disable_browsersteps_ui();
|
||||||
}
|
}
|
||||||
apply_buttons_disabled=false;
|
apply_buttons_disabled = false;
|
||||||
$("#loading-status-text").hide();
|
$("#loading-status-text").hide();
|
||||||
$('ul#browser_steps li .control .apply').css('opacity',1);
|
$('ul#browser_steps li .control .apply').css('opacity', 1);
|
||||||
$("#browsersteps-img").css('opacity',1);
|
$("#browsersteps-img").css('opacity', 1);
|
||||||
//$('#browsersteps-selector-wrapper .loader').fadeOut(2500);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
|
&:not(:first-child) {
|
||||||
|
&:hover {
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
list-style: decimal;
|
list-style: decimal;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
.control {
|
.control {
|
||||||
|
@ -70,6 +75,8 @@
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
margin-left: -40px;
|
margin-left: -40px;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
|
max-width: 350px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nice tall skinny one */
|
/* nice tall skinny one */
|
||||||
|
@ -78,4 +85,10 @@
|
||||||
height: 80px;
|
height: 80px;
|
||||||
font-size: 3px;
|
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 {
|
#browser_steps li {
|
||||||
list-style: decimal;
|
list-style: decimal;
|
||||||
padding: 5px; }
|
padding: 5px; }
|
||||||
|
#browser_steps li:not(:first-child):hover {
|
||||||
|
opacity: 1.0; }
|
||||||
#browser_steps li .control {
|
#browser_steps li .control {
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
padding-right: 5px; }
|
padding-right: 5px; }
|
||||||
|
@ -96,11 +98,15 @@ nvm use v14.18.1 && npm install && npm run build
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
margin-left: -40px;
|
margin-left: -40px;
|
||||||
z-index: 100; }
|
z-index: 100;
|
||||||
|
max-width: 350px;
|
||||||
|
text-align: center; }
|
||||||
#browsersteps-selector-wrapper .spinner, #browsersteps-selector-wrapper .spinner:after {
|
#browsersteps-selector-wrapper .spinner, #browsersteps-selector-wrapper .spinner:after {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
font-size: 3px; }
|
font-size: 3px; }
|
||||||
|
#browsersteps-selector-wrapper #browsersteps-click-start:hover {
|
||||||
|
cursor: pointer; }
|
||||||
|
|
||||||
.arrow {
|
.arrow {
|
||||||
border: solid #1b98f8;
|
border: solid #1b98f8;
|
||||||
|
|
|
@ -166,8 +166,12 @@ User-Agent: wonderbra 1.0") }}
|
||||||
<div id="browser-steps-ui" class="noselect" style="width: 100%; background-color: #eee; border-radius: 5px;">
|
<div id="browser-steps-ui" class="noselect" style="width: 100%; background-color: #eee; border-radius: 5px;">
|
||||||
|
|
||||||
<div class="noselect" id="browsersteps-selector-wrapper" style="width: 100%">
|
<div class="noselect" id="browsersteps-selector-wrapper" style="width: 100%">
|
||||||
<span class="loader">
|
<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>
|
</span>
|
||||||
<img class="noselect" id="browsersteps-img" src="" style="max-width: 100%; width: 100%;" />
|
<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>
|
<canvas class="noselect" id="browsersteps-selector-canvas" style="max-width: 100%; width: 100%;"></canvas>
|
||||||
|
|
Ładowanie…
Reference in New Issue