diff --git a/.gitignore b/.gitignore index bfe865e4..fd2f5784 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ client/test/integration/sandbox/ npm-debug.log client/www/scripts/modules/tracing/tracing.viz.module.js client/www/scripts/vendor +empty-*.tgz +arc-manager.json diff --git a/.npmignore b/.npmignore index 7b73db23..66924c76 100644 --- a/.npmignore +++ b/.npmignore @@ -4,3 +4,5 @@ node_modules client/test/integration/sandbox *-xunit.xml strong-arc-*.tgz +empty-*.tgz +arc-manager.json diff --git a/client/test/e2e/arc/login-logout.spec.js b/client/test/e2e/arc/login-logout.spec.js index c299a60e..7944f581 100644 --- a/client/test/e2e/arc/login-logout.spec.js +++ b/client/test/e2e/arc/login-logout.spec.js @@ -13,6 +13,8 @@ describe('arc-login-logout', function() { loginView.openLoginView(); + browser.sleep(500); + expect(loginView.userNameInput.getText()).toEqual(''); loginView.loginToLandingView(); diff --git a/client/test/e2e/arc/navigation.spec.js b/client/test/e2e/arc/navigation.short.spec.js similarity index 100% rename from client/test/e2e/arc/navigation.spec.js rename to client/test/e2e/arc/navigation.short.spec.js diff --git a/client/test/e2e/arc/views/header-view.js b/client/test/e2e/arc/views/header-view.js index 2333b4a6..a886c4dd 100644 --- a/client/test/e2e/arc/views/header-view.js +++ b/client/test/e2e/arc/views/header-view.js @@ -5,6 +5,7 @@ var ArcHeaderView = (function () { this.accountDropdown = element( by.css('span[data-id="ArcAccountDropdown"] a.dropdown-toggle')); this.logoutLink = element(by.id('arc-user-logout-btn')); + this.homeLink = element(by.css('a[ui-sref="home"]')); this.logout = function() { browser.driver.wait( @@ -18,6 +19,18 @@ var ArcHeaderView = (function () { browser.driver.sleep(500); browser.waitForAngular(); }; + + this.navigateToLandingPage = function () { + browser.driver.wait( + EC.presenceOf(this.homeLink), + 10000); + + this.homeLink.click(); + + browser.driver.wait( + EC.presenceOf(element(by.css('.sl-app-icon-composer'))), + 10000); + }; } return ArcHeaderView; })(); diff --git a/client/test/e2e/build-deploy/views/build-deploy-home-view.js b/client/test/e2e/build-deploy/views/build-deploy-home-view.js index 07cf8d42..58e9ed01 100644 --- a/client/test/e2e/build-deploy/views/build-deploy-home-view.js +++ b/client/test/e2e/build-deploy/views/build-deploy-home-view.js @@ -6,12 +6,59 @@ var BuildDeployHomeView = (function () { this.componentIdentifier = element( by.css('section .sl-build-deploy')); + this.buildButton = element( + by.css('form[name="builduniversal"] .primary')); + this.deployButton = element( + by.css('form[name="deployuniversal"] .primary')); + this.buildSuccessMessage = element( + by.cssContainingText( + 'form[name="builduniversal"]'+ + '[message="build.universal.message"]', 'Success' + ) + ); + this.deploySuccessMessage = element( + by.cssContainingText( + 'form[name="deployuniversal"]' + + ' [message="deploy.universal.message"]', 'Success' + ) + ); this.waitUntilLoaded = function() { browser.driver.wait( EC.presenceOf(self.componentIdentifier), 10000); }; + + this.buildApp = function () { + var self = this; + + browser.driver.wait( + EC.elementToBeClickable(self.buildButton), + 10000); + + self.buildButton.click(); + self.buildButton.click(); + + browser.driver.wait( + EC.visibilityOf(self.buildSuccessMessage), + 500000); + }; + + this.deployApp = function () { + var self = this; + + browser.driver.wait( + EC.elementToBeClickable(self.deployButton), + 10000); + + self.deployButton.click(); + self.deployButton.click(); + + browser.driver.wait( + EC.visibilityOf(self.deploySuccessMessage), + 150000); + }; + } return BuildDeployHomeView; })(); diff --git a/client/test/e2e/composer/datasource.spec.js b/client/test/e2e/composer/datasource.short.spec.js similarity index 100% rename from client/test/e2e/composer/datasource.spec.js rename to client/test/e2e/composer/datasource.short.spec.js diff --git a/client/test/e2e/composer/model.spec.js b/client/test/e2e/composer/model.short.spec.js similarity index 98% rename from client/test/e2e/composer/model.spec.js rename to client/test/e2e/composer/model.short.spec.js index 2d60df17..8b735229 100644 --- a/client/test/e2e/composer/model.spec.js +++ b/client/test/e2e/composer/model.short.spec.js @@ -63,14 +63,14 @@ describe('model-definition-interactions', function() { expect(modelEditorView.getCurrentModelName()).toEqual('mynewmodel'); modelEditorView.addCommentToProperty(0, 'comment1\n'); - browser.sleep(250); + browser.sleep(1000); expect(modelEditorView.getFirstComment()).toEqual('comment1'); browser.sleep(500); modelEditorView.addCommentToProperty(0, 'comment2\n'); - browser.sleep(250); + browser.sleep(1000); expect(modelEditorView.getFirstComment()).toEqual('comment2'); @@ -131,7 +131,7 @@ describe('model-definition-interactions', function() { mainTreeNavView.openFirstModel(); expect(modelEditorView.getCurrentModelName()).toEqual('mynewmodel'); - browser.sleep(750); + browser.sleep(1500); expect(modelEditorView.getCheckedElements().count()).toEqual(3); expect(modelEditorView.getFirstComment()).toEqual('comment2'); diff --git a/client/test/e2e/process-manager/build-test-app.spec.js b/client/test/e2e/process-manager/build-test-app.spec.js new file mode 100644 index 00000000..6d021796 --- /dev/null +++ b/client/test/e2e/process-manager/build-test-app.spec.js @@ -0,0 +1,59 @@ +var ArcViews = require('../arc/views/'); +var ProcessManagerViews = require('../process-manager/views/'); +var BuildDeployViews = require('../build-deploy/views/'); +var EC = protractor.ExpectedConditions; + +describe('process-manager-and-build-deploy-interactions', function () { + beforeEach(function() { + var loginView = new ArcViews.LoginView(); + var landingView = new ArcViews.LandingView(); + + loginView.loginToLandingView(); + landingView.openProcessManagerView(); + }); + + afterEach(function() { + var headerView = new ArcViews.HeaderView(); + + headerView.logout(); + }); + + it('should login and navigate to process manager,' + + 'should add a pm host and activate it (build)', function () { + var processManagerHostView = + new ProcessManagerViews.ProcessManagerHostView(); + var buildDeployHomeView = + new BuildDeployViews.BuildDeployHomeView(); + var headerView = new ArcViews.HeaderView(); + var landingView = new ArcViews.LandingView(); + + + browser.sleep(500); + + processManagerHostView.addNewPMHost( + 'ec2-52-8-216-111.us-west-1.compute.amazonaws.com', '8701' + ); + + headerView.navigateToLandingPage(); + + landingView.openBuildDeployView(); + + browser.sleep(500); + + buildDeployHomeView.buildApp(); + + buildDeployHomeView.deployApp(); + + headerView.navigateToLandingPage(); + + landingView.openProcessManagerView(); + + expect( + EC.visibilityOf( + processManagerHostView.processManagerStatusActive + ) + ); + + processManagerHostView.deleteProcessManagerHost(); + },5000000); +}); diff --git a/client/test/e2e/process-manager/load-balancer.spec.js b/client/test/e2e/process-manager/load-balancer.spec.js index aa0085ee..24b1c15d 100644 --- a/client/test/e2e/process-manager/load-balancer.spec.js +++ b/client/test/e2e/process-manager/load-balancer.spec.js @@ -1,6 +1,5 @@ var ArcViews = require('../arc/views/'); var ProcessManagerViews = require('../process-manager/views/'); -var EC = protractor.ExpectedConditions; describe('load-balancer-interactions', function () { beforeEach(function() { diff --git a/client/test/e2e/process-manager/pm-host.spec.js b/client/test/e2e/process-manager/pm-host.spec.js index 96a0a0e6..51ecbbdc 100644 --- a/client/test/e2e/process-manager/pm-host.spec.js +++ b/client/test/e2e/process-manager/pm-host.spec.js @@ -17,9 +17,9 @@ describe('process-manager-host-interactions', function () { headerView.logout(); }); - it('should login and navigate to process manager,' + + xit('should login and navigate to process manager,' + 'add a valid pm host,', function () { - var processManagerHostView = + var processManagerHostView = new ProcessManagerViews.ProcessManagerHostView(); browser.sleep(500); @@ -36,4 +36,39 @@ describe('process-manager-host-interactions', function () { processManagerHostView.deleteProcessManagerHost(); }); + + it('should login and navigate to process manager,' + + 'should add a pm host and activate it (test)', function () { + var landingView = new ArcViews.LandingView(); + var processManagerHostView = + new ProcessManagerViews.ProcessManagerHostView(); + var processManagerHomeView = + new ProcessManagerViews.ProcessManagerHomeView(); + var headerView = new ArcViews.HeaderView(); + + headerView.navigateToLandingPage(); + browser.driver.wait( + EC.presenceOf(this.processManagerAppCommand), + 10000); + landingView.openProcessManagerView(); + + browser.driver.wait( + EC.visibilityOf(processManagerHomeView.componentIdentifier), + 10000); + processManagerHostView.addNewPMHost( + 'ec2-52-8-216-111.us-west-1.compute.amazonaws.com', '8701' + ); + + processManagerHostView.checkForPMHostMessage(); + + expect( + EC.visibilityOf( + processManagerHostView.processManagerNoApplicationFoundMessage + ) + ); + + processManagerHostView.deleteProcessManagerHost(); + + + }); }); diff --git a/client/test/e2e/process-manager/views/process-manager-home-view.js b/client/test/e2e/process-manager/views/process-manager-home-view.js index a6efae6b..6c174955 100644 --- a/client/test/e2e/process-manager/views/process-manager-home-view.js +++ b/client/test/e2e/process-manager/views/process-manager-home-view.js @@ -2,32 +2,33 @@ var ProcessManagerHomeView = (function () { var EC = protractor.ExpectedConditions; function ProcessManagerHomeView() { - this.loadBalancerButton = element( + var self = this; + self.loadBalancerButton = element( by.css('button[ng-click="toggleManagerLoadBalancer()"]')); - this.loadBalancerForm = element( + self.loadBalancerForm = element( by.css('div .load-balancer-content')); - this.componentIdentifier = element( + self.componentIdentifier = element( by.css('.manager-pm-host-grid') ); - this.waitUntilLoaded = function() { + self.waitUntilLoaded = function() { browser.driver.wait( - EC.presenceOf(this.componentIdentifier), + EC.presenceOf(self.componentIdentifier), 10000); }; - this.openLoadBalancerForm = function () { - var self = this; - this.loadBalancerButton.click(); + self.openLoadBalancerForm = function () { + self.loadBalancerButton.click(); browser.driver.wait( EC.visibilityOf(self.loadBalancerForm), 10000); + }; this.closeLoadBalancerForm = function () { - var self = this; - this.loadBalancerButton.click(); + + self.loadBalancerButton.click(); browser.driver.wait( EC.invisibilityOf(self.loadBalancerForm), diff --git a/client/test/e2e/process-manager/views/process-manager-host-view.js b/client/test/e2e/process-manager/views/process-manager-host-view.js index 89dbb990..f35c8f70 100644 --- a/client/test/e2e/process-manager/views/process-manager-host-view.js +++ b/client/test/e2e/process-manager/views/process-manager-host-view.js @@ -10,12 +10,16 @@ var ProcessManagerHostView = (function () { by.css('button[ng-click="initAddNewPMHost()"]')); this.processManagerActivateButton = element( by.css('button[ng-click="savePM()"]')); - this.processManagerHostErrorIndicator = element( + this.processManagerHostMessageIndicator = element( by.css('.sl-icon-question-mark')); this.processManagerDeleteButton = element( by.css('a[ng-click="deleteHost(host)"]')); + this.processManagerStatusActive = + element(by.css('div.status-field span.status.active')); this.processManagerNoServerMessage = element( by.cssContainingText('h4', 'No Server')); + this.processManagerNoApplicationFoundMessage = element( + by.cssContainingText('h4', 'No Application Found')); this.processManagerErrorMessageCloseButton = element( by.css('button[ng-click="showPopover = false"]')); @@ -40,15 +44,15 @@ var ProcessManagerHostView = (function () { this.processManagerActivateButton.click(); }; - this.checkForPMHostErrors = function () { + this.checkForPMHostMessage = function () { var self = this; browser.driver.wait( - EC.elementToBeClickable(self.processManagerHostErrorIndicator), + EC.elementToBeClickable(self.processManagerHostMessageIndicator), 10000); - self.processManagerHostErrorIndicator.click(); - self.processManagerHostErrorIndicator.click(); + self.processManagerHostMessageIndicator.click(); + self.processManagerHostMessageIndicator.click(); }; this.closeErrorDialog = function () { diff --git a/client/test/e2e/tracing/pm-host-error-view.spec.js b/client/test/e2e/tracing/pm-host-error.short.spec.js similarity index 89% rename from client/test/e2e/tracing/pm-host-error-view.spec.js rename to client/test/e2e/tracing/pm-host-error.short.spec.js index 162917b5..f3d9a163 100644 --- a/client/test/e2e/tracing/pm-host-error-view.spec.js +++ b/client/test/e2e/tracing/pm-host-error.short.spec.js @@ -19,12 +19,13 @@ describe('tracing-interactions', function () { }); it('should login and navigate to process manager,' + - 'add a valid pm host,', function () { - var tracingHomeView = + 'validate error notice', function () { + var tracingHomeView = new TracingViews.TracingHomeView(); - var processManagerHomeView = + var processManagerHomeView = new ProcessManagerViews.ProcessManagerHomeView(); + // TODO: there is no error notice to accept, should there be? // tracingHomeView.acceptErrorNotice(); diff --git a/client/test/e2e/tracing/views/tracing-home-view.js b/client/test/e2e/tracing/views/tracing-home-view.js index 86ebc6d9..87ed4196 100644 --- a/client/test/e2e/tracing/views/tracing-home-view.js +++ b/client/test/e2e/tracing/views/tracing-home-view.js @@ -9,7 +9,7 @@ var TracingHomeView = (function () { this.waitUntilLoaded = function() { browser.driver.wait( - EC.presenceOf(this.componentIdentifier), + EC.visibilityOf(this.componentIdentifier), 10000); }; @@ -19,8 +19,8 @@ var TracingHomeView = (function () { browser.driver.wait( EC.elementToBeClickable( self.dismissErrorButton - ) - ); + ), + 10000); self.dismissErrorButton.click(); }; diff --git a/client/test/protractor.conf.js b/client/test/protractor.conf.js index 1e4367f8..48e39361 100644 --- a/client/test/protractor.conf.js +++ b/client/test/protractor.conf.js @@ -3,9 +3,15 @@ exports.config = { // but I'm not sure what side effects that has, if any directConnect: true, // seleniumAddress: 'http://127.0.0.1:4444/wd/hub', - specs: ['./e2e/**/*.spec.js'], + suites: { + short: './e2e/**/*.short.spec.js', + long: './e2e/**/*.spec.js' + }, framework: 'jasmine2', - jasmineNodeOpts: {isVerbose: true}, + jasmineNodeOpts: { + defaultTimeoutInterval: 60000, + isVerbose: true + }, params: { pm: { host: process.env.TEST_PM_HOST, @@ -39,7 +45,10 @@ exports.config = { return browser.sleep(500); } } - // capabilities: { - // 'browserName': 'firefox' - // } + // multipleCapabilities: [{ + // 'browserName': 'firefox' + // }, + // { + // 'browserName': 'chrome' + // }]; }; diff --git a/client/test/test-server.js b/client/test/test-server.js index b4f093f1..e1b6fde7 100644 --- a/client/test/test-server.js +++ b/client/test/test-server.js @@ -5,7 +5,7 @@ process.env.SL_ARC_FEATURE_FLAGS = 'tracing'; var given = require('loopback-workspace/test/helpers/given'); -var SANDBOX = path.resolve(__dirname, 'sandbox'); +var SANDBOX = path.resolve(__dirname, 'client/test/sandbox'); var ARC_ROOT = path.resolve(__dirname, '..', '..'); var EMPTY_PROJECT = path.resolve(ARC_ROOT, 'examples', 'empty'); @@ -22,6 +22,7 @@ var sandboxNeedsFullReset = false; var arc = require('../../server/server'); var workspace = arc.workspace; + // Inject `POST /reset` to reset the sandbox to initial state arc.post('/reset', function(req, res, next) { console.log('--reset-start--'); diff --git a/gulpfile.js b/gulpfile.js index 842029ce..8450db2e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -185,7 +185,8 @@ gulp.task('test-pm', function() { .pipe(mocha()); }); // WIP -gulp.task('test-e2e', function(callback) { + +function testE2E (callback, testSuite) { var pmContainerID; var webdriver; @@ -210,7 +211,7 @@ gulp.task('test-e2e', function(callback) { testServer.on('message', function(msg) { // async.series([ // // for future tests that require a PM instance - // //startTestPM, + // startTestPM, // // startWebDriver, // ], function(err) { // if (err) { @@ -252,7 +253,7 @@ gulp.task('test-e2e', function(callback) { } function runProtractorTests() { - spawn('protractor', ['client/test/protractor.conf.js'], {stdio: 'inherit'}) + spawn('protractor', [testSuite, 'client/test/protractor.conf.js'], {stdio: 'inherit'}) .on('error', protractorResults) .on('exit', function(code, signal) { var status = signal || code; @@ -262,7 +263,15 @@ gulp.task('test-e2e', function(callback) { } protractorResults(err); - fs.unlink('arc-manager.json'); //fix for this file being created in the root + // ensure test artifacts are removed + //fs.unlink(path.join(__dirname, 'client/test/sandbox/arc-manager.json'), function (err) { + // if (err) throw err; + // console.log('successfully deleted arc-manager.json'); + //}); + //fs.unlink(path.join(__dirname, 'client/test/empty-0.0.0.tgz'), function (err) { + // if (err) throw err; + // console.log('successfully deleted client/test/empty-0.0.0.tgz'); + //}); }); } @@ -285,8 +294,18 @@ gulp.task('test-e2e', function(callback) { } callback(err); } +} + +gulp.task('test-e2e-short', function(callback) { + testE2E(callback, '--suite=short'); +}); + +gulp.task('test-e2e-long', function(callback) { + testE2E(callback, '--suite=long'); }); +gulp.task('test-e2e', ['test-e2e-short']); + gulp.task('test-client-integration', function(callback) { var child = spawn( process.execPath, @@ -317,7 +336,7 @@ gulp.task('test-client-integration', function(callback) { gulp.task('setup-mysql', function(callback) { var ROOT_PASSWORD = process.env.MYSQL_ROOT_PWD || ''; - + setupMysql(ROOT_PASSWORD, function(err) { if (err) logMysqlErrorDescription(err); // Don't fail the build so that more tests will be run