===== Protractor =====
Is an **end-to-end testing** JavaScript solution.
* Executes the real application using selenium
* Run the tests against it
Protractor is nothing but a wrapper over the Selenium WebDriverJS Api that translates its succinct code and methods to WebDriver JS methods. That said, you can use WebDriverJS methods too inside your e2e script.
https://medium.com/paramsingh-66174/automate-e2e-testing-of-angular-4-apps-with-protractorjs-jasmine-fcf1dd9524d5
{{https://lh6.googleusercontent.com/-57e_I3NlcRQ/VTLHygh_5_I/AAAAAAAACKo/kLsPoEw5CPI/w1024-h768-no/Protractor.jpg}}
===== UI Tests =====
====== package.json ======
NPM dependency configs.
{
"name": "ui",
"version": "1.0.0",
"description": "This is a reference implementation of the Selenium test using javascript.",
"main": "conf.js",
"directories": {
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "0.19.0",
"dotenv": "8.1.0",
"jasmine-allure-reporter": "^0.2.3",
"protractor": "^5.4.4",
"protractor-jasmine2-html-reporter": "0.0.7",
"proxy-agent": "3.1.0",
"request": "2.88.0",
"request-promise": "^4.2.4"
},
"devDependencies": {
"jasmine-reporters": "^2.0.0"
}
}
====== Execution script ======
This script sets the environment variables, which then are passed into the
config files and then may be used in the tests.
if [ $# -eq 0 ]
then
echo "Please provide the environment: dev or stage"
exit 1
fi
#update IDs prior to processing Spec
if [ $1 == 'stage' ]
then
export APIURL=my.api.com
export SPACE_NAME="1.001"
export BUILDINGIDB=03fjvA5B1CWOG33uprLUQT
export SPACE_ISPARTOF=b5c703a7-627d-4562-ba2c-6399557c670d
export DEVICE_NAME="Sensor_block:T&LQ:1138260"
export DEVICE_SOURCE="3TYhTs\$S924vrYvWDC_1_z"
export DEVICE_TAG=air
export DEVICE_ISLOCATEDIN=233ffa56-c569-4ece-8781-23e021a8d990
export EQUIPMENT_NAME="Sensor_block:T&LQ:1138260"
export EQUIPMENT_SOURCE="3TYhTs\$S924vrYvWDC_1_z"
export EQUIPMENT_TAG=air
export EQUIPMENT_ISLOCATEDIN=233ffa56-c569-4ece-8781-23e021a8d990
export TEST_ID=7890
export FILE_ID=42be5ad2-fb95-4a3b-b4b9-c1a87699b711
elif [ $1 == 'dev' ]
then
export APIURL=my.api.com
export FLOOR_NAME=1OG
export SPACE_NAME="1.001"
export BUILDINGIDB=03fjvA5B1CWOG33uprLUQT
export SPACE_ISPARTOF=6bfed7de-ccbc-4780-b834-5d8cbf73560f
export DEVICE_NAME="Sensor_block:T&LQ:1138260"
export DEVICE_SOURCE="3TYhTs\$S924vrYvWDC_1_z"
export DEVICE_TAG=air
export DEVICE_ISLOCATEDIN=37124033-c860-43d0-b468-92b58198fbcb
export EQUIPMENT_NAME="Sensor_block:T&LQ:1138260"
export EQUIPMENT_SOURCE="3TYhTs\$S924vrYvWDC_1_z"
export EQUIPMENT_TAG=air
export EQUIPMENT_ISLOCATEDIN=37124033-c860-43d0-b468-92b58198fbcb
export TEST_ID=1234
export FILE_ID=2f6a1ae7-6a88-41a8-b2ba-bbf6f06ccf63
fi
export TARGETAWSACCOUNT=$1
export TOKEN_ENDPOINT=https://myoauthserver.com/oauth/token
export TOKEN_AUDIENCE=https://api.myapplication.com/
export TOKEN_DEFAULT=$(node createToken.js clientDefault)
echo $TOKEN_DEFAULT
export TOKEN_ALICE=$(node createToken.js clientAlice)
echo $TOKEN_ALICE
export TOKEN_BOB=$(node createToken.js clientBob)
echo $TOKEN_BOB
export TOKEN_AUTH=$(node createTokenAuth.js)
echo $TOKEN_AUTH
echo $API_URL
export LOG_REQUESTS=true
protractor test_config.js --suite $TARGETAWSACCOUNT
##protractor test_config.js
====== Configs ======
To configure the protractor you will need the configs
=== config.js ===
The file where the environment variables are injected into the JS
require('dotenv').config();
module.exports = {
seleniumAddress: process.env.SELENIUM_ADDRESS,
issuer:{
endpoint: process.env.TOKEN_ENDPOINT,
audience: process.env.TOKEN_AUDIENCE,
audience_auth: process.env.AUDIENCE_AUTH
},
params: {
apiUrl: process.env.APIURL,
buildingIdB: process.env.BUILDINGIDB,
floorName: process.env.FLOOR_NAME,
spaceName: process.env.SPACE_NAME,
spaceSource: process.env.SPACE_SOURCE,
spaceIsPartOf: process.env.SPACE_ISPARTOF,
deviceName: process.env.DEVICE_NAME,
deviceSource: process.env.DEVICE_SOURCE,
deviceTag: process.env.DEVICE_TAG,
deviceIsLocatedIn: process.env.DEVICE_ISLOCATEDIN,
equipName: process.env.EQUIPMENT_NAME,
equipSource: process.env.EQUIPMENT_SOURCE,
equipTag: process.env.EQUIPMENT_TAG,
equipIsLocatedIn: process.env.EQUIPMENT_ISLOCATEDIN,
testID: process.env.TEST_ID,
fileID: process.env.FILE_ID
},
clientDefault: {
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET
},
clientAlice: {
clientId: process.env.ALICE_CLIENT_ID,
clientSecret: process.env.ALICE_CLIENT_SECRET
},
clientBob: {
clientId: process.env.BOB_CLIENT_ID,
clientSecret: process.env.BOB_CLIENT_SECRET
},
clientAuth: {
clientId: process.env.CLIENT_ID_AUTH,
clientSecret: process.env.CLIENT_SECRET_AUTH
},
token:{
default: process.env.TOKEN_DEFAULT,
alice: process.env.TOKEN_ALICE,
bob: process.env.TOKEN_BOB,
auth: process.env.TOKEN_AUTH
},
target:{
url: process.env.URL,
auth_url: process.env.API_AUTH_URL
}
}
====== test_config.js ======
This is the configuration file used by protractor for managing any config parameter used globally within the web application.
Uses the config.js file
require('dotenv').config();
let options = require("./config");
var Jasmine2HtmlReporter = require('protractor-jasmine2-html-reporter');
exports.config = {
framework: 'jasmine',
seleniumAddress: options.seleniumAddress,
//specs is used for when calling protractor without passing suites to run
specs: ['spec/API_Widgets_tests.js',
'spec/Functional_tests.js',
'spec/API_CRUD_tests.js',
'spec/Negative_tests.js',
'spec/Filters_tests.js',
'spec/Negative_Filters_tests.js',
'spec/UI_tests_Main.js',
'spec/UI_tests.js',
'spec/UI_tests_files.js',
'spec/UI_tests_NavVis',
'spec/Auth_UI_tests.js'],
//'spec/UI_tests_NavVis.js'],
// //'spec/UI_tests_api_reference.js'],
//specs: ['spec/API_CRUD_tests.js'],
//Suites defined to run tests on Dev or Stage
suites: {
//dev: 'spec/*.js',
// dev: ['spec/Functional_tests.js',
// 'spec/Negative_tests.js',
// 'spec/Filters_tests.js',
// 'spec/Negative_Filters_tests.js',
// // 'spec/UI_tests.js',
// // 'spec/UI_tests_files.js',
// // 'spec/UI_tests_Main.js',
// // 'spec/UI_tests_template.js',
// 'spec/API_Widgets_tests.js',
// 'spec/API_CRUD_tests.js',
// 'spec/Auth_UI_tests.js'],
dev: ['spec/Auth_UI_tests.js'],
// stage: ['spec/API_CRUD_tests.js',
// 'spec/Negative_tests.js',
// 'spec/Filters_tests.js',
// 'spec/Negative_Filters_tests.js',
// 'spec/API_Widgets_tests.js',
// 'spec/UI_tests.js',
// 'spec/UI_tests_files.js',
// 'spec/API_CRUD_tests.js',
// 'spec/UI_tests_Main.js',
// 'spec/Auth_UI_tests.js']
stage: ['spec/Auth_UI_tests.js']
},
onPrepare: function () {
browser.driver.manage().window().maximize();
jasmine.getEnv().addReporter(new Jasmine2HtmlReporter({
savePath: './test/reports/',
screenshotsFolder: 'images',
takeScreenshots: true,
takeScreenshotsOnlyOnFailures: true,
fixedScreenshotName: true,
showPassed: false,
filePrefix: 'SeleniumReport'
// consolidate: false,
// consolidateAll: false
}));
var AllureReporter = require('./node_modules/jasmine-allure-reporter');
jasmine.getEnv().addReporter(new AllureReporter({
resultsDir: 'test/allure-results/'
}));
var jasmineReporters = require('./node_modules/jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
savePath: 'test/reports',
filePrefix: 'xmloutput'
})
)
},
ignoreUncaughtExceptions: true,
capabilities: {
browserName: 'chrome',
noGlobals: false,
binary: 'C:/Program Files/ChromePortable/App/Chrome-bin/chrome.exe',
//shardTestFiles: true,
//maxInstances:7,
chromeOptions: {
useAutomationExtension: false,
args: ["--headless",
"--disable-gpu",
"--disable-browser-side-navigation",
"--disable-infobars",
"--no-sandbox",
"--window-size=1200,900"]
// args: [ "--window-size=1400,900" ]
}
},
// capabilities: {
// browserName: 'firefox',
// 'moz:firefoxOptions': {
// args: ['--verbose'],
// binary: 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe'
// //Provide binary location to avoid potential binary not found errors
// //Need to start cmd via admin mode to avoid permission error
// }
// },
// capabilities: {
// browserName: 'chrome',
// noGlobals: false,
// //shardTestFiles: true,
// //maxInstances:7,
// chromeOptions: {
// useAutomationExtension: false,
// args: ["--headless",
// "--disable-gpu",
// "--disable-browser-side-navigation",
// "--disable-infobars",
// "--no-sandbox",
// "--window-size=1200,900"]
// // args: [ "--window-size=1400,900" ]
// }
// },
// TODO: Initial work proves multi browser testing works.
// multiCapabilities: [
// {'browserName': 'chrome',
// 'chromeOptions': {
// 'args': ['disable-infobars']
// }
// },
// {'browserName': 'firefox',
// 'moz:firefoxOptions': {
// 'args': ['--safe-mode']
// }
// }
// ],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 90000, //increased to 30 seconds
},
params: {
gWidgetID: 'empty',
gCampusID: 'empty'
}
}
====== Example test ======
In the test the injected environment variables can be retireved via **config.params**
Example:
config.params.apiUrl
require('dotenv').config();
var config = require('../lib/config');
var common = require('../lib/common');
const { element, browser } = require('protractor');
var EC = protractor.ExpectedConditions;
describe('UI Tests - Files', function() {
//Initialization of test case
common.SetupInitialize("UI_tests_files.js");
//Login, Navigate to Building B files, validate that it loads
it('TCER_ID-195611: Building B - Loads files', function () {
apiUrl = config.params.apiUrl;
var fPlans = element.all(by.cssContainingText('span', '2D Plans')).first();
var fsvg = element.all(by.cssContainingText('td', '.svg')).first();
var fThisIs = element.all(by.cssContainingText('td', 'This is a')).first();
browser.get(apiUrl + 'app/building/' + config.params.buildingIdB + '/files');
browser.wait(EC.visibilityOf(fPlans, 10000));
fPlans.click();
browser.wait(EC.visibilityOf(fsvg, 9000));
expect(fsvg).not.toBe(null);
browser.wait(EC.visibilityOf(fThisIs, 15000));
expect(fThisIs).not.toBe(null);
});
/*
* Confirm details content is present and viable for ifc file
* */
it('Building B - Details content is present',() => {
element.all(by.cssContainingText('td', '.svg')).first().click();
browser.sleep(1000);
browser.wait(EC.visibilityOf(element.all(by.css('.marengo-double-left')).first(), 15000));
element.all(by.css('.marengo-double-left')).first().click();
var detailsDrawer = element(by.css('.right-drawer-border.float-left'));
expect(detailsDrawer.isPresent()).toBe(true);
browser.sleep(1000);
var filterBox = element(by.css('.filter-box'));
browser.wait(EC.visibilityOf(filterBox),15000);
expect(filterBox.isPresent()).toBe(true);
expect(filterBox.getText()).toBe('System generated floorplan');
expect(element(by.css('.img-thumbnail')).isPresent()).toBe(true);
var labels = element.all(by.css('.col-form-label'));
var texts = element.all(by.css('.form-text'));
expect(labels.get(2).getText()).toBe('Last update');
expect(labels.get(3).getText()).toBe('Updated By');
expect(labels.get(4).getText()).toBe('Size');
expect(labels.get(5).getText()).toBe('Version');
expect(labels.get(6).getText()).toBe('Source IFC:');
//expect(texts.get(5).getText()).toContain('buildingB.ifc'); <- issues on dev with name of file
element(by.css('.marengo-double-right')).click();
browser.sleep(1000);
element(by.cssContainingText('.files-breadcrumb', 'Building Files')).click();
browser.sleep(3000);
var columns = element.all(by.css('.ui-sortable-column'));
browser.wait(EC.visibilityOf(columns.get(0)),9000);
columns.get(0).click();
expect(columns.get(0).isPresent()).toBe(true);
});
/*
* IFC that is source for should not be able to be deleted.
* */
it('Building B - check ifc delete option', function() {
browser.sleep(3000);
var ifcFile = element(by.cssContainingText('td', '.ifc'));
browser.wait(EC.visibilityOf(ifcFile),15000);
ifcFile.click();
browser.sleep(4000);
element(by.cssContainingText('.nav-item-title', 'More')).click();
browser.wait(EC.presenceOf(element(by.css('.navigator-delete')) ),17000);
//dropdown-item-icon navigator-delete ng-star-inserted
browser.sleep(3500);
expect(element(by.cssContainingText('.dropdown-item.disabled', 'Delete')).isPresent()).toBe(true);
});
/*
* Renaming of building files
* Ensure that file name changes are propogated through both rename option and edit option
* */
describe('Building B - Rename functions', function(){
it ('Building B - rename file via More Rename button', function(){
var ifcFile = element(by.cssContainingText('td', '.ifc'));
browser.wait(EC.visibilityOf(ifcFile),15000);
ifcFile.click();
element(by.cssContainingText('.nav-item-title', 'More')).click();
element(by.cssContainingText('.dropdown-item-text', 'Rename')).click();
var displayName = element.all(by.css('input[name="displayName"]')).first();
var btnPrimary = element(by.css('.btn-primary'));
browser.wait(EC.visibilityOf(displayName, 10000));
displayName.clear();
displayName.sendKeys('buildingB1');
btnPrimary.click();
browser.sleep(1000);
browser.wait(EC.visibilityOf(element(by.cssContainingText('.toast-message', 'Rename successful')), 15000));
browser.wait(EC.visibilityOf(element(by.cssContainingText('td', 'buildingB1.ifc')), 15000));
expect(ifcFile.getText()).toBe('buildingB1.ifc');
});
it ('Building B - rename file back via More Rename button', function(){
browser.sleep(1000);
var displayName = element.all(by.css('input[name="displayName"]')).first();
var btnPrimary = element(by.css('.btn-primary'));
var ifcFile = element(by.cssContainingText('td', '.ifc'));
element(by.cssContainingText('.nav-item-title', 'More')).click();
element(by.cssContainingText('.dropdown-item-text', 'Rename')).click();
browser.wait(EC.visibilityOf(displayName, 3000));
displayName.clear();
displayName.sendKeys('buildingB');
//browser.wait(EC.invisibilityOf(element.all(by.css('.toast-message.ng-star-inserted')).first()),15000);
browser.wait(EC.visibilityOf(element(by.cssContainingText('.toast-message', 'Rename successful')), 15000));
btnPrimary.click();
browser.wait(EC.visibilityOf(element(by.cssContainingText('td', 'buildingB.ifc')), 15000));
expect(ifcFile.getText()).toBe('buildingB.ifc');
browser.sleep(1000);
});
it ('Building B - rename file via More Edit button', function(){
browser.sleep(1000);
var displayName = element.all(by.css('input[name="displayName"]')).first();
var btnPrimary = element(by.css('.btn-primary'));
var ifcFile = element(by.cssContainingText('td', '.ifc'));
browser.wait(EC.visibilityOf(element(by.cssContainingText('.nav-item-title', 'More')), 15000));
element(by.cssContainingText('.nav-item-title', 'More')).click();
element(by.cssContainingText('.dropdown-item-text', 'Edit')).click();
browser.wait(EC.visibilityOf(displayName, 3000));
displayName.clear();
displayName.sendKeys('buildingB1');
displayName.click();
browser.sleep(5000);
browser.wait(EC.visibilityOf(btnPrimary),14000);
btnPrimary.click();
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('.col', 'buildingB1.ifc')).first()),25000);
var arrowRight = element(by.css(".marengo-double-right"));
expect(ifcFile.getText()).toBe('buildingB1.ifc');
});
it ('Building B - rename file back from More Edit button', function(){
browser.sleep(2000);
var displayName = element.all(by.css('input[name="displayName"]')).first();
var btnPrimary = element(by.css('.btn-primary'));
var ifcFile = element(by.cssContainingText('td', '.ifc'));
element(by.cssContainingText('.nav-item-title', 'More')).click();
browser.wait(EC.visibilityOf(element(by.cssContainingText('.dropdown-item-text', 'Edit'))),15000);
element(by.cssContainingText('.dropdown-item-text', 'Edit')).click();
browser.sleep(1000);
browser.wait(EC.visibilityOf(displayName, 7000));
displayName.clear();
displayName.sendKeys('buildingB');
browser.sleep(1000);
expect(btnPrimary.isEnabled()).toBe(true);
btnPrimary.click();
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('.col', 'buildingB.ifc')).first()),25000);
//var arrowRight = element(by.css(".marengo-double-right"));
//arrowRight.click();
});
it ('Building B - check file name is back to default text', function(){
var ifcFile = element(by.cssContainingText('td', '.ifc'));
var arrowRight = element(by.css(".marengo-double-right"));
arrowRight.isPresent().then(function(result) {
if (result) {
browser.wait(EC.visibilityOf(arrowRight),25000);
arrowRight.click();
browser.wait(EC.visibilityOf(element(by.cssContainingText('td', 'buildingB.ifc')), 15000));
expect(ifcFile.getText()).toBe('buildingB.ifc');
browser.sleep(1000);
}
});
});
/* Neg case - Long building names
* Ensure that building names past api allowable length result in an error
* */
it('Building B - negative - rename file - check toast message', function() {
console.log('Building B - negative - rename file - check toast message');
var ifcFile = element(by.cssContainingText('td', '.ifc'));
var toastMessage = element(by.cssContainingText('.toast-message', 'Unable to update file information'));
browser.wait(EC.visibilityOf(ifcFile),10000);
ifcFile.click();
element(by.cssContainingText('.nav-item-title', 'More')).click();
element(by.cssContainingText('.dropdown-item-text', 'Edit')).click();
browser.sleep(1500);
var displayName = element.all(by.css('input[name="displayName"]')).first();
browser.wait(EC.visibilityOf(displayName, 9000));
displayName.sendKeys('MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMHMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM');
//change file name to a value we know will fail
browser.wait(EC.visibilityOf(element(by.css('.btn-primary'))),25000);
element(by.css('.btn-primary')).click();
//TODO:forced to add .sleep method below due to high delay in response from application
browser.sleep(4000);
browser.wait(EC.visibilityOf(toastMessage, 35000));
expect(toastMessage.getText()).toBe('Unable to update file information');
toastMessage.click();
//close toast message
});
it('Building B - negative - rename file - verify default name', function() {
var ifcFile = element(by.cssContainingText('td', '.ifc'));
var arrowRight = element(by.css(".marengo-double-right"));
browser.wait(EC.visibilityOf(arrowRight),5000);
arrowRight.click();
// close side menu
browser.wait(EC.visibilityOf(ifcFile),20000);
expect(ifcFile.getText()).toBe('buildingB.ifc');
});
it('Building B - add file description', function() {
element(by.cssContainingText('.nav-item-title', 'More')).click();
element(by.cssContainingText('.dropdown-item-text', 'Edit')).click();
browser.sleep(1500);
var txtDescription = element(by.name('description'));
browser.wait(EC.visibilityOf(txtDescription),7000);
txtDescription.clear();
txtDescription.sendKeys('description text');
element(by.cssContainingText('.btn-primary', 'Save')).click();
browser.wait(EC.visibilityOf(element(by.linkText('History'))), 69000);
expect(element(by.id('description')).getText()).toBe('description text');
browser.sleep(3000);
});
it('Building B - remove file description', function() {
element(by.cssContainingText('.nav-item-title', 'More')).click();
element(by.cssContainingText('.dropdown-item-text', 'Edit')).click();
browser.sleep(1500);
var txtDescription = element(by.name('description'));
browser.wait(EC.visibilityOf(txtDescription),7000);
txtDescription.clear();
txtDescription.sendKeys('a');
txtDescription.sendKeys(protractor.Key.BACK_SPACE);
txtDescription.clear();
element(by.cssContainingText('.btn-primary', 'Save')).click();
browser.wait(EC.visibilityOf(element(by.linkText('History'))), 39000);
expect(element(by.id('description')).getText()).toBe('');
expect(element(by.css('.form-text.text-muted')).getText()).toBe('No description yet');
});
});
/*
* Create Folders
* From Root directory
* Create folder 1 and folder 2 , via the folder creation menu
* assert that folders exist in table and in side bar
* */
describe('Building B - Create functions', function(){
it ('Building B - create folders', function(){
browser.sleep(3000);
var folder1 = element(by.cssContainingText('td', 'folder1'));
var folder2 = element(by.cssContainingText('td', 'folder2'));
var btnNew = element(by.cssContainingText('.nav-item-title', 'New'));
browser.wait(EC.visibilityOf(btnNew),20000);
btnNew.click();
element(by.cssContainingText('.dropdown-item-text', 'Create New Folder')).click();
browser.wait(EC.visibilityOf(element(by.css('input[name="folderName"]'))),6500);
element(by.css('input[name="folderName"]')).sendKeys('folder1');
element(by.cssContainingText('.btn-primary', 'Create')).click();
browser.sleep(2000);
browser.wait(EC.visibilityOf(folder1) ,20000);
expect(folder1.isPresent()).toBe(true);
element(by.cssContainingText('.nav-item-title', 'New')).click();
element(by.cssContainingText('.dropdown-item-text', 'Create New Folder')).click();
browser.wait(EC.visibilityOf(element(by.css('input[name="folderName"]'))),4000);
element(by.css('input[name="folderName"]')).sendKeys('folder2');
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('.btn-primary', 'Create')).first(), 6000));
element(by.cssContainingText('.btn-primary', 'Create')).click();
browser.sleep(2000);
browser.wait(EC.visibilityOf(folder2), 20000);
//check folder is in table
expect(folder2.isPresent()).toBe(true);
// check folder is in sidebar
expect(element(by.cssContainingText('span', 'folder2')).isPresent()).toBe(true);
});
/*
* Trigger navigation via folder icon click
* get list of folders
* click first folder ( should be 2D Floorplans)
* confirm we were navigated by folder contents
* */
it('Building B - navigate through table folder icon click', function() {
var folders = $$('a.table-folder-icon');
var fPlans = element.all(by.cssContainingText('span', '2D Plans')).first();
// There should be three folders currently in the table
expect(folders.count()).toBe(3);
// navigate to 2D Floorplans folder through click on the folder icon
fPlans.click();
//folders.get(0).click();
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('td', '.svg')).first(), 10000));
// expect we have loaded the contents of the folder
expect(element.all(by.cssContainingText('td', '.svg'))).not.toBe(null);
});
/*
* Trigger navigation via breadcrumb
* Analyze bread crumbs in current path ( should be started in 2d floor plans folder)
* click breadcrumb to go to building files
* confirm we were navigated by folder contents
* confirm breadcrumbs were rebuilt properly.
* */
it ('Building B - navigate through breadcrumbs', function() {
// get list of breadcrumbs, in the current state there should be 2
var crumbs = $$('.files-breadcrumb');
expect(crumbs.count()).toBe(2);
expect(crumbs.get(0).getText()).toBe('Building Files');
expect(crumbs.get(1).getText()).toContain('\/\n' + 'Generated 2D Plans');
element(by.cssContainingText('.files-breadcrumb', 'Building Files')).click();
//Expect navigation back to root folder - Table
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('td', '.ifc')).first(), 10000));
expect(element(by.cssContainingText('td', '.ifc')).isPresent()).toBe(true);
// Expect crumbs to be 1 long after navigation
var newCrumbs = $$('.files-breadcrumb');
expect(newCrumbs.count()).toBe(1);
expect(newCrumbs.get(0).getText()).toBe('Building Files');
});
/**
* Creation of a sub-folder
* select folder 1, choose create new folder
* interact with folder modal , provide name and confirmation
* after- confirm that the folder exists
**/
it('Building B - Create Folder inside folder - from within folder', function() {
// select folder 1 and click
element.all(by.cssContainingText('span', 'folder1')).first().click();
browser.sleep(1000);
// select create new folder
element(by.cssContainingText('.nav-item-title', 'New')).click();
element(by.cssContainingText('.dropdown-item-text', 'Create New Folder')).click();
browser.sleep(1000);
element(by.css('input[name="folderName"]')).sendKeys('folderInsideFolder');
browser.sleep(1000);
element(by.cssContainingText('.btn-primary', 'Create')).click();
browser.sleep(2000);
// Folder should be created check for folder presence in folder 1
var folderInsideFolder = element.all(by.css('td.table-text-truncate')).first();
browser.wait(EC.visibilityOf(folderInsideFolder, 10000));
expect(folderInsideFolder.getText()).toBe('folderInsideFolder');
element.all(by.cssContainingText('span', 'Building Files')).first().click();
});
});
describe('Building B - Upload/Copy/Move functions',function(){
/**
* disabling this test until we solve the challenge of uploading files in the pipeline
* Navigate to folder 1 clicks 'upload' option, select ifc file, checks if 'upload' button is enabled after
* selecting a file, clicks 'upload', then uploads another file (text file)
* Check for file presence
* */
if(config.params.targetAwsAccount =="dev" ){
xit('upload ifc file to folder', function() {
var path = require('path');
var remote = require('selenium-webdriver/remote');
browser.setFileDetector(new remote.FileDetector());
element.all(by.cssContainingText('span', 'folder1')).first().click();
browser.sleep(2000);
var textFileToUpload = './extras/testinput.txt';
var ifcFileToUpload = './extras/working.ifc';
absolutePath = path.resolve(__dirname, textFileToUpload);
absolutePath2 = path.resolve(__dirname, ifcFileToUpload);
element(by.cssContainingText('.nav-item-title', 'New')).click();
element(by.cssContainingText('.dropdown-item-text', 'Upload')).click();
browser.sleep(1000);
browser.wait(EC.visibilityOf(element(by.css('input[type="file"]'))) ,5000);
element(by.css('input[type="file"]')).sendKeys(absolutePath2);
browser.sleep(1000);
var uploadButton = element(by.css('.btn-primary'));
expect(uploadButton.isEnabled()).toBe(true);
uploadButton.click();
browser.wait(EC.visibilityOf($('.toast-message')),10000);
expect($('.toast-message').getText()).toBe('File working.ifc uploaded');
browser.wait(EC.invisibilityOf($('.toast-message')),10000);
//browser.wait(EC.visibilityOf(element(by.cssContainingText('.toast-message', 'File working.ifc uploaded')), 10000));
//browser.wait(EC.invisibilityOf(element(by.cssContainingText('.toast-message', 'File working.ifc uploaded')), 10000));
});
xit('upload txt file to folder', function() {
var path = require('path');
var remote = require('selenium-webdriver/remote');
browser.setFileDetector(new remote.FileDetector());
var uploadButton = element(by.css('.btn-primary'));
var textFileToUpload = './extras/testinput.txt';
var ifcFileToUpload = './extras/working.ifc';
absolutePath = path.resolve(__dirname, textFileToUpload);
absolutePath2 = path.resolve(__dirname, ifcFileToUpload);
element(by.cssContainingText('.nav-item-title', 'New')).click();
element(by.cssContainingText('.dropdown-item-text', 'Upload')).click();
browser.sleep(1000);
browser.wait(EC.visibilityOf(element(by.css('input[type="file"]'))) ,5000);
element(by.css('input[type="file"]')).sendKeys(absolutePath);
browser.sleep(1000);
uploadButton.click();
browser.wait(EC.visibilityOf($('.toast-message')),10000);
expect($('.toast-message').getText()).toBe('File testinput.txt uploaded');
browser.wait(EC.invisibilityOf($('.toast-message')),10000);
//expect($('.toast-message').getText()).toBe('File textinput.txt uploaded');
//browser.wait(EC.visibilityOf(element(by.cssContainingText('.toast-message', 'File testinput.txt uploaded')), 10000));
console.log("files were uploaded");
});
};
/*
* Currently working test disabled until clean up implemented in next test
* */
it('Building B - copy file', function() {
element.all(by.cssContainingText('span', 'Building Files')).first().click();
browser.sleep(1000);
var ifcFile = element.all(by.cssContainingText('td', '.ifc')).first();
browser.wait(EC.visibilityOf(ifcFile, 10000));
ifcFile.click();
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('.nav-item-title', 'More')).first(), 1000));
element(by.cssContainingText('.nav-item-title', 'More')).click();
//note: using a browser.wait here instead of .sleep causes timeout.
browser.sleep(1000);
var cutButton = element(by.css('.marengo-copy'));
cutButton.click();
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('td', 'Copy of buildingB.ifc')).first(), 1000));
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('td', '.ifc')).first(), 1000));
let ifcFiles = element.all(by.cssContainingText('td', '.ifc'));
expect(ifcFiles.count()).toBe(2);
browser.sleep(1000);
});
/*
* Inprogress soec
* */
it('Building B - move file', function() {
apiUrl = config.params.apiUrl;
browser.get(apiUrl + 'app/building/' + config.params.buildingIdB +'/files');
browser.sleep(5000);
let ifcFile = element(by.cssContainingText('td', 'Copy of'));
expect(ifcFile).not.toBe(null);
browser.wait(EC.visibilityOf(ifcFile, 14000));
ifcFile.click();
browser.wait(EC.visibilityOf(element(by.cssContainingText('.nav-item-title', 'More')), 14000));
element(by.cssContainingText('.nav-item-title', 'More')).click();
//note: using a browser.wait here instead of .sleep causes timeout.
var moveButton = element(by.cssContainingText('.dropdown-item-text', 'Move to'));
expect(moveButton).not.toBe(null);
moveButton.click();
// Wait for modal here.
browser.wait(EC.visibilityOf(element.all(by.cssContainingText('div', 'Move Files to')).first(), 15000));
browser.wait(EC.visibilityOf(element(by.cssContainingText('.modal-tree', 'folder1')), 15000));
// wait for tree content to load - need a better check
let target = element.all(by.cssContainingText('.modal-tree', 'folder1')).last();
target.click();
let moveBtn = element.all(by.cssContainingText('button', 'Move'));
moveBtn.click();
//browser.sleep(10000);
browser.wait(EC.visibilityOf(element(by.cssContainingText('.toast-message', 'Move successful')), 15000));
browser.wait(EC.invisibilityOf(element(by.cssContainingText('td', 'Copy of')), 15000));
browser.sleep(2000);
//Verify that item is not in current folder
var detailsDrawer = element(by.cssContainingText('td', 'Copy of'));
expect(detailsDrawer.isPresent()).toBe(false);
});
it('Building B - move file - verify move', function() {
let ifcFile = element(by.cssContainingText('td', 'Copy of'));
let folder1 = element.all(by.cssContainingText('span', 'folder1')).first();
//navigate to folder 1 and validate it is there.
browser.wait(EC.invisibilityOf(ifcFile),9000);
browser.wait(EC.visibilityOf(folder1, 10000));
folder1.click();
browser.wait(EC.visibilityOf(ifcFile, 10000));
expect(ifcFile.isPresent()).toBe(true);
//go back to root for next test
element.all(by.cssContainingText('span', 'Building Files')).first().click();
});
/*
* delete of Folders
* clicks folder 2, and deletes.
* Clicks folders 1 and deletes
*
* */
it('Building B - delete folder', function() {
browser.sleep(1000);
browser.wait(EC.visibilityOf(element(by.cssContainingText('td', 'folder2')), 5000));
var folder = element(by.cssContainingText('td', 'folder2'));
folder.click();
element(by.cssContainingText('.nav-item-title', 'More')).click();
var deleteButton = element(by.css('.navigator-delete'));
deleteButton.click();
browser.sleep(1000);
element(by.css('.btn-danger')).click();
browser.wait(EC.visibilityOf(element(by.cssContainingText('.toast-message', 'Item deleted')), 5000));
browser.wait(EC.invisibilityOf(element(by.cssContainingText('.toast-message', 'Item deleted')), 5000));
browser.sleep(2000);
expect(folder.isPresent()).toBe(false);
browser.wait(EC.visibilityOf(element(by.cssContainingText('td', 'folder1')), 5000));
folder = element(by.cssContainingText('td', 'folder1'));
folder.click();
element(by.cssContainingText('.nav-item-title', 'More')).click();
deleteButton = element(by.css('.navigator-delete'));
deleteButton.click();
browser.sleep(1000);
element(by.css('.btn-danger')).click();
browser.wait(EC.visibilityOf(element(by.cssContainingText('.toast-message', 'Item deleted')), 5000));
browser.wait(EC.visibilityOf(element(by.css('.ui-table-loading')), 5000));
let loader = element(by.css('.ui-table-loading'));
browser.wait(EC.not(EC.presenceOf(loader)));
browser.sleep(1000);
expect(folder.isPresent()).toBe(false);
});
/*
* upload without file path provided -
* clicks 'files' button, clicks 'upload' option, opens new window, checks if 'upload' button is disabled
* when no file is selected and then clicks 'cancel' button
* */
it ('wont allow upload without file path provided', function() {
element(by.cssContainingText('.nav-item-title', 'New')).click();
element(by.cssContainingText('.dropdown-item-text', 'Upload')).click();
//browser.sleep(1000);
var cancelButton = element(by.css('.btn-link'));
var uploadButton = element(by.css('.btn-primary'));
browser.wait(EC.visibilityOf(cancelButton),5000);
expect(uploadButton.isEnabled()).toBe(false);
expect(cancelButton.isPresent()).toBe(true);
cancelButton.click();
browser.sleep(1000);
expect(cancelButton.isPresent()).toBe(false);
});
});
/*
* Check files details - **Currently disabled as uploads not working on pipeline.
* first clicks ifc file, checks if drawer shows up, changes description of file, downloads file, clicks
* 'history' option, 'creation' option, then clicks 'create' option and waits until
* message banner shows up at the bottom of the page, then clicks text file, again checks if drawer is present,
* clicks 'history' option and since it is not an ifc file,
* 'creation' option should not be there, so it checks its presence
* */
if(config.params.targetAwsAccount =="dev" ){
xit('check file details', function() {
browser.sleep(2000);
browser.wait(EC.visibilityOf(element(by.cssContainingText('td', '.ifc'))),5000);
element(by.cssContainingText('td', '.ifc')).click();
browser.sleep(1000);
element.all(by.css('.marengo-double-left')).first().click();
var detailsDrawer = element(by.css('.right-drawer-border'));
expect(detailsDrawer.isPresent()).toBe(true);
browser.sleep(1000);
var downloadButton = element(by.css('i[title="Download File"]'));
browser.wait(EC.visibilityOf(downloadButton),5000);
expect(downloadButton.isEnabled()).toBe(true);
downloadButton.click();
browser.sleep(1000);
element(by.css('i[title="Edit file information"]')).click();
browser.sleep(1000);
var labels = element.all(by.css('.col-form-label'));
expect(labels.get(1).getText()).toBe('Description');
expect(labels.get(2).getText()).toBe('Last update');
expect(labels.get(3).getText()).toBe('Updated By');
expect(labels.get(4).getText()).toBe('Size');
expect(labels.get(5).getText()).toBe('Version');
expect(labels.get(6).getText()).toBe('Created');
var txtDescription = element(by.name('description'));
txtDescription.clear();
txtDescription.sendKeys('ifc file');
element(by.cssContainingText('.btn-primary', 'Save')).click();
browser.wait(EC.visibilityOf(element(by.linkText('History'))), 5000);
var historyButton = element(by.linkText('History'));
var createButton = element(by.linkText('Creation'));
expect(element(by.id('description')).getText()).toBe('ifc file');
expect(createButton.isPresent()).toBe(true);
historyButton.click();
createButton.click();
element(by.cssContainingText('.nav-item-title', 'Title')).click();
browser.sleep(1500);
var fileName = element(by.cssContainingText('.margin-top-offset', 'Selected IFC'));
expect(fileName.getText()).toBe('Selected IFC: buildingB.ifc');
//click cancel button
element(by.css('.btn.btn-link')).click();
browser.sleep(1500);
element.all(by.css('.marengo-double-right')).first().click();
browser.sleep(3000);
element(by.cssContainingText('.breadcrumb-item', 'Buildings')).click();
});
};
});