summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintrc25
-rw-r--r--.gitignore3
-rw-r--r--CHANGELOG.md110
-rw-r--r--gulpfile.js195
-rw-r--r--jquery.matchHeight.js5
-rw-r--r--package.json10
-rw-r--r--test/conf/cloud-all.conf.js175
-rw-r--r--test/conf/cloud.conf.js69
-rw-r--r--test/conf/local.conf.js43
-rw-r--r--test/conf/wdio.conf.js24
-rw-r--r--test/page/img/800x150.pngbin0 -> 8159 bytes
-rw-r--r--test/page/img/800x180.pngbin0 -> 8740 bytes
-rw-r--r--test/page/img/800x200.pngbin0 -> 9770 bytes
-rw-r--r--test/page/img/800x220.pngbin0 -> 10735 bytes
-rw-r--r--test/page/lib/jasmine-2.3.4/boot.js12
-rw-r--r--test/page/test.html12
-rw-r--r--test/specs/matchHeight.spec.js243
-rw-r--r--test/specs/webdriver.spec.js85
18 files changed, 879 insertions, 132 deletions
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..9785b3d
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,25 @@
+{
+ "rules": {
+ "indent": [
+ 2,
+ 4
+ ],
+ "quotes": [
+ 2,
+ "single"
+ ],
+ "linebreak-style": [
+ 2,
+ "windows"
+ ],
+ "semi": [
+ 2,
+ "always"
+ ]
+ },
+ "env": {
+ "browser": true,
+ "jquery": true
+ },
+ "extends": "eslint:recommended"
+} \ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 7dc4f0e..9d1abd4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.idea
-node_modules \ No newline at end of file
+node_modules
+private.conf.js \ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8f3c185..07036f5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,7 @@
-# jquery.matchHeight.js Changelog
+<a name="0.6.0"></a>
+# 0.6.0 (2015-03-31)
-[brm.io/jquery-match-height](http://brm.io/jquery-match-height/)
-
-----------
-
-## 0.6.0
+### release summary
- added options parameter
- added `property` option
@@ -23,14 +20,78 @@
- fixed Safari row detection
- fixed inline style preservation
-## 0.5.2
+### commit log
+
+* Fix usage of data-mh attribute ([816850d](https://github.com/liabru/jquery-match-height/commit/816850d))
+* Improve support when concatenated or minified ([09c4b1a](https://github.com/liabru/jquery-match-height/commit/09c4b1a))
+* Merge branch 'kwoodfriend-patch-1' ([dde46f9](https://github.com/liabru/jquery-match-height/commit/dde46f9))
+* Merge branch 'nyordanov-master' ([dc77dbe](https://github.com/liabru/jquery-match-height/commit/dc77dbe))
+* Merge branch 'patch-1' of https://github.com/kwoodfriend/jquery-match-height into kwoodfriend-patch- ([e009c4c](https://github.com/liabru/jquery-match-height/commit/e009c4c))
+* Merge branch 'stefanozoffoli-patch-1' ([c0104c4](https://github.com/liabru/jquery-match-height/commit/c0104c4))
+* Preserve inline styles when using byRow ([72ba5cf](https://github.com/liabru/jquery-match-height/commit/72ba5cf))
+* added display property tests ([5dafa0c](https://github.com/liabru/jquery-match-height/commit/5dafa0c))
+* added gitignore ([d76b02c](https://github.com/liabru/jquery-match-height/commit/d76b02c))
+* added local jquery ([9239f4e](https://github.com/liabru/jquery-match-height/commit/9239f4e))
+* added maintainScroll functionality, closes #18 ([ee83317](https://github.com/liabru/jquery-match-height/commit/ee83317)), closes [#18](https://github.com/liabru/jquery-match-height/issues/18)
+* added support for hidden elements, closes #12 ([9a8944b](https://github.com/liabru/jquery-match-height/commit/9a8944b)), closes [#12](https://github.com/liabru/jquery-match-height/issues/12)
+* added support for options, added property option for min-height ([94c9d28](https://github.com/liabru/jquery-match-height/commit/94c9d28))
+* added update callback events ([0b31e21](https://github.com/liabru/jquery-match-height/commit/0b31e21))
+* avoid call to .is when no target specified ([db9996d](https://github.com/liabru/jquery-match-height/commit/db9996d))
+* changed master build description ([6dcc13d](https://github.com/liabru/jquery-match-height/commit/6dcc13d))
+* early out on options parser ([b4326d3](https://github.com/liabru/jquery-match-height/commit/b4326d3))
+* fix for single item rows, closes #48 ([64b9a54](https://github.com/liabru/jquery-match-height/commit/64b9a54)), closes [#48](https://github.com/liabru/jquery-match-height/issues/48)
+* fix handling of hidden elements by row, closes #28 ([71a5151](https://github.com/liabru/jquery-match-height/commit/71a5151)), closes [#28](https://github.com/liabru/jquery-match-height/issues/28)
+* fix row detection on safari (windows) ([b52448a](https://github.com/liabru/jquery-match-height/commit/b52448a))
+* fix to preserve inline styles ([e9de702](https://github.com/liabru/jquery-match-height/commit/e9de702))
+* fix typo in target option, closes #63 ([290dfcf](https://github.com/liabru/jquery-match-height/commit/290dfcf)), closes [#63](https://github.com/liabru/jquery-match-height/issues/63)
+* fixed IE8 border reset issue, closes #10 ([246820d](https://github.com/liabru/jquery-match-height/commit/246820d)), closes [#10](https://github.com/liabru/jquery-match-height/issues/10)
+* fixed support for inline-block ([b3df801](https://github.com/liabru/jquery-match-height/commit/b3df801))
+* fixed throttling issue ([fdc8f7a](https://github.com/liabru/jquery-match-height/commit/fdc8f7a))
+* implemented target option ([a01fb70](https://github.com/liabru/jquery-match-height/commit/a01fb70))
+* improved readme ([9ba9529](https://github.com/liabru/jquery-match-height/commit/9ba9529))
+* preserve inline styles on hidden parents, closes #46 ([4917d6c](https://github.com/liabru/jquery-match-height/commit/4917d6c)), closes [#46](https://github.com/liabru/jquery-match-height/issues/46)
+* refactored plugin definition ([467d928](https://github.com/liabru/jquery-match-height/commit/467d928))
+* release 0.6.0 ([aef80df](https://github.com/liabru/jquery-match-height/commit/aef80df))
+* removed redundant css setter ([6c7e6ad](https://github.com/liabru/jquery-match-height/commit/6c7e6ad))
+* reorganised source, closes #27 ([cae21cd](https://github.com/liabru/jquery-match-height/commit/cae21cd)), closes [#27](https://github.com/liabru/jquery-match-height/issues/27)
+* skip apply to rows with only one item ([f72ab91](https://github.com/liabru/jquery-match-height/commit/f72ab91))
+* updated min file ([56214a1](https://github.com/liabru/jquery-match-height/commit/56214a1))
+* updated min file ([9aa96f1](https://github.com/liabru/jquery-match-height/commit/9aa96f1))
+* updated min file ([b6f612a](https://github.com/liabru/jquery-match-height/commit/b6f612a))
+* updated min file ([128c363](https://github.com/liabru/jquery-match-height/commit/128c363))
+* updated readme ([667e516](https://github.com/liabru/jquery-match-height/commit/667e516))
+* updated readme ([a30551f](https://github.com/liabru/jquery-match-height/commit/a30551f))
+* updated readme with known limitations ([57ee64a](https://github.com/liabru/jquery-match-height/commit/57ee64a))
+* updating minified version ([ab3963f](https://github.com/liabru/jquery-match-height/commit/ab3963f))
+
+
+
+<a name="0.5.2"></a>
+## 0.5.2 (2014-06-10)
+
+### release summary
- improved demo
- added matchHeight('remove')
- added update throttling
- removed forced `display:block` after application
-## 0.5.1
+### commit log
+
+* added matchHeight('remove') ([8f5f13f](https://github.com/liabru/jquery-match-height/commit/8f5f13f))
+* added updated throttling ([6d9a6a7](https://github.com/liabru/jquery-match-height/commit/6d9a6a7))
+* prettier demo ([f7ea426](https://github.com/liabru/jquery-match-height/commit/f7ea426))
+* release 0.5.2 ([4b8f8e4](https://github.com/liabru/jquery-match-height/commit/4b8f8e4))
+* removed forced `display:block` after application ([a3a058c](https://github.com/liabru/jquery-match-height/commit/a3a058c))
+* updated changelog ([ecee5f9](https://github.com/liabru/jquery-match-height/commit/ecee5f9))
+* updated readme, changelog, build ([ae0a825](https://github.com/liabru/jquery-match-height/commit/ae0a825))
+
+
+
+<a name="0.5.1"></a>
+## 0.5.1 (2014-04-15)
+
+### release summary
- fixed IE8 NaN bug when parsing 'auto' properties
- fixed IE8 window resize event loop bug
@@ -38,6 +99,35 @@
- added bower package file
- added jquery package file
-## 0.5.0 - 2014-03-02
+### commit log
+
+* Making the library compatible with old jQuery versions < 1.7 ([4c3f945](https://github.com/liabru/jquery-match-height/commit/4c3f945))
+* Making the library compatible with old jQuery versions < 1.7 ([7d467aa](https://github.com/liabru/jquery-match-height/commit/7d467aa))
+* Merge pull request #3 from dcorb/master ([18a6fa1](https://github.com/liabru/jquery-match-height/commit/18a6fa1))
+* added CHANGELOG ([b1ed72d](https://github.com/liabru/jquery-match-height/commit/b1ed72d))
+* added bower package ([56c9902](https://github.com/liabru/jquery-match-height/commit/56c9902))
+* added minified version ([44c4554](https://github.com/liabru/jquery-match-height/commit/44c4554))
+* fixed IE8 NaN bug when parsing 'auto' properties ([702eea6](https://github.com/liabru/jquery-match-height/commit/702eea6))
+* fixed IE8 window resize event loop bug ([22b74da](https://github.com/liabru/jquery-match-height/commit/22b74da))
+* increment version ([0cb6082](https://github.com/liabru/jquery-match-height/commit/0cb6082))
+* updated minified build ([3873f7d](https://github.com/liabru/jquery-match-height/commit/3873f7d))
+* updated readme ([b62297b](https://github.com/liabru/jquery-match-height/commit/b62297b))
+
+
+
+<a name="0.5.0"></a>
+# 0.5.0 (2014-03-02)
+
+### release summary
+
+- initial release
+
+### commit log
+
+* added jquery package file ([3fdbeae](https://github.com/liabru/jquery-match-height/commit/3fdbeae))
+* initial commit ([35b8209](https://github.com/liabru/jquery-match-height/commit/35b8209))
+* updated readme ([ae41130](https://github.com/liabru/jquery-match-height/commit/ae41130))
+* updated readme ([6e1b0f8](https://github.com/liabru/jquery-match-height/commit/6e1b0f8))
+
+
-- initial release \ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 3da2d0d..6ee1d74 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,23 +1,192 @@
-// TODO: build task
-// TODO: minify task
-// TODO: eslint task
-// TODO: cloud selenium server to test more browsers
// TODO: add more test specs (see matchHeight.spec.js)
// TODO: travis CI
var gulp = require('gulp');
+var uglify = require('gulp-uglify');
+var rename = require('gulp-rename');
+var header = require('gulp-header');
+var eslint = require('gulp-eslint');
+var gulpBump = require('gulp-bump');
+var changelog = require('gulp-conventional-changelog');
+var tag = require('gulp-tag-version');
+var sequence = require('run-sequence');
+var replace = require('gulp-replace');
var webdriver = require('gulp-webdriver');
var webserver = require('gulp-webserver');
+var selenium = require('selenium-standalone');
+var browserStack = require('gulp-browserstack');
+var staticTransform = require('connect-static-transform');
+var privateConfig = require('./test/conf/private.conf.js').config;
+var pkg = require('./package.json');
+var server;
-gulp.task('test', function() {
- return gulp.src('test/conf/wdio.conf.js').pipe(webdriver());
+gulp.task('release', function(callback) {
+ var type = process.argv[4] || 'minor';
+ sequence('lint', 'test', 'build', 'bump:' + type, 'changelog', 'tag', callback);
+});
+
+gulp.task('build', function() {
+ return gulp.src(pkg.main)
+ .pipe(replace("version = 'master'", "version = '" + pkg.version + "'"))
+ .pipe(uglify())
+ .pipe(header(banner, { pkg: pkg }))
+ .pipe(rename({ suffix: '-min' }))
+ .pipe(gulp.dest('.'));
+});
+
+gulp.task('lint', function() {
+ return gulp.src(pkg.main)
+ .pipe(eslint())
+ .pipe(eslint.format())
+ .pipe(eslint.failAfterError());
+});
+
+var bump = function(options) {
+ return gulp.src(['package.json', 'bower.json'])
+ .pipe(gulpBump(options))
+ .pipe(gulp.dest('.'));
+};
+
+gulp.task('bump:patch', function() {
+ return bump({ type: 'patch' });
+});
+
+gulp.task('bump:minor', function() {
+ return bump({ type: 'minor' });
+});
+
+gulp.task('bump:major', function() {
+ return bump({ type: 'major' });
+});
+
+gulp.task('tag', function() {
+ return gulp.src('package.json')
+ .pipe(tag({ prefix: '' }));
+});
+
+gulp.task('changelog', function () {
+ return gulp.src('CHANGELOG.md')
+ .pipe(changelog())
+ .pipe(gulp.dest('.'));
});
gulp.task('serve', function() {
- gulp.src('.')
- .pipe(webserver({
- livereload: true,
- directoryListing: true,
- open: 'http://localhost:8000/test/page/test.html'
- }));
-}); \ No newline at end of file
+ server = gulp.src('.')
+ .pipe(webserver({
+ host: '0.0.0.0',
+ //livereload: true,
+ directoryListing: true,
+ middleware: function(req, res, next) {
+ var ieMode = (req._parsedUrl.query || '').replace('=','');
+ if (ieMode in emulateIEMiddleware) {
+ emulateIEMiddleware[ieMode](req, res, next);
+ } else {
+ next();
+ }
+ }
+ }));
+});
+
+gulp.task('selenium', function(done) {
+ console.log('Setting up Selenium server...');
+ selenium.install({
+ logger: function(message) { console.log(message); }
+ }, function(err) {
+ if (err) {
+ done(err);
+ return;
+ }
+ console.log('Starting Selenium server...');
+ selenium.start(function(err, child) {
+ console.log('Selenium server started');
+ selenium.child = child;
+ done(err);
+ });
+ });
+});
+
+gulp.task('test', ['serve', 'selenium'], function(done) {
+ var error;
+ console.log('Starting webdriver...');
+
+ var finish = function(err) {
+ console.log('Webdriver stopped');
+ selenium.child.kill();
+ console.log('Selenium server stopped');
+ if (server) {
+ try {
+ server.emit('kill');
+ } catch(e) {}
+ console.log('Web server stopped');
+ }
+ done(error || err);
+ };
+
+ gulp.src('test/conf/local.conf.js')
+ .pipe(webdriver())
+ .on('error', function(err) { error = err; })
+ .on('finish', finish);
+});
+
+gulp.task('test:cloud', ['serve'], function(done) {
+ gulp.src('test/conf/cloud.conf.js')
+ .pipe(browserStack.startTunnel({
+ key: privateConfig.key,
+ hosts: [{
+ name: 'localhost',
+ port: 8000,
+ sslFlag: 0
+ }]
+ }))
+ .pipe(webdriver())
+ .pipe(browserStack.stopTunnel())
+ .on('finish', function(err) {
+ if (server) {
+ try {
+ server.emit('kill');
+ } catch(e) {}
+ console.log('Web server stopped');
+ }
+ done(err);
+ });
+});
+
+gulp.task('test:cloud:all', function(done) {
+ return gulp
+ .src('test/conf/cloud-all.conf.js')
+ .pipe(browserStack.startTunnel({
+ key: privateConfig.key,
+ hosts: [{
+ name: 'localhost',
+ port: 8000,
+ sslFlag: 0
+ }]
+ }))
+ .pipe(webdriver())
+ .pipe(browserStack.stopTunnel());
+});
+
+var banner = [
+ '/*',
+ '* <%= pkg.name %> v<%= pkg.version %> by @liabru',
+ '* <%= pkg.homepage %>',
+ '* License <%= pkg.license %>',
+ '*/',
+ ''
+].join('\n');
+
+var emulateIEMiddlewareFactory = function(version) {
+ return staticTransform({
+ root: __dirname,
+ match: /(.+)\.html/,
+ transform: function (path, text, send) {
+ send(text.replace('content="IE=edge,chrome=1"', 'content="IE=' + version + '"'));
+ }
+ });
+};
+
+var emulateIEMiddleware = {
+ 'ie8': emulateIEMiddlewareFactory(8),
+ 'ie9': emulateIEMiddlewareFactory(9),
+ 'ie10': emulateIEMiddlewareFactory(10)
+}; \ No newline at end of file
diff --git a/jquery.matchHeight.js b/jquery.matchHeight.js
index f4ab786..18a75cf 100644
--- a/jquery.matchHeight.js
+++ b/jquery.matchHeight.js
@@ -4,7 +4,7 @@
* License: MIT
*/
-;(function($) {
+;(function($) { // eslint-disable-line no-extra-semi
/*
* internal
*/
@@ -131,12 +131,15 @@
* plugin global options
*/
+ matchHeight.version = 'master';
matchHeight._groups = [];
matchHeight._throttle = 80;
matchHeight._maintainScroll = false;
matchHeight._beforeUpdate = null;
matchHeight._afterUpdate = null;
matchHeight._rows = _rows;
+ matchHeight._parse = _parse;
+ matchHeight._parseOptions = _parseOptions;
/*
* matchHeight._apply
diff --git a/package.json b/package.json
index e3f6005..9dc8cd4 100644
--- a/package.json
+++ b/package.json
@@ -26,9 +26,19 @@
},
"devDependencies": {
"gulp": "^3.9.0",
+ "gulp-browserstack": "^1.0.0",
+ "gulp-bump": "^1.0.0",
+ "gulp-eslint": "^1.0.0",
+ "gulp-header": "^1.7.1",
+ "gulp-rename": "^1.2.2",
+ "gulp-replace": "^0.5.4",
+ "gulp-tag-version": "^1.3.0",
+ "gulp-uglify": "^1.4.2",
"gulp-webdriver": "^1.0.1",
"gulp-webserver": "^0.9.1",
"jasmine": "^2.3.2",
+ "run-sequence": "^1.1.4",
+ "selenium-standalone": "^4.7.0",
"webdriverio": "^3.2.5"
}
}
diff --git a/test/conf/cloud-all.conf.js b/test/conf/cloud-all.conf.js
new file mode 100644
index 0000000..cd58ae8
--- /dev/null
+++ b/test/conf/cloud-all.conf.js
@@ -0,0 +1,175 @@
+var privateConfig = require('./private.conf.js').config;
+
+var testUrl = 'http://localhost:8000/test/page/test.html',
+ viewports = [[1280, 1024], [640, 480], [320, 640]];
+
+var capabilities = [
+ {
+ browser: 'ie',
+ browser_version: '11',
+ os: 'windows',
+ os_version: '10'
+ },
+ {
+ browser: 'ie',
+ browser_version: '10',
+ os: 'windows',
+ os_version: '7'
+ },
+ {
+ browser: 'ie',
+ browser_version: '9',
+ os: 'windows',
+ os_version: '7'
+ },
+ {
+ browser: 'ie',
+ browser_version: '8',
+ os: 'windows',
+ os_version: '7',
+ viewports: [[1280, 1024]]
+ },
+ {
+ browserName: 'chrome',
+ os: 'windows',
+ os_version: '8'
+ },
+ {
+ browserName: 'firefox',
+ os: 'windows',
+ os_version: '8'
+ },
+ {
+ browser: 'safari',
+ browser_version: '8'
+ },
+ {
+ browser: 'safari',
+ browser_version: '7.1'
+ },
+ {
+ browser: 'safari',
+ browser_version: '6.2'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 6',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 6',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 5S',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 5S',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 4S',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 4S',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 5S',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 5S',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'iPad',
+ device: 'iPad 4th',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPad',
+ device: 'iPad 4th',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'iPad',
+ device: 'iPad 3rd',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPad',
+ device: 'iPad 3rd',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'iPad',
+ device: 'iPad 2nd',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPad',
+ device: 'iPad 2nd',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'android',
+ device: 'Samsung Galaxy S5',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'android',
+ device: 'Samsung Galaxy S5',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'android',
+ device: 'Samsung Galaxy Tab 4 10.1',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'android',
+ device: 'Samsung Galaxy Tab 4 10.1',
+ deviceOrientation: 'landscape'
+ }
+];
+
+for (var i = 0; i < capabilities.length; i += 1) {
+ var capability = capabilities[i];
+ capability['browserstack.local'] = true;
+ capability['browserstack.debug'] = true;
+ capability['initialBrowserUrl'] = testUrl;
+ capability['urls'] = capability['urls'] || [testUrl];
+
+ if (!capability['deviceOrientation']) {
+ capability['viewports'] = capability['viewports'] || viewports;
+ capability['resolution'] = capability['resolution'] || '1680x1050';
+ }
+}
+
+exports.config = {
+ user: privateConfig.user,
+ key: privateConfig.key,
+ capabilities: capabilities,
+ specs: [
+ './test/specs/webdriver.spec.js'
+ ],
+ logLevel: 'silent',
+ coloredLogs: true,
+ waitforTimeout: 60000,
+ framework: 'jasmine',
+ reporter: 'spec',
+ pauseOnFail: false,
+ jasmineNodeOpts: {
+ defaultTimeoutInterval: 60000
+ }
+};
diff --git a/test/conf/cloud.conf.js b/test/conf/cloud.conf.js
new file mode 100644
index 0000000..91d94d3
--- /dev/null
+++ b/test/conf/cloud.conf.js
@@ -0,0 +1,69 @@
+var privateConfig = require('./private.conf.js').config;
+
+var testUrl = 'http://localhost:8000/test/page/test.html',
+ viewports = [[1280, 1024], [640, 480], [320, 640]];
+
+var capabilities = [
+ {
+ browser: 'ie',
+ browser_version: '8',
+ os: 'windows',
+ os_version: '7',
+ viewports: [[1280, 1024]]
+ },
+ {
+ browser: 'safari',
+ browser_version: '8'
+ },
+ {
+ browser: 'iPhone',
+ device: 'iPhone 6',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'iPad',
+ device: 'iPad 4th',
+ deviceOrientation: 'landscape'
+ },
+ {
+ browser: 'android',
+ device: 'Samsung Galaxy S5',
+ deviceOrientation: 'portrait'
+ },
+ {
+ browser: 'android',
+ device: 'Samsung Galaxy Tab 4 10.1',
+ deviceOrientation: 'landscape'
+ }
+];
+
+for (var i = 0; i < capabilities.length; i += 1) {
+ var capability = capabilities[i];
+ capability['browserstack.local'] = true;
+ capability['browserstack.debug'] = true;
+ capability['initialBrowserUrl'] = testUrl;
+ capability['urls'] = capability['urls'] || [testUrl];
+
+ if (!capability['deviceOrientation']) {
+ capability['viewports'] = capability['viewports'] || viewports;
+ capability['resolution'] = capability['resolution'] || '1600x1200';
+ }
+}
+
+exports.config = {
+ user: privateConfig.user,
+ key: privateConfig.key,
+ capabilities: capabilities,
+ specs: [
+ './test/specs/webdriver.spec.js'
+ ],
+ logLevel: 'silent',
+ coloredLogs: true,
+ waitforTimeout: 60000,
+ framework: 'jasmine',
+ reporter: 'spec',
+ pauseOnFail: false,
+ jasmineNodeOpts: {
+ defaultTimeoutInterval: 60000
+ }
+};
diff --git a/test/conf/local.conf.js b/test/conf/local.conf.js
new file mode 100644
index 0000000..6ca9580
--- /dev/null
+++ b/test/conf/local.conf.js
@@ -0,0 +1,43 @@
+var testUrl = 'http://localhost:8000/test/page/test.html',
+ viewports = [[1280, 1024], [640, 480], [320, 640]];
+
+var capabilities = [
+ {
+ browserName: 'chrome'
+ },
+ {
+ browserName: 'firefox'
+ },
+ {
+ browserName: 'internet explorer',
+ urls: [testUrl, testUrl + '?ie=9', testUrl + '?ie=10'],
+ },
+ {
+ browserName: 'internet explorer',
+ urls: [testUrl + '?ie=8'],
+ viewports: [[1280, 1024]]
+ }
+];
+
+for (var i = 0; i < capabilities.length; i += 1) {
+ var capability = capabilities[i];
+ capability['initialBrowserUrl'] = testUrl;
+ capability['urls'] = capability['urls'] || [testUrl];
+ capability['viewports'] = capability['viewports'] || viewports;
+}
+
+exports.config = {
+ capabilities: capabilities,
+ specs: [
+ './test/specs/webdriver.spec.js'
+ ],
+ logLevel: 'silent',
+ coloredLogs: true,
+ waitforTimeout: 99999999,
+ framework: 'jasmine',
+ reporter: 'spec',
+ pauseOnFail: true,
+ jasmineNodeOpts: {
+ defaultTimeoutInterval: 99999999
+ }
+};
diff --git a/test/conf/wdio.conf.js b/test/conf/wdio.conf.js
deleted file mode 100644
index c323e0e..0000000
--- a/test/conf/wdio.conf.js
+++ /dev/null
@@ -1,24 +0,0 @@
-exports.config = {
- capabilities: [
- {
- browserName: 'firefox'
- },
- {
- browserName: 'chrome'
- },
- {
- browserName: 'internet explorer'
- }
- ],
- specs: [
- './test/specs/webdriver.spec.js'
- ],
- logLevel: 'silent',
- coloredLogs: true,
- waitforTimeout: 10000,
- framework: 'jasmine',
- reporter: 'spec',
- jasmineNodeOpts: {
- defaultTimeoutInterval: 10000
- }
-};
diff --git a/test/page/img/800x150.png b/test/page/img/800x150.png
new file mode 100644
index 0000000..82a4a2c
--- /dev/null
+++ b/test/page/img/800x150.png
Binary files differ
diff --git a/test/page/img/800x180.png b/test/page/img/800x180.png
new file mode 100644
index 0000000..a44e80b
--- /dev/null
+++ b/test/page/img/800x180.png
Binary files differ
diff --git a/test/page/img/800x200.png b/test/page/img/800x200.png
new file mode 100644
index 0000000..78c17d3
--- /dev/null
+++ b/test/page/img/800x200.png
Binary files differ
diff --git a/test/page/img/800x220.png b/test/page/img/800x220.png
new file mode 100644
index 0000000..33a1979
--- /dev/null
+++ b/test/page/img/800x220.png
Binary files differ
diff --git a/test/page/lib/jasmine-2.3.4/boot.js b/test/page/lib/jasmine-2.3.4/boot.js
index 63fdd1f..324798c 100644
--- a/test/page/lib/jasmine-2.3.4/boot.js
+++ b/test/page/lib/jasmine-2.3.4/boot.js
@@ -105,11 +105,13 @@
var currentWindowOnload = window.onload;
window.onload = function() {
- if (currentWindowOnload) {
- currentWindowOnload();
- }
- htmlReporter.initialize();
- env.execute();
+ setTimeout(function() {
+ if (currentWindowOnload) {
+ currentWindowOnload();
+ }
+ htmlReporter.initialize();
+ env.execute();
+ }, 1000);
};
/**
diff --git a/test/page/test.html b/test/page/test.html
index 882abe5..244923f 100644
--- a/test/page/test.html
+++ b/test/page/test.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<!-- IE testing -->
- <!-- <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">-->
+ <!--<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">-->
<!-- <meta http-equiv="X-UA-Compatible" content="IE=9">-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex">
@@ -13,7 +13,7 @@
<link rel="stylesheet" href="./test.css">
<script type="text/javascript" src="./lib/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="../../jquery.matchHeight.js"></script>
- <script type="text/javascript" src="../test/test.js"></script>
+ <script type="text/javascript" src="./test.js"></script>
<!-- jasmine tests -->
<link rel="stylesheet" type="text/css" href="./lib/jasmine-2.3.4/jasmine.css">
<script type="text/javascript" src="./lib/jasmine-2.3.4/jasmine.js"></script>
@@ -159,16 +159,16 @@
<div class="items-container image-items">
<div class="item item-0">
- <img src="http://placehold.it/800x150/fafafa/666" alt="a test image">
+ <img src="./img/800x150.png" alt="a test image">
</div>
<div class="item item-1">
- <img src="http://placehold.it/800x180/fafafa/666" alt="a test image">
+ <img src="./img/800x180.png" alt="a test image">
</div>
<div class="item item-2">
- <img src="http://placehold.it/800x200/fafafa/666" alt="a test image">
+ <img src="./img/800x200.png" alt="a test image">
</div>
<div class="item item-3">
- <img src="http://placehold.it/800x220/fafafa/666" alt="a test image">
+ <img src="./img/800x220.png" alt="a test image">
</div>
</div>
diff --git a/test/specs/matchHeight.spec.js b/test/specs/matchHeight.spec.js
index 7f290e0..c7e4fd8 100644
--- a/test/specs/matchHeight.spec.js
+++ b/test/specs/matchHeight.spec.js
@@ -1,14 +1,10 @@
// NOTE: these test specs are a work in progress
// manual testing before going into production is still advised!
+// the following features are implemented, but do not have specs yet:
-// TODO: spec for _parse
-// TODO: spec for _parseOptions
// TODO: spec for $(elements).matchHeight({ property: 'min-height' })
// TODO: spec for $(elements).matchHeight({ remove: true })
// TODO: spec for events: ready, load, resize, orientationchange
-// TODO: spec for $.fn.matchHeight._update
-// TODO: spec for $.fn.matchHeight._beforeUpdate
-// TODO: spec for $.fn.matchHeight._afterUpdate
// TODO: spec for $.fn.matchHeight._groups
// TODO: spec for $.fn.matchHeight._throttle
// TODO: spec for $.fn.matchHeight._maintainScroll
@@ -16,10 +12,28 @@
describe('matchHeight', function() {
+ beforeEach(function(){
+ jasmine.addMatchers({
+ toBeWithinTolerance: function() {
+ return {
+ compare: function(actual, expected, tolerance) {
+ if (tolerance !== 0) {
+ tolerance = tolerance || 1;
+ }
+
+ return {
+ pass: Math.abs(expected - actual) <= tolerance
+ };
+ }
+ }
+ }
+ });
+ });
+
it('has been defined', function(done) {
var matchHeight = $.fn.matchHeight;
expect(typeof matchHeight).toBe('function');
- expect(Array.isArray(matchHeight._groups)).toBe(true);
+ expect(testHelper.isArray(matchHeight._groups)).toBe(true);
expect(typeof matchHeight._throttle).toBe('number');
expect(typeof matchHeight._maintainScroll).toBe('boolean');
expect(typeof matchHeight._rows).toBe('function');
@@ -32,23 +46,20 @@ describe('matchHeight', function() {
it('has matched heights automatically after images load', function(done) {
var $items = $('.image-items'),
currentBreakpoint = testHelper.getCurrentBreakpoint(),
- image0Width = $items.find('.item-0 img')[0].naturalWidth,
item0Height = $items.find('.item-0').outerHeight(),
item1Height = $items.find('.item-1').outerHeight(),
item2Height = $items.find('.item-2').outerHeight(),
item3Height = $items.find('.item-3').outerHeight();
- expect(image0Width).toBe(800);
-
if (currentBreakpoint === 'mobile') {
// all heights will be different
} else if (currentBreakpoint === 'tablet') {
- expect(item0Height).toBe(item1Height);
- expect(item2Height).toBe(item3Height);
+ expect(item0Height).toBeWithinTolerance(item1Height);
+ expect(item2Height).toBeWithinTolerance(item3Height);
} else if (currentBreakpoint === 'desktop') {
- expect(item0Height).toBe(item3Height);
- expect(item1Height).toBe(item3Height);
- expect(item2Height).toBe(item3Height);
+ expect(item0Height).toBeWithinTolerance(item3Height);
+ expect(item1Height).toBeWithinTolerance(item3Height);
+ expect(item2Height).toBeWithinTolerance(item3Height);
}
done();
@@ -61,12 +72,14 @@ describe('matchHeight', function() {
expectedNumberCols = 4,
expectedNumberRows = 2;
- if (currentBreakpoint === 'mobile') {
- expectedNumberCols = 1;
- expectedNumberRows = 8;
- } else if (currentBreakpoint === 'tablet') {
- expectedNumberCols = 2;
- expectedNumberRows = 4;
+ if (testHelper.isMediaQueriesSupported) {
+ if (currentBreakpoint === 'mobile') {
+ expectedNumberCols = 1;
+ expectedNumberRows = 8;
+ } else if (currentBreakpoint === 'tablet') {
+ expectedNumberCols = 2;
+ expectedNumberRows = 4;
+ }
}
expect(rows.length).toBe(expectedNumberRows);
@@ -83,6 +96,15 @@ describe('matchHeight', function() {
});
it('has matched heights when byRow true', function(done) {
+ // test custom toBeWithinTolerance matcher
+ expect(-1.0001).not.toBeWithinTolerance(0);
+ expect(-1).toBeWithinTolerance(0);
+ expect(-0.1).toBeWithinTolerance(0);
+ expect(0).toBeWithinTolerance(0);
+ expect(0.1).toBeWithinTolerance(0);
+ expect(1).toBeWithinTolerance(0);
+ expect(1.0001).not.toBeWithinTolerance(0);
+
$('.simple-items, .image-items, .nested-items-parent, .nested-items,' +
'.fixed-items, .inline-block-items, .inline-flex-items, .items-with-float')
.each(function() {
@@ -102,14 +124,14 @@ describe('matchHeight', function() {
var naturalHeight = $item.outerHeight();
$item.css('height', heightCss);
- expect(actualHeight).toBe(targetHeight);
+ expect(actualHeight).toBeWithinTolerance(targetHeight);
if (naturalHeight > maxNaturalHeight) {
maxNaturalHeight = naturalHeight;
}
});
- expect(targetHeight).toBe(maxNaturalHeight);
+ expect(targetHeight).toBeWithinTolerance(maxNaturalHeight);
});
});
@@ -140,7 +162,7 @@ describe('matchHeight', function() {
var naturalHeight = $item.outerHeight();
$item.css('height', heightCss);
- expect(actualHeight).toBe(targetHeight);
+ expect(actualHeight).toBeWithinTolerance(targetHeight);
if (naturalHeight > maxNaturalHeight) {
maxNaturalHeight = naturalHeight;
@@ -148,7 +170,7 @@ describe('matchHeight', function() {
});
// TODO: solve this for .nested-items-parent, .nested-items
- expect(targetHeight).toBe(maxNaturalHeight);
+ expect(targetHeight).toBeWithinTolerance(maxNaturalHeight);
});
$.each($.fn.matchHeight._groups, function() {
@@ -182,14 +204,14 @@ describe('matchHeight', function() {
var naturalHeight = $item.outerHeight();
$item.css('height', heightCss);
- expect(actualHeight).toBe(targetHeight);
+ expect(actualHeight).toBeWithinTolerance(targetHeight);
if (naturalHeight > maxNaturalHeight) {
maxNaturalHeight = naturalHeight;
}
});
- expect(targetHeight).toBe(maxNaturalHeight);
+ expect(targetHeight).toBeWithinTolerance(maxNaturalHeight);
});
});
@@ -207,10 +229,10 @@ describe('matchHeight', function() {
item3Height = $items.find('.item-3').outerHeight();
if (currentBreakpoint !== 'mobile') {
- expect(item0Height).toBe(item1Height);
- expect(item2Height).toBe(item3Height);
- expect(item0Height).not.toBe(item2Height);
- expect(item1Height).not.toBe(item3Height);
+ expect(item0Height).toBeWithinTolerance(item1Height);
+ expect(item2Height).toBeWithinTolerance(item3Height);
+ expect(item0Height).not.toBeWithinTolerance(item2Height);
+ expect(item1Height).not.toBeWithinTolerance(item3Height);
}
done();
@@ -223,9 +245,133 @@ describe('matchHeight', function() {
item2Height = $items.find('.item-2').outerHeight(),
item3Height = $items.find('.item-3').outerHeight();
- expect(item0Height).toBe(item1Height);
- expect(item2Height).toBe(item1Height);
- expect(item3Height).toBe(item1Height);
+ expect(item0Height).toBeWithinTolerance(item1Height);
+ expect(item2Height).toBeWithinTolerance(item1Height);
+ expect(item3Height).toBeWithinTolerance(item1Height);
+
+ done();
+ });
+
+ it('can manually update heights and fires global callbacks', function(done) {
+ var currentBreakpoint = testHelper.getCurrentBreakpoint(),
+ calledBefore = false,
+ calledAfter = false;
+
+ var oldBefore = $.fn.matchHeight._beforeUpdate,
+ oldAfter = $.fn.matchHeight._afterUpdate;
+
+ // set some test update callbacks
+ $.fn.matchHeight._beforeUpdate = function() {
+ calledBefore = true;
+ };
+
+ $.fn.matchHeight._afterUpdate = function() {
+ calledAfter = true;
+ };
+
+ // add more content to one of the items to change it's height
+ $('.simple-items .item-1').append('<p>Test content update.</p>');
+
+ // call update which should match heights again
+ $.fn.matchHeight._update();
+
+ if (currentBreakpoint === 'mobile') {
+ // all heights will be different
+ } else {
+ // check item heights are as expected
+ $('.simple-items').each(function() {
+ var $items = $(this).children('.item'),
+ rows = $.fn.matchHeight._rows($items);
+
+ $.each(rows, function(index, $row) {
+ var targetHeight = $row.first().outerHeight(),
+ maxNaturalHeight = 0;
+
+ $row.each(function() {
+ var $item = $(this),
+ heightCss = $item.css('height'),
+ actualHeight = $item.outerHeight();
+
+ $item.css('height', '');
+ var naturalHeight = $item.outerHeight();
+ $item.css('height', heightCss);
+
+ expect(actualHeight).toBeWithinTolerance(targetHeight);
+
+ if (naturalHeight > maxNaturalHeight) {
+ maxNaturalHeight = naturalHeight;
+ }
+ });
+
+ expect(targetHeight).toBeWithinTolerance(maxNaturalHeight);
+ });
+ });
+ }
+
+ // check callbacks were fired
+ expect(calledBefore).toBe(true);
+ expect(calledAfter).toBe(true);
+
+ // revert callbacks
+ $.fn.matchHeight._beforeUpdate = oldBefore;
+ $.fn.matchHeight._afterUpdate = oldAfter;
+
+ done();
+ });
+
+ it('parses numbers and NaN', function(done) {
+ var _parse = $.fn.matchHeight._parse;
+ expect(_parse(1)).toBe(1);
+ expect(_parse(1.1)).toBe(1.1);
+ expect(_parse('1')).toBe(1);
+ expect(_parse('1.1')).toBe(1.1);
+ expect(_parse(NaN)).toBe(0);
+ done();
+ });
+
+ it('parses options', function(done) {
+ var _parseOptions = $.fn.matchHeight._parseOptions,
+ defaultOptions = {
+ byRow: true,
+ property: 'height',
+ target: null,
+ remove: false
+ };
+
+ expect(_parseOptions()).toEqual(defaultOptions);
+
+ expect(_parseOptions({
+ byRow: false,
+ property: 'min-height',
+ target: null,
+ remove: true
+ })).toEqual({
+ byRow: false,
+ property: 'min-height',
+ target: null,
+ remove: true
+ });
+
+ expect(_parseOptions('remove')).toEqual({
+ byRow: defaultOptions.byRow,
+ property: defaultOptions.property,
+ target: defaultOptions.target,
+ remove: true
+ });
+
+ expect(_parseOptions(true)).toEqual({
+ byRow: true,
+ property: defaultOptions.property,
+ target: defaultOptions.target,
+ remove: defaultOptions.remove
+ });
+
+ expect(_parseOptions(false)).toEqual({
+ byRow: false,
+ property: defaultOptions.property,
+ target: defaultOptions.target,
+ remove: defaultOptions.remove
+ });
done();
});
@@ -234,34 +380,39 @@ describe('matchHeight', function() {
jasmine.getEnv().addReporter({
suiteStarted: function() {
- window.specsPassed = 0;
- window.specsFailed = 0;
+ window.specsPassed = [];
+ window.specsFailed = [];
$('.test-summary').text('running tests...');
},
specDone: function(result) {
if (result.status === 'passed') {
- window.specsPassed += 1;
+ window.specsPassed.push(result.id);
} else {
- window.specsFailed += 1;
+ window.specsFailed.push(result.id);
}
},
suiteDone: function() {
$('.test-summary')
- .toggleClass('has-passed', window.specsFailed === 0)
- .toggleClass('has-failed', window.specsFailed !== 0)
- .text(window.specsPassed + ' tests passed, ' + window.specsFailed + ' failed');
+ .toggleClass('has-passed', window.specsFailed.length === 0)
+ .toggleClass('has-failed', window.specsFailed.length !== 0)
+ .text(window.specsPassed.length + ' tests passed, ' + window.specsFailed.length + ' failed');
}
});
var testHelper = {
+ isMediaQueriesSupported: typeof (window.matchMedia || window.msMatchMedia) !== 'undefined' || navigator.userAgent.indexOf('MSIE 9.0') >= 0,
+ isArray: function(obj) {
+ return Object.prototype.toString.call(obj) === '[object Array]';
+ },
getCurrentBreakpoint: function() {
- var windowWidth = $(window).width();
-
- if (windowWidth <= 640) {
- return 'mobile';
- } else if (windowWidth <= 1024) {
- return 'tablet';
+ if (testHelper.isMediaQueriesSupported) {
+ var windowWidth = $(window).width();
+ if (windowWidth <= 640) {
+ return 'mobile';
+ } else if (windowWidth <= 1024) {
+ return 'tablet';
+ }
}
return 'desktop';
diff --git a/test/specs/webdriver.spec.js b/test/specs/webdriver.spec.js
index 6800034..9396f8c 100644
--- a/test/specs/webdriver.spec.js
+++ b/test/specs/webdriver.spec.js
@@ -1,31 +1,64 @@
+var async = require('async');
+
describe('matchHeight webdriver', function() {
- var runAllTests = function(done, width, height) {
- browser
- .setViewportSize({ width: width, height: height })
- .url('http://localhost:8000/test/page/test.html')
- .waitForExist('.jasmine_html-reporter', 5000)
- .execute(function() {
- return {
- total: window.specsPassed + window.specsFailed,
- passed: window.specsPassed,
- failed: window.specsFailed
- };
- })
- .then(function(ret) {
- expect(ret.value.passed).toBe(ret.value.total, 'number of specs passed');
- expect(ret.value.failed).toBe(0, 'number of specs failed');
- }).call(done);
- };
+ var capabilities = browser.desiredCapabilities,
+ urls = capabilities.urls,
+ viewports = capabilities.viewports,
+ browserInfo = capabilities.browserName;
+
+ if (capabilities.browser) {
+ browserInfo = capabilities.browser + ' ' + capabilities.browser_version;
+ }
- it('passes matchHeight.spec.js at desktop breakpoint', function(done) {
- runAllTests(done, 1280, 1024);
- });
+ var runAllTests = function(pageUrls, width, height, done) {
+ var next = browser;
- it('passes matchHeight.spec.js at tablet breakpoint', function(done) {
- runAllTests(done, 640, 480);
- });
+ if (typeof width === 'number' && typeof height === 'number') {
+ next = next.setViewportSize({ width: width, height: height })
+ .windowHandlePosition({ x: 0, y: 0 });
+ } else {
+ done = width;
+ }
+
+ async.eachSeries(pageUrls, function(pageUrl, callback) {
+ next = next.url(pageUrl)
+ .waitForExist('.jasmine_html-reporter', 60000)
+ .execute(function() {
+ return {
+ total: window.specsPassed.concat(window.specsFailed),
+ passed: window.specsPassed,
+ failed: window.specsFailed
+ };
+ })
+ .then(function(ret) {
+ var message = ret.value.failed.join(', ') + ' failed on ' + browserInfo + ' on ' + pageUrl;
+ expect(ret.value.passed.length).toBe(ret.value.total.length, message);
+
+ if (browser.options.pauseOnFail && ret.value.passed.length !== ret.value.total.length) {
+ console.log(message);
+ console.log('paused on failure...');
+ next = next.pause(99999999);
+ }
+ })
+ .then(callback);
+ }, done);
+ };
- it('passes matchHeight.spec.js at mobile breakpoint', function(done) {
- runAllTests(done, 320, 640);
- });
+ if (viewports) {
+ for (var i = 0; i < viewports.length; i += 1) {
+ (function(width, height) {
+ it('passes matchHeight.spec.js at viewport ' + width + 'x' + height, function(done) {
+ runAllTests(urls, width, height, function() {
+ done();
+ });
+ });
+ })(viewports[i][0], viewports[i][1]);
+ }
+ } else {
+ it('passes matchHeight.spec.js', function(done) {
+ runAllTests(urls, function() {
+ done();
+ });
+ });
+ }
}); \ No newline at end of file