I want to test message functionality in my browser game. Instead of sending messages manually to 50 test accounts I thought maybe I can do it automatically in Chrome console.
For first I would make a for loop.
for (i=0; i > 50; i++)
{
//to do
}
I would use my games link to fill the sending form
game.php?page=messages&mode=write&id=1&subject=message_test
ID is for user ids and Subject fill the subject area.
In my message send template I use this JavaScript to send a message
function check(){
if($('#text').val().length == 0) {
alert('{$LNG.mg_empty_text}');
return false;
} else {
$('submit').attr('disabled','disabled');
$.post('game.php?page=messages&mode=send&id={$id}&ajax=1', $('#message').serialize(), function(data) {
alert(data);
parent.$.fancybox.close();
return true;
});
}
}
Maybe someone can help me how to execute a function using Chrome console and send out messages? Maybe put me to a proper tutorial.
if you want to "export" your functions to the console into the google chrome or another dev tools, you can export it to a window object, so
// create a namespace to have all functions under your custom namespace
window.MyCustomNS = {};
window.MyCustomNS.yourFunction = function(id, dataObject) {
if($('#text').val().length == 0) {
alert('{$LNG.mg_empty_text}');
return false;
} else {
$('submit').attr('disabled','disabled');
$.post('game.php?page=messages&mode=send&id=' + + '&ajax=1', $.param(dataObject), function(data) {
alert(data);
parent.$.fancybox.close();
return true;
});
}
};
then into the console you try this,
window.MyCustomNS.yourFunction('YOUR_ID', { name: 'some parameter', another: 'another parameter' });
Related
I'm working on a standalone script that will eventually be published as an add-on. It will have a sidebar users interact with and from there they can launch the Google File Picker to upload a report for processing. I previously was looking for a way for the sidebar to know that the file picker was done. I replicated this answer successfully and got the File picker dialog to send a message back to the sidebar indicating it was finished. However, the console is full of some errors and warnings that I'm wondering if I should be concerned about. The errors are:
Unsafe attempt to initiate navigation for frame with origin
'https://docs.google.com' from frame with URL
'https://***.googleusercontent.com/userCodeAppPanel'.
The frame attempting navigation of the top-level window is sandboxed,
but the flag of 'allow-top-navigation' or
'allow-top-navigation-by-user-activation' is not set.
DOMException: Blocked a frame with origin
"https://###.googleusercontent.com"
from accessing a cross-origin frame.
at findSideBar (https://###.googleusercontent.com/userCodeAppPanel:80:18)
at w0.pickerCallback [as Fb] (https://###.googleusercontent.com/userCodeAppPanel:98:11)
at w0._.h.iV (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.uAzDleg2hnU.O/m=picker/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AGLTcCMT6b3QcRI88QolvkcdUjC8YnoTvA/cb=gapi.loaded_0:740:393)
at d (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.uAzDleg2hnU.O/m=picker/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AGLTcCMT6b3QcRI88QolvkcdUjC8YnoTvA/cb=gapi.loaded_0:215:143)
at b (https://apis.google.com/_/scs/apps-static/_/js/k=oz.gapi.en.uAzDleg2hnU.O/m=picker/rt=j/sv=1/d=1/ed=1/am=AQ/rs=AGLTcCMT6b3QcRI88QolvkcdUjC8YnoTvA/cb=gapi.loaded_0:210:1)
Refused to get unsafe header "X-HTTP-Status-Code-Override"
The first error I have seen before, however, the second is new and relevant to sending the message from the file picker dialog back to the sidebar.
It's worth mentioning that everything still works. My question is primarily are these errors I should be worried about, will they cause problems when the add-on is being reviewed before being published, and how can I correct them?
I've included below my code for the sidebar creation, picker creation, and the relevant code for sending the message from the picker to the sidebar.
Sidebar Creation:
function buildSidebar(type) {
hideColumns();
hideRows();
hideSheets();
if(type == 'setup' || checkSetup()) {
var html = HtmlService.createTemplateFromFile('SidebarSetupHTML')
.evaluate()
.setTitle('Test');
} else {
var html = HtmlService.createTemplateFromFile('SidebarMainHTML')
.evaluate()
.setTitle('Test');
}
SpreadsheetApp.getUi().showSidebar(html);
}
Picker Creation:
function showPicker() {
var html = HtmlService.createHtmlOutputFromFile('PickerHTML.html')
.setWidth(600)
.setHeight(425)
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
SpreadsheetApp.getUi().showModalDialog(html, 'Select Report(s)');
}
Picker Message Code:
function pickerCallback(data) {
var action = data[google.picker.Response.ACTION];
if (action == google.picker.Action.PICKED) {
(function findSideBar(limit) {
let f = window.top.frames;
for (let i = 0; i < limit; ++i) {
try {
if (
f[i] /*/iframedAppPanel*/ &&
f[i].length &&
f[i][0] && //#sandboxFrame
f[i][0][0] && //#userHtmlFrame
window !== f[i][0][0] //!== self
) {
console.info('Sidebar found');
var sidebar = f[i][0][0];
sidebar.modalDone('PICKED'); //Modal has finished
console.log('Message sent');
google.script.host.close();
}
} catch (e) {
console.error(e);
continue;
}
}
})(10);
}
}
Sidebar launch picker and receive message:
function testPicker() {
google.script.run.withSuccessHandler(pickerResponse).showPicker();
}
function pickerResponse(e) {
(async () => {
let receiver = new Promise((res, rej) => {
window.modalDone = res;
});
var message = await receiver;
console.log('message received');
if(message == 'PICKED' || message == "NOT_PICKED") {
console.log(message);
}
//Do what you want here
})();
}
When I saw your script, I thought that the reason for your issue might be the loop after the if statement was true. So for example, when the if statement is true, how about putting break in the last line? So, how about the following modification?
From:
if (
f[i] /*/iframedAppPanel*/ &&
f[i].length &&
f[i][0] && //#sandboxFrame
f[i][0][0] && //#userHtmlFrame
window !== f[i][0][0] //!== self
) {
console.info('Sidebar found');
var sidebar = f[i][0][0];
sidebar.modalDone('PICKED'); //Modal has finished
console.log('Message sent');
google.script.host.close();
}
To:
if (
f[i] /*/iframedAppPanel*/ &&
f[i].length &&
f[i][0] && //#sandboxFrame
f[i][0][0] && //#userHtmlFrame
window !== f[i][0][0] //!== self
) {
console.info('Sidebar found');
var sidebar = f[i][0][0];
sidebar.modalDone('PICKED'); //Modal has finished
console.log('Message sent');
google.script.host.close();
break; // <--- Added
}
Note:
When I tested a following sample script for a custom dialog on Google Docs (For example, it's Google Spreadsheet),
<script>
google.script.host.close();
alert("ok");
</script>
I confirmed that the alert window is opened and also, the dialog is closed. So I thought that google.script.host.close() might work with the asynchronous process.
For example, when google.script.run with the high process cost is used as follows,
<script>
google.script.host.close();
google.script.run.withSuccessHandler(_ => alert("ok2")).myFunction();
alert("ok1");
</script>
it seems that myFunction() and alert("ok2") are not run because the dialog is closed before run myFunction(), while alert("ok1") is run. On the other hand, when the process cost is low, it seems that the script after google.script.host.close() is run.
From these situation, as an attempt, I have proposed to add break after google.script.host.close() for OP's issue.
Reference:
Loops and iteration
I'm facing an issue trying to implement notifications in my website.
In fact, I'm trying to make a function that calls PHP with an ajax request, in order to check with mysql if there are any notification. Then, if there is one/few notification(s), I get back from PHP the information I need, and display them using notification API. I do this every 5 seconds.
In fact, notifications are displayed in the top right corner, and I can only see the bottom of it.
Other weird fact, when I use function alert();, notifications are properly displayed.. This issue is happening with Firefox, but not on chromium.
So my question is, do you have any idea why notifications are not placed properly on firefox but not on Chromium? If you need any more information do not hesitate. Thanks in advance, and if you need it, here is some code :
With this two functions, I get what I need thanks to a php script.
function notifications() {
$.ajax({ url: './get_notifications.php/',
type: 'post',
data: {"name": window.user},
success: function(output) {
if (output != "")
{
split_notifications(output);
}
else
return;
},
failure: function() {
console.log("failed");
}
});
}
function check_notifications() {
setInterval(function() {
notifications();
}, 10000);
}
In this function, I just split information and then call another function, in charge of creating my notification.
function split_notifications(notif) {
var tmp_notif = notif.split(";");
var index = 0;
while (tmp_notif[0].split(",,,")[index])
{
//!\\ When I put alert() HERE it's working
display_notification(tmp_notif[1].split(",,,")[index], tmp_notif[2].split(",,,")[index], tmp_notif[0].split(",,,")[index]);
index += 1;
}
}
Here is the function that creates my notification :
function display_notification(title, message, someone) {
{
if(window.Notification && Notification.permission !== "denied") {
Notification.requestPermission(function(status) { // status is "granted", if accepted by user
var project_notification = new Notification(title, {
body: someone + " " + message + '\nSee more...',
icon: "../img/" + someone.split(" ")[1] + ".png"
});
project_notification.onclick = function() {
alert("");
}
});
}
}
I wrote a script to do some automated actions on a website (which is not mine).
That website is some kind of online shop for a pc game. The user selects an item and clicks a "withdraw" button. When the website is under heavy load (quite often), the user often gets a message saying "Heavy load - try again!" and has to click the same button again and again until he either gets the item or receives a message saying "The item was already sold!".
Everything is running inside a chrome extension!
My script does the following:
Add an onClick event to the button to run a function
Click "withdraw"
Read the message that comes from the website
Depends on the message:
"Offer is being sent..." - Do nothing and read again after interval
"Item was already sold!" - Stop the interval
"Heavy load - try again!" - Click an element to remove the message and "withdraw" again
The problem:
The interval is set to 2000ms, but the script just seems to be spamming the withdraw button nonstop and it seems to ignore the clearInterval().
My code:
function buy() {
//Get the innerHTML for the box that displays the message
var message = document.getElementsByClassName("pm-content")[0].innerHTML;
//Message: Offer is being sent! - DO NOTHING!
if (message == "Please wait while your trade offer is being sent...") {
console.log("Loading: Going on!")
}
//Message: Item is gone! - STOP EVERYTHING!
if (message == "Items unavailable") {
console.log("Unavailable: Stopping!")
clearInterval(buyInterval);
}
//Message: Transaction successfull! - STOP EVERYTHING
if (message.includes("Trade offer has been sent! Code: ")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
if (message == "Heavy load! - Try again!") {
console.log("Overload: Going on!")
document.getElementById("pgwModal").click(); //Click to remove the message
document.getElementById("withdraw").click(); //Click withdraw again
}
}
function forceBuy() {
buyInterval = setInterval(function(){ buy() }, 2000);
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ forceBuy () };
Any help is appreciated!
Edit_1
Code right now:
(function(){ //creating isolated scope to avoid using global variables.
var buyInterval; // declaring sharing variables.
function buy() {
var message = document.getElementsByClassName("pm-content")[0].innerHTML;
if (message == "Please wait while your trade offer is being sent...<br><small>(this might take up to 5 minutes)</small>") {
console.log("Loading: Going on!")
}
if (message == "You cannot afford that withdrawal.") {
console.log("Broke: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "Items unavailable") {
console.log("Unavailable: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message.includes("Trade offer has been sent!")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
if (message.includes("missing")) {
console.log("Missing: Stopping")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "You can have only one pending deposit or withdrawal.") {
console.log("Pending: Stopping!")
document.getElementById("pgwModal").click();
clearInterval(buyInterval);
}
if (message == "Too many active trades") {
console.log("Overload: Going on!")
document.getElementById("pgwModal").click();
document.getElementById("withdraw").click();
}
}
function forceBuy() {
return setInterval(function(){ buy(); }, 2000); // not necessary but // will be more readable
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ //making a closure to catch buyInterval variable
buyInterval = forceBuy ();
};
}())
Thanks to Vitalii for this code - It seems to work better now since it's not constantly spamming the button anymore. Sadly, the other problem persists: If the script reaches for example this part of the code:
if (message.includes("Trade offer has been sent!")) {
console.log("Success: Stopping!")
clearInterval(buyInterval);
}
It successfully reads the message and prints out "Success: Stopping!" - once every two seconds ... ongoing until i stop it from doing that by hand. It seems like clearInterval(buyInterval); is still being ignored.
What am I doing wrong here?
(function(){ //creating isolated scope to avoid using global variables.
var buyInterval; // declaring sharing variables.
function buy() {
... buying action
}
function forceBuy() {
return setInterval(function(){ buy(); }, 2000); // not necessary but // will be more readable
}
var button = document.getElementById("withdraw");
withdraw.onclick=function(){ //making a closure to catch buyInterval variable
buyInterval = forceBuy ();
};
}())
rewrite your forceBuy function like this -
function forceBuy() {
if(buyInterval) clearInterval(buyInterval);
buyInterval = setInterval(function(){ buy() }, 2000);
}
I have a web application, where some internal pages use an EventSource to receive live updates from the server.
The client code looks like this:
var LiveClient = (function() {
return {
live: function(i) {
var source = new EventSource("/stream/tick");
source.addEventListener('messages.keepalive', function(e) {
console.log("Client "+ i + ' received a message.');
});
}
};
})();
You can see a live demo on heroku: http://eventsourcetest.herokuapp.com/test/test/1. If you open the developer console, you will see a message printed every time an event is received.
The problem is that when visiting internal links, the EventSource remains open, causing messages to be printed even after the visitor moves from one page to another - so if you visit the three links on the top, you will get messages from three sources.
How can I close the previous connection after the user moves from one internal page to another?
A hacky workaround that I tried was to use a global variable for the EventSource object, like this:
var LiveClient = (function() {
return {
live_global: function(i) {
// We set source as global, otherwise we were left
// with sources remaining open after visiting internal
// pages
if (typeof source != "undefined" && source != null) {
if (source.OPEN) {
source.close();
console.log("Closed source");
}
}
source = new EventSource("/stream/tick");
source.addEventListener('messages.keepalive', function(e) {
console.log("Client "+ i + ' received a message.');
});
}
};
})();
Demo here: http://eventsourcetest.herokuapp.com/test/test_global/1, but I am looking for a solution that would avoid the use of a global variable if possible.
The HTML code that is generated is:
Page 1 |
Page 2 |
Page 3 |
<p>This is page 3</p>
<script>
$(function() {
LiveClient.live_global(3);
});
</script>
or with LiveClient.live_global(1); for the case with the global variable.
Try this. I haven't tested it. If it works, you might be able to replace LiveClient.source with this.source which is a lot cleaner imo.
var LiveClient = (function() {
return {
source: null,
live_global: function(i) {
// We set source as global, otherwise we were left
// with sources remaining open after visiting internal
// pages
if (typeof LiveClient.source != "undefined" && LiveClient.source != null) {
if (source.OPEN) {
source.close();
console.log("Closed source");
}
}
LiveClient.source = new EventSource("/stream/tick");
LiveClient.source.addEventListener('messages.keepalive', function(e) {
console.log("Client "+ i + ' received a message.');
});
}
};
})();
I am new to phantomjs, Java script and WebScraping in General. What I want to do is basic http authentication and then visit another URL to get some information. Here is what I have till now. Please tell me what I am doing wrong.
var page = require('webpage').create();
var system = require('system');
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onAlert = function(msg) {
console.log('alert!!>' + msg);
};
page.settings.userName = "foo";
page.settings.password = "bar";
page.open("http://localhost/login", function(status) {
console.log(status);
var retval = page.evaluate(function() {
return "test";
});
console.log(retval);
page.open("http://localhost/ticket/" + system.args[1], function(status) {
if ( status === "success" ) {
page.injectJs("jquery.min.js");
var k = page.evaluate(function () {
var a = $("div.description > h3 + p");
if (a.length == 2) {
console.log(a.slice(-1).text())
}
else {
console.log(a.slice(-2).text())
}
//return document.getElementById('addfiles');
});
}
});
phantom.exit();
});
I am passing an argument to this file: a ticket number which gets appended to the 2nd URL.
I would recommend CasperJS highly for this.
CasperJS is an open source navigation scripting & testing utility written in Javascript and based on PhantomJS — the scriptable headless WebKit engine. It eases the process of defining a full navigation scenario and provides useful high-level functions, methods & syntactic sugar for doing common tasks such as:
defining & ordering browsing navigation steps
filling & submitting forms
clicking & following links
capturing screenshots of a page (or part of it)
testing remote DOM
logging events
downloading resources, including binary ones
writing functional test suites, saving results as JUnit XML
scraping Web contents
(from the CasperJS website)
I recently spent a day trying to get PhantomJS by itself to do things like fill out a log-in form and navigate to the next page.
CasperJS has a nice API purpose built for forms as well:
http://docs.casperjs.org/en/latest/modules/casper.html#fill
var casper = require('casper').create();
casper.start('http://some.tld/contact.form', function() {
this.fill('form#contact-form', {
'subject': 'I am watching you',
'content': 'So be careful.',
'civility': 'Mr',
'name': 'Chuck Norris',
'email': 'chuck#norris.com',
'cc': true,
'attachment': '/Users/chuck/roundhousekick.doc'
}, true);
});
casper.then(function() {
this.evaluateOrDie(function() {
return /message sent/.test(document.body.innerText);
}, 'sending message failed');
});
casper.run(function() {
this.echo('message sent').exit();
});