How to get results after submit form with PhantomJS? - phantomjs

I'm trying to get results from a simple form using PhantomJS. I'm using jQuery but don't work. I have this HTML:
<!doctype html>
<html>
<head>
<title>PhantomJS!</title>
</head>
<body>
<form method="post" id="frm">
<input type="text" name="nombre" id="nombre" />
<input type="submit" value="Publicar" id="btn-submit" />
</form>
Your name is <span id="nombrez"><?php if (isset($_POST['nombre'])) { echo $_POST['nombre'];} ?></span>
</body>
</html>
And this Javascript code:
var page = require('webpage').create();
page.open('http://localhost/phantom/', function() {
page.includeJs("https://code.jquery.com/jquery-3.1.1.slim.js", function() {
page.evaluate(function() {
$('#nombre').val('Fabian');
document.forms[0].submit();
});
page.onLoadFinished = function(){
console.log($("#nombrez").html());
phantom.exit();
};
});
});

page.onLoadFinished must not be called inside of page.evaluate, but inside the main PhantomJS script:
var page = require('webpage').create();
page.onLoadFinished = function(){
var html = page.evaluate(function(){
return document.getElementById("nombrez").innerHTML;
});
console.log(html);
phantom.exit();
};
page.open('http://localhost/phantom/', function() {
page.includeJs("https://code.jquery.com/jquery-3.1.1.slim.js", function() {
page.evaluate(function() {
$('#nombre').val('Fabian');
document.forms[0].submit();
});
});
});
However page.onLoadFinished fires every time a page is done loading and with this implementation phantom will exit the first the time page is loaded, even before the form is submitted.
You need to implement some check to distinguish between the first and the second load of the page. For example, if return html variable is empty it means that we haven't submitted page yet.

Related

how do you loop through checkboxes using puppeteer?

I have a list of checkboxes , every time puppeteer run the test I need to :
if a box is already selected then
move to next box and select it , and if the next is selected move to the next checkbox and so on
if(await page.$eval(firstcheckbox, check=>check.checked =true)) { //check if the box is selected
await page.waitForSelector(do something, ele=>elem.click())//if the checkbox is already selected , move to the second row and select a undecked box
}else if{
await page.$eval(firstcheckbox, check=>check.checked =false)){ //if the checkbox is not ticked
await page.$eval(clickcheckbox, elem=>elem.click);//tick the checkbox
You can use all the testing and changing inside one page.evaluate():
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: false, defaultViewport: null });
const html = `
<!doctype html>
<html>
<head><meta charset='UTF-8'><title>Test</title></head>
<body>
<input type="checkbox" id="checkbox1"><label for="checkbox1">checkbox1</label><br>
<input type="checkbox" id="checkbox2" checked><label for="checkbox2">checkbox2</label><br>
<input type="checkbox" id="checkbox3" checked><label for="checkbox3">checkbox3</label><br>
<input type="checkbox" id="checkbox4"><label for="checkbox4">checkbox4</label><br>
</body>
</html>`;
try {
const [page] = await browser.pages();
await page.goto(`data:text/html,${html}`);
await page.evaluate(() => {
for (const checkbox of document.querySelectorAll('input')) {
if (!checkbox.checked) checkbox.click();
}
});
console.log('Done.');
} catch (err) { console.error(err); }
Or, if you need a loop over element handles, you can try this:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: false, defaultViewport: null });
const html = `
<!doctype html>
<html>
<head><meta charset='UTF-8'><title>Test</title></head>
<body>
<input type="checkbox" id="checkbox1"><label for="checkbox1">checkbox1</label><br>
<input type="checkbox" id="checkbox2" checked><label for="checkbox2">checkbox2</label><br>
<input type="checkbox" id="checkbox3" checked><label for="checkbox3">checkbox3</label><br>
<input type="checkbox" id="checkbox4"><label for="checkbox4">checkbox4</label><br>
</body>
</html>`;
try {
const [page] = await browser.pages();
await page.goto(`data:text/html,${html}`);
for (const checkbox of await page.$$('input')) {
if (!await checkbox.evaluate(elem => elem.checked)) {
await checkbox.click();
}
}
console.log('Done.');
} catch (err) { console.error(err); }

How to request multiple channels using IBM Cloud Speech to Text API

I want to convert a wav file to text using speech-to-text on IBM Cloud.
How do I send a request to get results for two channels?
Do I use websocketAPI?
If so, is there a channel specification in the parameters?
Can anyone tell me?
Thank you for your reply.
I am trying websocket connection with javascript.
In the following program, there is no response of "websocket.send (blob);".
Is the information corresponding to the blob incorrect?
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<script>
var websocket = null;
function start() {
var IAM_access_token = "{my-token}";
var wsURI = 'wss://gateway-tok.watsonplatform.net/speech-to-text/api/v1/recognize'
+ '?access_token=' + IAM_access_token
+ '&model=ja-JP_BroadbandModel';
console.log(wsURI);
websocket = new WebSocket(wsURI);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
}
function onOpen(evt) {
var message = {
'action': 'start',
'content-type': 'audio/wav'
};
console.log(JSON.stringify(message));
websocket.send(JSON.stringify(message));
}
function onClose(evt) {
websocket.close();
}
function onMessage(evt) {
console.log(evt);
}
function onError(evt) {
console.log(evt);
}
function sendfile() {
console.log("send click!");
console.log(document.getElementById( "data" ));
var blob = document.getElementById( "data" );
websocket.send(blob) ;
}
</script>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<div id="wrap">
<button type="button" onclick="start();">start</button>
<input type="file" id="data" name="data">
<button type="button" id="send" onclick="sendfile();">send</button>
</div>
</form>
</body>
</html>

binding dynamic img in vuejs does not work for me

I have a dynamic img being pulled from an api using vue.js. For some strange reason, the image won't bind. I have tried both :src. and :attr but neither works. The url does display in the vue console inside of the data but can't get the image to display on the page. any help will go a long way.
<html>
<head>
<style></style>
</head>
<body>
<div class="container">
<div id="editor">
<img v-bind:src="PictureURL" />
</div>
</div>
<script type="text/javascript" src="https://unpkg.com/vue#2.0.3/dist/vue.js"></script>
<script>
new Vue({
el: "#editor",
data: {
PictureUrl: "",
},
created: function() {
this.getCurrentUser();
},
methods: {
getCurrentUser: function() {
var root = 'https://example.com';
var headers = {
accept: "application/json;odata=verbose"
}
var vm = this;
var __REQUESTDIGEST = '';
$.ajax({
url: root + "_api/Properties",
type: 'Get',
headers: headers,
success: function(data) {
vm.PictureUrl = data.d.PictureUrl;
}
})
},
}
})
</script>
</body>
</html>
Change <img v-bind:src="PictureURL" /> to <img v-bind:src="PictureUrl" />, so that you match the data item name. Vue should be giving you an error in the console about this.
https://jsfiddle.net/kch7sfda/
Example here.
You can try to:
1. add v-if to img element
2. rename PictureUrl to pictureUrl (first lowercase letter)

google custom search search button and autocomplete table event

I used Google Custom Search API in my project and I try to detect the following events:
Enter is pressed in the search input box;
Search button is hit;
A option is selected from the recommendation list.
I have done a lot of searches, however, my code can only capture the first event. If anyone can point me to a right direction, this will be much appreciated.
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>My Search</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div>
<h3 align="center">My Search</h3>
</div>
<div>
<script>
(function () {
var cx = 'xxxx:xxxx';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<script>
function addExtraParams(){
alert($("input.gsc-input").val()); //For debugging only
};
$(document).ready(function(){
setTimeout(
function(){
$( 'input.gsc-input' ).keyup( function(e){
if ( e.keyCode == 13 ) {
addExtraParams();
}
});
$( 'input.gsc-search-button' ).click(function(){
addExtraParams();
});
$( 'input.gsc-completion-container' ).click(function(){
addExtraParams();
});
}, 1000
);
});
</script>
<gcse:search></gcse:search>
</div>
</body>
</html>

dgrid (onDemandGrid) loads on first time button click, but error on second time button is clicked

Thanks to some previous help here, I got the Dojo dgrid to work; and even figured out how to tie it to data from my rest service.
Now I added an input box, a button, and all the logic happens on the button-click. But the second time I click the button, even with the same input value in the input field, I get an error.
ERROR:
TypeError: Cannot read property 'element' of undefined in StoreMixin.js:33
Including the picture so you can see my console.logs
I read this How To reset the OnDemandGrid, but is it necessary to check to see if grid exists and do different logic? Can't I just "new up" a new one each time?
CODE:
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"CustomersGrid"'>
<label for="lastnameStartsWith">Lastname Starts With:</label>
<input id="lastnameStartsWith" type="text" name="lastnameStartsWith" value="Wag"
data-dojo-type="dijit/form/TextBox"
data-dojo-props="trim:true, propercase:true" />
<br />
<br />
<button id="queryStudentsButton" data-dojo-type="dijit/form/Button"
data-dojo-type="dijit/form/Button"
data-dojo-props="iconClass:'dijitIconTask'">
<span>Query</span>
<script type='dojo/on' data-dojo-event='click'>
require([
'dstore/RequestMemory',
'dstore/Memory',
'dgrid/OnDemandGrid'
], function (RequestMemory, Memory, OnDemandGrid) {
var url = '../students/' + dojo.byId('lastnameStartsWith').value;
console.log("query students for dataGrid latsnameStartsWith:" + dojo.byId('lastnameStartsWith').value);
require(['dojo/request'], function(request){
request.get(url,
{headers: {"Content-Type": 'application/json',
"username": securityConfig.username,
"password": securityConfig.password}}
)
.then(function(response){
//console.log("string response=" + response);
var respJSON = JSON.parse(response);
var respDataForDGrid = respJSON.recordset;
console.log("got respJSON back, num rows= " + respDataForDGrid.length);
//================================================
// Create an instance of OnDemandGrid referencing the store
console.log("Debug1");
var grid2 = new OnDemandGrid({
collection: new Memory({ data: respDataForDGrid }),
columns: {
student_id: 'ID',
student_firstname: 'First Name',
student_lastname: 'Last Name',
student_city: 'City',
student_state: 'State',
student_zip: 'Zip'
}
}, 'grid2');
console.log("Debug2");
grid2.startup();
console.log("Debug3");
},
function(error){
console.log("Error=" + error);
//dom.byId('studentFeedback').value += response;
});
});
});
</script>
</button>
<h2>My demoGrid - From JSON RestService (Database)</h2>
<div id='grid2'></div>
</div>
Part 2 -
I tried mix of your code and code on this page:
How To reset the OnDemandGrid
if (grid2Registered){
console.log("reuse existing grid");
grid2Registered.set('collection', memStore);
// refresh: clear the grid and re-queries the store for data.
grid2Registered.refresh();
}
else{...
Doc here (https://github.com/SitePen/dgrid/blob/v0.4.3/doc/components/core-components/OnDemandList-and-OnDemandGrid.md) says:
Clears the grid and re-queries the store for data. If
keepScrollPosition is true on either the instance or the options
passed to refresh, an attempt will be made to preserve the current
scroll position. OnDemandList returns a promise from refresh, which
resolves when items in view finish rendering. The promise resolves
with the QueryResults that were rendered.
This one has been tough! Below a working example.
First I switched from declarative to programmatic for the onClick function: declarative scripts are parsed by dojo, and as a consequence you cannot examine them (set break points, etc.) under the debugger (at least I don't know how to do that). So it seems to me good practice to avoid them.
Then, indeed the bug is due to re-instantiating the dgrid with the same id, so that you do need a way to detect that the dgrid already exists. But there is a trick: for dgrids to be properly handled by the dijit system, they need to be mixed in with the dijitRegistry extension. See here for details.
Then you can use registry.byId('grid2') to detect that the dgrid already exists.
Also I had to skip the respDataForDgrid part and used directly respJSON instead (may be due to a difference with your server side(?) - I used a simple text file with a json array on the server side).
<!DOCTYPE HTML><html lang="en">
<head>
<meta charset="utf-8">
<title>Neal Walters stask overflow test</title>
<link rel="stylesheet"
href="dojo-release-1.12.2-src/dijit/themes/claro/claro.css"
media="screen">
<link rel="stylesheet"
href="dojo-release-1.12.2-src/dgrid/css/dgrid.css" media="screen">
</head>
<body class="claro">
<div data-dojo-type="dijit/layout/ContentPane"
data-dojo-props='title:"CustomersGrid"'>
<label for="lastnameStartsWith">Lastname Starts With:</label> <input
id="lastnameStartsWith" type="text" name="lastnameStartsWith"
value="Wag" data-dojo-type="dijit/form/TextBox"
data-dojo-props="trim:true, propercase:true" /> <br /> <br />
<button id="queryStudentsButton" data-dojo-type="dijit/form/Button"
data-dojo-props="iconClass:'dijitIconTask', onClick: myClick">Query</button>
<h2>My demoGrid - From JSON RestService (Database)</h2>
<div id='grid2'></div>
</div>
<script src="dojo-release-1.12.2-src/dojo/dojo.js"
data-dojo-config="async:true"></script>
<script type="text/javascript">
require(["dojo", "dojo/parser", "dojo/domReady!"],
function(dojo, parser){
parser.parse();
});
function myClick(){
var url = 'students/' + dojo.byId('lastnameStartsWith').value, securityConfig = {username: 'john', password: 'Doe'};
console.log("query students for dataGrid latsnameStartsWith:" + dojo.byId('lastnameStartsWith').value);
require(['dojo/_base/declare', 'dojo/request', "dijit/registry", "dstore/RequestMemory", "dstore/Memory", "dgrid/OnDemandGrid", "dgrid/extensions/DijitRegistry"], function(declare, request, registry, RequestMemory, Memory, OnDemandGrid, DijitRegistry){
request.get(url,{})
.then(function(response){
console.log("string response=" + response);
var respJSON = JSON.parse(response);
//var respDataForDGrid = respJSON.recordset;
//console.log("got respJSON back, num rows= " + respDataForDGrid.length);
//================================================
// Create an instance of OnDemandGrid referencing the store
console.log("Debug1");
var theGrid = registry.byId('grid2');
if (theGrid){
theGrid.set('collection', new Memory({data: respJSON}));
}else{
var grid2 = new (declare([OnDemandGrid, DijitRegistry]))({
collection: new Memory({ data: respJSON }),
columns: {
student_id: 'ID',
student_firstname: 'First Name',
student_lastname: 'Last Name',
student_city: 'City',
student_state: 'State',
student_zip: 'Zip'
}
}, 'grid2');
console.log("Debug2");
grid2.startup();
console.log("Debug3");
}
},
function(error){
console.log("Error=" + error);
//dom.byId('studentFeedback').value += response;
});
});
};
</script>
</body>
</html>