vanamco.com https://www.vanamco.com The Vanamco Site Mon, 12 Jun 2017 08:22:13 +0000 en-US hourly 1 https://wordpress.org/?v=4.8 Ghostlab 3 is here https://www.vanamco.com/2017/06/06/ghostlab-3-is-here/ https://www.vanamco.com/2017/06/06/ghostlab-3-is-here/#respond Tue, 06 Jun 2017 10:16:39 +0000 https://www.vanamco.com/?p=3841 We’re excited to announce that Ghostlab 3 is now available! We’ve been working on it for the past year, and are happy to present you with some features we find to be really useful. As before, Ghostlab 3 focuses on making your responsive, multi-client development and testing workflow more efficient and fun. You can simultaneously […]

The post Ghostlab 3 is here appeared first on vanamco.com.

]>
We’re excited to announce that Ghostlab 3 is now available! We’ve been working on it for the past year, and are happy to present you with some features we find to be really useful.

As before, Ghostlab 3 focuses on making your responsive, multi-client development and testing workflow more efficient and fun. You can simultaneously browse any site that you’re developing or testing on multiple browsers and devices. Scrolls, link clicks, form fills and basically any interaction you can imagine are synchronized across all clients. This means you can go through any web workflow on multiple clients at once.

But let’s get to the new stuff! And if you’re not into reading, just download the new Ghostlab and see for yourself.

Screenshots

Ghostlab allows you to take screenshots on any connected device. You can annotate and export the screenshots to document layout problems and communicate them fast and effectively.

A/B Testing

Use the A/B testing feature to compare two versions of a website that are same same but different! This can be your site in two language versions, a staging versus a production host, and much more. You can define any number of A/B test cases in the Site settings.

Remote Form Filling

We’ve added another form filling tool – Remote form filling. On any connected client, triple-click into (or use Ctrl-Space in) an input field – this will open a popup that lets you fill out this field on every connected client individually. Works not only for input fields, but also radios, checkboxes, and selects 🙂

Redone: Workspace feature

The Workspace feature is – well, quite redone. You can now configure your workspace in a convenient list, selecting browser, window position and size. And while the workspace is open, you can dynamically configure it to your pixel perfect needs.

Security

Ghostlab can now run a secure server and let’s your devices connect via HTTPS. You can configure your certificates (including intermediate certificates) in the application preferences. Also, we’ve added support for client certificates. This means you can now run a tight ship in terms of security while having fun on the web!

Autoprefixing and Shell

We’ve added autoprefixing as an option in the preprocessors – you can now run autoprefixing after compiling Scss/Less/Stylus, should you want to. Also, you now have the ability to execute arbitrary scripts when certain files change (shell scripts on Mac, Batch on Windows).

Inspector upgrade

We’ve upgraded the dev tools, giving you features like debugging CSS animations, support for server-sent events, and a websockets tab.

UI Facelift

We’ve done a minor facelift of the UI, giving a better overview in the settings, and improving various minor things.

Wrapper update

We’re not really sure if you care, but: we have updated our native wrapper Zephyros, so even on a Mac, you’ll now be running Ghostlab on Chromium!

 

Pricing and Upgrade

A Ghostlab 3 license costs 49 USD, or 49 CHF if you’re shopping from Switzerland, or 45€ if you’re shopping from a Euro country.

If you own a Ghostlab 2 license, this license is not valid for Ghostlab 3, as it is a major version upgrade. However, we offer a discounted upgrade for Ghostlab 2 license holders.

  • If you have purchased Ghostlab 2 on or after January 1st, 2017, you receive a free upgrade to version 3.
  • If you have purchased Ghostlab 2 on or before December 31, 2016, you receive a 30% discount, amounting to a price of 34.40 USD (34.40 CHF, 31.50 EUR).

A coupon code for either the free or discounted upgrade is available in our store for every Ghostlab 2 license. It can be used exactly once,  and for the number of licenses as the license count on the license.

All Ghostlab 2 license keys have been made into coupons into our store. When you enter it, you will receive your discount as per the rules above. You can enter your license key upper or lower case. Example: GAWAE-FDUJM-P4S2A-YL9HF-7754S-VDNPH-3UX8A-35RYC-CRSNS-UWDWW-636VX-C3HMX-A3GJU-6UH8K-5K8E

 

Want to give it a spin?

You can of course try it for free! Please download the fully functional demo (valid for 7 days – only actual days of usage are counted) from our downloads page.

 

The post Ghostlab 3 is here appeared first on vanamco.com.

]>
https://www.vanamco.com/2017/06/06/ghostlab-3-is-here/feed/ 0
Idea pool: your input, our challenge https://www.vanamco.com/2017/01/24/your-ideas-our-challenge/ Tue, 24 Jan 2017 15:37:54 +0000 https://www.vanamco.com/?p=3313 For three years, our development of Ghostlab has been accompanied by our “Idea Pool” – an interactive feedback forum hosted on Uservoice that allowed everyone to post their ideas for future Ghostlab developments. By upvoting, ideas came on our radar and we’ve realized quite some of them. We are moving the Idea Pool to our […]

The post Idea pool: your input, our challenge appeared first on vanamco.com.

]>
For three years, our development of Ghostlab has been accompanied by our “Idea Pool” – an interactive feedback forum hosted on Uservoice that allowed everyone to post their ideas for future Ghostlab developments. By upvoting, ideas came on our radar and we’ve realized quite some of them.

We are moving the Idea Pool to our own infrastructure, and are looking to improve it’s features. This is why currently, we have paused the idea pool. But do not worry: we are working on getting it back in greater shape as soon as possible!

During the transition, we thought it would be cool to briefly think about the impact of the Idea Pool. First, let’s have a look at all the ideas we have implemented thanks to our users suggesting and voting them up. Note that as long as ideas are good, they don’t necessarily need a big number of votes…

Completed Features Votes Contributing User
Windows/PC Version 314 Anonymous
Synchronize JS event clicks 47 Luis Martins
Mouse to touch synchronization 34 darren
Add Master/Slave mode 18 Simon Bächler
Soft CSS refreshes 13 Luis Martins
Include VM name in browser list 7 Alan
Support SASS compilation 6 Asif Amin
Allow remote IE inspection 5 Yann
Add full screen mode 2 Anonymous
Add custom quick fill shortcuts 2 Anonymous

Of course, we haven’t been able to implement all the user ideas. But there are some that we are still working on. Currently, we’re actively developing a next major version, and the table below indicates some of the stuff we’re working on to bring out soon….

Feature we’re working on Votes Contributing User
Ubuntu/Debian Version 300 Jeremy “Jay” Zahner
Taking screenshots of device’s viewports in Ghostlab 167 Guillem Mazarico
Add HTTPS support to Ghostlab server 32 Maarten Manders

In essence, we want to say a big *thank you* to all of you who have contributed to our idea pool. It has inspired our development, and we are looking forward to continue the conversation to improve our software. The new idea pool will be online soon – and if, in the meantime, you have a brilliant idea that can’t wait, let us know via our contact form!

The post Idea pool: your input, our challenge appeared first on vanamco.com.

]>
Automated web shop testing with WebdriverIO https://www.vanamco.com/2017/01/13/automated-web-shop-testing-with-webdriverio/ Fri, 13 Jan 2017 17:17:43 +0000 https://www.vanamco.com/?p=3152 We’ve recently migrated our website to a new environment. While we were at it, we thought we could complement our simple uptime-Testing with some automated web shop testing, so that we can sleep at night knowing our site is OK. We’ve implemented some tests with WebdriverIO and thought we’d share the procedure, in case you’re looking for […]

The post Automated web shop testing with WebdriverIO appeared first on vanamco.com.

]>
We’ve recently migrated our website to a new environment. While we were at it, we thought we could complement our simple uptime-Testing with some automated web shop testing, so that we can sleep at night knowing our site is OK. We’ve implemented some tests with WebdriverIO and thought we’d share the procedure, in case you’re looking for a quick guide. The entire test script is available for download here.

Our test scenario

When somebody buys Ghostlab from our website, they have to do several things: add Ghostlab to the cart, go to the cart page, click the checkout button, provide all required information in the checkout form, pay for the order, and finally they will expect to receive their license information via E-mail. And that’s exactly the procedure we want to pack into an automated test run.

  • Automated test steps
  • Go to Ghostlab landing page
  • Click “Buy” link to get to WooCommerce product page
  • Add Ghostlab to the cart
  • Click on “View cart” to see the cart contents
  • Proceed to checkout
  • Complete checkout form
  • Pay – we’ll do that with a trick
  • On order completion, receive E-mail with license key

 

Set up WebdriverIO project

Before you can get started, you have to set up a WebdriverIO project. It’s really easy, just follow the WebdriverIO guide. What you’re doing is basically:

  • set up your project directory
  • download selenium server and driver – be sure to start the server after download.
  • install webbdriverio via npm

Once you’re set up, let’s directly create a test runner for our project. Just follow the instructions for how to complete the testrunner setup dialog (WebdriverIO guide, “Let’s get serious”). Note that as of today (January 13 2017), there is one additional setup step in the dialog that is not described in the guide – I just selected the default value.

I’m assuming that you now have your test/specs directory. Now create a JavaScript file there that lets you write your test. You should end up with a setup comparable to the one in the image below.

# To run your test(s), simply execute the 
# following from the command line in the 
# project directory. 
./node_modules/.bin/wdio wdio.conf.js
Why WebdriverIO?
There are many tools to create automated tests. When we set up our tests, we were looking for something that was powerful, well-documented, easy to setup, and locally available (i.e. no SaaS). We gave several tools a quick spin, and WebdriverIO convinced us because the time to your first hello world is really short, and it is very well documented.

Now on to the actual test steps…we will only be looking at a small set of features of the Webdriver API – for the full reference, see WebdriverIO API Docs.

1: Navigate to landing page, follow to WooCommerce product page, add Ghostlab to cart

We want to start from our product landing page, so we need to point the browser to that location.

browser.url('https://www.vanamco.com/ghostlab');

On this page, there is a Buy button. We’d expect visitors who want to buy Ghostlab to click it and get to the WooCommerce product page. After clicking the button, we need to wait for the WooCommerce product page to load before we can perform our further actions. Therefore, we’re waiting for an element to be present that was not on the landing page, but is on the WooCommerce product page, namely the “Add to cart” button.

browser.click('=Buy');
browser.waitForExist('.single_add_to_cart_button.button', 5000);

Both the click and waitForExist function expect a Selector as first argument. A selector is used to specify the element in question – the one that we want to click on, or the one we’re waiting for to be present.

We’re specifying a timeout of 5000 milliseconds for waitForExist – in case the page does not load within this time, the test will fail. So make sure you specify a timeout long enough for your page to load.

Selectors
There’s a wide range of possible selectors, we’ve found the link text (‘=Buy’, on anchor elements) and CSS selectors to be easy to handle. Of course, which selectors best suit you depends on the content of your page. As soon as you start using selectors, be aware that changes in your page might break your test. For example, if we were to change the text of the buy button to “Get one now”, the test would no longer work. See the Developer Guide for a full reference of available selectors.

As soon as the WooCommerce product page has loaded, there will be an element to add the product to the cart, and our test run will continue. Next we actually want to add 1x Ghostlab to the cart by pressing the button. When this is done, the page will show a confirmation message that we’ve added it to the cart – and there will be a link that takes us to our shopping cart. So we wait for the confirmation to appear, then follow the cart link.

browser.click('.single_add_to_cart_button.button');
browser.waitForExist('.woocommerce-message > a', 5000);
browser.click('.woocommerce-message > a');

2: Enter coupon code so we don’t have to provide payment information, continue to checkout

As soon as the cart is displayed, we enter a coupon code we’ve prepared for the test that gives us 100% off. This means that our order totals 0$ and we can perform the checkout without entering payment information.  We detect whether the cart has loaded by checking for the presence of the coupon code field. We then wait for the confirmation message WooCommerce writes to the page to show that the code was applied, and verify that it was successfully applied by examining the content of the message.

browser.waitForExist('input[name="coupon_code"]');
browser.setValue('input[name="coupon_code"]', config.couponCode);
browser.click('input[name="apply_coupon"]');
browser.waitForExist('.woocommerce-message', 5000);
var msg = browser.getText('.woocommerce-message').trim();
assert(msg === 'Coupon code applied successfully.', 'Did not see coupon code applied successfully message');

Once the coupon code is applied, we go to the checkout form by clicking the proceed to checkout link. We detect the load of the checkout form by checking for the presence of the place order button – which we will use in the end to actually place our order.

browser.click('.wc-proceed-to-checkout > a');
browser.waitForExist('input[name="woocommerce_checkout_place_order"]');

3: Complete checkout form

Now we can fill out the checkout form. We’ve stored the field selectors and the associated values in a separate array over which we can iterate – of course, you could also solve this differently. One field we have to treat specially is the country selector – this is not a simple select, but a JavaScript-enhanced select component where you can search for values, then select them by clicking them. We are unable to simply set the value as with a regular input field, so we need to perform the click-search-select pattern that a real user would use.

 

config.checkoutForm = [
 {s: 'input[name="billing_first_name"]', v: 'Automatic'} /*, ... */
];

for (var i = 0; i < config.checkoutForm.length; i++) {
    var item = config.checkoutForm[i];
    browser.setValue(item.s, item.v);
 }
browser.click('.country_select');
myWait(1000);
browser.setValue('#s2id_autogen1_search', 'Switzerland');
myWait(500);
browser.click('.select2-result-label');

 

We are using the myWait function. This will simply make the test wait for a specified number of milliseconds by using the waitUntil function in combination with some time math. We use it on the JavaScript select box to make sure that the page has had the time to first render the search box, then filter down the results. We’ll later use the myWait function before trying to fetch the license e-mail.

/*
 * Simple function to wait for a specified number of milliseconds (roughly)
 */
function myWait(ms) {
    console.log('Waiting for ' + (ms/1000) + ' seconds');
    var now = new Date().getTime();
    browser.waitUntil(function(){
        return (new Date().getTime() - now) > ms;
    }, ms + 1000)
}

4: Place order, verify order confirmation, extract order number

Now that the form is completely filled out, we can place the order. For that, we simply click the place order button. After the order has been processed, we will see a confirmation page. We verify that we have reached it by waiting for the thank you note, and by examining the content of the message. Also, we extract the order number assigned to our order by the system. We need this to check if we have received the license e-mail.

browser.click('input[name="woocommerce_checkout_place_order"]');
browser.waitForExist('.woocommerce-thankyou-order-received');
msg = browser.getText('.woocommerce-thankyou-order-received').trim();
assert(msg === 'Thank you. Your order has been received.', 'Did not see order has been received message.');

console.log('Extracting order number...');
var orderNumber = browser.getText('.woocommerce-thankyou-order-details.order_details > li:first-child > strong').trim();

 

5: Verify that license e-mail has been sent

On order placement, our backend should have generated a license key for Ghostlab and sent it to the e-mail address we have provided in the checkout form. In order to complete the test, we need to see if that e-mail has actually been delivered. For that, we use a node imap package to connect to the e-mail account we provided on purchase. Before we try and fetch the e-mail, we wait for 30 seconds, otherwise, it might not have been delivered yet.

Mocha timeouts
By default, mocha (which we’re using in our example) has a timeout of 10s – so when we would wait for 30s, that would fail, as the global timeout would apply after 10s. You can increase the mocha timeout in the mocha options (mochaOpts.timeout), this can be found in the file wdio.conf.js, which is automatically created for your project.

We know that the Subject text of that license e-mail is unique – it is some static text combined with the order number (that’s the unique part). So we can simply search for a message with the expected subject, and will be satisfied if the number of messages returned by the search is exactly 1. Of course, we could go on to examine the content of the license email, maybe even try to activate the software product with the license – but we’ll leave that for some other time.

// Let's wait a bit before we try to fetch the E-mail
myWait(10 * 1000);

var subject = 'Ghostlab 2 license for your order ' + orderNumber + ' (1 x Ghostlab)'
var foundEmail = false;
imap.once('ready', function(){
  imap.openBox('INBOX', true, function(err, box){
    imap.search([ 'UNSEEN', ['SUBJECT', subject] ], function(err, results) {
      if (err) 
        throw err;
       var resultsLength = results.length;
       assert(resultsLength === 1, 'Did not find exactly one e-mail with license information');
       foundEmail = true;
      imap.end();
    }); 
  });
});
imap.connect();

// Wait for e-mail to be confirmed.
browser.waitUntil(function() { return foundEmail; }, 10000);

Note that the call to imap.connect() is asynchronous – so how do we “notify” our test that e-mail fetching has been successful? We use the waitUntil function and pass it a function that returns a variable. In the e-mail handling, we set the variable to true if we successfully fetch the e-mail.

The entire test script is available for download here.

The post Automated web shop testing with WebdriverIO appeared first on vanamco.com.

]>
Ghostlab 2 is here https://www.vanamco.com/2015/03/18/ghostlab-2-is-here/ https://www.vanamco.com/2015/03/18/ghostlab-2-is-here/#comments Wed, 18 Mar 2015 10:24:10 +0000 http://blog.vanamco.com/?p=914 We’re excited to announce that Ghostlab 2 is now available! Let us give you a quick tour of what’s new, and what’s the same. As in version one, Ghostlab 2 focuses on helping you making responsive and multi-device testing much faster and more convenient. It lets you browse any site you’re interested in, keeping any […]

The post Ghostlab 2 is here appeared first on vanamco.com.

]>
We’re excited to announce that Ghostlab 2 is now available! Let us give you a quick tour of what’s new, and what’s the same.

As in version one, Ghostlab 2 focuses on helping you making responsive and multi-device testing much faster and more convenient. It lets you browse any site you’re interested in, keeping any number of connected clients in sync by propagating scrolling, clicking, and any other site interactions it discovers. This works for local browsers and mobile devices on your network. It lets you (validly!) fill out forms automatically within a fraction of a second, lets you keep track of all connected clients, and offers you the ability to identify problems and fix them on any of them.

At the same time, we’ve introduced many changes in version 2 – some of them significant, some of them more on the minor-but-useful side. We’d like to present three of them that we’re particularly happy to share with you.

Client inspection

In Ghostlab 1, we’ve included Weinre, an awesome project that allowed us to remotely inspect the DOM on any connected device. However, we wanted to do more than that, and decided we’d have to rethink how we provide remote inspection tools. In Ghostlab 2, we are including the developer tools you know from Google Chrome – with some tweaks of our own. You are still able to inspect any connected client – but in addition, you can now inspect all of them synchronously.

That means that when you remotely “fix” that CSS property that destroys your page in Chrome or Firefox, you’ll immediately also see what the consequences are for any other connected browser or device.

On top of that, we decided that inspecting CSS is often not enough – especially after some bad experiences finding JavaScript bugs on mobile phones. So we’ve come up with a solution that lets you remotely debug JavaScript on any client that is connected to Ghostlab – be it a browser, a tablet, a mobile phone or even a TV set. We’ve even been told it works on IE8!

Preprocessors

To allow Ghostlab to further integrate into the workflow, we’ve also added the ability to compile several languages. Initially, we’re shipping support for Sass / Less / Stylus, Jade / Haml, and CoffeeScript / Typescript. When you’re using Ghostlab with your local site, it will now be able to compile all these source files into browser-ready HTML/CSS/JS and then automatically refresh the page on your devices.

We’re not including binary compiler packages in our distribution, rather, Ghostlab will attempt to install them them should they not be present on your system. We’re using npm and gem for that purpose. This makes it easy to offer a wide range of preprocessors in the future while not making the Ghostlab distribution too heavy. While the initial set of precompilers may seem limited, we’ll constantly be on the lookout for interesting candidates to include.

Redirection service

We’ve been told by several customers that when working in a team, pointing mobile devices to the Ghostlab server can be cumbersome. Of course, in order to avoid having to enter the URL on every one of them each time (which is slow even using the provided QR Code), they had bookmarked the Ghostlab server URL on every device. but: which URL? Several developers means several computers means several IP addresses – so each developer has a different (and potentially changing) IP address and the device bookmark will ever so often point to the wrong URL.

The idea of the redirection service is simple. A redirection bookmark is just a URL, looking something like http://302.pm/ABC677. It redirects to an IP address in your local network, like http://192.168.2.3:8005. The redirection bookmark has an access token, and using that access token, Ghostlab is able to update the redirection bookmark to the current IP and port where Ghostlab runs. When on a device, you access the bookmark, you will always be redirected to the up-to-date Ghostlab address. This way, you can either share redirection bookmarks within a team (by sharing the access token), or simply create your individual and permanent Ghostlab URL for your devices to use.

Enough said. Give it a spin!

So much from us. You can have a look at the Ghostlab website, where you can download a full-featured and completely free 7-day trial!

The post Ghostlab 2 is here appeared first on vanamco.com.

]>
https://www.vanamco.com/2015/03/18/ghostlab-2-is-here/feed/ 11
Inside Ghostlab Podcast https://www.vanamco.com/2014/12/10/inside-ghostlab-podcast/ Wed, 10 Dec 2014 16:56:27 +0000 http://blog.vanamco.com/?p=890 This month Andi (one of the brains behind Ghostlab App) got the chance to be a guest on responsivedesign.is podcast. He talks about what we do at Vanamco, coming into web design from a industrial design background, Ghostlab App and the open source wrapper Zephyros we use for it and all thing responsive. Enjoy     Your browser does not […]

The post Inside Ghostlab Podcast appeared first on vanamco.com.

]>
This month Andi (one of the brains behind Ghostlab App) got the chance to be a guest on responsivedesign.is podcast. He talks about what we do at Vanamco, coming into web design from a industrial design background, Ghostlab App and the open source wrapper Zephyros we use for it and all thing responsive.

Enjoy

 

 

 

Transcripts and links can be found on http://responsivedesign.is/articles/rwd-podcast-episode-27-andi-dysart
Inside Ghostlab Podcast

The post Inside Ghostlab Podcast appeared first on vanamco.com.

]>
IndexedDB fundamentals – Plus a indexeddb example – tutorial https://www.vanamco.com/2014/11/14/indexeddb-fundamentals-plus-a-indexeddb-example-tutorial/ https://www.vanamco.com/2014/11/14/indexeddb-fundamentals-plus-a-indexeddb-example-tutorial/#comments Fri, 14 Nov 2014 13:21:18 +0000 http://blog.vanamco.com/?p=479 IndexedDB is a relatively fresh NOSQL database implemented in modern browsers. In this blog post I’m going to show you how to perform some basic operations with it. The tutorial has been optimised for use with Google’s latest Chrome browser. In Chrome’s developer tools, IndexedDB can be found in the Resources tab. For the moment, […]

The post IndexedDB fundamentals – Plus a indexeddb example – tutorial appeared first on vanamco.com.

]>
IndexedDB is a relatively fresh NOSQL database implemented in modern browsers. In this blog post I’m going to show you how to perform some basic operations with it. The tutorial has been optimised for use with Google’s latest Chrome browser.

In Chrome’s developer tools, IndexedDB can be found in the Resources tab. For the moment, any changes to your IndexedDB databases aren’t automatically visible in the developer tools – you have to either refresh the page or right-click on “IndexedDB” in the Resources tab and choose “Refresh IndexedDB”.

After two short general remarks, we’ll dive right into the code!

Limits
IndexedDB has no hard storage limits on it’s own. However, browser vendors have soft limits. Firefox will ask for permission to store blobs bigger than 50 MB. Google Chrome has various limits for different use cases, for more information about Chrome limits see https://developers.google.com/chrome/whitepapers/storage

Fallback
For older browsers that don’t support IndexedDB, you can use IndexedDBShim. It allows WebSQL (which is no longer developed) to handle IndexedDB API calls when they are not present in the browser. Available at https://github.com/axemclion/IndexedDBShim.

Creating, dropping and retrieving databases

Firefox does not prefix IndexedDB, Chrome had prefixed it for a while but now no longer does it, and Internet Explorer uses an MS vendor prefix. To achieve compatibility across browsers, you might want to use the declaration solution below.


var indexedDB = window.indexedDB || window.webkitIndexedDB || window.msIndexedDB;
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
var openCopy = indexedDB && indexedDB.open;

var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;

if (IDBTransaction)
{
IDBTransaction.READ_WRITE = IDBTransaction.READ_WRITE || 'readwrite';
IDBTransaction.READ_ONLY = IDBTransaction.READ_ONLY || 'readonly';
}

Remember IndexedDB is a NoSQL database, so it doesn’t contain tables, but object stores. Object stores contain data in the form <key, value> – where the value can be a simple string or a complex object. To create your first database, simply attempt to open it. Since it doesn’t exist yet, the upgradeneeded event will be triggered – which you handle in order to create your object store(s). Notice that whenever you want to modify your databases object store, you need to do this by increasing the version number of your database – the version upgrade will again trigger the upgradeneeded event, which you can handle to make the necessary modifications. To open a database indicating that you want to create a new version, simply add the version number as the second parameters to your indexedDb.open() call. Dropping a database is straightforward.


/***
* Create database snippet
* */
var request = indexedDB.open('todos');

request.onupgradeneeded = function(e)
{
// e is an instance of IDBVersionChangeEvent
var idb = e.target.result;

if (idb.objectStoreNames.contains('todo'))
{
idb.deleteObjectStore('todo');
}

var store = idb.createObjectStore('todo', {keyPath: 'text', autoIncrement: true});
// createIndex operations possible to be pefromed on store.createIndex
store.createIndex('by_todo', 'todo', {unique: true, multiEntry: false});
};

request.onsuccess = function(e) { /* add, update, delete, ... */ };
request.onerror = function(e) { /* handle error */ };

/***
* Remove database snippet
* */
var dropDatabase = function(name)
{
var request = indexedDB.deleteDatabase(name);
request.onsuccess = function() { /* drop succeeded */ };
request.onerror = function() { /* drop failed */ };
};

If you want to programatically find out which databases are available, you are currently limited to webkit (other browsers don’t offer such a method). Note that IndexedDB follows a same-origin policy – so you won’t be able to read databases from domains other than your own.


indexedDB.webkitGetDatabaseNames().onsuccess = function(e)
{
var databaseNames = [];
for (var i = 0, l = e.target.result.length; i < l; i++)
databaseNames.push(e.target.result[i]);
};

Creating records

Adding a record to object store requires creating a “readwrite” transaction, as demonstrated below. If your browser supports IndexedDB, you can populate a database with a todo object store and some example entries by clicking the button below the code sample. Make sure you have your dev tools open so that you can see what is going on on the database.


var request = indexedDB.open('todos');

request.onsuccess = function(e)
{
var idb = e.target.result;
var trans = idb.transaction('todo', IDBTransaction.READ_WRITE);
var store = trans.objectStore('todo');

// add
var requestAdd = store.add({text: 'Go to Coop', todo: 'Groceries'});

requestAdd.onsuccess = function(e) {
// do something
};

requestAdd.onfailure = function(e) {
// failed
};
};

Retrieving records

You can retrieve records in a read-only transaction. For iterating over all entries in an object store, simply use the openCursor function. If you have previously chosen to add the six predefined todo entries to the demo store, you can retrieve them using the button below the code.


var request = indexedDB.open('todos');
request.onsuccess = function(e)
{
idb = e.target.result;
var transaction = idb.transaction('todo', IDBTransaction.READ_ONLY);
var objectStore = transaction.objectStore('todo');

objectStore.openCursor().onsuccess = function(event)
{
var cursor = event.target.result;
if (cursor)
{
console.log('Cursor data', cursor.value);
cursor.continue();
}
else
{
console.log('Entries all displayed.');
}
};
};

When opening a cursor to the object store, you can specify various parameters for limiting the scope of the cursor. The following examples demonstrate several of these constraints. Again, if you have chosen to use the build-in demo via the buttons, you can continue to do so for every code example.

The interface we are using to apply constraints to our cursor is IDBKeyRange. When specifying bounds, you can indicate if you want them to be open (excluding the endpoint values, pass true) or closed (including the endpoint values, pass false – this is the default). For in-depth information refer to the documentation on the Mozilla Developer Network.


...
// Retrieve all records after and including 'Groceries' key
var cursor = IDBKeyRange.lowerBound('Groceries', false);
objectStore.openCursor(cursor).onsuccess = function(event)
...


...
// Retrieve all records up to and including 'Groceries' key
var cursor = IDBKeyRange.upperBound('Groceries', false);
objectStore.openCursor(cursor).onsuccess = function(event)
...


...
// Retrieve all records between 'Bills' and 'Flat' keys (inclusive)
var cursor = IDBKeyRange.bound('Bills', 'Flat', false, false);
objectStore.openCursor(cursor).onsuccess = function(event)
...


...
// Retrieve only the record matching the 'FeedTheDog' key
var cursor = IDBKeyRange.only('FeedTheDog');
objectStore.openCursor(cursor).onsuccess = function(event)
...

 

Editing data

To edit or delete records on a database, you will need to create a read-write transaction. The following examples show you how you can edit a record (basically, retrieve it and update it via the object store’s put method) and delete a record (calling delete on the object store and passing the key). If you have populated the demo database using the buttons before, you can now edit and delete these records using the buttons below the code.


// Editing a record
var editRecord = function(key, newValue) {
var request = indexedDB.open('todos');
request.onsuccess = function(e)
{
var idb = e.target.result;
var objectStore = idb.transaction('todo', IDBTransaction.READ_WRITE).objectStore('todo');
var request = objectStore.get(key);

request.onsuccess = function(ev)
{
var data = ev.target.result;
var editDivEl = document.querySelector('#editRecordDiv');

if (data === undefined)
{
editDivEl.innerHTML = 'Key doesnt exist or has been previously' +
'removed';
return;
}

data.text = newValue;
var result = objectStore.put(data);

result.onsuccess = function(ev)
{
var todoName = ev.target.result;
editDivEl.innerHTML = 'Successfully edited key <b>' +
todoName + '</b>';
};

result.onerror = function(ev)
{
console.log('Error occured', ev.srcElement.error.message);
};
};

request.onerror = function(ev)
{
console.log('Error occured', ev.srcElement.error.message);
};
};
};

var reminderDate = new Date();
editRecord('Bills', 'Reminder ' + reminderDate.getHours() + ':' + reminderDate.getMinutes() +
':' + reminderDate.getSeconds());


// Deleting a record
var request = indexedDB.open('todos');
request.onsuccess = function(e)
{
var idb = e.target.result;
var objectStore = idb.transaction('todo', IDBTransaction.READ_WRITE).objectStore('todo');
var request = objectStore.delete('Bills');

request.onsuccess = function(ev)
{
console.log(ev);
};

request.onerror = function(ev)
{
console.log('Error occured', ev.srcElement.error.message);
};
};

Limiting queries

As a final example in this tutorial, I want to show you a way of limiting the number of results returned by a query. IndexedDB doesn’t provide a straightforward method for limiting and grouping database results. Therefore, I have created a simple helper function that helps us limiting the number of records retrieved by a query. Note that in such a context, the IDBCursor.advance method might come in handy, as it lets you skip retrieved records. In the example below, we abort the transaction once the indicated limit has been reached.


/***
* IndexedDB limit output syntax similar to LIMIT 10, 5;
* */
var limitRecords = function(pageSize, skipCount)
{
var request = indexedDB.open('todos');

request.onsuccess = function(e)
{
idb = e.target.result;
var transaction = idb.transaction('todo', IDBTransaction.READ_ONLY);
var objectStore = transaction.objectStore('todo');
var idx = 0;

objectStore.openCursor().onsuccess = function(e)
{
var cursor = e.target.result;
if (cursor)
{
if (skipCount <= idx && idx < pageSize + skipCount)
console.log('Cursor is in the range ', cursor);

idx++;

if (idx >= pageSize + skipCount + 1)
{
// we have all data we requested
// abort the transaction
transaction.abort();
} else {
// continue iteration
cursor.continue();
}
}

};
};
};

Done.

We hope you’ve enjoyed this little tutorial! Of course, there is much more to IndexedDB than what we have covered here – this was just to get you started!









The post IndexedDB fundamentals – Plus a indexeddb example – tutorial appeared first on vanamco.com.

]>
https://www.vanamco.com/2014/11/14/indexeddb-fundamentals-plus-a-indexeddb-example-tutorial/feed/ 1
I love my team – Convince your boss to buy the Device Lab https://www.vanamco.com/2014/11/07/i-love-my-team/ Fri, 07 Nov 2014 11:47:22 +0000 http://blog.vanamco.com/?p=682 One of our biggest client sectors are agencies, they kitting out in-house developers with our complete testing solution called the Agency package. Even though they sell well and the package suites the agencies, developers working for these agencies keep asking us for a little help to convince the boss that they need this tool. Below are only a few reasons why you need […]

The post I love my team – Convince your boss to buy the Device Lab appeared first on vanamco.com.

]>
One of our biggest client sectors are agencies, they kitting out in-house developers with our complete testing solution called the Agency package. Even though they sell well and the package suites the agencies, developers working for these agencies keep asking us for a little help to convince the boss that they need this tool.

Below are only a few reasons why you need the Device Lab and we have also packaged them into a PDF: Convince your Boss PDF

 

1_ Bring order to chaos

Instead of having mobile devices floating around in your office, establish a professional setup with one or several mobile testing stations that keep your devices systematically organized, easily available and readily charged.

2_ Speed up your development

The Device Lab helps you go from landscape to portrait on all attached devices in two seconds – simply turn it around on your table (it has a small footprint) and you’re all set! Plus, you’re looking at your devices like if they were a display – that means you won’t have to clumsily switch from operating keyboard and mouse to holding your 599$ device.

3_ Don’t miss out on bugs

By keeping a full mobile testing environment readily available for everyone, there’s no excuse for not testing your projects on the platforms you require. For your developers, mobile testing will become easy and hassle-free, since they can simply grab the lab and have a go!

4_ Circulate your Lab

The Device Lab is portable, so once you’ve set it up, it is not bound to a specific desk. Any developer can simply pick it up and take it to her workplace, then pass it on once she’s done testing.

5_ Impress your clients

Show your clients you mean business with your responsive strategy and explain to them how awesome mobile testing has become since introducing the Device Lab. They will be thrilled when they see all their target platforms lined up and ready for testing in a stylish manner!

6_ Add some style

Besides saving you a great deal of time and hassle, the Device lab stands proud and stylish on any developers desk. You don’t develop your awesome projects on a rusty 486 computer either, right?

7_ Make a testing statement

Ever thought about why your developers miss out on testing for mobile platforms? It’s not because they’re lazy, it’s because they lack infrastructure. Invest into your Device lab and show your people that after building the latest and greatest of frontend fancy, it’s just as important to make sure it actually works!

 

I love my team you say? Show them!

How has the Device Lab helped you? Let me know in the comments below

 

The post I love my team – Convince your boss to buy the Device Lab appeared first on vanamco.com.

]>
Responsive web design tutorial – infographic – 8 reasons to use responsive web design https://www.vanamco.com/2014/09/19/responsive-web-design-tutorial/ Fri, 19 Sep 2014 11:22:03 +0000 http://blog.vanamco.com/?p=445 Responsive web design tutorial - infographic - 8 reasons to use responsive web design

The post Responsive web design tutorial – infographic – 8 reasons to use responsive web design appeared first on vanamco.com.

]>
 

In this responsive web design tutorial we look at a cool infographic

8 reasons to use responsive web design

 

The post Responsive web design tutorial – infographic – 8 reasons to use responsive web design appeared first on vanamco.com.

]>
Javascript Quiz. And the winner is… https://www.vanamco.com/2014/08/26/javascript-quiz-winner/ https://www.vanamco.com/2014/08/26/javascript-quiz-winner/#comments Tue, 26 Aug 2014 09:44:58 +0000 http://blog.vanamco.com/?p=433 We have recently collaborated with Chris Coyier from CSS-Tricks.com, and designed a Javascript quiz that challenged hundreds of developer to compete with each other in order to win a free Ghostlab license. Of all the entries we are proud to say that the winner is…. Sérgio Lopes! Let’s congratualate Sérgio for getting all the questions […]

The post Javascript Quiz. And the winner is… appeared first on vanamco.com.

]>

We have recently collaborated with Chris Coyier from CSS-Tricks.com, and designed a Javascript quiz that challenged hundreds of developer to compete with each other in order to win a free Ghostlab license.

Of all the entries we are proud to say that the winner is….

Sérgio Lopes!

Let’s congratualate Sérgio for getting all the questions right and who has been awarded with a free Ghostlab license.

We wish great success to Sérgio and to all the other developers who participated. Keep up the great work guys and keep being awesome.

In a short interview we were happy to get to know Sérgio a bit more and we want to share it with you too.

Tell us a bit about your career

I’m a Brazilian programmer focused on Front-end development. My career started 15 years ago and my first coding was in HTML. After that, came PHP and Java (at that time, if you want to be a “real programmer” you needed to focus on Back-end). With the advent of HTML5 and Front-end getting more attention, I refocused my career. Nowadays, I’m very passionate about HTML, CSS and JavaScript, specially mobile challenges, responsive web design and front-end performance.

What’s the future of responsive web design?

I strongly believe in responsive web design to solve the problems this new multi device world imposes. Some argue that a specific mobile experience is better than RWD. The problem today is now to define “mobile”. We have a wide range of devices and there are no clear lines to define device categories. If you try to draw this line, you will get it wrong and maybe exclude a lot of devices. I believe RWD (and its evolutions) is the only solution to target so many devices today and in the future.

What are the top 3 most referred resources or books you recommend to people?

My list is a very unstable one. I change it a lot. Today, I would recommend Mobile-first by Luke Wroblewski, High Performance Browser Networking by Ilya Grigorik and The Mobile Book by Smashing Magazine. I also recommend my book The Mobile Web, programming for a multi device world, which was initially release in Portuguese in Brazil and now is also available in English.

What are your 80/20 principles in business and life?

I think you should spend your time with things you are passionate about, that make you a better person. Both in business and life. Those moments should be at least 80% of your life.

What do you recommend to do if somebody wants to begin a career in front-end development?

To code a lot. You will only be good at this if you write a lot of code. You should study and read a lot of course, but I think practice is the most important factor.

What are your tools of choice, software?

A Mac with Sublime Text and Chrome Canary represents 90% of my time working. Other important softwares in my workflow include Pixelmator, ImageOptim, ImageAlpha and JPEGmini. For task automation I’m a huge grunt fan.

Who are your mentors & the people you admire in the industry?

My mentors are all the people that work in Caelum, where I work. I started here 10 years ago as an intern and learned a lot from everybody here since then. And I admire many people in our fantastic industry. To name a few: Brad Frost, Ilya Grigorik, Peter-Paul Koch, Luke Wroblewski.

What blogs do you read?

I read too many blogs (currently 250 feeds on my feedly account!). A few ones I read as soon as the author publishes something new. I love QuirksBlog, PerfPlanet (which aggregates great blogs about performance), MobileXWeb, Dev.Opera, HTML5Rocksgetblog, igvita, insouciant, A List Apart.

What are your long term personal and business plan?

I intend to work in my current company for many years to come. We are a education company in Brazil with programming training (I teach front-end and mobile), online classes and a book publisher. My plan is to help the company grow to new areas and continue improving IT education in Brazil. Personally, I will keep focusing on Web development. I love to write and want to write other books (already have published 3 books in Portuguese and 1 in English).

We want to thank Sèrgio again and everybody who took part of the Javascript quiz.

If you would like to connect with Sérgio you can find him here:

Twitter

Website

Stay tuned for the next challenge.

The Vanamco team.

 

The post Javascript Quiz. And the winner is… appeared first on vanamco.com.

]>
https://www.vanamco.com/2014/08/26/javascript-quiz-winner/feed/ 1
Web Design Inspiration – Collective #4 https://www.vanamco.com/2014/08/18/web-design-inspiration-collective-4/ https://www.vanamco.com/2014/08/18/web-design-inspiration-collective-4/#comments Mon, 18 Aug 2014 14:09:55 +0000 http://blog.vanamco.com/?p=421 A collection of discoveries from the web design & web development community, curated by the Vanamco team. Enjoy it! 1) Web Design Inspiration Jumo Jumo is not only a super cool lamp but a great way to showcase a product via the web. Get inspired! 2) Development Roots Roots is a toolkit built on best practices […]

The post Web Design Inspiration – Collective #4 appeared first on vanamco.com.

]>

A collection of discoveries from the web design & web development community, curated by the Vanamco team. Enjoy it!

1) Web Design Inspiration

Jumo

Jumo is not only a super cool lamp but a great way to showcase a product via the web. Get inspired!

2) Development

Roots

Roots is a toolkit built on best practices for advanced front-end web development.

3) Industry

Sidebar

The 5 best design links, everyday

4) Resource

Principles of writing conistent, idiomatic HTML

Style guide for HTML development made easy.

5) Design

Fonts

A collection of pretty cool fonts from Abduzeedo.

 

If you enjoyed this collective, sign up below to receive a weekly one. You won’t regret it.

The Vanamco team.

The post Web Design Inspiration – Collective #4 appeared first on vanamco.com.

]>
https://www.vanamco.com/2014/08/18/web-design-inspiration-collective-4/feed/ 1