Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

WIP: add E2E test suite unrelated to docs examples #9557

Closed
wants to merge 14 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ var files = require('./angularFiles').files;
var util = require('./lib/grunt/utils.js');
var versionInfo = require('./lib/versions/version-info');
var path = require('path');
var e2e = require('./test/e2e/tools');

module.exports = function(grunt) {
//grunt plugins
@@ -50,6 +51,7 @@ module.exports = function(grunt) {
return [
util.conditionalCsp(),
util.rewrite(),
e2e.middleware(),
connect.favicon('images/favicon.ico'),
connect.static(base),
connect.directory(base)
@@ -76,6 +78,7 @@ module.exports = function(grunt) {
next();
},
util.conditionalCsp(),
e2e.middleware(),
connect.favicon('images/favicon.ico'),
connect.static(base)
];
2 changes: 1 addition & 1 deletion lib/grunt/plugins.js
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ module.exports = function(grunt) {
util.updateWebdriver.call(util, this.async());
});

grunt.registerMultiTask('protractor', 'Run Protractor integration tests', function() {
grunt.registerMultiTask('protractor', 'Run Protractor Docs integration tests', function() {
util.startProtractor.call(util, this.data, this.async());
});

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -60,7 +60,8 @@
"semver": "~4.0.3",
"shelljs": "~0.3.0",
"sorted-object": "^1.0.0",
"stringmap": "^0.2.2"
"stringmap": "^0.2.2",
"cheerio": "^0.17.0"
},
"licenses": [
{
1 change: 1 addition & 0 deletions protractor-conf.js
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
var config = require('./protractor-shared-conf').config;

config.specs = [
'test/e2e/tests/**/*.js',
'build/docs/ptore2e/**/*.js',
'docs/app/e2e/**/*.scenario.js'
];
3 changes: 2 additions & 1 deletion protractor-jenkins-conf.js
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ exports.config = {
allScriptsTimeout: 11000,

specs: [
'test/e2e/tests/**/*.js',
'build/docs/ptore2e/**/*.js',
'docs/app/e2e/*.scenario.js'
],
@@ -30,7 +31,7 @@ exports.config = {

require('jasmine-reporters');
jasmine.getEnv().addReporter(
new jasmine.JUnitXmlReporter('test_out/e2e-' + exports.config.capabilities.browserName + '-', true, true));
new jasmine.JUnitXmlReporter('test_out/docs-e2e-' + exports.config.capabilities.browserName + '-', true, true));
},

jasmineNodeOpts: {
8 changes: 7 additions & 1 deletion scripts/travis/build.sh
Original file line number Diff line number Diff line change
@@ -9,12 +9,18 @@ if [ $JOB = "unit" ]; then
grunt test:promises-aplus
grunt test:unit --browsers SL_Chrome,SL_Safari,SL_Firefox,SL_IE_9,SL_IE_10,SL_IE_11 --reporters dots
grunt tests:docs --browsers SL_Chrome,SL_Safari,SL_Firefox,SL_IE_9,SL_IE_10,SL_IE_11 --reporters dots
grunt test:travis-protractor --specs "docs/app/e2e/**/*.scenario.js"
grunt test:travis-protractor-docs --specs "docs/app/e2e/**/*.scenario.js"
elif [ $JOB = "e2e" ]; then
if [ $TEST_TARGET = "jquery" ]; then
export USE_JQUERY=1
fi

export TARGET_SPECS="build/docs/ptore2e/**/default_test.js"
if [ $TEST_TARGET = "jquery" ]; then
TARGET_SPECS="build/docs/ptore2e/**/jquery_test.js"
fi

export TARGET_SPECS="test/e2e/tests/**/*.js,$TARGET_SPECS"
grunt test:travis-protractor --specs "$TARGET_SPECS"
else
echo "Unknown job type. Please set JOB=unit or JOB=e2e-*."
8 changes: 8 additions & 0 deletions test/e2e/fixtures/.jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"browser": true,
"globals": {
"angular": false,
"jQuery": false,
"$": false
}
}
9 changes: 9 additions & 0 deletions test/e2e/fixtures/sample/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html ng-app="test">
<div ng-controller="TestCtrl">
<p>{{text}}</p>
</div>

<script src="angular.js"></script>
<script src="script.js"></script>
</html>
4 changes: 4 additions & 0 deletions test/e2e/fixtures/sample/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
angular.module("test", []).
controller("TestCtrl", function($scope) {
$scope.text = "Hello, world!";
});
23 changes: 23 additions & 0 deletions test/e2e/templates/test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
{% if eq(test.ngAppTag, "html") %}
<html ng-app="{{ test.ngApp }}">
{% else %}
<html>
{% endif %}
<head>
{% if scripts.jQuery %}
<script src="{{ scripts.jQuery }}"></script>
{% endif %}
{% for script in test.scripts %}
<script src="{{ test.scripts[script] }}"></script>
{% endfor %}
{{ test.head }}
</head>
{% if test.ngAppTag === "body" %}
<body ng-app="{{ test.ngApp }}">
{% else %}
<body>
{% endif %}
{% test.body %}
</body>
</html>
11 changes: 11 additions & 0 deletions test/e2e/tests/.jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"node": true,
"globals": {
"describe": false,
"ddescribe": false,
"xdescribe": false,
"it": false,
"xit": false,
"iit": false
}
}
23 changes: 23 additions & 0 deletions test/e2e/tests/helpers/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
var helper = {
andWaitForAngular: function() {
browser.waitForAngular();
},
loadFixture: function(fixture) {
var i = 0;
while (fixture[i] === '/') ++i;
fixture = fixture.slice(i);
if (!/\/(index\.html)?$/.test(fixture)) {
fixture += '/';
}

if (process.env.USE_JQUERY) {
fixture += '?jquery';
}

browser.get('/e2e/fixtures/' + fixture);
return helper;
}
};

global.test = helper;
global.loadFixture = helper.loadFixture;
12 changes: 12 additions & 0 deletions test/e2e/tests/sampleSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Sample E2E test:
//
describe('Sample', function() {
beforeEach(function() {
loadFixture("sample").andWaitForAngular();
});

it('should have the interpolated text', function() {
expect(element(by.binding('text')).getText())
.toBe('Hello, world!');
});
});
3 changes: 3 additions & 0 deletions test/e2e/tools/.jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"node": true
}
83 changes: 83 additions & 0 deletions test/e2e/tools/fixture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
'use strict';

var fs = require('fs');
var path = require('path');
var $ = require('cheerio');
var util = require('./util');

var root = path.resolve(__dirname, '..');
var fixtures = path.resolve(root, 'fixtures');

var projectRoot = path.resolve(__dirname, '../../..');
var build = path.resolve(projectRoot, 'build');

function rewriteAngularSrc(src, query) {
if (query) {
if (query.build) {
return query.build + '/' + src;
} else if (query.cdn) {
return '//ajax.googleapis.com/ajax/libs/angularjs/' + query.cdn + '/' + src;
}
}
return '/build/' + src;
}

function generateFixture(test, query) {
var indexFile = path.resolve(fixtures, test, 'index.html');
var text = fs.readFileSync(indexFile, 'utf8');

var $$ = $.load(text);

var firstScript = null;
var jquery = null;
var angular = null;
$$('script').each(function(i, script) {
var src = $(script).attr('src');
if (src === 'jquery.js' && jquery === null) jquery = script;
else if (src === 'angular.js' && angular === null) angular = script;
if (firstScript === null) firstScript = script;
if (src) {
var s = util.stat(path.resolve(build, src));
if (s && s.isFile()) {
$(script).attr('src', rewriteAngularSrc(src, query));
} else {
$(script).attr('src', util.rewriteTestFile(test, src));
}
}
});

if (jquery && (!('jquery' in query) || (/^(0|no|false|off|n)$/i).test(query.jquery))) {
$(jquery).remove();
} else if ('jquery' in query) {
if ((/^(0|no|false|off|n)$/i).test(query.jquery)) {
if (jquery) {
$(jquery).remove();
}
} else {
if (!jquery) {
jquery = $.load('<script></script>')('script')[0];
if (firstScript) {
$(firstScript).before(jquery);
} else {
var head = $$('head');
if (head.length) {
head.prepend(jquery);
} else {
$$.root().first().before(jquery);
}
}
}
if (!/^\d+\.\d+.*$/.test(query.jquery)) {
$(jquery).attr('src', '/bower_components/jquery/dist/jquery.js');
} else {
$(jquery).attr('src', '//ajax.googleapis.com/ajax/libs/jquery/' + query.jquery + '/jquery.js');
}
}
}

return $$.html();
}

module.exports = {
generate: generateFixture
};
5 changes: 5 additions & 0 deletions test/e2e/tools/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

module.exports = {
middleware: require('./middleware')
};
44 changes: 44 additions & 0 deletions test/e2e/tools/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
'use strict';

var url = require('url');
var util = require('./util');
var fixture = require('./fixture');

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to have a file level comment of what this does.

module.exports = middlewareFactory;

function middlewareFactory(base) {
base = base || '/e2e';
while (base.length && base[base.length-1] === '/') base = base.slice(0, base.length-1);
var fixture_regexp = new RegExp('^' + base + '/fixtures/([a-zA-Z0-9_-]+)(/(index.html)?)?$');
var static_regexp = new RegExp('^' + base + '/fixtures/([a-zA-Z0-9_-]+)(/.*)$');

return function(req, res, next) {
var match;
var basicUrl = req.url;
var idx = basicUrl.indexOf('?');
if (idx >= 0) {
basicUrl = basicUrl.slice(0, idx);
}
if ((match = fixture_regexp.exec(basicUrl))) {
if (util.testExists(match[1])) {
try {
var query = url.parse(req.url, true).query;
res.write(fixture.generate(match[1], query));
res.end();
} catch (e) {
return next(e);
}
} else {
return next('Fixture ' + match[1] + ' not found.');
}
} else if ((match = static_regexp.exec(basicUrl))) {
var rewritten = util.rewriteTestFile(match[1], match[2]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what base is used for, but it seems that rewriteTestFile will ignore it (and always use '/e2e').
(Haven't taken a proper look yet, so this might be intended.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intended.

There are two "base directories", one is the virtual root of E2E tests, and one is the root of the project tree. Static files are served relative to the root of the project tree, so we rewrite relative to that.

if (rewritten !== false) {
req.url = rewritten;
}
next();
} else {
return next();
}
};
}
41 changes: 41 additions & 0 deletions test/e2e/tools/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

var fs = require('fs');
var path = require('path');
var url = require('url');

var root = path.resolve(__dirname, '..');
var tests = path.resolve(root, 'fixtures');

function stat(path) {
try {
return fs.statSync(path);
} catch (e) {
// Ignore ENOENT.
if (e.code !== 'ENOENT') {
throw e;
}
}
}

function testExists(testname) {
var s = stat(path.resolve(tests, testname));
return s && s.isDirectory();
}

function rewriteTestFile(testname, testfile) {
var i = 0;
while (testfile[i] === '/') ++i;
testfile = testfile.slice(i);
var s = stat(path.resolve(tests, testname, testfile));
if (s && (s.isFile() || s.isDirectory())) {
return ['/test/e2e/fixtures', testname, testfile].join('/');
}
return false;
}

module.exports = {
stat: stat,
testExists: testExists,
rewriteTestFile: rewriteTestFile
};