Codeception Acceptance tests with Javascript

I had an issue on this old legacy site in work where I was writing a basic acceptance test where it clicks all the links in the top section of the home page. The problem was that one of the links opened another window using JavaScript. So I had to reconfigure Codeception to get it running.

There are various different drivers that codeception uses, PhpBrowser which doesn’t do JS, Selenium WebDriver does, and you have several options; you could install Selenium, chrome headless browser, or phantomjs. I chose phantomjs, as it was easiest (for me) to get up and running on a non X Server.

First up, you’ll need phantomjs. Go download it, unpack the zip, move the folder somewhere, and then symlink the bin/phantomjs to /usr/bin/phantomjs.

Next, launch phantomjs like so:

phantomjs --webdriver=4444 --ignore-ssl-errors=true --ssl-protocol=any

Now, in your YAML:

# Codeception Test Suite Configuration

# suite for acceptance tests.
# Run the following command FIRST:
# phantomjs --webdriver=4444 --ignore-ssl-errors=true --ssl-protocol=any

# RUN `build` COMMAND AFTER ADDING/REMOVING MODULES.

class_name: WebGuy
modules:
     enabled:
         - WebDriver
         - WebHelper
     config:
         WebDriver:
             url: 'https://USER:PASS@YOUR_URL_HERE'
             browser: phantomjs
             capabilities:
                 acceptSslCerts: true

If you have a site using HTTP Basic Auth, put USER:PASSWORD@ in yopur URL, if not, remove it.

Now in your acceptance test, you can write:

$i->click('Nouvel abonnement');
$i->switchToWindow('webformswin');

Note that, in your Javascript, when you run the open window function, you specify a name. This is the name you use, and not the title from the HTML <head> section!

And there you have it! We can now test with javascript functionality!

Advertisements

Adding CSS & Javascript to Magento Themes

There is an XML configuration folder located in app/design/frontend/PROJECT/THEME/layout. The main one is called page.xml. Within there, you add JS resources you do it like this:

<action method="addJs"><script>madskull/cookie/jquery.cookiebar.js</script></action>

When you add Css, you add it like this:

<action method="addCss"><stylesheet>css/styles.css</stylesheet></action>

Magento does some stuff in the background and auto tries to put you in the /js dir. There is a third way called addItem:

<action method="addItem"><type>skin_css</type><name>css/styles-ie.css</name><params/><if>lt IE 8</if></action>

You can say skin_css or skin_js, and it will set the path for the module.

Apparently, adding files stored in say bower_components just won’t work. The solution is either to hardcode the html into the head.phtml file (which they dont recommend), symlink the bower library to the JS folder you require, or just dont use bower and copy it straight in to your theme. lternatively, there is a class written by some guy that extends Mage_Page_Block_Html_Head. He hasn’t put it on Github, which I’m  uneasy with (I like stuff on Github and versioned!) but in the meantime you can get it here https://inchoo.net/magento/how-to-add-external-javascript-css-file-to-magento/

Debug compiled CSS and JS in Firefox using sourcemaps

If you haven’t used sourcemaps, now is the time!

With the advent of compiled CSS like LESS or SASS, or minified/uglified JS, it makes debugging awkward as you cant see the original lines of code that you wrote. Cue CTRL_F’ing to find that line to tweak! But not any more!

When you generate your LESS/SASS, if you tell it to compile a sourcemap too, it will create one! This allows your browser to report which line of the less or scss file the rule in question came from.

For the Less compiler command, you have several options:

--source-map[=FILENAME]  Outputs a v3 sourcemap to the filename (or output filename.map)
--source-map-rootpath=X  adds this path onto the sourcemap filename and less file paths
--source-map-basepath=X  Sets sourcemap base path, defaults to current working directory.
--source-map-less-inline puts the less files into the map instead of referencing them
--source-map-map-inline  puts the map (and any less files) into the output css file
--source-map-url=URL     the complete url and filename put in the less file

For Sass, you just add the option at the end of the command:

sass sass/screen.scss:stylesheets/screen.css --sourcemap

Now in Firefox, open your page, right click, and click Inspect Element (not the Firebug one, the default Firefox Inspector!)

In the CSS rules pane, right click, and make sure show original sources is checked.

Screen Shot 2015-05-18 at 16.57.27 (2)

To the right of the actual rule, you click the link which would usually take you to the CSS file for viewing, but now, it takes you to your Less/Sass file! You can now tweak rules and save them directly from the inspector!

Screen Shot 2015-05-18 at 17.01.11

In my new workplace, our SASS files are compiled by Gulp automatically. (In my last work I had lessc configured in PHPStorm). If your own files are automatically built, then you should also checkout Firefox addons for live reloading! The great thing about that is that the CSS files update without refreshing! Great if you have session info or other info that might need reinstantiating, you dont have to keep keying stuff in! Have fun!

Priniting another URL via Javascript

This is remarkably easy! Create an with = hidden class and the source being your other page.

Then, create an tag with an onclick event listener:

<a class="btn" onclick="frames['frame'].print()">Print</a>

That’s it!

NB. WordPress doesn’t seem to allow iframe code at all! So without the < or > tags, It’s iframe src=”/your/url/to/print” name=”frame” class=”hide”

jQuery UI Datepickers with Bootstrap Modals

If you’re here, that’s probably because you just put a datepicker into a bootstrap modal, but realised that the Year dropdown isn’t working properly, and when you click it, nothing appears to happen.

Luckily, it’s quite easy to fix. After initialising your element with

$('#mytextbox').datepicker({//options here});

All that is required is to paste this line of code, which does something regarding javascript’s dom focus :

$.fn.modal.Constructor.prototype.enforceFocus = function() {}

Job done! You can get back on with your work now! 🙂

Geolocate your visitors!

Right now I’m building a mobile app using Intel’s AppFramework for a single page site, and Apigility for the API.

In the app, there is an autosuggest for towns and postcodes, however I thought it would be nice to have a “Locate Me” button, able to pinpoint your visitor (hopefully with a decent degree of accuracy!), so I Googled away and found the following:

https://github.com/estebanav/javascript-mobile-desktop-geolocation

In your site go into your js folder and clone the repo:

cd js
git clone git@github.com:estebanav/javascript-mobile-desktop-geolocation.git

In your page you’ll include the scripts and add your functionality as required:

<script src="js/javascript-mobile-desktop-geolocation/js/geoPosition.js" type="text/javascript" charset="utf-8"></script>
 <script src="js/javascript-mobile-desktop-geolocation/js/geoPositionSimulator.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
if(geoPosition.init())
 { 
    // Geolocation Initialisation
    geoPosition.getCurrentPosition(success_callback,error_callback,    {enableHighAccuracy:true});
 }
 else
 {
    // You cannot use Geolocation in this device
 }
 geoPositionSimulator.init();
// p : geolocation object
 function success_callback(p)
 {
    // p.latitude : latitude value
    // p.longitude : longitude value
    console.log(p);
 }
function error_callback(p)
 {
    // p.message : error message
    console.log(p);
 }
</script>

Now if you load your page and go into the web inspector, hopefully you should have some coordinates!

The next part of the puzzle is where it gets interesting: How to find the closest match in your table of areas, postcodes, and lat longs!

I would never have figured this out, but there is an equation called the Haversine formula, which uses spherical trigonometry to calculate areas within a certain distance! It looks like this:

R = earths radius (mean radius = 6,371km)
Δlat = lat2 lat1
Δlong = long2 long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1a))
d = R.c
Angles need to be in radians to pass to Trigonometric functions

http://en.wikipedia.org/wiki/Haversine_formula

Here’s my actual query itself:

SELECT *, 
 ( 3959 * acos( cos( radians(55.864237) ) * cos( radians( latitude ) ) 
 * cos( radians( longitude ) - radians(-4.251806) ) + sin( radians(55.864237) ) 
 * sin( radians( latitude ) ) ) ) AS distance 
FROM postcodes HAVING distance < 20 
ORDER BY distance LIMIT 1;

Here I check for any area within 20 miles, but you can make this as short or long as you want.  The 3959 figure at the start of the query is the number used for miles, if you are using kilometres you should change this number to 6371.  I have limited it to 1 row, as I only want the closest match, however you may want to change this in other situations!

So there we have it! NSA-like spying on your visitors! (With their permission of course!)

jQuery Form Submit Handling with Return Key

If you have ever done any stuff with jquery/javascript that redirects you upon submitting a form, you’ll have noticed that the return key slips through the net and doesn’t obviously trigger the click event.
I’ve dealt with this nonsense plenty of times but i always end up hunting through my code to find it again. So to spare my sanity, I’m putting it here!

$('#submit').click(function(e){
 e.preventDefault();
 var name = $('#search').val();
 window.location.href = '/some/url/'+name;
 });
$("#search").keyup(function(event){
 if(event.keyCode == 13){
 $("#submit").click();
 }
 });