Node Promises with webdriver.io - selenium

I am trying to run selenium web scraping and failing. Please look at the code snippet.
var webdriverio = require('webdriverio');
var client = webdriverio
.remote({
desiredCapabilities: {
browserName:'chrome'
}
});
module.exports = function(some_url) {
return new Promise(function(resolve) {
client
.init()
.newWindow(some_url)
.getHTML('html')
.then(function(html) {
var some_data = someFactory(html); // do some data scraping
Promise
.all(
some_data
.some_array
.map(function (data) {
return new Promise(function(resolve) {
client
.newWindow(data.other_link)
.getHTML('html')
.then(function (html) {
var $ = cheerio.load(html); // do some more scraping
resolve(html);
})
.end();
});
})
)
.then(function (data) {
// execution never comes here while I get html in
// the mapped function
resolve(some_data, data);
});
).end();
});
This above execution never completes. It never comes out of the inner block.
Any help would be greatly appreciated.

Related

How to use basic commands in webdriver.io

I'm using webdriver.io to do some browser automation. Not really testing , just saving time by automating things. I can see examples of how to use some of the functions .. but I can't seem to access them. I'm quite new to node.js
** Important ** I realise you can use browser.getAttribute - but looking at this example: http://webdriver.io/api/property/getAttribute.html
I should be able to execute getAttribute on the element object..?
var allInputs = $$('.loginForm input')
console.log(allInputs.map(function(el) { return el.getAttribute('name'); }))
My code:
var webdriverio = require('webdriverio');
var options = {
desiredCapabilities: {
browserName: 'chrome'
}
};
var browser = webdriverio.remote(options)
async function browserTest(){
await browser
.init()
.url('http://www.google.com')
.getTitle().then(function(title) {
console.log('Title was: ' + title);
})
.catch(function(err) {
console.log(err);
});
var body = await browser.element("//body")
console.log(body)
//the following line fails
console.log(await body.getAttribute("id"))
}
browserTest()

How to test vue component method with ajax request in Mocha?

I have a vue component with methods send out ajax request, I tried done() provided by Mocha to test this method, but it seems do not work correctly by the coverage report(the success and complete methods are not covered according to the report). The codes are as follows:
Vue component code in demo.vue
```
loadData: function(cb) {
var that = this;
$.ajax(
{
url: "/api/nodesWithTask",
async: true,
success: function(data) {
that.nodes = data;
},
complete: function(xhr, status) {
if (cb && typeof (cb) == 'function') {
cb.call();
}
}
}
);
}
```
Test code
```
import Vue from 'vue'
import demo from '#/components/demo'
describe('demo.vue', () => {
var mockData = {"id":"abc"};
var server;
var vm;
before(function () {
server = sinon.fakeServer.create();
//mock response for ajax request
server.respondWith("/api/nodesWithTask",[200,{"Content-Type":"application/json"},JSON.stringify(mockData)]);
const Constructor = Vue.extend(demo);
vm = new Constructor().$mount();
});
after(function () { server.restore(); });
it('load data async', (done) => {
vm.loadData(function(){
done();
});
})
})
```
Thanks for any suggestion in advance.
Advised by my leader, I find one magic config option of sinon fake server as follows
before(function () {
server = sinon.fakeServer.create();
//mock response for ajax request
server.respondWith("/api/nodesWithTask",[200,{"Content-Type":"application/json"},JSON.stringify(mockData)]);
server.respondImmediately = true;
const Constructor = Vue.extend(demo);
vm = new Constructor().$mount();
});
After I set the respondImmediately option to true, the test can run correctly.

Chrome, recognize open tab

I'm creating an extenstion for google chrome that will perform checking if a stream on twitch.tv is online and will notify the user evey X minutes, I got that covered. What I'm looking for is a JScirpt code that will recognize if user is already on the streamers channel and will stop notifying him.
var username="$user";
setInterval(check,300000);
function check()
{
request("https://api.twitch.tv/kraken/streams/" + username, function() {
var json = JSON.parse(this.response);
if (json.stream == null)
{
chrome.browserAction.setIcon({ path: "offline.png" });
}
else
{
notify();
}
});
return 1;
}
function notify(){
var opt = {type: "basic",title: username + " is streaming!",message: "Click to join!",iconUrl: "start.png"};
chrome.notifications.create("", opt, function(notificationId)
{
setTimeout(function()
{
chrome.notifications.clear(notificationId, function(wasCleared) { console.log(wasCleared); });
}, 3000);
});
chrome.browserAction.setIcon({path:"online.png" });
}
chrome.browserAction.onClicked.addListener(function () {
chrome.tabs.create({ url: "http://www.twitch.tv/"+username });
});
function request(url, func, post)
{
var xhr = new XMLHttpRequest();
xhr.onload = func;
xhr.open(post == undefined ? 'GET' : 'POST', url, true);
xhr.send(post || '');
return 1;
}
check();
Use window.location.href to get the complete URL.
Use window.location.pathname to get URL leaving the host.
You can read more here.

PhantomJs Injecting jQuery in different pages

I have a PhantomJs script in which I create a new wepage, inject jQuery into it and scrape a list of URL from it. After that I call a function passing the list of URL and create a new webpage for each one and try to recover certain information from it
var pageGlobal = require('webpage');
function createPage(){
var page = pageGlobal.create();
page.onAlert = function(msg) {
console.log(msg);
};
return page;
}
var page=createPage();
page.open('http://www.example.com/', function(status){
if ( status === "success" ) {
page.injectJs('jquery-1.6.1.min.js');
var urlList=page.evaluate(
function(){
var urlList=[];
window.console.log = function(msg) { alert(msg) };
$("td.row1>a").each(function(index, link) {
var link=$(link).attr('href');
urlList.push(link);
});
return urlList;
});
processUrlList(urlList);
}
});
function processUrlList(urlList){
for(i=0;i<urlList.length;i++){
var currentPage=createPage();
currentPage.open("http://www.example.com"+urlList[i], function(status){
if ( status === "success" ) {
if(currentPage.injectJs('jquery-1.6.1.min.js')===false){
console.log("Error en la inyeccion");
}
currentPage.evaluate(function() {
window.console.log = function(msg) { alert(msg) };
console.log("Evaluating");
$("showAdText").each(function(index, link) {
//Capture information about the entity in this URL
})
});
}
});
}
}
The problem is in the processUrlList function the injection of jQuery always fail returning false. Would it be a problem to create two or more page objects instead of reusing only one? What could be happening here?

JS and CSS file fails to load when the page is refreshed in grails application which uses Atmosphere Meteor plugin

In my grails 2.3.7 application,
I am using atmosphere-meteor 0.8.3.
On my home page load, I subscribe the client. And by default I run long-polling; and it works fine.
On page refresh, I unsubscribe the client.
However, if I refresh the page; then some of the JS and CSS fails to load. It happens 5 out of 10 times of refresh.
Am I doing anything wrong? (As I subscribe on document.ready()).
Or do I need to do anything else?
Any help is appreciated.
Update:
Code inside gsp for subscription:
$('body').bind('beforeunload',function(){
Jabber.unsubscribe();
});
$(document).ready(function () {
if (typeof atmosphere == 'undefined') {
Jabber.socket = $.atmosphere;
} else {
Jabber.socket = atmosphere;
}
var atmosphereRequest = {
type: 'public',
url: 'atmosphere/public',
trackMessageLength: false
};
//setTimeout(function(){
Jabber.subscribe(atmosphereRequest);
//}, 10000);
});
And the Jabber variable
var Jabber = {
socket: null,
publicSubscription: null,
transport: null,
subscribe: function (options) {
var defaults = {
type: '',
contentType: "application/json",
shared: false,
//transport: 'websocket',
transport: 'long-polling',
fallbackTransport: 'long-polling',
trackMessageLength: true
},
atmosphereRequest = $.extend({}, defaults, options);
console.log(atmosphereRequest);
atmosphereRequest.onOpen = function (response) {
console.log('atmosphereOpen transport: ' + response.transport);
};
atmosphereRequest.onReconnect = function (request, response) {
console.log("atmosphereReconnect");
};
atmosphereRequest.onMessage = function (response) {
console.log("on message");
Jabber.onMessage(response);
};
atmosphereRequest.onError = function (response) {
console.log('atmosphereError: ' + response);
};
atmosphereRequest.onTransportFailure = function (errorMsg, request) {
console.log('atmosphereTransportFailure: ' + errorMsg);
};
atmosphereRequest.onClose = function (response) {
console.log('atmosphereClose: ' + response);
};
switch (options.type) {
case 'public':
Jabber.publicSubscription = Jabber.socket.subscribe(atmosphereRequest);
break;
default:
return false;
}
//Jabber.publicSubscription = Jabber.socket.subscribe(atmosphereRequest);
},
unsubscribe: function () {
if (Jabber.socket)
Jabber.socket.unsubscribe();
},
onMessage:function(response){....}
}
I'm the plugin author. Please update to version 1.0.1. If you still have trouble after updating the plugin, create a new issue. We can work through the problem then. However, I do have a question. When you say the JS fails to load, do you mean the atmosphere JavaScript or your own? There is no plugin related CSS.