Skip to content

Commit

Permalink
workflows: add CI workflow for unit tests and support running locally
Browse files Browse the repository at this point in the history
* Load qunit package from npm, this is the start of a larger transition.
  ref at kiwix#554.

* Update QUnit from 2.3 to 2.12.

* Use Karma for the running of unit tests (instead of Nightwatch).

  While it was possible to use a fake "UI" test to open the QUnit
  web page with Nightwatch, this had numerous limitations:

  - relies on the fragile and unsupported DOM scraping to collect
    results, which breaks between versions.
    ref kiwix#660.

  - severely limits debugging information for failing tests.

  - cannot easily be run or debugged locally from the command-line since
    as the Nightwatch config was pinned to Sauce Labs, and creating
    a local configuration is not easy because Nightwatch has a hard
    requirement for installing and running a WebDriver server first.
    People usually do not have this installed and is hard to set up.

  - cannot easily be run in a secure container separate from your
    personal computer, thus putting personal data at risk.

  - lacks wider integration and plugins to enrich unit testing,
    such as test coverage reports.

  Using Karma means:
  - We can run 'npm test' locally during development and have it
    automatically run the tests in headless Firefox and Chrome
    and report back, all from the command-line.
  - The same exact same stack is also used in CI with SauceLabs
    for additional browser coverage (same as before).
  - It has no external dependencies other than the plain web
    browser itself. This means if you have a development container
    (e.g. based on Docker) that has Node.js + Firefox + Chromium,
    you can run the tests there without exposing anything from
    your personal computer, besides the current directory.
    <https://timotijhof.net/posts/2019/protect-yourself-from-npm/>
  - In a future change, we can plug in karma-coverage to generate
    a test coverage report, to submit to Codecov or Coveralls.
    ref kiwix#528.

* I have pinned the version of 'http-server' and 'nightwatch'
  in package.json so that these don't silently upgrade in a way
  that may introduce security issues or drop compatibility for
  the environment we currently support.

Fixes kiwix#653.
  • Loading branch information
Krinkle committed Dec 29, 2020
1 parent 755a56f commit ee5bf96
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 5,401 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI

on:
- push
- pull_request
# Allow running manually
- workflow_dispatch

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
build:

# Packages 'firefox' and 'google-chrome' are pre-installed.
#
# https://github.com/actions/virtual-environments/blob/ubuntu20/20201210.0/images/linux/Ubuntu2004-README.md
runs-on: ubuntu-20.04

steps:
# Clone the repo and checkout the commit for which the workflow was triggered
- uses: actions/checkout@v2

# Install Node.js LTS
- uses: actions/setup-node@v2
with:
node-version: 10.x

- name: Install npm packages
run: npm ci

- name: Run Tests (Local)
run: npm test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ www-ghdeploy
/scripts/travisci_builder_id_key
/scripts/ssh_key
/scripts/secret_files.tar.gz
/reports/

#Visual Studio
/.vs/
Expand Down
46 changes: 28 additions & 18 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
sudo : true
dist : trusty
os: linux
language: node_js
node_js:
- "node"
addons:
sauce_connect: true
ssh_known_hosts: download.kiwix.org
before_script:
- npm install nightwatch http-server
- "./node_modules/http-server/bin/http-server . &"
script:
# The free account on Sauce does not allow more than 5 concurrent sessions (including the main one)
# So we separate the recent and old browsers in order to respect this limit.
# NB : latest edge should be added to this list when Microsoft releases the new Edge based on Chromium
- "./node_modules/nightwatch/bin/nightwatch -c nightwatch.js --env firefox,chrome"
- "./node_modules/nightwatch/bin/nightwatch -c nightwatch.js --env edge40,edge44"
- "./node_modules/nightwatch/bin/nightwatch -c nightwatch.js --env firefox45,chrome58,ie11"
- pkill node || echo "Node process not running (anymore)"
node_js: "14"

jobs:
fast_finish: true
include:

- stage: "Cross-browser testing"
# This stage only runs when saucelabs credentials are available
# (e.g. direct pushes and local non-fork PRs)
# https://docs.travis-ci.com/user/environment-variables/
# https://docs.travis-ci.com/user/conditions-v1
if: NOT fork
addons:
sauce_connect: true
script:
- npm run test-unit-saucelabs
- "./node_modules/.bin/http-server . &"
- sleep 2
- curl "http://localhost:8080" | head
# The free account on Sauce does not allow more than 5 concurrent sessions (including the main one)
# So we separate the recent and old browsers in order to respect this limit.
# REMINDER: Keep this list in sync with the Unit tests, in tests/karma.conf.saucelabs.js
# NB : latest edge should be added to this list when Microsoft releases the new Edge based on Chromium
- "./node_modules/.bin/nightwatch -c nightwatch.js --env firefox,chrome"
- "./node_modules/.bin/nightwatch -c nightwatch.js --env edge40,edge44"
- "./node_modules/.bin/nightwatch -c nightwatch.js --env firefox45,chrome58,ie11"
- pkill node || echo "Node process not running (anymore)"
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ It might also work with other content in the OpenZIM format: https://wiki.openzi

If your Internet access is expensive/rare/slow/unreliable/watched/censored, you still can browse this amazing repository of knowledge and culture.

[![Build Status](https://github.com/kiwix/kiwix-js/workflows/Release/badge.svg?query=branch%3Amaster)](https://github.com/kiwix/kiwix-js/actions?query=branch%3Amaster)
[![Build Status: Continuous Integration](https://github.com/kiwix/kiwix-js/workflows/CI/badge.svg?query=branch%3Amaster)](https://github.com/kiwix/kiwix-js/actions?query=branch%3Amaster)
[![Build Status: Release](https://github.com/kiwix/kiwix-js/workflows/Release/badge.svg?query=branch%3Amaster)](https://github.com/kiwix/kiwix-js/actions?query=branch%3Amaster)
[![CodeFactor](https://www.codefactor.io/repository/github/kiwix/kiwix-js/badge)](https://www.codefactor.io/repository/github/kiwix/kiwix-js)
[![Kiwix for Firefox](https://img.shields.io/amo/v/kiwix-offline?label=Kiwix%20for%20Firefox)](https://addons.mozilla.org/fr/firefox/addon/kiwix-offline/)
[![Kiwix for Chrome](https://img.shields.io/chrome-web-store/v/donaljnlmapmngakoipdmehbfcioahhk?label=Kiwix%20for%20Chrome)](https://chrome.google.com/webstore/detail/kiwix/donaljnlmapmngakoipdmehbfcioahhk)
Expand Down Expand Up @@ -58,7 +59,7 @@ The source code can be found at https://github.com/kiwix/kiwix-js

## Unit tests

Unit tests can be run by opening tests.html file on Firefox or Edge (or Chromium/Chrome with some tweaks).
Unit tests can be run by opening `tests/index.html` file in Firefox, Edge, or Chromium/Chrome.

## Public releases and nightly builds

Expand Down
14 changes: 0 additions & 14 deletions browser-tests/nightwatch_runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,6 @@
*/
'use strict';
module.exports = {
'Unit Tests': function(browser) {
// We need to skip the UI tests on Internet Explorer,
// because they are not supported, even if the UI tests are supported on this browser
if (browser.options.desiredCapabilities.browserName !== "internet explorer") {
browser
.url('http://localhost:8080/tests.html')
.waitForElementVisible('#qunit-testresult', 10000)
.pause(10000);
browser.expect.element('#qunit-testresult').text.to.contain('tests completed in');
browser.expect.element('#qunit-testresult .failed').text.to.equal('0');
browser.expect.element('#qunit-testresult .passed').text.not.to.equal('0');
browser.end();
}
},
'UI Tests': function(browser) {
browser
.url('http://localhost:8080/')
Expand Down
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"private": true,
"scripts": {
"test": "npm run test-unit-local",
"test-unit-local": "karma start tests/karma.conf.local.js",
"test-unit-saucelabs": "karma start tests/karma.conf.saucelabs.js"
},
"engines": {
"node": ">=10"
},
"devDependencies": {
"http-server": "^0.12.3",
"karma": "5.2.3",
"karma-chrome-launcher": "3.1.0",
"karma-firefox-launcher": "2.1.0",
"karma-qunit": "4.1.1",
"karma-requirejs": "1.1.0",
"karma-sauce-launcher": "^4.3.3",
"nightwatch": "^1.5.1",
"qunit": "2.12.0",
"requirejs": "2.3.3"
}
}
18 changes: 9 additions & 9 deletions tests.html → tests/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta charset="utf-8">
<base href="../">
<title>Kiwix-js Unit tests</title>

<!--
Expand All @@ -24,23 +25,22 @@
along with Kiwix (file LICENSE-GPLv3.txt). If not, see <http://www.gnu.org/licenses/>
-->

<link rel="stylesheet" href="tests/qunit-2.3.2.css" />
<script src="tests/qunit-2.3.2.js"></script>
<link rel="stylesheet" href="node_modules/qunit/qunit/qunit.css" />
<script src="node_modules/qunit/qunit/qunit.js"></script>
<script>
QUnit.config.autostart = false;
</script>

<!-- Using require.js, a module system for javascript, include the
js files. This loads "main.js", which in turn can load other
files, all handled by require.js:
http://requirejs.org/docs/api.html#jsfiles -->
<script type="text/javascript"
data-main="tests/init.js"
src="www/js/lib/require.js"></script>


<script src="www/js/lib/require.js" data-main="tests/init.js"></script>
</head>
<body>
<b>NOTE:</b> Firefox and Chrome do not allow access to some local filesystem files used in testing. So, if you're opening this through a file:// URL, you should instead go through a web server : either through a local one (http://localhost/...) or through a remote one (but you need SSL : https://webserver/...).<br/>
Another option is to force your browser to accept that (but you'll open a security breach) : on Chrome, you can start it with --allow-file-access-from-files command-line argument; on Firefox, you can set privacy.file_unique_origin to false in about:config
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
</html>
2 changes: 1 addition & 1 deletion tests/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var params = {};
var webpMachine = true;

require.config({
baseUrl: 'www/js/lib',
baseUrl: (window.__karma__ ? 'base/' : '') + 'www/js/lib/',
paths: {
'jquery': 'jquery-3.2.1.slim',
'webpHeroBundle': 'webpHeroBundle_0.0.0-dev.27',
Expand Down
25 changes: 25 additions & 0 deletions tests/karma.conf.local.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = function (config) {
config.set({
basePath: '../',
// https://karma-runner.github.io/5.2/config/browsers.html
browsers: [
'FirefoxHeadless',
'ChromeHeadless'
],
frameworks: ['qunit'],
client: {
qunit: {
autostart: false
}
},
// logLevel: 'DEBUG',
files: [
'www/js/lib/require.js',
'tests/init.js',
{ pattern: 'www/**/*', included: false },
{ pattern: 'tests/**/*', included: false }
],
singleRun: true,
autoWatch: false
});
};
83 changes: 83 additions & 0 deletions tests/karma.conf.saucelabs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
module.exports = function (config) {
config.set({
basePath: '../',
// https://karma-runner.github.io/5.2/config/browsers.html
// https://github.com/karma-runner/karma-sauce-launcher
// https://github.com/karma-runner/karma-sauce-launcher/issues/73
sauceLabs: {
startConnect: process.env.TRAVIS_JOB_NUMBER ? false : true,
username: process.env.SAUCE_USERNAME,
accessKey: process.env.SAUCE_ACCESS_KEY,
tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER,
},
customLaunchers: {
firefox45: {
base: 'SauceLabs',
browserName: 'firefox',
version: '45.0'
},
firefox: {
base: 'SauceLabs',
browserName: 'firefox',
},
chrome58: {
base: 'SauceLabs',
browserName: 'chrome',
version: '58.0',
},
chrome: {
base: 'SauceLabs',
browserName: 'chrome',
},
edge: {
base: 'SauceLabs',
browserName: 'MicrosoftEdge',
},
edge40: {
base: 'SauceLabs',
browserName: 'MicrosoftEdge',
version: '15.15063',
},
edge44: {
base: 'SauceLabs',
browserName: 'MicrosoftEdge',
version: '18.17763',
},
ie11: {
base: 'SauceLabs',
browserName: 'internet explorer',
}
},
// The free account on Sauce does not allow more than 5 concurrent sessions
concurrency: 4,

// REMINDER: Keep this list in sync with the UI tests, in nightwatch.js and .travis.yml.
browsers: [
// latest edge should be added when Microsoft releases the new Edge based on Chromium
'firefox',
'chrome',
'edge40',
'edge44',
'firefox45',
'chrome58'
// Skip unit tests in Internet Explorer due to Promise undefined
// 'ie11'
],
frameworks: ['qunit'],
client: {
qunit: {
autostart: false
}
},
reporters: ['dots'],
logLevel: 'WARN',
files: [
'www/js/lib/require.js',
'tests/init.js',
{ pattern: 'www/**/*', included: false },
{ pattern: 'tests/**/*', included: false }
],
singleRun: true,
autoWatch: false
});
};
Loading

0 comments on commit ee5bf96

Please sign in to comment.