This is a pretty exciting change. If you've recently updated to the latest version of Cordova, you will notice that a new platform exists: browser. What exactly does this mean? It means the browser is now (well, becoming) a viable way to test your PhoneGap/Cordova applications. For a long time now I've done a lot of my development in the browser. Most of the time I'm not concerned about some random Cordova feature, instead I'm more concerned about something else. So I'll skip, or mock, a Cordova feature and focus on the important stuff. But eventually I hit that point where I need to do something via a core plugin and then I leave the desktop. Now we have an alternative.
With the addition of "Browser" as a platform, a plugin can write code to support running under a desktop environment. How it does this is completely up to the plugin. As an example, the Barcode scanner plugin could simply return a hard coded barcode value.
As an additional change, when you run the browser platform, the deviceready event will automatically fire. Normally when I'm running on the desktop I add a line of code to fake it until I switch to a device, but now I can skip it. So how does it work?
First and foremost - there are some bugs with the implementation right now. These are going away soon. Keep that in mind if you are reading this in the future. (How did the iPad 5 Plus turn out?)
To begin, you need to add browser as a platform. However, you cannot do the normal
cordova platform add browser. Instead, use the --usegit flag, like so:
cordova platform add browser --usegit. As I warned above, this is one of those bugs that will go away soon.
To run your application in the browser, you must close Chrome. Completely. Why? Because currently the CLI has to start Chrome with a few flags attached. So kill Chrome, and then type:
cordova run browser. This will open up Chrome and point it at your application. You will see a warning about the flags it added but you can ignore those.
The next issue is updating. If you edit your code and run
cordova run browser again, Chrome will become focused, but will not reload. Nor will it select the tab with your application if you happened to switch it. So just select the tab (if changed) and click reload.
So to be clear, the process is - do the run at the CLI, let Chrome focus, and just hit reload. Again, this can, and will, become better.
Alright - now that you can test it, what's supported? I checked the core plugins only, but here are the plugins with browser as a platform support:
- Device Motion (Accelerometer)
- Device Orientation (Compass)
- Network Information
I then worked on a sample application that would let me test how these guys react in the browser environment. Here is that report. (As the sample app just runs the standard APIs, I didn't bother attaching the code to the blog post, but if anyone wants it, just ask.)
Everything works as you would expect except that you can only use base64 strings for the captured image, not file URIs. This is documented but as the docs suggest you normally should use file URIs, so keep it in mind. My demo application used two buttons, one to ask for a new image from the camera and one for an image from the photo gallery. When you try to select an image from the camera, the plugin makes use of your web cam.
After you grant permission, the plugin adds a little video output screen to the page and lets you select an image.
Finally, when you click capture, the base64 data is transmitted back to your success handler and you can add it to the DOM.
If you select to use an image from the photo gallery, the plugin just makes use of a file picker.
Cool - so the only real oddity is that the webcam version also uses your mic. When I tested I got some weird feedback. I've already filed a bug for the plugin to simply skip the mic. There really isn't any use for it. (But the Media Capture plugin could certainly use it.)
For Device, it simply sniffs the browser and uses some sensible defaults. I kinda wish Chrome would pretend to be Android, or maybe even iOS. I wrote code to simply dump out the device object to the console. Here is that result.
Device Motion (Accelerometer)
Using this API will simply return random data. It will not integrate with Chrome's DevTools Accelerometer tester, which is unfortunate, but I can live without it. Both the getCurrent and watch APIs work as expected, although I noticed a bit of delay in the watch version. I did not see this in the orientation plugin. Here is a screen shot.
Device Orientation (Compass)
Yep, just repeat what I said above. Random data. The only real difference is that the watch interval seemed to be perfectly in sync. Again, a screen shot.
So - all in all - this is a pretty exciting change. I hope more plugin authors adopt this platform and add support for it. (In fact, I'd consider it required but that's just me.) I should point out that the PhoneGap CLI does not support this platform yet.
"I should point out that the PhoneGap CLI does not support this platform yet". Maybe this is the line to separate Phonegap and continue just with Cordova
I got cordova 3.6.3-0.2.13 and when i try cordova platform add browser it send me this message:
Unable to fetch platform browser: Error: No compatible version found: cordova-broser@'master'
Valid install tarjets:
Just waiting for an update :)
Martin - read my blog post again. I explain how to get around that.
This will save a lot of time and mocking.
Great article Ray, I have fallen behind tracking progress on browser platform.
In case you are working on it, or know who is, you can fix the "need to shut down chrome" problem by passing --user-data-dir=some_temp_dir. Chrome process is a singleton only per user profile, so by creating a new profile you can start with new command line flags applied. (This strategy is often also used by chrome devs to make sure the browser is in a clean state.)
I tried to write a patch for the cordova-browser run script, but someone its use of "open -a" is making the user-data-dir argument not apply. I think perhaps open command using its own internal magic to bring the process into the foreground if its already running.. If I instead run "Applications/Google\ Chrome.app/Contents/MacOS/G...\ Chrome --user-data-dir=test --disable-web-security" it works.
If you aren't working on this, let me know and I'll just open PR for the repo.
When you say pass so and so (and my blog auto formats comments a bit so I apologize it munged it a bit) are you saying pass it to the cordova run message?
And no - I'm a Cordova user and pretend evangelist, I don't hack on the source itself. I'm sure they would love a PR. :)
Some more details..
Seems open has a '-n' which will open a fresh application instead of bringing to front, resolving the previous issue. However now I get auth errors with my user-data-dir (perhaps open runs commands under a different user?), and /dev/null is apparently no longer a valid user-data-dir and silently fails.
If I pre-create a user-dir with chmod 1777, then it works fine. Likely there is an even easier alternative by just modifying the flags to open command, but I cannot find it.
Ray, I meant we should update the run script within the cordova-browser repo so that users don't have to kill Chrome first.
I've resolved the permissions issue by just hardcoding to use a profile in /tmp/ and opened a PR for it here: https://github.com/apache/c...
Only tested on Mac, but I think that is true for the current run script, too.
Out of curiosity, how does this compare with ripple-emulator that I am using currently?
@Michal: Got ya.
@Joe: Good question. So - Ripple has been a bit quiet lately. I'm on the dev list (and a contributor), and there was some recent activity around Cordova 3.6.3, but in general, not much is going on. I'd like to spend more time on it, but honestly, I just don't have it. It does have the advantage of creating a visual wrapper around your web view, and while it is fake, it makes it feel a bit more real. You can fake the accelerometer a bit better (with data you specify I mean). It also has better localization support (you can switch to French I believe). Also, you could test changing network stuff via the UI.
In general, Ripple has some nicer controls on top of the mocking - if that makes sense. As a project though I don't know how much further it will be developed.
The *ideal* solution, maybe, would be for Ripple to remove it's own mocking stuff and make use of the mocking here, and just provide the nice UI/control type stuff.
Ray, have you tried Chrome Dev Tools mobile emulation for the UI stuff? https://developer.chrome.co...
Not sure that it replaces everything ripple did, but it also adds a lot of new awesome. Combined with browser-platform polyfills, I think we are pretty set..
I have. I think I mentioned it above in terms of the accelerometer. It's nice. Ripple is a bit better - especially for GPS. (They let you select from a map instead of just entering long/lat points which no one really knows off the top of their head. :)
As a completely OT note - their network emulation is bad though. If you try to use it to change network conditions or go offline, they don't fire the appropriate offline/online events. I need to blog about that bug.
More on that bug: https://code.google.com/p/c...
Thank you Raymond!
Ray, cordova-browser run script has been updated. If you re-add the browser platform from git, you should not need to kill your primary chrome instance any more.
I normally just update my main cordova CLI. Is this something I'd do separate w/ npm?
I updated cordova and added the browser platform. It builds fine, but when I run `cordova run browser` I get a cryptic fail error: ENOENT. Any ideas?
@Daniel: Sorry, no. Sounds familiar. Maybe remove/add it back?
I tried that already, it did nothing. I guess I'll just use Weinre.
Oh lord no - if you want to debug, use Chrome Remote Debug or Safari Remote Debug. Or see my article on GapDebug.
What do you think about "Ripple as a platform" idea? Ripple has almost all core plugin functionality + sexy UI.
P.S I also faced ENOENT error on windows
I like Ripple and used to use it a lot. I'm even a contributor. But this feels like a better approach. This also doesn't make Ripple obsolete. In my mind, I think Ripple provides a cooler UI and could be modified to use plugins like this does.
Basically - what i said to Michal above. :)
I might be missing a step in your post, but when I try to run the command: _cordova platform add browser --usegit_, I get a _TypeError: Cannot read property 'text' of null_ error. I made sure that Chrome was not running and readding/removing the platform does not seem to fix the issue. Any ideas why this is happening?
Hmm, no, sorry, I don't. Best I can suggest is to file a bug report.
Figured out the issue. Our config.xml file was missing the description tag, which was causing the cli to crash. After adding that in it worked fine. Thanks for posting this, excited to use this in our development process.
Hi Raymond - Thank you for this, this is good news. How's support for other browsers?
Any news for support for other browser?
Support for generate an Open Web App (https://developer.mozilla.o... for Firefox/Firefox for Android?
I'm running Cordova on Windows 7 with Chrome 38.0.2125.101 m.
Android version works fine but I got following error on Browser.
>*cordova run browser*
Running command: cmd "/s /c ""d:\..\platforms\browser\cordova\run.bat"""
throw er; // Unhandled 'error' event
Error: spawn ENOENT
at errnoException (child_process.js:1001:11)
at Process.ChildProcess._handle.onexit (child_process.js:792:34)
Error: cmd: Command failed with exit code 8
at ChildProcess.whenDone (C:\...\AppData\Roaming\npm\node_modules\cordova\node_modules\cordova-lib\src\cordova\superspawn.js:135:23)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:756:16)
at Process.ChildProcess._handle.onexit (child_process.js:823:5)
@eliot/@mte90 - I only tested in Chrome, but honestly I don't think the code is Chrome specific in terms of the mock portion. I think it's just Chrome specific in how it *launches*. I wrote brwoser support for the Barcode Scanner plugin and my code just uses a simple prompt/confirm. Unfortunately the other hasn't approved it yet.
@babak: I can't fire up a VM at the moment. Ensure you are updated to latest (4.0) and if you still see it, file a bug report.
Hi Raymond and babak,
I got the same error as you. "Error: spawn ENOENT".
After checking codes, I found the root cause and the temp solution.
Solution: run chrome.exe directly or change the above file to include the correct path.
>chrome.exe --user-data-dir="C:/Chromedevsession --disable-web-security
then open file <project_path>/platforms/browser/www/index.html directly.
for details, please refer to http://alanzhu.cn/blog/?p=64
BTW: up to now, I only run the basic example without camera etc.
Alan, thank you very much for sharing that!
Thanks to Alan my problem has been solved. Thank you to you, too, Raymond.
After I do cordova run browser it opens up a new browser window in chrome. However, localstorage doesn't seem to work, i.e. it forgot everything from the last time. Sort of like incongnito mode.
Any fix to this?
On OSX I'm not able to replicate this. I just did a quick test and LS persisted.
Just a note. I had to change the command slightly to make it work on the linux box:
cordova platform add browser@master --usegit
Any plans to update "phonegap serve" and the underlying cordova piece to serve up the browser version of cordova.js file instead of android cordova.js when using Google Chrome over HTTP? I am trying to use protractor to drive system tests using an http location instead of having to mash together a file path is a lot cleaner.
Are you sure it isn't using the cordova.js from platforms/browser/www?
Hi I've been developing on Ubuntu 14.04. I was able to add the browser platform in my phonegap app however when I try 'cordova run browser' nothing happens. Chrome does not open up. I looked at /platforms/ browser/cordova/run script that 'cordova run browser' initiates and it seems to be build for Windows. I'm just wondering if someone has been using this functionality in an Linux development evironment and running into the same issue. The fix would be for the script to recognize that its in a Linux environment and execute Chrome that way. Correct me if I'm wrong and let me know if there's a fix.
I'd file a ticket w/ the CLI project that way you would know yourself when it is corrected. :)
Thanks for the blog. Browser platform is really useful. I did not achieve to capture an image with browser. Could you please share your code?
Sorry, what? Can you rephrase what you asked?
I have used Ripple emulator in the past too. It's great but like i said, it is still in the PAST. I think last time I looked it was supporting PhoneGap 2.0 or something. Has anyone had a chance to put Adobe Edge Inspect up to the task yet? I have tested it when building responsive website design against my iPhone and iPad.
I have not tested it on any new Cordova applications yet but I'd bet that it would definitely be handy for testing. Just not sure about the API working and all. Can anyone confirm this?
Edge Inspect lets you inspect running web pages, but will not work with PhoneGap/Cordova apps. You can use Remote Debugging (Android, iOS) instead.
Not too sure what Remote Debugging is. In the past I have just connected Android/iOS devices and ran them through code in Terminal with Node.JS. Are you referring to the Phonegap developer app? http://app.phonegap.com/. Sorry I have just been away from PhoneGap and Apache Cordova for a while...
Go to my About Me page (http://www.raymondcamden.co... and see my two articles on mobile debugging.
FWIW, I'm finding Cordova Mocks Chrome Plugin a fairly useful extension for mocking plugins for the browser. Avoids going through some of the hoops of cordova run browser :)
Thanks for this post Raymond! Great stuff many months after the release. :)
Just a quick question: I've noticed that when I take a picture using the Camera plugin, the datauri that comes back and is set to an IMG element ends up not being the full picture that was displayed in the injected video element.
Any ideas on this? It looks like the same behaviour you received in the post (video element is bigger than the actual picture saved).
If I had to guess, I'd say the developers probably didn't care since the video was just meant to represent the camera temporarily - not actually be what is displayed after the picture is taken - if that makes sense.
It does make sense. I suppose it's meant to wire in the core functionality rather than a refined UX. You need to start somewhere.
Thanks for the reply!
I am using:
But when clicking on the button than launches this method nothing happens, no error, no webcam prompt... any idea?
Do you see anything in the console?
Very good post!
In the new platform "Browser", you can use the plugin for file transfer? File and File Transfer.
I haven't checked in a while. Go to the git repo for those plugins and check - then let us know. :)
Is there any plan to have the browser as a supported platforn by Cordova in the near future? I am asking because I would like to have a subset on my Cordova application to run in the browser and I was wondering If I should wait for Cordova to do more progress on the Browser platform support or I should just go a head an create my own version of the cordova.js for the browser...
The best thing I can suggest for checking on "support for x" is to sign up for the developer list and ask there - that's where all plans/etc are discussed: http://cordova.apache.org/#...
Thanks Raymond. I will go there :)
Hi , I am using barcode scanner plugin for browser platform . The scanner is not opening it is just prompting me for the barcode number and nothing else. Please tell me how barcode scanner can open in browser platform ?
You can't do a barcode scan on desktop. The prompt you are seeing is how the browser platform handles it.
Thank you Raymond for your quick response . :)
Raymond can you please suggest me any other alternative to run barcode scanner in web application ?
Not really. Some barcode scanners will automatically fill in a selected form field. You can try that.
I cannot get a file picker to appear at all, in either Chrome or Firefox. The following code does nothing at all. If I change the sourceType to CAMERA then I can access my web cam OK. Any ideas?
Does the same code work in Chrome?
It doesn't work on any desktop browser I've tried (Windows). Each time you call getPicture a new file input as added to the DOM but nothing else happens. I guess it should simulate a click on the input but it seems to be broken. I've opened an issue on the official tracker.
Oh, I think you are wrong. I believe the idea of the file input is to let you select an image and then it is added. In that way, it kind of acts like the device mechanism of selecting an image from the gallery.
Remember, the idea here isn't to 100% mimic what you get on device, but to let you test functionality.
OK. Not particularly elegant, but fair enough. Your article is really all people have to go on regarding the browser platform, and it's not at all clear from the official site where it fits. I was hoping we might see it become something more than a test bed...
Speaking for myself, and NOT for the Cordova team, I still stand by my original assertion that this is only appropriate for testing, and *not* for having a web based version of a Cordova app. I don't believe the Cordova team (which technically I'm part of :) agrees with me there, but that's my opinion.
That doesn't make this feature any less useful of course. I still like it. :)
I'm looking at building both web apps and hybrid mobile apps from the same source, so having the browser as a platform is a big deal. Even if it is not fully functional, it could make life a lot easier. Just being able to rely on little things like window.cordova.platformId being present can simplify my development. My next challenge is to try and find a way to get "cordova prepare browser" to run when any of my source files change. Any ideas? :)
Use gulp or grunt. Will take you five minutes. I've got a blog post showing an example of this. One sec.
This is old, but may help: http://www.raymondcamden.co...
Ha! I knew it would be simple. This is excellent. You're a star.
Hi all, thanks for helping out with questions as these. I have been trying to get Cordova to add the browser platform but keep getting this error-- https://uploads.disquscdn.c...
I'd mighty appreciate any help on this. Thanks in advance.
Is your CLI 100% up to date?
Can you add any other platform, like Android?
My CLI is up to date, and I get the same message when I try to add Android as well.
I assumed you Googled, right? This help any? http://stackoverflow.com/qu...
*smiles. I did google but could not find my specific case as per the screengrab. I'll use the SO link you provided and post back when the issue goes away. Thanks again.
UPDATE: I'm simply trying to add the browser platform on my main work laptop, most of the guides point to adding android. I tried the process on a virgin windows laptop and it worked just fine. So I'm thinking maybe my node file structure got 'baggage' needs sorting.
Can i Have a your code of this example ??
All the code did was test the various APIs. It is nothing special.
Hi Raymond, was there a solution or workaround to the microphone being included in the camera access? Seems like chrome ties mic and camera together for the access. Couldn't find your bug report.
Sorry, no, I don't think I filed a bug report for it. Since (imo) this is mainly for testing, it seems harmless. But I'd encourage you to file a bug report for it. :) (Yes, I'm being lazy.)
This was a relief! I'm using Cordova 5.4 and still did not know there is a platform named browser. Thanks for the Info.
I want to use barcode scanner plugin for browser(mobile browser) platform , will it possible.?
If I remember right, on the browser, the barcode scanner just prompts you to enter the number. So technically, it works, but it isn't what you want probably.