Use node.js for browser-based CI
This commit is contained in:
11
.travis.yml
11
.travis.yml
@@ -1,12 +1,7 @@
|
|||||||
language: ruby
|
language: node_js
|
||||||
cache: bundler
|
node_js:
|
||||||
sudo: false
|
- "11"
|
||||||
|
|
||||||
rvm: 2.5
|
|
||||||
|
|
||||||
before_install:
|
|
||||||
- gem update --system
|
|
||||||
- gem install bundler
|
|
||||||
script: $TEST_COMMAND
|
script: $TEST_COMMAND
|
||||||
|
|
||||||
env:
|
env:
|
||||||
|
|||||||
13
Gruntfile.js
13
Gruntfile.js
@@ -6,15 +6,16 @@ module.exports = function(grunt) {
|
|||||||
pkg: pkg,
|
pkg: pkg,
|
||||||
jshint: require('./grunt/config/jshint.js'),
|
jshint: require('./grunt/config/jshint.js'),
|
||||||
concat: require('./grunt/config/concat.js'),
|
concat: require('./grunt/config/concat.js'),
|
||||||
compass: require('./grunt/config/compass.js'),
|
sass: require('./grunt/config/sass.js'),
|
||||||
compress: require('./grunt/config/compress.js')
|
compress: require('./grunt/config/compress.js'),
|
||||||
|
imageEmbed: require('./grunt/config/imageEmbed.js')
|
||||||
});
|
});
|
||||||
|
|
||||||
require('load-grunt-tasks')(grunt);
|
require('load-grunt-tasks')(grunt);
|
||||||
|
|
||||||
grunt.loadTasks('grunt/tasks');
|
grunt.loadTasks('grunt/tasks');
|
||||||
|
|
||||||
grunt.registerTask('default', ['jshint:all']);
|
grunt.registerTask('default', ['jshint:all', 'sass:dist', "imageEmbed:dist"]);
|
||||||
|
|
||||||
var version = require('./grunt/tasks/version.js');
|
var version = require('./grunt/tasks/version.js');
|
||||||
|
|
||||||
@@ -25,11 +26,11 @@ module.exports = function(grunt) {
|
|||||||
grunt.registerTask('buildDistribution',
|
grunt.registerTask('buildDistribution',
|
||||||
'Builds and lints jasmine.js, jasmine-html.js, jasmine.css',
|
'Builds and lints jasmine.js, jasmine-html.js, jasmine.css',
|
||||||
[
|
[
|
||||||
'compass',
|
'sass:dist',
|
||||||
|
"imageEmbed:dist",
|
||||||
'jshint:beforeConcat',
|
'jshint:beforeConcat',
|
||||||
'concat',
|
'concat',
|
||||||
'jshint:afterConcat',
|
'jshint:afterConcat'
|
||||||
'build:copyVersionToGem'
|
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
150
ci.js
Normal file
150
ci.js
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
const path = require("path"),
|
||||||
|
port = 3000,
|
||||||
|
colors = {
|
||||||
|
"passed" : "\x1B[32m",
|
||||||
|
"failed": "\x1B[31m",
|
||||||
|
"pending": "\x1B[33m",
|
||||||
|
"none": "\x1B[0m"
|
||||||
|
};
|
||||||
|
symbols = {
|
||||||
|
"passed" : ".",
|
||||||
|
"failed": "F",
|
||||||
|
"pending": "*",
|
||||||
|
"none": ""
|
||||||
|
},
|
||||||
|
host = `http://localhost:${port}`,
|
||||||
|
exitCode = 0;
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const html = await (() => {
|
||||||
|
console.log("Generating index.html for express app...");
|
||||||
|
const pug = require("pug"),
|
||||||
|
fg = require("fast-glob"),
|
||||||
|
patterns = [
|
||||||
|
"lib/jasmine-core/jasmine.js",
|
||||||
|
"lib/jasmine-core/json2.js",
|
||||||
|
"lib/jasmine-core/jasmine-html.js",
|
||||||
|
"lib/jasmine-core/boot.js",
|
||||||
|
"src/core/requireCore.js",
|
||||||
|
"src/core/base.js",
|
||||||
|
"src/core/util.js",
|
||||||
|
"src/core/Spec.js",
|
||||||
|
"src/core/Env.js",
|
||||||
|
"src/**/*.js",
|
||||||
|
"spec/helpers/*.js",
|
||||||
|
"spec/**/*[Ss]pec.js"
|
||||||
|
],
|
||||||
|
ignore = [
|
||||||
|
"spec/helpers/nodeDefineJasmineUnderTest.js",
|
||||||
|
"spec/npmPackage/**/*",
|
||||||
|
"lib/jasmine-core/node_boot.js"
|
||||||
|
];
|
||||||
|
files = fg.sync(patterns, {ignore});
|
||||||
|
return Promise.resolve(pug.compileFile(path.resolve(__dirname, "index.pug"), { pretty: true })({files}));
|
||||||
|
})();
|
||||||
|
|
||||||
|
await (() => new Promise(resolve => {
|
||||||
|
console.log("Creating an express app for browers to run the tests...")
|
||||||
|
const express = require("express"),
|
||||||
|
app = express();
|
||||||
|
|
||||||
|
app.use(express.static(__dirname));
|
||||||
|
app.get("/", (req, res) => res.send(html));
|
||||||
|
app.listen(port, resolve);
|
||||||
|
}))();
|
||||||
|
|
||||||
|
const driver = await (() => new Promise(resolve => (async () => {
|
||||||
|
console.log("Running the tests in browser...")
|
||||||
|
const webdriver = require("selenium-webdriver"),
|
||||||
|
driver = new webdriver.Builder()
|
||||||
|
.forBrowser(process.env["JASMINE_BROWSER"] || "firefox")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
await driver.get(`${host}/?throwFailures=false&failFast=false&random=true`)
|
||||||
|
const intervalId = setInterval(async () => {
|
||||||
|
const isFinished = await driver.executeScript("return jsApiReporter && jsApiReporter.finished")
|
||||||
|
if (isFinished) {
|
||||||
|
clearInterval(intervalId)
|
||||||
|
resolve(driver)
|
||||||
|
}
|
||||||
|
}, 500)
|
||||||
|
})()))();
|
||||||
|
|
||||||
|
await (() => new Promise(resolve => (async () => {
|
||||||
|
// output the summary
|
||||||
|
(await driver.executeScript("return jsApiReporter && jsApiReporter.specs().map(function(spec) { return spec.status })"))
|
||||||
|
.map(status => `${colors[status]}${symbols[status]}`).join("") + colors["none"];
|
||||||
|
resolve();
|
||||||
|
})()))();
|
||||||
|
|
||||||
|
await (() => new Promise(resolve => (async () => {
|
||||||
|
// output the pending and failure details
|
||||||
|
const result = (await driver.executeScript("return jsApiReporter && jsApiReporter.specs().filter(function(spec) { return spec.status !== \"passed\" })"))
|
||||||
|
.reduce((result, spec) => {
|
||||||
|
result[spec.status] = result[spec.status] || [];
|
||||||
|
result[spec.status] = [...result[spec.status], spec];
|
||||||
|
return result;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
if ((result["pending"] || []).length) {
|
||||||
|
console.log(`${colors["pending"]}Pending:`);
|
||||||
|
result["pending"].forEach((spec, index) => {
|
||||||
|
console.log(`${colors["none"]}${index}) ${spec.fullName}`)
|
||||||
|
console.group();
|
||||||
|
console.log(`${colors["pending"]}${spec.pendingReason || "no reason given"}`);
|
||||||
|
console.groupEnd();
|
||||||
|
console.log();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result["failed"] || []).length) {
|
||||||
|
exitCode = 1
|
||||||
|
console.log(`${colors["failed"]}Failed:`);
|
||||||
|
result["failed"].forEach((spec, index) => {
|
||||||
|
console.log(`${colors["none"]}${index}) ${spec.fullName}`)
|
||||||
|
console.group();
|
||||||
|
spec.failedExpectations.forEach((expect) => {
|
||||||
|
console.log(`${colors["none"]}Message:`);
|
||||||
|
console.group();
|
||||||
|
console.log(`${colors["failed"]}${expect.message}`);
|
||||||
|
console.groupEnd();
|
||||||
|
console.log(`${colors["none"]}Stack:`);
|
||||||
|
console.group();
|
||||||
|
console.log(`${colors["failed"]}${expect.stack}`);
|
||||||
|
console.groupEnd();
|
||||||
|
console.groupEnd();
|
||||||
|
})
|
||||||
|
console.groupEnd();
|
||||||
|
console.log();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
})()))();
|
||||||
|
|
||||||
|
await (() => new Promise(resolve => (async () => {
|
||||||
|
const result = await driver.executeScript(`
|
||||||
|
return {
|
||||||
|
executionTime: jsApiReporter.executionTime(),
|
||||||
|
random: jsApiReporter.runDetails.order.random,
|
||||||
|
seed: jsApiReporter.runDetails.order.seed,
|
||||||
|
specCount: jsApiReporter.specs().length,
|
||||||
|
failureCount: jsApiReporter.specs().filter(function (spec) { return spec.status === \"failed\" }).length,
|
||||||
|
pendingCount: jsApiReporter.specs().filter(function (spec) { return spec.status === \"pending\" }).length
|
||||||
|
}`);
|
||||||
|
|
||||||
|
if (result.specCount > 0) {
|
||||||
|
console.log(`${colors["none"]}${result.specCount} spec(s), ${result.failureCount} failure(s), ${result.pendingCount} pending spec(s)`);
|
||||||
|
console.log(`Finished in ${result.executionTime / 1000} second(s)`);
|
||||||
|
console.log(`Randomized with seed ${result.seed} ( ${host}/?random=${result.random}&seed=${result.seed} )`);
|
||||||
|
} else {
|
||||||
|
console.log(`No specs found`)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
|
})()))();
|
||||||
|
|
||||||
|
await driver.close();
|
||||||
|
process.exit(exitCode);
|
||||||
|
})()
|
||||||
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
jasmine: {
|
|
||||||
options: {
|
|
||||||
cssDir: 'lib/jasmine-core/',
|
|
||||||
sassDir: 'src/html',
|
|
||||||
outputStyle: 'compact',
|
|
||||||
noLineComments: true,
|
|
||||||
bundleExec: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
7
grunt/config/imageEmbed.js
Normal file
7
grunt/config/imageEmbed.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
module.exports = {
|
||||||
|
dist: {
|
||||||
|
src: [ "lib/jasmine-core/jasmine.css" ],
|
||||||
|
dest: "lib/jasmine-core/jasmine.css",
|
||||||
|
baseDir: "images"
|
||||||
|
}
|
||||||
|
};
|
||||||
14
grunt/config/sass.js
Normal file
14
grunt/config/sass.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const sass = require('node-sass');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
options: {
|
||||||
|
implementation: sass,
|
||||||
|
outputStyle: 'compact',
|
||||||
|
sourceComments: false
|
||||||
|
},
|
||||||
|
dist: {
|
||||||
|
files: {
|
||||||
|
"lib/jasmine-core/jasmine.css": "src/html/jasmine.scss"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
10
index.pug
Normal file
10
index.pug
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
html
|
||||||
|
head
|
||||||
|
title Jasmine suite
|
||||||
|
link(rel="shortcut icon" href="images/jasmine_favicon.png" type="image/png")
|
||||||
|
link(rel="stylesheet" href="lib/jasmine-core/jasmine.css" type="text/css" media="screen")
|
||||||
|
-
|
||||||
|
each file in files
|
||||||
|
script(src=file type="text/javascript")
|
||||||
|
body
|
||||||
File diff suppressed because one or more lines are too long
@@ -19,16 +19,22 @@
|
|||||||
"homepage": "https://jasmine.github.io",
|
"homepage": "https://jasmine.github.io",
|
||||||
"main": "./lib/jasmine-core.js",
|
"main": "./lib/jasmine-core.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"express": "^4.16.4",
|
||||||
|
"fast-glob": "^2.2.6",
|
||||||
"glob": "^7.1.3",
|
"glob": "^7.1.3",
|
||||||
"grunt": "^1.0.3",
|
"grunt": "^1.0.3",
|
||||||
"grunt-cli": "^1.3.2",
|
"grunt-cli": "^1.3.2",
|
||||||
"grunt-contrib-compass": "^1.1.1",
|
|
||||||
"grunt-contrib-compress": "^1.3.0",
|
"grunt-contrib-compress": "^1.3.0",
|
||||||
"grunt-contrib-concat": "^1.0.1",
|
"grunt-contrib-concat": "^1.0.1",
|
||||||
"grunt-contrib-jshint": "^2.0.0",
|
"grunt-contrib-jshint": "^2.0.0",
|
||||||
|
"grunt-image-embed": "^0.3.3",
|
||||||
|
"grunt-sass": "^3.0.2",
|
||||||
"jasmine": "^3.3.1",
|
"jasmine": "^3.3.1",
|
||||||
"jsdom": "^13.1.0",
|
"jsdom": "^13.1.0",
|
||||||
"load-grunt-tasks": "^4.0.0",
|
"load-grunt-tasks": "^4.0.0",
|
||||||
|
"node-sass": "^4.11.0",
|
||||||
|
"pug": "^2.0.3",
|
||||||
|
"selenium-webdriver": "^3.6.0",
|
||||||
"shelljs": "^0.8.3",
|
"shelljs": "^0.8.3",
|
||||||
"temp": "^0.9.0"
|
"temp": "^0.9.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
@import "compass";
|
|
||||||
|
|
||||||
$line-height: 14px;
|
$line-height: 14px;
|
||||||
$margin-unit: 14px;
|
$margin-unit: 14px;
|
||||||
|
|
||||||
@@ -68,9 +66,12 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.jasmine-banner .jasmine-title {
|
.jasmine-banner .jasmine-title {
|
||||||
background: inline-image('jasmine-horizontal.png') no-repeat;
|
background: url('../../images/jasmine-horizontal.png') no-repeat;
|
||||||
background: inline-image('jasmine-horizontal.svg') no-repeat, none;
|
background: url('../../images/jasmine-horizontal.svg') no-repeat, none;
|
||||||
@include background-size(100%);
|
-moz-background-size: 100%;
|
||||||
|
-o-background-size: 100%;
|
||||||
|
-webkit-background-size: 100%;
|
||||||
|
background-size: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
width: 90px;
|
width: 90px;
|
||||||
@@ -110,7 +111,7 @@ body {
|
|||||||
//--- Symbol summary ---//
|
//--- Symbol summary ---//
|
||||||
|
|
||||||
.jasmine-symbol-summary {
|
.jasmine-symbol-summary {
|
||||||
@include clearfix;
|
overflow: hidden;
|
||||||
margin: $line-height 0;
|
margin: $line-height 0;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
bundle exec rake jasmine:ci
|
node ci.js
|
||||||
|
|||||||
@@ -11,4 +11,9 @@ if [ "$1" = "v4" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
|
if [ "$1" = "v8" ] || [ "$1" = "v9" ]; then
|
||||||
|
npm rebuild node-sass --force
|
||||||
|
fi
|
||||||
|
|
||||||
npm test
|
npm test
|
||||||
|
|||||||
Reference in New Issue
Block a user