modernizr todataurljpeg is asynchronous, how to use? - modernizr

Modernizr's test for canvas-todataurl-type has a comment:
// This test is asynchronous. Watch out.
So.. what is the best practice for knowing when it is safe to use this test. I see it loads in an image, but the library does not look like it offers any callbacks for when to test.

#jedierikb - I think you know the answer, as you helped us with this! But for the sake of others...
In Modernizr 2.x, it takes a little bit of manual work. Async detects will be undefined until they complete, so...:
<script src="path/to/modernizr.js"></script>
<script>
(function withDataURL () {
if (typeof Modernizr.todataurljpeg !== 'undefined') {
// Do things with `Modernizr.todataurljpeg`
}
else {
setTimeout(withDataURL, 100);
}
}());
</script>
Alternatively, use a watch library/shim/plugin, e.g. https://gist.github.com/eligrey/384583
In Modernizr 3.0, we're making 2 relevant changes:
Canvas todataurl detects are all synchronous (thanks to #jedierikb)
Other synchronous detects will have first-class support, probably with callbacks (we're still working out the finer details of this)

Related

Cypress command vs JS function

The Cypress documentation suggests that commands are the right way to reuse fragments of code, e.g.
Cypress.Commands.add("logout", () => {
cy.get("[data-cy=profile-picture]").click();
cy.contains("Logout").click();
});
cy.logout();
For simple cases like this, why would I use a command over a plain JS function (and all the nice IDE assistance that comes with it). What are the drawbacks of rewriting the above snippet as
export function logout(){
cy.get("[data-cy=profile-picture]").click();
cy.contains("Logout").click();
}
// and now somewhere in a test
logout();
Based on my experience with Cypress (one year project and several hundred test cases), I can say that a plan JS function is great for grouping cy commands.
From my point of view, a custom cy command may be really useful only if it is incorporated into the chain processing (utilizes the subject parameter or returns a Chainable to be used further in the chain). Otherwise, a plain JS function is preferable due to it simplicity and full IDE support (unless you're using an additional plugin).
If you for any reason need to do something inside the cypress loop, you can always wrap you code by cy.then() in a plain JS function:
function myFunction() {
cy.then(() => {
console.log(("I'm inside the Cypress event loop"))
})
}
Commands are for behavior that is needed across all tests. For example, cy.setup or cy.login. Otherwise, use functions.
See official docs: https://docs.cypress.io/api/cypress-api/custom-commands#1-Don-t-make-everything-a-custom-command

Remove a particular event listener in EmberJS

I would like to only listen the first didRender in a EmberJS Component.
initialDidRender: Ember.on('didRender', function() {
// Do some stuff
this.off('didRender');
}),
allOtherDidRender: Ember.on('didRender', function() {
// Do some stuff
})
Using this.off works great for my usecase but if I want to define another didRender listener in the future, it will also remove that one.
Is there a way to only disable initialDidRender of my example?
I also tried this.set('initialDidRender', null); but it throw error on future didRender events.
You need to use didInsertElement hook instead of didRender hook like this:
didInsertElement(){
// Do some stuff
}
Also, you may consider changing the usage of Ember.on usage because they may be deprecated soon. Take a look at this twiddle for the usage of didInsertElement hook.

Protractor with mocha and chai

I started using Protractor and the first thing I've tried to do is to use Mocha and Chai instead of Jasmine. Although now I'm not sure if that was a good idea.
first I needed to make Chai accessible from all the spec files, without having to import everytime, I found it's possible to do in protractor.conf file:
onPrepare: ->
global.chai = require 'chai'
chai.use require 'chai-string'
chai.use require 'chai-as-promised'
global.expect = chai.expect
now in a spec like this:
it "when clicked should sort ",->
headerColumns.get(0).click()
firstCellText = $$(".first-cell").getText()
secondCellText = $$(".second-cell").getText()
# this won't work
expect(firstCellText).eventually.be.above(secondCellText)
to make it work I could do:
# now this works
$$(".second-cell").getText().then (secondCellText)->
expect(firstCellText).eventually.be.above(secondCellText)
but that's ugly, and I don't want to wrap stuff inside of .then all the time. I'm thinking there should be a better way(?)
I was having the same problem. The issue for me was to add a longer timeout to mocha through the Protractor config.js.
This works because Protractor tests take considerably longer relative to other modules like supertest since an actual browser is being interacted with.
I added
mochaOpts: {
timeout: 5000
}
to my protractor config and the tests passed.
Either you need to mention timeout for the whole test suite using "this.timeout(1000);" just below the describe block, or you can change it for individual test cases by explicitly defining timeout for each "it" block.
example for describe block:
describe("test-suite",function () {
this.timeout(5000);
it("test-case",function () {
//test case code goes here
});
});
example for it block:
it("test-case",function () {
this.timeout("20000");
});
I found this question while I was trying to do the same thing in TypeScript, but the approach in the protractor.conf.js is identical.
Making chai available globally
It appears to achieve this you're right that it needs to be done in the on prepare. a fairly terse example is below. As I understand it this is needed because chai is of course not apart of mocha but some additional candy that we can use with mocha. Unlike jasmine where everything is bundled into the framework.
protractor.conf.js fragment
onPrepare: function() {
var chai = require('chai'); // chai
var chaiAsPromised = require("chai-as-promised"); // deal with promises from protractor
chai.use(chaiAsPromised); // add promise candy to the candy of chai
global.chai = chai; // expose chai globally
}
example spec
Once you've got chai and chai-as-promised setup globally you need to add a "little" boiler plate to your spec to expose expect which comes from chai.
example.e2e-spec.ts fragment
const expect = global['chai'].expect; // obviously TypeScript
it('will display its title', () => {
pageObject.navigateTo();
const title = element(by.css('app-root h1')).getText();
expect(title).to.eventually.contain('An awesome title');
});
Avoiding then
I can't tell what your $$ references are, but if you're using the protractor components browser and by etc. then things clean up a little bit.
The call const title = element(by.css('app-root h1')).getText(); seems to return a promise which jasmine seems to deal with out of the box while mocha+chai doesn't. That's where chai-as-promised comes in.
using our additional syntax candy expect(title).to.eventually.contain('An awesome title'); resolves the promise quite neatly and we've avoided all those then calls, but we do need the eventually.
I've provided you a link to a working TypeScript example that might help demonstrate.

Jasmine 2.0 rc* waits is not defined

Just upgraded to jasmine 2.0 rc5 from 1.3 and now all my tests that used waits() are broken because the waits() and waitsFor() function are undefined. I can't seem to find any reference to that anywhere online, is anyone aware of what is the new API to replace wait() ?
Well, the usage syntax for asynchronous calls changed.
You can easily see the differences between the two versions in its documentations:
Jasmine 1.3 Asynchronous support uses waitsFor() and run() functions.
According to Jasmine 2.0 Asynchronous support, these functions has been wiped out from the library. However, Jasmine 2.0 adds async support to the primitive beforeEach(), afterEach() and it() functions. The callback functions passed to these functions now can take an argument that indicates if the spec can or can't run.
Then, when you reach the necessary conditions to run your test (whenever your async job is complete), you simply call done(). And all the magic happens ;)
From the documentation:
describe("Asynchronous specs", function() {
var value;
beforeEach(function(done) {
setTimeout(function() {
value = 0;
done();
}, 1);
});
it("should support async execution of test preparation and expectations", function(done) {
value++;
expect(value).toBeGreaterThan(0);
done();
});
});
The it() spec above will run only after the setTimeout() call, because done() is called there. Note the it() callback takes an argument (done).
Use jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000
Please refer the below URL for Jasmine Documentation...
http://jasmine.github.io/2.0/introduction.html
Section is "Asynchronous Support" in the documentation.

How sophisticated should my Ajax code be?

I have seen simple example Ajax source codes in many online tutorials. What I want to know is whether using the source code in the examples are perfectly alright or not?
Is there anything more to be added to the code that goes into a real world application?
What all steps are to be taken to make the application more robust and secure?
Here is a sample source code I got from the web:
function getChats() {
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null) {
return;
}
var url="getchat.php?latest="+latest;
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function GetXmlHttpObject() {
var xmlHttp=null;
try {
xmlHttp=new XMLHttpRequest();
} catch (e) {
try {
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
The code you posted is missing one important ingredient: the function stateChanged.
If you don't quite understand the code you posted yourself, then what happens is when the call to getchats.php is complete, a function "stateChanged" is called and that function will be responsible for handling the response. Since the script you're calling and the function itself is prefixed with "gets" then I'm pretty sure the response is something you're going to be interested in.
That aside, there are a number of ways to improve on the code you posted. I'd guess it works by declaring a single "xmlHttp" object and then making that available to every function (because if it doesn't, the stateChanged function has no way of getting the response). This is fine until you run an AJAX request before the last one (or last few) haven't replied yet, which in that case the object reference is overwritten to the latest request each time.
Also, any AJAX code worth its salt provides functionality for sucess and failure (server errors, page not found, etc.) cases so that the appriopiate message can be delivered to the user.
If you just want to use AJAX functionality on your website then I'd point you in the direction of jQuery or a similar framework.
BUT if you actually want to understand the technology and what is happening behind the scenes, I'd continue doing what you're doing and asking specific questions as you try to build a small lightweight AJAX class on your own. This is how I done it, and although I use the jQuery framework today.. I'm still glad I know how it works behind the scenes.
I would use a framework like DOMAssistant which has already done the hard work for you and will be more robust as well as adding extra useful features.
Apart from that, you code looks like it would do the job.
I would honestly recommend using one of the many libraries available for Ajax. I use prototype myself, while others prefer jQuery. I like prototype because it's pretty minimal. The Prototype Ajax tutorial explains it well. It also allows you to handle errors easily.
new Ajax.Request('/some_url',
{
method:'get',
onSuccess: function(transport){
var response = transport.responseText || "no response text";
alert("Success! \n\n" + response);
},
onFailure: function(){ alert('Something went wrong...') }
});

Resources