I am new to mocha. My scripts below works when i run from the terminal. However, there is no result when i run from testrunner.html. On checking, it seems to be because of var xl = require('./excel');. if i comment this statement, it works. How can i make this work? i need to import custom modules for my script.
Updated test.js to incorporate RequireJS
Post changes: works on browser and termial
module1.js
if(typeof define !== 'undefined')
{
define([], function() {
return {
get: function() {
return get();
}
};
});
}
else if(typeof exports !== 'undefined') {
module.exports = {
get: function(){
return get();
}
};
}
function get(){
return "hello node world";
}
test.js
if(typeof requirejs == 'undefined') {var requirejs = require('requirejs');}
if(typeof chai == 'undefined') {var chai = require('chai');}
requirejs.config({
baseUrl: '.',
paths: {
},
nodeRequire: require
});
describe("RequireTest()", function(){
var module1;
before(function(done){
requirejs(['./module1'],
function(_module) {
console.log('before fired');
module1 = _module;
if(typeof requirejs == 'undefined') {mocha.run();}
done();
});
});
it('test case: ', function(){
console.log(module1.get());
chai.expect(1+1).to.equal(2);
});
});
testrunner.html (snippet)
<div id="mocha"></div>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/requirejs/require.js"></script>
<script>mocha.setup('bdd')</script>
<script src="./test.js"></script>
<script>mocha.run();</script>
When you run Mocha at the command line you are using Node.js, which provides require.
When you run it in the browser, there is no require that the browser provides. You need to use a module loader at run-time like RequireJS or SystemJS. Or you need to use a packager like Webpack or Browserify that will process your code beforehand and turn it into a single bundle that incorporates all your code.
Note that whether third-party modules you use can be loaded in a browser, is a determination you have to make module-by-module. If you use a module that uses Node's child_process module to spawn a new process, for instance, you won't be able to just use that module in the browser because browsers don't provide child_process.
Related
I am new to mocha. My scripts below works when i run from the terminal. However, there is no result when i run from testrunner.html. On checking, it seems to be because of var xl = require('./excel');. if i comment this statement, it works. How can i make this work? i need to import custom modules for my script.
Updated test.js to incorporate RequireJS
Post changes: works on browser and termial
module1.js
if(typeof define !== 'undefined')
{
define([], function() {
return {
get: function() {
return get();
}
};
});
}
else if(typeof exports !== 'undefined') {
module.exports = {
get: function(){
return get();
}
};
}
function get(){
return "hello node world";
}
test.js
if(typeof requirejs == 'undefined') {var requirejs = require('requirejs');}
if(typeof chai == 'undefined') {var chai = require('chai');}
requirejs.config({
baseUrl: '.',
paths: {
},
nodeRequire: require
});
describe("RequireTest()", function(){
var module1;
before(function(done){
requirejs(['./module1'],
function(_module) {
console.log('before fired');
module1 = _module;
if(typeof requirejs == 'undefined') {mocha.run();}
done();
});
});
it('test case: ', function(){
console.log(module1.get());
chai.expect(1+1).to.equal(2);
});
});
testrunner.html (snippet)
<div id="mocha"></div>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/requirejs/require.js"></script>
<script>mocha.setup('bdd')</script>
<script src="./test.js"></script>
<script>mocha.run();</script>
When you run Mocha at the command line you are using Node.js, which provides require.
When you run it in the browser, there is no require that the browser provides. You need to use a module loader at run-time like RequireJS or SystemJS. Or you need to use a packager like Webpack or Browserify that will process your code beforehand and turn it into a single bundle that incorporates all your code.
Note that whether third-party modules you use can be loaded in a browser, is a determination you have to make module-by-module. If you use a module that uses Node's child_process module to spawn a new process, for instance, you won't be able to just use that module in the browser because browsers don't provide child_process.
The magiczoom documentation describes callbacks that will execute at given times, but it's unclear how to use or assign those callbacks.
For example, how would I print a console message onZoomReady?
The closest I've found is a MagicZoom.defaults.onready property, but it's unclear how to set it via javascript (my attempts aren't working as expected).
The callbacks are configured via mzOptions, for example:
var mzOptions = {
onZoomReady: function() { … } }
;
Or:
var mzOptions = {};
mzOptions.onZoomReady = function() { … };
You can do something like this:
MagicZoom.registerCallback('onUpdate',
function() {
console.log('onUpdated', arguments[0], arguments[1], arguments[2]);
});
That will log stuff in the console like this:
onUpdated (id-of-mz-wraper) (html of old element) (html of new element)
Other options that you can use are as per the documentation:
MagicZoom.registerCallback('onZoomReady', function() {
console.log('onReady', arguments[0]);
});
MagicZoom.registerCallback('onZoomIn', function() {
console.log('onZoomIn', arguments[0]);
});
MagicZoom.registerCallback('onZoomOut', function() {
console.log('onZoomOut', arguments[0]);
});
I'm new to Gulp and I wanted to make use of its automatic scss compiling and browser sync. But I can't get it to work.
I stripped everything down to leave only the contents of the example on the Browsersync website:
http://www.browsersync.io/docs/gulp/#gulp-sass-css
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var sass = require('gulp-sass');
// Static Server + watching scss/html files
gulp.task('serve', ['sass'], function() {
browserSync.init({
server: "./app"
});
gulp.watch("app/scss/*.scss", ['sass']);
gulp.watch("app/*.html").on('change', browserSync.reload);
});
// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function() {
return gulp.src("app/scss/*.scss")
.pipe(sass())
.pipe(gulp.dest("app/css"))
.pipe(browserSync.stream());
});
gulp.task('default', ['serve']);
I can call gulp serve. The site is showing and I get a message from Browsersync. When I modify the HTML, the page is reloaded. When however I modify the scss, I can see this:
[BS] 1 file changed (test.css)
[15:59:13] Finished 'sass' after 18 ms
but I have to reload manually. What am I missing?
I also faced a similar problem when I was new to browser-sync usage, the command-line was saying "reloading browsers" but the browser was not refreshed at all, the problem was I had not included body tag in my HTML page where the browser-sync can inject script for its functionality, make sure your HTML page has body tag.
You can just inject the changes instead of having to force a full browser refresh on SASS compile if you like.
browserSync.init({
injectChanges: true,
server: "./app"
});
gulp.task('sass', function() {
return gulp.src("app/scss/*.scss")
.pipe(sass())
.pipe(gulp.dest("app/css"))
.pipe(browserSync.stream({match: '**/*.css'}));
});
This is because you're calling browserSync.reload on the html watch and not on the scss watch.
Try this:
gulp.watch("app/scss/*.scss", ['sass']).on('change', browserSync.reload);
gulp.watch("app/*.html").on('change', browserSync.reload);
This is what I use and it work's fine in sass or any other files
gulp.task('browser-sync', function () {
var files = [
'*.html',
'css/**/*.css',
'js/**/*.js',
'sass/**/*.scss'
];
browserSync.init(files, {
server: {
baseDir: './'
}
});
});
I include this on my html, right below the body tag. It works.
<script type='text/javascript' id="__bs_script__">//<![CDATA[
document.write("<script async src='http://HOST:3000/browser-sync/browser-sync-client.2.11.1.js'><\/script>".replace("HOST", location.hostname));//]]>
</script>
Ran into this same problem trying to reload php and js files and stream css files. I was able to use stream only by using a pipe method, which makes sense. Anyway, here's what worked for me:
gulp.watch(['./**/*.css']).on('change', function (e) {
return gulp.src( e.path )
.pipe( browserSync.stream() );
});
But, I actually prefer #pixie's answer modified:
gulp.task('default', function() {
var files = [
'./**/*'
];
browserSync.init({
files : files,
proxy : 'localhost',
watchOptions : {
ignored : 'node_modules/*',
ignoreInitial : true
}
});
});
I also had the same issue. It worked when I called the reload method as a separate task.
gulp.task('browserSync', function() {
browserSync.init(null, {
server: {
baseDir: './'
},
});
})
gulp.task('reload', function(){
browserSync.reload()
})
gulp.task('watch', ['sass', 'css', 'browserSync'], function(){
gulp.watch('*.html', ['reload']);
})
Sometimes when using the CLI you don't have the script inserted in your HTML main files so you should manually add this or use gulp.
<!-- START: BrowserSync Reloading -->
<script type='text/javascript' id="__bs_script__">
//<![CDATA[
document.write("<script async src='/browser-sync/browser-sync-client.js'><\/script>".replace("HOST", location.hostname));
//]]>
</script>
<!-- END: BrowserSync Reloading -->
I'm using Rails 3.2.16 and require.js ('requirejs-rails' gem).
My app has a module named ExpensesUI (here is a snippet of it):
$(function() {
define('ExpensesUI', ['OperationsUI'], function(operationsUI) {
var expenses = {
operationConsolidatedCheckbox: "#operation_consolidated",
parcelledNoCheckbox: "#operation_parcelled_no",
parcelledYesCheckbox: "#operation_parcelled_yes",
/* more things */
};
}
});
I can use it perfectly in any .js file with:
require(['ExpensesUI'], function(expensesUI) { console.log(expensesUI.parcelledNoCheckbox); });
But when I try the same require call in a .js.erb, I got 'undefined' logged.
It's not possible to use requirejs with *.js.erb files. Just because requirejs get files out of sprockets.
But instead, you can use named modules in *.html.erb views, for instance:
<script>
define('mymodule', function() {
'use strict';
return {
user: <%= #user.to_json.html_safe %>
};
});
</script>
describe('my homepage', function() {
var ptor = protractor.getInstance();
beforeEach(function(){
// ptor.ignoreSynchronization = true;
ptor.get('http://localhost/myApp/home.html');
// ptor.sleep(5000);
})
describe('login', function(){
var email = element.all(protractor.By.id('email'))
, pass = ptor.findElement(protractor.By.id('password'))
, loginBtn = ptor.findElement(protractor.By.css('#login button'))
;
it('should input and login', function(){
// email.then(function(obj){
// console.log('email', obj)
// })
email.sendKeys('josephine#hotmail.com');
pass.sendKeys('shakalakabam');
loginBtn.click();
})
})
});
the above code returns
Error: Error while waiting for Protractor to sync with the page: {}
and I have no idea why this is, ptor load the page correctly, it seem to be the selection of the elements that fails.
TO SSHMSH:
Thanks, your almost right, and gave me the right philosophy, so the key is to ptor.sleep(3000) to have each page wait til ptor is in sync with the project.
I got the same error message (Angular 1.2.13). My tests were kicked off too early and Protractor didn't seem to wait for Angular to load.
It appeared that I had misconfigured the protractor config file. When the ng-app directive is not defined on the BODY-element, but on a descendant, you have to adjust the rootElement property in your protractor config file to the selector that defines your angular root element, for example:
// protractor-conf.js
rootElement: '.my-app',
when your HTML is:
<div ng-app="myApp" class="my-app">
I'm using ChromeDriver and the above error usually occurs for the first test. I've managed to get around it like this:
ptor.ignoreSynchronization = true;
ptor.get(targetUrl);
ptor.wait(
function() {
return ptor.driver.getCurrentUrl().then(
function(url) {
return targetUrl == url;
});
}, 2000, 'It\'s taking too long to load ' + targetUrl + '!'
);
Essentially you are waiting for the current URL of the browser to become what you've asked for and allow 2s for this to happen.
You probably want to switch the ignoreSynchronization = false afterwards, possibly wrapping it in a ptor.wait(...). Just wondering, would uncommenting the ptor.sleep(5000); not help?
EDIT:
After some experience with Promise/Deferred I've realised the correct way of doing this would be:
loginBtn.click().then(function () {
ptor.getCurrentUrl(targetUrl).then(function (newURL){
expect(newURL).toBe(whatItShouldBe);
});
});
Please note that if you are changing the URL (that is, moving away from the current AngularJS activated page to another, implying the AngularJS library needs to reload and init) than, at least in my experience, there's no way of avoiding the ptor.sleep(...) call. The above will only work if you are staying on the same Angular page, but changing the part of URL after the hashtag.
In my case, I encountered the error with the following code:
describe("application", function() {
it("should set the title", function() {
browser.getTitle().then(function(title) {
expect(title).toEqual("Welcome");
});
});
});
Fixed it by doing this:
describe("application", function() {
it("should set the title", function() {
browser.get("#/home").then(function() {
return browser.getTitle();
}).then(function(title) {
expect(title).toEqual("Welcome");
});
});
});
In other words, I was forgetting to navigate to the page I wanted to test, so Protractor was having trouble finding Angular. D'oh!
The rootElement param of the exports.config object defined in your protractor configuration file must match the element containing your ng-app directive. This doesn't have to be uniquely identifying the element -- 'div' suffices if the directive is in a div, as in my case.
From referenceConf.js:
// Selector for the element housing the angular app - this defaults to
// body, but is necessary if ng-app is on a descendant of <body>
rootElement: 'div',
I got started with Protractor by watching the otherwise excellent egghead.io lecture, where he uses a condensed exports.config. Since rootElement defaults to body, there is no hint as to what is wrong with your configuration if you don't start with a copy of the provided reference configuration, and even then the
Error while waiting for Protractor to sync with the page: {}
message doesn't give much of a clue.
I had to switch from doing this:
describe('navigation', function(){
browser.get('');
var navbar = element(by.css('#nav'));
it('should have a link to home in the navbar', function(){
//validate
});
it('should have a link to search in the navbar', function(){
//validate
});
});
to doing this:
describe('navigation', function(){
beforeEach(function(){
browser.get('');
});
var navbar = element(by.css('#nav'));
it('should have a link to home in the navbar', function(){
//validate
});
it('should have a link to search in the navbar', function(){
//validate
});
});
the key diff being:
beforeEach(function(){
browser.get('');
});
hope this may help someone.
I was getting this error:
Failed: Error while waiting for Protractor to sync with the page: "window.angular is undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"
The solution was to call page.navigateTo() before page.getTitle().
Before:
import { AppPage } from './app.po';
describe('App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should have the correct title', () => {
expect(page.getTitle()).toEqual('...');
})
});
After:
import { AppPage } from './app.po';
describe('App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
page.navigateTo();
});
it('should have the correct title', () => {
expect(page.getTitle()).toEqual('...');
})
});
If you are using
browser.restart()
in your spec some times, it throws the same error.
Try to use
await browser.restart()