Upload APK File to Google Play using CasperJS - javascript

I need to create a script that uploads for the first time a APK file to Google Play (their API only allows to upload APKs after the first version has been published).
Here is the script I have so far:
var fs = require('fs');
var data = fs.read('test.cookies');
phantom.cookies = JSON.parse(data);
var x = require('casper').selectXPath;
var casper = require('casper').create({
//verbose: true,
//logLevel: 'debug',
stepTimeout: 60000,
pageSettings: {
loadImages: false,
loadPlugins: false,
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4'
}
});
casper.start().thenOpen('https://play.google.com/apps/publish/?dev_acc=14088528817615018970', function() {
if (this.getCurrentUrl().indexOf('accounts.google.com') == -1) {
// cookies working
this.bypass(3);
} else {
console.log('sign in page opened!')
}
});
casper.then(function() {
console.log('populating form with email');
this.evaluate(function() {
document.querySelector('input#Email').value = "email#address.com";
document.querySelector('input#next').click();
});
})
casper.waitForSelector("input#Email-hidden", function() {
console.log('populating form with password');
this.evaluate(function() {
document.querySelector('input#Passwd').value = "passwd";
document.querySelector('input#signIn').click();
});
})
//Wait to be redirected to the Home page, and then make a screenshot
casper.then(function(){
console.log(this.getCurrentUrl());
var cookies = JSON.stringify(phantom.cookies);
fs.write('test.cookies', cookies, 644);
});
// Google play page
casper.then(function() {
console.log('Current page: ' + this.getCurrentUrl());
});
casper.waitForSelector(".BVO4BTD-b-a.BVO4BTD-b-o.BVO4BTD-Be-a", function() {
console.log('Add new app');
this.evaluate(function() {
document.querySelector('.BVO4BTD-b-a.BVO4BTD-b-o.BVO4BTD-Be-a').click();
});
});
casper.waitForSelector(".BVO4BTD-hj-a", function() {
console.log('Filling form');
this.capture('5.png',{
top: 0,
left: 0,
width: 500,
height: 400
});
this.evaluate(function() {
document.querySelector('.BVO4BTD-hj-a > input.gwt-TextBox').value = "App Teste";
document.querySelector('.BVO4BTD-g-K .BVO4BTD-b-a.BVO4BTD-b-o').click();
});
});
casper.waitForSelector(".BVO4BTD-gg-a .BVO4BTD-b-a.BVO4BTD-b-o", function() {
this.capture('6.png',{
top: 0,
left: 0,
width: 500,
height: 400
});
console.log('Current page: ' + this.getCurrentUrl());
console.log('Click for app upload');
this.evaluate(function() {
document.querySelector(".BVO4BTD-gg-a .BVO4BTD-b-a.BVO4BTD-b-o").click();
});
});
casper.waitForSelector(".BVO4BTD-Re-b.BVO4BTD-g-U.BVO4BTD-d-b", function() {
this.capture('7.png',{
top: 0,
left: 0,
width: 500,
height: 400
});
/**/
this.evaluate(function() {
document.querySelector(".BVO4BTD-Re-b.BVO4BTD-g-U.BVO4BTD-d-b .BVO4BTD-b-a.BVO4BTD-b-m").click();
casper.page.uploadFile(".BVO4BTD-Re-b.BVO4BTD-g-U.BVO4BTD-d-b input[type=file]", '/path/to/apk/file.apk');
});
this.wait(3000, function() {
this.capture('8.png',{
top: 0,
left: 0,
width: 500,
height: 400
});
});
});
casper.run(function() {
console.log('end');
});
These steps already work:
Sign In at Google Play (saves a cookie, so it skips this part)
Creates an app named App Teste
Goes to Upload APK screen
I can't make the upload script work, I guess there is a lot of javascript behind Google Play's upload mechanism.
My attempt to upload happens on the last waitForSelector section.
Thank you.

casper.page is actually just a phantomjs WebPage object, and probably shouldn't be used inside of the this.evaluate.
To accomplish the same goal, you can try:
casper.waitForSelector(".form-selector", function() {
// your capture code
casper.page.uploadFile('selector', '/path/to/file');
});
casper.then(function() {
// whatever you need to do after file upload
});
Also, to fill out the forms, you can try casper.fill().
Sources: http://docs.casperjs.org/en/latest/modules/casper.html#then (casper), http://phantomjs.org/api/webpage/method/upload-file.html (phantomjs)

Check the following script it might work
Note: where 'filename' is the path of the file from your local directory.
var filename = /home/xyz/android/file_you_want_to_upload.apk
casper.then(function () {
this.evaluate(function (fileName) {
__utils__.findOne('input[type="file"]').setAttribute('value', fileName)
}, {fileName: fileName});
this.page.uploadFile('input[type="file"]', fileName);
console.log('Selecting a file');
});
casper.then(function () {
console.log("Clicking on Upload ");
this.click(x("xpath of upload button"));
});

Related

How to get and save images from cache - chrome extension

I would like to be able to download an image that has be cached by chrome to a specified folder using a chrome extension. Currently I am getting the url of the image and passing it to the background.js which then downloads the image. Yet on this specific website (the website this chrome extension is being built around), does not allow you to get the url of the image.
What changes to my code will I need to be able to do this?
(the extension flips to another page, and attempts to download around 50 images per subsection of the site. this site also does not have 1 class for each image, and regularly makes the class name or Id the token of the individual)
popup.js
const scriptCodeCollect =
`(function() {
// collect all images
let images = document.querySelectorAll('img');
let srcArray = Array.from(images).map(function(image) {
return image.currentSrc;
});
chrome.storage.local.get('savedImages', function(result) {
// remove empty images
imagestodownload = [];
for (img of srcArray) {
if (img) {
img.substring("data:image/".length, img.indexOf(";base64"));
console.log(img);
}imagestodownload.push(img);
};
result.savedImages = imagestodownload;
chrome.storage.local.set(result);
console.log("local collection setting success:"+result.savedImages.length);
});
})();`;
const scriptCodeDownload =
`(function() {
chrome.storage.local.get('savedImages', function(result) {
let message = {
"savedImages" : result.savedImages
};
chrome.runtime.sendMessage(message, function(){
console.log("sending success");
});
});
})();`;
function injectTheScript() {
// Gets all tabs that have the specified properties, or all tabs if no properties are specified (in our case we choose current active tab)
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
// Injects JavaScript code into a page
chrome.tabs.executeScript(tabs[0].id, {file: "content_script.js"});
});
}
// adding listener to your button in popup window
document.getElementById('flipbtn').addEventListener('click', injectTheScript);
document.getElementById("startbtn").addEventListener("click", function() {
if((url.includes('http://127.0.0.1:5500/example%20test/physics/'))) {
document.getElementById("success").innerHTML = "<strong><u>In progress<br></u></strong> Currently downloading: <br>" +urlfilename
setInterval(function(){ //Loops download
chrome.tabs.query({active: true, lastFocusedWindow: true}, tabs => {
let urlfilename = tabs[0].url.replace('http://127.0.0.1:5500/example%20test/', '').replace('.html', '').replace('?','');
document.getElementById("success").innerHTML = "<strong><u>In progress<br></u></strong> Currently downloading: <br>" +urlfilename
let bknb= tabs[0].url.replace('http://127.0.0.1:5500/example%20test/', '').replace('.html', '').replace('/',' ').replace('?', '').replace(/\D/g, '');
chrome.storage.local.set({'foo': urlfilename, 'bar': bknb}, function() {
console.log('Settings saved');
console.log(urlfilename);
});
function sleep (time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
sleep(5000).then(() => { //Pauses so URL can write and display correctly
chrome.tabs.executeScript({code : scriptCodeCollect}); //Collects Image (page is saved as image on the website)
let textCollect = document.getElementById('textCollect');
chrome.storage.local.get('savedImages', function(result) {
textCollect.innerHTML = "collected "+ result.savedImages.length + " images";
});
});
chrome.tabs.executeScript({code : scriptCodeDownload}); //Downloads Image
document.getElementById("warning").innerHTML = "test"
sleep(5000).then(() => { //Waits so image can download fully
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.executeScript(tabs[0].id, {file: "content_script.js"}); //Injects Script to flip page
});
});
});
}, 10000); //Waits 10s and then loops
background.js
let downloadsArray= [];
let initialState = {
'savedImages': downloadsArray
};
chrome.runtime.onInstalled.addListener(function() {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
css: ['img'],
css: ['img[input[type="image"[aspect-ratio[attr(1000)/attr(1419)]]]]'],
css: ['id[image]']
})],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}]);
});
chrome.storage.local.set(initialState);
console.log("initialState set");
});
//chrome.downloads.onChanged.addListener(function() {
chrome.storage.local.get(['foo', 'bar'], function(items) {
var urlfilename = items.foo
console.log(urlfilename)
var bkpg= items.bar
// });
chrome.runtime.onMessage.addListener(
function(message, callback) {
console.log("message coming");
console.log(message);
let srcArray = message.savedImages;
var counter = bkpg-1;
for (let src of srcArray) {
console.log(src);
chrome.downloads.download({url:src, filename:urlfilename + ".png"});
};
});
});

win.reload showing showing blank white window in electron

I need to reload my site/app after network re-connect. So, I'm using win.reload after reconnect but after reloading it shows me a blank white screen
I have tried to re-create the window but it gives me the same output. Another question reported here by me.
I found window.location.href is set to "chrome-error://chromewebdata/" after reload
This sample code from is main.js
let mainWindow = null;
let offlineWindow = null;
let loadingwindow = null;
let mainWindowWidth = 1100;
let mainWindowHeight = 650;
var nativeApp = {
appUrl: "https://google.com",
connected: false
}
function createWindow () {
// Create the browser window.
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: false,
preload: path.join(app.getAppPath(), 'preload.js')
},
minWidth: mainWindowWidth,
width: mainWindowWidth,
minHeight: mainWindowHeight,
height: mainWindowHeight,
show: false
});
createLoadingWindow();
mainWindow.once('ready-to-show', () => {
closeLoadingWindow();
mainWindow.show();
});
mainWindow.setMenu(null);
mainWindow.loadURL(nativeApp.appUrl);
mainWindow.webContents.openDevTools();
}
function createLoadingWindow(){
// codes to create the loading window
// .....
}
function createOfflineWindow(){
// codes to create the offline window
//....
}
function checkAndConnect() {
checkInternet(function (connected) {
if (!connected) {
if (!offlineWindow) { createOfflineWindow(); }
} else {
if (offlineWindow) {
offlineWindow.close();
mainWindow.reload();
}
}
nativeApp.connected = connected;
});
}
function checkInternet(callback) {
if(navigator.onLine){
return callback(true);
}
return callback(false);
}
I need to reload my site/app after re-connection. Is there anything wrong in my code? or is it a bug by the electron?
It's an old thread, but if someone comes across the same problem, you can fix it by adding the following in the main js file:
function createMainWindow () {
mainWindow = new BrowserWindow({
width: 1280,
height: 720,
...
})
// This code block is not related to the issue
// I included it to demostrate how my app loads the index page
if (process.env.WEBPACK_DEV_SERVER_URL) {
if (!process.env.IS_TEST) {
mainWindow.webContents.openDevTools()
}
}
else {
createProtocol('app')
mainWindow.loadURL('app://./index.html')
}
// Create listener that will handle the white screen issue
mainWindow.webContents.on('did-fail-load', () => {
if (process.env.NODE_ENV === 'production') {
// Load the index URL the same way you load it above
mainWindow.loadURL('app://./index.html')
}
})
...

Download progress bar pops and ends up, with no errors and no output file in the device

I am creating a image download server for my APP with Rest API, there are two buttons in the HTML, one is download button and other is load button.
When clicked on download button progress bar shows the progress, but there is no output file and doesn't show any error even load button doesn't load anything.
This script works fine with static URL (without API) by making certain changes in the script.
Link for my temporary Server.
http://freaksearch.com/aarti/rest-api.php?json=image&Id=
Plugin required by this script : cordova-plugin-file-transfer
(this is not depreciated plugin)
Link for the plugin: https://www.npmjs.com/package/cordova-plugin-file-transfer
Here is my HTML:
<div class="padding">
<button class="button" ng-click="download()">Download</button>
<button class="button" ng-click="load()">Load</button>
{{imgFile}}
<img ng-src="{{imgFile}}">
</div>
Here is my script:
$scope.download = function(imageId, imageName) {
$ionicLoading.show({
template: 'Downloading...'
});
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {
fs.root.getDirectory(
"MyProject",
{
create: true
},
function (dirEntry) {
dirEntry.getFile(
imageName + ".jpg",
{
create: true,
exclusive: false
},
function gotFileEntry(fe) {
var p = fe.toURL();
fe.remove();
ft = new FileTransfer();
ft.download(
encodeURI('http://freaksearch.com/aarti/rest-api?json=image' + imageId),
p,
function (entry) {
$ionicLoading.hide();
$scope.imgFile = entry.toURL();
},
function (error) {
$ionicLoading.hide();
alert("Download Error Source --> " + error.source);
},
false,
null
);
},
function () {
$ionicLoading.hide();
console.log("Get the file failed");
}
);
}
);
},
function () {
$ionicLoading.hide();
console.log("Request for filesystem failed");
});
}
$scope.load = function() {
$ionicLoading.show({
template: 'Loading...'
});
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
fs.root.getDirectory(
"MyProject",
{
create: false
},
function(dirEntry) {
dirEntry.getFile(
imageName + ".jpg",
{
create: false,
exclusive: false
},
function gotFileEntry(fe) {
$ionicLoading.hide();
$scope.imgFile = fe.toURL();
},
function(error) {
$ionicLoading.hide();
console.log("Error getting file");
}
);
}
);
},
function() {
$ionicLoading.hide();
console.log("Error requesting filesystem");
});
}
Adding <preference name="AndroidPersistentFileLocation" value="Compatibility" />to the config.xml made my folder & file visible. I hope this could help someone.
Now i can see the images, but all the images are Corrupt.

How can I send Global varibale data from view to controller?

I have my Angular view file like below.
<!DOCTYPE html>
<video id="myVideo" class="video-js vjs-default-skin"></video>
<script>
var dataUri;
var videoData;
var player = videojs("myVideo", {
controls: true,
width: 320,
height: 240,
fluid: false,
plugins: {
record: {
audio: true,
video: true,
maxLength: 100,
debug: true
}
}
}, function(){
// print version information at startup
videojs.log('Using video.js', videojs.VERSION,
'with videojs-record', videojs.getPluginVersion('record'),
'and recordrtc', RecordRTC.version);
});
// error handling
player.on('deviceError', function() {
console.log('device error:', player.deviceErrorCode);
});
player.on('error', function(error) {
console.log('error:', error);
});
// user clicked the record button and started recording
player.on('startRecord', function() {
console.log('started recording!');
});
// user completed recording and stream is available
player.on('finishRecord', function() {
console.log('player : ', player.recordedData.video.name);
videoData = player.recordedData;
console.log('finished recording: ', player.recordedData);
}
);
function getVideoData()
{
return videoData;
}
</script>
<button id="record" onClick="getVideoData();" ng-model="onFileSelect()"></button>
When player.on('finishRecord', function() function is called it will have the recorded video data in player.recordedData variable. What My problem is, I want to send the player.recordedData to the angular controller on button click whose id is record.
If the vairiable is defined globally, you can directly use it in any of controllers. Try to put you data in object.xxx format.
example:
var model = {videoData: null};
player.on('finishRecord', function() {
...
model.videoData = player.recordedData;
}
in controller:
//directly use it, ensure it has data
model.videoData

Opening a PDF in cordova javascript

I have generated a PDF invoice using the file plugin. Now I want to open the file in the app. I tried inAppBrowser, but its giving an empty page. I tried fileopener, its neither giving a success or failed message. How do I specify the path to my file . please help!!
In app Browser Method
var cdr='';
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dir) {
cdr=dir;
alert("cdr "+cdr);
dir.getFile("test.pdf", {create: true, exclusive: false}, function (fileEntry)
{
fileEntry.createWriter(function (writer) {
writer.onwrite = function(evt) {
console.log(" write success");
};
console.log("writing to file");
writer.write( pdfOutput );
},function () {
console.log("ERROR SAVEFILE");
});
});
});
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory, function(dir) {
alert("open file");
dir.getFile("test.pdf", {create:false}, function(fileEntry) { //EXISTS
alert("native url "+cdr.toNativeURL());
var url =cdr.toNativeURL() + "test.pdf";
alert(url);
window.open(url, '_blank');
}, function() { //NOT EXISTS
alert("no file found");
});
});
}
Fileopener Method
var cdr='';
window.resolveLocalFileSystemURL(cordova.file.externalDataDirectory , function(dir) {
cdr=dir;
console.log(" vidhya cdr "+cdr);
dir.getFile("test.pdf", {create: true, exclusive: false}, function (fileEntry)
{
fileEntry.createWriter(function (writer) {
writer.onwrite = function(evt) {
console.log("vidhya write success");
openFile(cdr);
};
console.log("vidhya writing to file");
writer.write( pdfOutput );
},function () {
console.log("vidhya ERROR SAVEFILE");
});
});
});
function openFile(cdr) {
var fs;
function fsSuccess(fileSystem)
{
fs = fileSystem;
console.log("vidhya "+fs);
}
function fsFail(event)
{
console.log(event.target.error.code);
}
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, fsSuccess, fsFail);
console.log("vidhya opening file " +cdr.toNativeURL());
cordova.plugins.fileOpener2.open(
fs.root.toURL() +'test.pdf',
"application/pdf", //mimetype
{
error: function(e) {
alert("Error Opening the File.Unsupported document format.");
},
success: function() {
// success callback handler
alert("success");
}
}
);
}
My file is getting saved in /internal storage/Android/Data/app_folder/files/test.pdf
This is how i made it work in my hybrid mobile app:
var cdr;
sessionStorage.platform = device.platform;
var fileTransfer = new FileTransfer();
if (sessionStorage.platform.toLowerCase() == "android") {
window.resolveLocalFileSystemURL(cordova.file.externalRootDirectory, onFileSystemSuccess, onError);
} else {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, onError);
}
function onError(e) {
navigator.notification.alert("Error : Downloading Failed");
};
function onFileSystemSuccess(fileSystem) {
var entry = "";
if (sessionStorage.platform.toLowerCase() == "android") {
entry = fileSystem;
} else {
entry = fileSystem.root;
}
entry.getDirectory("Cordova", {
create: true,
exclusive: false
}, onGetDirectorySuccess, onGetDirectoryFail);
};
function onGetDirectorySuccess(dir) {
dir.getDirectory("My_App", {
create: true,
exclusive: false
}, onGetDirectorySuccess1, onGetDirectoryFail);
};
function onGetDirectorySuccess1(dir) {
cdr = dir;
dir.getFile(filename, {
create: true,
exclusive: false
}, gotFileEntry, errorHandler);
};
function gotFileEntry(fileEntry) {
var documentUrl = "http://myserverurl.com/test.pdf";
var uri = documentUrl;
fileTransfer.download(uri, cdr.nativeURL + docFileNameToView,
function(entry) {
openFile();
},
function(error) {
navigator.notification.alert("Error");
},
false
);
};
function openFile() {
cordova.plugins.fileOpener2.open(
cdr.nativeURL + docFileNameToView,
'application/pdf', {
error: function(e) {
navigator.notification.alert("Error Opening the File.Unsupported document format.");
},
success: function() {
}
}
);
};
function fail(error) {
navigator.notification.alert("Error");
};
function errorHandler(e) {
navigator.notification.alert("Error");
};
function onGetDirectoryFail(error) {
navigator.notification.alert("Error");
};
This code uses cordova file transfer plugin to download pdf and file opener plugin to view the pdf. This sample code also use device plugin to get the device platform (iOS or Android) and dialog plugin to display notification.
Code was tested on iOS 9 and Android 6 devices and works fine. In Android, the file gets stored in storage/emulated/0/Cordova/My_App folder
If someone faces an issue while opening the file stored in device even with proper destination file path specified, please do ensure that the file is downloaded properly without corruption.
Many a times file opening fails due to improper or corrupted download. You can also trace any error during download using chrome inspect devices option. Also ensure to use latest version of file transfer plugin to avoid download error.

Categories