Protractor running tests on PhantomJS - node.js

I can't seem to get PhantomJS through a test successfully. I tried to integrate it into my project, but after that failed I tried to just run the basic Angular Docs samples and I'm getting the same issue. My steps so far:
npm install -g phantomjs
phantomjs --webdriver=9515 // ... GhostDriver - Main - running on port 9515
protractor protractorConf.js
This is the same file from the example with only browserName, and seleniumAddress port changed:
// An example configuration file.
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://localhost:9515',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'phantomjs'
},
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['onProtractorRunner.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
}
};
I get the following error message:
UnknownError: Error Message => 'Detected a page unload event; asynchronous script execution does not work across page loads.'
I found this issue on github, which seemed to be related. I thought I had made enough sense of their brower-setup.md to include it in one of my beforeEach functions. Then I found here ptor is just wrapping the driver anyway. Wow, I know I'm a noob here in protractor/selenium land, but the signal to noise ratio is intensively dissuasive. I'd really like to get the performance benefits of using PhantomJS, but the prospect of losing several more hours on this is hurting my head. I'm on Windows 7 Enterprise 64-bit, in case that matters. Thanks!

Acutally this fix was solving the same issue for me:
https://github.com/pschwartau/protractor/commit/1eeff8b1b2e3e8f3b7c8152264411f26d4665a07
As originally described here: https://github.com/angular/protractor/issues/85#issuecomment-26846255 by renanmartins
Inside protractor/lib/protractor.js Replace
this.driver.get('about:blank');
this.driver.executeScript(
'window.name = "' + DEFER_LABEL + '" + window.name;' +
'window.location.href = "' + destination + '"');
with
var driver = this.driver;
this.getCapabilities().then(function (capabilities) {
if (capabilities.caps_.browserName === 'phantomjs') {
driver.executeScript('window.name = "' + DEFER_LABEL + '" + window.name;');
driver.get(destination);
} else {
driver.get('about:blank');
driver.executeScript(
'window.name = "' + DEFER_LABEL + '" + window.name;' +
'window.location.href = "' + destination + '"');
}
// Make sure the page is an Angular page.
driver.executeAsyncScript(clientSideScripts.testForAngular, 10).
then(function(hasAngular) {
if (!hasAngular) {
throw new Error('Angular could not be found on the page ' +
destination);
}
});
});

Related

App launched from npm works perfectly, but complied x64 app works incorrect

I use the Electron-forge framework and try to make an audio player. When I launch my app from npm start it works perfectly. But when I compile app using npm run package to x64 app and launch from its .exe file, the app works incorrectly. Window creates, but audio doesn't play.
Error in console.log:"Uncaught (in promise) DOMException: Failed to load because no supported source was found."
Paths to audio files are definitely correct, I wrote them to console too.
Edit: I found it is better to use Promise for tag audio, but the problem still persists. Code:
$(document).ready(function () {
prepare_song('D:' + '\\' + 'Downloads' + '\\' + 'audio_1.mp3');
$("#button_play_pause").click(function () {
console.log("click play");
var playPromise = document.querySelector('audio').play();
if (playPromise !== undefined) {
playPromise.then(function () {
console.log("play !");
// triggered from npm start and music is playing
}).catch(function (error) {
console.log("play error:" + error);
// triggered from npm run package (x64 .exe app) Error: NotSupportedError: The element has no supported sources.
});
}
});
});
function prepare_song(filepath) {
console.log(" prepare: " + filepath);
$("#audio").attr("src", filepath);
let audio = document.getElementById('audio');
audio.load();
}

Mac spawn startosinstall process with node.js

I'm trying to spawn the startosinstall binary to begin a macOS upgrade. However, I'm seeing startosinstall binary run as root but then a sub process osinstallersetupd gets invoked but seems to run under my standard user account and not root.
Ultimately it breaks the automation because I get hit with an administrative authentication prompt.
auth
Showing the processes: grep
Is this likely an Apple bug/limitation or could it be related to the way of invoking the first binary?
const spawn = require("child_process").spawn;
child = spawn("/Applications/Install macOS High Sierra.app/Contents/Resources/startosinstall",
[
"--applicationpath",
"/Applications/Install macOS High Sierra.app",
"--agreetolicense"
],
{
//maybe try some config options?
}
);
child.stderr.on("data", (data) => {
console.log(data.toString() + "\n");
});
child.stdout.on("data", (data) => {
console.log(data.toString() + "\n");
});
child.on("exit", (code, signal) => {
console.log("child process exited: " + code + "\n");
});
For what it's worth I'm logged in as root and running the script above.
Any help with this is greatly appreciated!
I believe I've found the issue. I am using parts of a script that helps in facilitating upgrades and found that when using the FileVault authenticated reboots you create and load a plist.
macOSUpgrade: https://github.com/kc9wwh/macOSUpgrade/blob/master/macOSUpgrade.sh#L278
However, it seems I was not actually loading the plist and that caused an issue.
tl;dr I wasn't loading the plist: https://github.com/kc9wwh/macOSUpgrade/blob/master/macOSUpgrade.sh#L337

how to create a spritesheet using node-spritesheet?

I installed node-spritesheet and tried to create a spritesheet like this.
I created main.js and 3 images - image1.png, image2.png and image3.png in my home folder and in the same folder I've another folder called node-modules in which node modules like express, node-spritesheet etc. are present.
This's my main.js file
var Builder = require( 'node-spritesheet' ).Builder;
var builder = new Builder({
outputDirectory: '/home/XYZ',
outputImage: 'sprite.png',
outputCss: 'sprite.css',
selector: '.sprite',
images: [ 'image1.png', 'image2.png', 'image3.png' ]
});
builder.build( function() {
console.log( "Built from " + builder.files.length + " images" );
});
Next I ran
node main.js
which gave the following result
--------------------------------------------------------------
Building 'default' at pixel ratio 1
--------------------------------------------------------------
/home/XYZ/node_modules/node-spritesheet/lib/imagemagick.js:14
throw "Error in identify (" + filepath + "): " + (error || stderr);
^
Error in identify (image1.png): Error: Command failed: /bin/sh: 1: identify: not found
I tried different paths for image like ./image1.png, /home/XYZ/image1.png instead of just image1.png.
Can someone please explain why this's happening?
P.S : I'm new to node, so please excuse any silly mistakes I made and correct me.
The problem seems to be because the command identify isn't found, which is in imagemagick module. So it worked fine after installing imagemagick.

phantomjs and requirejs

codes in file main.js is like this:
phantom.injectJs("libs/require-1.0.7.js");
require.config(
{
baseUrl: ""
}
);
require([], function(){});
when i run "phantomjs main.js" in the commandline, requirejs doesn't work well in the main.js. I know how to use requirejs in the page running in the browser(including phantomjs' way: page.open(url, callback)), but not like above. I tries using requirejs like the main.js, it is a popular problem, i think. Thank you!
I just struggled for some time. My solution is not clean, but it works, and I'm happy with that due to the unfinished api documentation from phantomjs.
Wordy explanation
You need three files. One is your amd phantomjs test file which I'll call "amd.js". The second is your html page to load which I'll name "amd.html". Finally the browser test which I called "amdTestModule.js".
In amd.html, declare your script tag per normal:
<script data-main="amdTestModule.js" src="require.js"></script>
In your phantomjs test file, this is where it gets hacky. Create your page, and load in the 'fs' module. This allows you to open a relative file path.
var page = require('webpage').create();
var fs = require('fs');
page.open('file://' + fs.absolute('tests/amd.html'));
Now since requirejs loads files asynchronously, we can't just pass in a callback into page.open and expect things to go smoothly. We need some way to either
1) Test our module in the browser and communicate the result back to our phantomjs context. Or
2) Tell our phantomjs context that upon loading all the resources, to run a test.
#1 was simpler for my case. I accomplished this via:
page.onConsoleMessage = function(msg) {
msg = msg.split('=');
if (msg[1] === 'success') {
console.log('amd test successful');
} else {
console.log('amd test failed');
}
phantom.exit();
};
**See full code below for my console.log message.
Now phantomjs apparently has an event api built in but it is undocumented. I was also successfully able to get request/response messages from their page.onResourceReceived and page.onResourceRequested - meaning you can debug when all your required modules are loaded. To communicate my test result however, I just used console.log.
Now what happens if the console.log message is never ran? The only way I could think of resolving this was to use setTimeout
setTimeout(function() {
console.log('amd test failed - timeout');
phantom.exit();
}, 500);
That should do it!
Full Code
directory structure
/projectRoot
/tests
- amd.js
- amdTestModule.js
- amd.html
- require.js (which I symlinked)
- <dependencies> (also symlinked)
amd.js
'use strict';
var page = require('webpage').create();
var fs = require('fs');
/*
page.onResourceRequested = function(req) {
console.log('\n');
console.log('REQUEST');
console.log(JSON.stringify(req, null, 4));
console.log('\n');
};
page.onResourceReceived = function(response) {
console.log('\n');
console.log('RESPONSE');
console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response, null, 4));
console.log('\n');
};
*/
page.onConsoleMessage = function(msg) {
msg = msg.split('=');
if (msg[1] === 'success') {
console.log('amd test successful');
} else {
console.log('amd test failed');
}
phantom.exit();
};
page.open('file://' + fs.absolute('tests/amd.html'));
setTimeout(function() {
console.log('amd test failed - timeout');
phantom.exit();
}, 500);
amd.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script data-main='amdTestModule.js' src='require.js'></script>
</body>
</html>
amdTestModule.js
require([<dependencies>], function(<dependencies>) {
...
console.log(
(<test>) ? "test=success" : "test=failed"
);
});
console
$ phantomjs tests/amd.js
amd test successful
you are misunderstanding webpage.injectJs()
it's for injecting scripts into the page you are loading, not into the phantomjs runtime environment.
So using .injectJs() is making requirejs load up into your page, not into phantomjs.exe.
That said, phantomjs's runtime environment has an aproximation of commonjs. RequireJs will not run on there by default. If you felt especially (VERY) motivated, you could attempt porting the require-shim made for nodejs, but it doesn't work out of the box, and would require an incredibly deep understanding of the runtimes. for more details: http://requirejs.org/docs/node.html
a better idea:
probably you should make sure you have commonjs versions of your javascript you wish to run. i personally write my code in typescript so i can build for either commonjs or amd. i use commonjs for phantomjs code, and amd for nodejs and browser.

JsTestDriver firefox browser crash

I'm just starting out with JsTestDriver and I've created very simple demo code to see if I have configured my environment correctly. However about 40-50% of the time I'm getting the following error when Firefox is launched (via JsTestDriver) "Firefox Closed Unexpectedly While Starting".
This error does not occur if I use Chrome.
My environment consists of:
VirtualBox 4.1.18 running Ubuntu 10.04.4 LTS 32bit
Firefox 13.0.1
JsTestDriver-1.3.4.b
openjdk-6-jre-headless
I'm executing:
java -jar /home/developer/bin/JsTestDriver.jar --port 9876 --browser /usr/bin/firefox --tests all --testOutput results
My JsTestDriver config is:
server: http://localhost:9876
load:
- src/*.js
test:
- test/*.js
timeout: 10
The source code (code under test) is:
Person = function()
{
this.firstName = "";
this.lastName = "";
this.fullName = function()
{
if((this.firstName != "") && (this.lastName != ""))
{
return this.lastName + ", " + this.firstName;
}
var name = this.firstName + " " + this.lastName;
return name.trim();
}
};
The test code (JsTestDriver based code) is:
PersonTest = TestCase("PersonTest");
PersonTest.prototype.testFullName = function()
{
fixture = new Person();
fixture.firstName = "John";
fixture.lastName = "Doe";
assertEquals("Doe, John", fixture.fullName());
};
PersonTest.prototype.testFullName_FirstNameOnly = function()
{
fixture = new Person();
fixture.firstName = "John";
assertEquals("John", fixture.fullName());
};
PersonTest.prototype.testFullName_LastNameOnly = function()
{
fixture = new Person();
fixture.lastName = "Doe"
assertEquals("Doe", fixture.fullName());
};
Thanks!
Your problem may be in that you're spinning up your server opening your browser every time you run your tests. I think a less error prone solution would be to start your server and have it capture some browsers, and then leave it running. Then you can run your tests against that server as needed. Our solution at work involves three virtual machines running IE7,IE8,IE9,Firefox, and Chrome all the time, and our Maven build process runs our javascript unit tests at every build. Also, make sure that you always use the '--reset' argument as well. It will keep your browsers fresh. I wrote a post that shows how to integrate QUnit, Requirejs, and code coverage with JSTD that is independent of Maven: js-test-driver+qunit+coverage+requirejs. Hope it helps.

Resources