Babel Does not Change Promises at All - babeljs

I don't totally get how Babel is meant to work. I've played around with it and it transpiles some things but not others. An example of this is promises. I'll set out the config of my project and the results:
I've targeted IE 10 (.browserslistrc):
>= 1%
last 1 major version
not dead
Chrome >= 45
Firefox >= 38
Edge >= 12
Explorer >= 10
iOS >= 9
Safari >= 9
Android >= 4.4
Opera >= 30
babel.config.js
const presets = [
[
'#babel/preset-env',
{
useBuiltIns: 'entry',
debug: true,
corejs: { version: '3.2.1' }
}
]
];
module.exports = { presets };
A file called promises.js
var promise1 = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('foo');
}, 300);
});
promise1
.then(function (value) {
console.log(value);
});
I'm just calling the cli using "babel src -d lib"
As I said, the promises file is reproduced, as is, despite the fact that IE10 does not support them. I have included core-js in the solution as a dependency, but have not manually invoked it at all (I'm not sure whether Babel uses it).
If someone could help me understand this, it would be great.
Thanks

A little bit more time (read as, a heck of a LOT of time) with Babel.js and I have learnt the answer to my question.
I did not comprehend the fact that Babel transpiles some things and polyfills others. And by polyfill, I mean it delegates the job of polyfilling to core.js.
This took ages for the penny to drop, because Babel is touted as a Javascript compiler. Technically it is. But it is also a delegator :)
To canvas a few things, these are transpiled:
arrow functions
classes
the Destructuring operator
whilst these are polyfilled:
fetch
promises
My question was about promises. And therein lies the answer.
Hope this helps others new to Babel.

Related

Protractor - Cannot read property '$$testability' of undefined

I am getting an error which reads:
"Error while waiting for Protractor to synce with the page: "Cannot read property '$$testability' of undefined"
Below is my test.
describe('On the MyMoments page', function(){
beforeEach(function() {
var editLocationText = 'Location';
browser.driver.get('http://192.168.0.6:8100/#/page1/myMoments');
});
it('The edit button should work', function() {
browser.driver.get('http://192.168.0.6:8100/#/page1/myMoments').then(function() {
// browser.waitForAngular();
browser.getCurrentUrl().then(function(url) {
});
});
});
});
This is my config file:
exports.config = {
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
args: ['--disable-web-security']
}
},
baseUrl: 'http://192.168.0.6:8100',
specs: [
'*.test.js'
],
jasmineNodeOpts: {
isVerbose: true,
}
};
I don't think this is something to do with my test since my test is incredibly simple. Has anybody run into this issue before? I'm a bit stuck.
Thanks.
EDIT:
Downgraded my Protractor version all the way to 4.0.14 in order to fix this error. Now i'm getting:
"Failed: Error while waiting for Protractor to sync with the page: "[ng:test] no injector found for element argument to getTestability/http://errors.angularjs.org/1.5.3/ng/test"
If anyone knows what this is or how to resolve this, let me know!
Thanks.
This is a known issue in Protractor, see here. As mentioned in the issue this is because browser.angularAppRoot() is expected to return the current value of app root if a value isn't passed to it, but currently returns undefined.
A new release is coming that should fix this issue.
Hope it helps
Although it's sometimes caused by documents without an html tag in the root, "Cannot read property '$$testability' of undefined" is more likely to manifest as a symptom of another error that prevented the page from loading, or any interaction with a page that isn't loaded for whatever reason.
Try using a browser.sleep above the line that is throwing the error, to give the page time to load.
A browser.ExpectedConditions clause which is intended to wait for a specific condition can throw this error if the page is not ready for protractor.
Sometimes, hard coded sleeps can not be avoided.
To diagnose and fix it,
Place browser.enterRepl(); into the code just before the line
that seems to be throwing the $$testability error.
If the $$testability error still gets thrown, then move browser.enterRepl(); up a few lines
Each time enterRepl() gets triggered without the $$testability error, then move browser.enterRepl(); down one line
Finally, when enterRepl is moved to the line directly below the line causing the error, you may now see a different error message which is more meaningful.
Place a browser.sleep() or other code to fix your specific issue just prior to the line causing that error.
Changing the browser from chrome to firefox worked for me.
// conf.js
exports.config = {
framework: 'jasmine',
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: {
'browserName': 'firefox'
},
specs: ['login-spec.js']
}
I had the same issue with an Angular hybrid app.
In my case the issue was fixed after removing,
rootElement: 'myRootElement'
from the config.

Is it possible to run async code in a Babel Plugin Visitor?

I'm working on a babel plugin that runs some code through an async module. I need to wait on that result before I modify the path.
visitor: {
TaggedTemplateExpression(path) {
if (path.node.tag.name !== 'Style') return;
ProcessStyle(path).then((data) => {
path.replaceWith(t.StringLiteral(data.data));
});
},
}
Is this currently possible?
Babel's API, for example babel.transform(), synchronously returns the resulting transformed. This means that plugins have no way of being async, because Babel itself is fully synchronous.
Depending on what your requirements are, you could consider using child_process.execSync to synchronously run another Node process to do your async work while blocking Babel.
https://github.com/ForbesLindesay/sync-rpc
this runs async code in a separate process, and communicates over a network connection
i found it surprisingly hard to do this reliably with child_process and execSync / spawnSync. i always had problems with limited buffer size, even when setting maxBuffer to Infinity, resulting in incomplete data transfers and mysterious syntax errors (code lines were cut off after some 1000 characters)

How to stop automatically closing browser when writing protractor test cases

I am new to writing test cases using protractor for non angular application. I wrote a sample test case.Here the browser closes automatically after running test case.How can I prevent this. Here is my code
var submitBtnElm = $('input[data-behavior=saveContribution]');
it('Should Search', function() {
browser.driver.get('http://localhost/enrollments/osda1.html');
browser.driver.findElement(by.id('contributePercentValue')).sendKeys(50);
submitBtnElm.click().then(function() {
});
});
I was also struggling with a similar issue where i had a test case flow where we were interacting with multiple application and when using Protractor the browser was closing after executing one conf.js file. Now when I looked into the previous response it was like adding delay which depends on how quick your next action i performed or it was hit or miss case. Even if we think from debugging perspective most of the user would be performing overnight runs and they would want to have browser active for couple of hours before they analyze the issue. So I started looking into the protractor base code and came across a generic solution which can circumvent this issue, independent of any browser. Currently the solution is specific to requirement that browser should not close after one conf.js file is executed, then could be improved if someone could add a config parameter asking the user whether they want to close the browser after their run.
The browser could be reused for future conf.js file run by using tag --seleniumSessionId in command line.
Solution:
Go to ..\AppData\Roaming\npm\node_modules\protractor\built where your
protractor is installed.
Open driverProvider.js file and go to function quitDriver
Replace return driver.quit() by return 0
As far as my current usage there seems to be no side effect of the code change, will update if I came across any other issue due to this change. Snapshot of code snippet below.
Thanks
Gleeson
Snapshot of code snippet:
Add browser.pause() at the end of your it function. Within the function itself.
I found Gleeson's solution is working, and that really helped me. The solution was...
Go to %APPDATA%Roaming\npm\node_modules\protractor\built\driverProviders\
Find driverProviders.js
Open it in notepad or any other text editor
Find and Replace return driver.Quit() to return 0
Save the file
Restart your tests after that.
I am using
node v8.12.0
npm v6.4.1
protractor v5.4.1
This solution will work, only if you installed npm or protractor globally; if you have installed your npm or protractor locally (in your folder) then, you have to go to your local protractor folder and do the same.
I suggest you to use browser.driver.sleep(500); before your click operation.
See this.
browser.driver.sleep(500);
element(by.css('your button')).click();
browser.driver.sleep(500);
Add a callback function in It block and the browser window doesn't close until you call it.
So perform the action that you need and place the callback at your convenience
var submitBtnElm = $('input[data-behavior=saveContribution]');
it('Should Search', function(callback) {
browser.driver.get('http://localhost/enrollments/osda1.html');
browser.driver.findElement(by.id('contributePercentValue')).sendKeys(50);
submitBtnElm.click().then(function() {
// Have all the logic you need
// Then invoke callback
callback();
});
});
The best way to make browser NOT to close for some time, Use browser.wait(). Inside the wait function write logic for checking either visibilityOf() or invisibilityOf() of an element, which is not visible or it will take time to become invisible on UI. In this case wait() keep on checking the logic until either condition met or timeout reached. You can increase the timeout if you want browser visible more time.
var EC=protractor.ExpectedConditions;
var submitBtnElm = $('input[data-behavior=saveContribution]');
it('Should Search', function() {
browser.driver.get('http://localhost/enrollments/osda1.html');
browser.driver.findElement(by.id('contributePercentValue')).sendKeys(50);
submitBtnElm.click().then(function() {
browser.wait(function(){
EC.invisibilityOf(submitBtnElm).call().then(function(isPresent){
if(isPresent){
return true;
}
});
},20000,'error message');
});
});
I'm sure there is a change triggered on your page by the button click. It might be something as subtle as a class change on an element or as obvious as a <p></p> element with the text "Saved" displayed. What I would do is, after the test, explicitly wait for this change.
[...]
return protractor.browser.wait(function() {
return element(by.cssContainingText('p', 'Saved')).isPresent();
}, 10000);
You could add such a wait mechanism to the afterEach() method of your spec file, so that your tests are separated even without the Protractor Angular implicit waits.
var submitBtnElm = $('input[data-behavior=saveContribution]');
it('Should Search', function() {
browser.driver.get('http://localhost/enrollments/osda1.html');
browser.driver.findElement(by.id('contributePercentValue')).sendKeys(50);
submitBtnElm.click().then(function() {
});
browser.pause(); // it should leave browser alive after test
});
browser.pause() should leave browser alive until you let it go.
#Edit Another approach is to set browser.ignoreSynchronization = true before browser.get(...). Protractor wouldn't wait for Angular loaded and you could use usual element(...) syntax.
Protractor will close browsers, that it created, so an approach that I am using is to start the browser via the webdriver-reuse-session npm package.
DISCLAIMER: I am the author of this package
It is a new package, so let me know if it solves your problem. I am using it with great success.

Meteor.startup(func) - when is the DOM "ready" in Meteor?

http://docs.meteor.com/#meteor_startup
Concerning Meteor.startup(func)
On a client, the function will run as soon as the DOM is ready.
At what point is the "DOM ready"?
The reason why I ask is because you can have a Meteor template that uses many other templates (ie. other DOM elements) inside of it and have many other things loading at different times depending on how long those things take to load (ie. more DOM elements).
In the past I've loaded Javascript files on Meteor.startup but they were still loaded too early because the entire DOM actually had not been loaded yet.
Meteor.startup( function() {
//load JS files now
});
So what does it mean by "DOM ready?" It most definitely does not mean "When the DOM is loaded in its entirety."
Meteor.startup actually runs when all the files have completely downloaded from the server (javascript files). If you place your code to run at startup without putting it in a Meteor.startup it may not run because it would run where the JS/html has not been fully downloaded yet
This is when the 'DOM is ready', but not necessarily when your HTML is rendered, because this (the HTML) renders when the DOM is ready too.
If you're looking for something that runs after both the DOM is ready and after your page's html is ready look for the template's .rendered callback - http://docs.meteor.com/#template_rendered
The confusion may come from the concept of $(document).ready in JQuery, but this applies because the page is already rendered on the server side so you can assume its also rendered on the client (since its downloaded that way). In Meteor pages are rendered on the client so there is this slight difference.
Here's what the .startup method actually does on the client:
Meteor.startup = function (cb) {
var doScroll = !document.addEventListener &&
document.documentElement.doScroll;
if (!doScroll || window !== top) {
if (loaded)
cb();
else
queue.push(cb);
} else {
try { doScroll('left'); }
catch (e) {
setTimeout(function() { Meteor.startup(cb); }, 50);
return;
};
cb();
}
};

Why does PhoneGap seem faster than Titanium?

I'm trying to measure the execution perfomance of a few cross-platform solutions, among which are: Titanium and PhoneGap.
So here's an example of the Titanium version of my performance tester, it's very simple, but I'm just trying to get a feeling of how fast my code gets executed:
var looplength;
var start1;
var start2;
var end1;
var end2;
var duration1;
var duration2;
var diff;
var diffpiter;
var power;
var info;
for (power = 0; power < 24; power++) {
looplength = Math.pow(2, power);
start1 = new Date().getTime();
for (iterator = 0; iterator < looplength; iterator++) {a=iterator;b=iterator;}
end1 = new Date().getTime();
start2 = new Date().getTime();
for (iterator = 0; iterator < looplength; iterator++) {a=iterator;}
end2 = new Date().getTime();
duration1 = end1 - start1;
duration2 = end2 - start2;
diff = duration1 - duration2;
diffpiter = diff / looplength;
info={title:'2^' + power + ' ' + diffpiter};
tableView.appendRow(Ti.UI.createTableViewRow(info),{animated:true});
}
The PhoneGap version is the same except for the last two lines which get replaced
document.write('2^' + power + ' ' + diffpiter + '<br />');
Both are executed on an iPhone 4S. I've run the test numerous times, to eliminate errors.
How in the name of all that is holy can the Titanium version measure ~0.0009 milliseconds per iteration while the PhoneGap version measures ~0.0002 milliseconds per iteration?
Titanium is supposed to compile my javascript code so I expect it to be faster. In this case however it's at least 4 times slower! I'm not an expert on performance testing, but the test I designed should be at least remotely accurate...
Thank you for any tips you can give me.
Titanium doesn't convert javascript code to objective-c. Titanium simply uses a javascript to objective-c bridge to communicate with objective-c iOS framework (most importantly User interface objects). More appropriate comparison would be to code titanium's User Interface element (button, label, window, view ), manipulate them and use html,css,image buttons in phonegap.
Phonegap also uses a bridge of it's own and if you know java or objective-c you can make plugins to use native User Interface elements and other Native features of iOS or Android.
http://zsprawl.com/iOS/2012/05/navigation-bar-with-nativecontrols-in-cordova/
This is basic JavaScript, and not all JavaScript is compiled to native code. Basically when you use the Titanium API, that will be converted to Objective-C or Java code. But to be flexible and dynamic there is a JavaScript interpreter compiled with the App, and that basically runs the JavaScript you have written.
This makes the App slower. But testing it purely on these things is useless. If you want to do a full suit of testing you need to use the Titanium API too, and compare that to the PhoneGap one.
What you'll notice, as Phonegap does not compile to native code, it will feel different, and visually Titanium will behave faster.
Oh man, I don't want to start a flame war but I will put in my two cents. First, full disclosure: I'm a contributor to PhoneGap and I've never used Titanium. However I am answering from 15 years of development experience.
I've never found tools that convert code from one language to another to be particularly efficient. Yes, native code should run faster than JavaScript code but I'm willing to bet there are inefficiencies introduced during the translation phase.
Again this is just from past experience using tools that compile one language into another it is not a knock on Titanium as that is a great framework.
In your TItanium code, your last line is creating UI objects - this is making a call to Objective-C to create a UITableViewRow and an animation object and then appending it to a UITableView - you are doing 3 operations. I'd be pretty confident that this is what is taking the time. The preferred Ti way of doing this would be create an array of title objects, then using setData on the table at the end.
PhoneGap has already created the UIWebView on app load and you are just updating the html in one DOM element so I would expect the UI will be faster.