Skip to content

Commit

Permalink
playground tutorial protractor test (hyperledger-archives#2871)
Browse files Browse the repository at this point in the history
Signed-off-by: awjh-ibm <[email protected]>
  • Loading branch information
awjh-ibm authored and nklincoln committed Dec 4, 2017
1 parent 3ffef85 commit 4f2055a
Show file tree
Hide file tree
Showing 16 changed files with 756 additions and 19 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@
],
"author": "Hyperledger Composer",
"license": "Apache-2.0"
}
}
2 changes: 1 addition & 1 deletion packages/composer-playground/e2e/component/add-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class AddFile {

// Get all radio buttons
static retrieveAddFileRadioButtons() {
return OperationsHelper.retriveMatchingElementsByCSS('.file-types-list', '[type="radio"]', 0)
return OperationsHelper.retrieveMatchingElementsByCSS('.file-types-list', '[type="radio"]', 0)
.map((elm) => { return {name: elm.getAttribute('id'), enabled: elm.isEnabled()}; });
}

Expand Down
23 changes: 21 additions & 2 deletions packages/composer-playground/e2e/component/editor-file.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
import { browser, element, by } from 'protractor';
import { ExpectedConditions } from 'protractor';
import { OperationsHelper } from '../utils/operations-helper';

export class EditorFile {

static retrieveEditorCodeMirrorText() {
return OperationsHelper.retriveTextFromElement(element(by.id('editor-file_CodeMirror')));
return browser.executeScript(`
var editor = document.getElementsByClassName('CodeMirror')[0].CodeMirror;
editor.focus();
return editor.getValue();
`)
}

static setEditorCodeMirrorText(value: string) {
return browser.executeScript(`
var editor = document.getElementsByClassName('CodeMirror')[0].CodeMirror;
editor.focus();
return editor.setValue('');
`)
.then(() => {
return element(by.css('.CodeMirror textarea')).sendKeys(value)
.then(() => {
return browser.sleep(1000); // DEBOUNCE
})
});
}

static retrieveEditorText() {
return OperationsHelper.retriveTextFromElement(element(by.css('.readme')));
return OperationsHelper.retrieveTextFromElement(element(by.css('.readme')));
}

}
34 changes: 26 additions & 8 deletions packages/composer-playground/e2e/component/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { browser, element, by } from 'protractor';
import { ExpectedConditions } from 'protractor';
import { OperationsHelper } from '../utils/operations-helper';
import { Constants } from '../utils/constants';
import { EditorFile } from './editor-file';

let scrollMe = (target) => {
target.scrollIntoView(true);
Expand Down Expand Up @@ -34,44 +35,61 @@ export class Editor {
return OperationsHelper.click(element(by.id('editor_import')));
}

static makeFileActive(filename: string) {
let startFileData = EditorFile.retrieveEditorCodeMirrorText();
return OperationsHelper.retrieveMatchingElementsByCSS('.side-bar-nav', '.flex-container', 0)
.then((elements) => {
for (var i = 0; i < elements.length; i++) {
let elm = elements[i];
browser.executeScript(scrollMe, elm);
OperationsHelper.retrieveTextFromElement(elm)
.then((text) => {
if(text.toString().split(/\r\n|\n/)[1] === filename) {
return OperationsHelper.click(elm)
}
});
}
});
}

// Wait for editor files to load
static waitForProjectFilesToLoad() {
return OperationsHelper.retriveMatchingElementsByCSS('.side-bar-nav', '.flex-container', 0);
return OperationsHelper.retrieveMatchingElementsByCSS('.side-bar-nav', '.flex-container', 0);
}

// Retrieve Editor Side Navigation FileNames
static retrieveNavigatorFileNames() {
// Due to scroll bar, need to scroll element into view in order to inspect text
return OperationsHelper.retriveMatchingElementsByCSS('.side-bar-nav', '.flex-container', 0)
return OperationsHelper.retrieveMatchingElementsByCSS('.side-bar-nav', '.flex-container', 0)
.map((elm) => { browser.executeScript(scrollMe, elm);
return OperationsHelper.retriveTextFromElement(elm); });
return OperationsHelper.retrieveTextFromElement(elm); });
}

// Retrieve Editor Side Navigation File Action buttons (Add/Deploy)
static retrieveNavigatorFileActionButtons() {
return OperationsHelper.retriveMatchingElementsByCSS('.files', '[type="button"]', 0)
return OperationsHelper.retrieveMatchingElementsByCSS('.files', '[type="button"]', 0)
.map((elm) => { return {text: elm.getText(), enabled: elm.isEnabled()}; });
}

// Retrieve Editor Side Navigation Action Buttons
static retrieveBusinessArchiveActionButtons() {
return OperationsHelper.retriveMatchingElementsByCSS('.actions', '[type="button"]', 0)
return OperationsHelper.retrieveMatchingElementsByCSS('.actions', '[type="button"]', 0)
.map((elm) => { return {text: elm.getText(), enabled: elm.isEnabled()}; });
}

// Retrieve Editor Side Navigation File Elements
static retrieveNavigatorFileElements() {
return OperationsHelper.retriveMatchingElementsByCSS('.side-bar-nav', '.flex-container', 0);
return OperationsHelper.retrieveMatchingElementsByCSS('.side-bar-nav', '.flex-container', 0);
}

// Retrieve Editor Deployed Package Name from navlogo section
static retrieveDeployedPackageName() {
return OperationsHelper.retriveTextFromElement(element(by.id('network-name')));
return OperationsHelper.retrieveTextFromElement(element(by.id('network-name')));
}

// Retrieve current 'active' file from navigator
static retrieveNavigatorActiveFiles() {
return OperationsHelper.retriveMatchingElementsByCSS('.files', '.active', 0)
return OperationsHelper.retrieveMatchingElementsByCSS('.files', '.active', 0)
.map((elm) => { browser.executeScript(scrollMe, elm);
browser.wait(ExpectedConditions.visibilityOf(elm), Constants.shortWait);
return elm.getText(); });
Expand Down
6 changes: 3 additions & 3 deletions packages/composer-playground/e2e/component/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export class Import {
return browser.wait(ExpectedConditions.visibilityOf(element(by.css('.drawer'))), Constants.longWait)
.then(() => {
// must have file drag drop visible
OperationsHelper.retriveMatchingElementsByCSS('.sample-network-list-container', '.sample-network-list-item', 3);
OperationsHelper.retrieveMatchingElementsByCSS('.sample-network-list-container', '.sample-network-list-item', 3);
return browser.wait(ExpectedConditions.visibilityOf(element(by.id('file-importer_input'))), Constants.longWait);
})
.then(() => {
Expand Down Expand Up @@ -94,7 +94,7 @@ export class Import {
browser.wait(ExpectedConditions.visibilityOf(element(by.css('.chosen-network'))), Constants.longWait);

// Wait for poplation of sample-network-list-item(s)
OperationsHelper.retriveMatchingElementsByCSS('.sample-network-list-container', '.sample-network-list-item', 3)
OperationsHelper.retrieveMatchingElementsByCSS('.sample-network-list-container', '.sample-network-list-item', 3)
.then(() => {
let confirmElement = element(by.id('import_confirm'));
browser.executeScript('arguments[0].scrollIntoView();', confirmElement.getWebElement());
Expand All @@ -108,7 +108,7 @@ export class Import {
browser.wait(ExpectedConditions.visibilityOf(element(by.css('.chosen-network'))), Constants.longWait);

// Wait for poplation of sample-network-list-item(s)
OperationsHelper.retriveMatchingElementsByCSS('.sample-network-list-container', '.sample-network-list-item', 3)
OperationsHelper.retrieveMatchingElementsByCSS('.sample-network-list-container', '.sample-network-list-item', 3)
.then(() => {
let cancelElement = element(by.id('import_cancel'));
browser.executeScript('arguments[0].scrollIntoView();', cancelElement.getWebElement());
Expand Down
146 changes: 146 additions & 0 deletions packages/composer-playground/e2e/component/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { browser, element, by } from 'protractor';
import { ExpectedConditions } from 'protractor';
import { OperationsHelper } from '../utils/operations-helper';
import { Constants } from '../utils/constants';

let scrollMe = (target) => {
target.scrollIntoView(true);
};

export class Test {
// Wait to appear
static waitToAppear() {
return browser.wait(ExpectedConditions.visibilityOf(element(by.css('.main-view'))), Constants.shortWait);
}

static retrieveHeader() {
return OperationsHelper.retrieveMatchingElementsByCSS('.resource-header', 'h1', 0)
.map((elm) => { browser.executeScript(scrollMe, elm);
return OperationsHelper.retrieveTextFromElement(elm); });
}

// Retrieve Test Side Navigation Participants
static retrieveAssetTypes() {
// Due to scroll bar, need to scroll element into view in order to inspect text
return OperationsHelper.retrieveMatchingElementsByCSS('.side-bar-nav:nth-of-type(2)', 'h3', 0)
.map((elm) => { browser.executeScript(scrollMe, elm);
return OperationsHelper.retrieveTextFromElement(elm); });
}

// Retrieve Test Side Navigation Participants
static retrieveParticipantTypes() {
// Due to scroll bar, need to scroll element into view in order to inspect text
return OperationsHelper.retrieveMatchingElementsByCSS('.side-bar-nav:first-of-type', 'h3', 0)
.map((elm) => { browser.executeScript(scrollMe, elm);
return OperationsHelper.retrieveTextFromElement(elm); });
}

static selectRegistry(type: string, name: string) {
let sideBar: string;
switch(type) {
case 'participants': sideBar = '.side-bar-nav:first-of-type'; break;
case 'assets': sideBar = '.side-bar-nav:nth-of-type(2)'; break;
default: throw new Error('Invalid type');
}

return OperationsHelper.retrieveMatchingElementsByCSS(sideBar, 'h3', 0)
.then((elements) => {
for (var i = 0; i < elements.length; i++) {
let elm = elements[i];
browser.executeScript(scrollMe, elm);
OperationsHelper.retrieveTextFromElement(elm)
.then((text) => {
if(text.toString() === name) {
return OperationsHelper.click(elm)
}
});
}
})
}

// create registry item on selected registry page
static createRegistryItem(item: string) {
return OperationsHelper.retrieveMatchingElementsByCSS('.resource-header', '.registry', 0)
.then((elm) => {
return OperationsHelper.click(elm[0]);
})
.then(() => {
return browser.wait(ExpectedConditions.visibilityOf(element(by.css('.resource-modal'))), Constants.shortWait);
})
.then(() => {
return browser.executeScript(`
var editor = document.getElementsByClassName('CodeMirror')[0].CodeMirror;
editor.focus();
return editor.setValue('');
`)
})
.then(() => {
return element(by.css('.CodeMirror textarea')).sendKeys(item)
})
.then(() => {
return OperationsHelper.click(element(by.id('createResourceButton')));
})
}

// Get the current list of ids and data from opened registry section
static retrieveRegistryItem() {
let idsPromise = OperationsHelper.retrieveMatchingElementsByCSS('.resource-list', '.resource-container .id', 0)
.map((elm) => {
browser.executeScript(scrollMe, elm);
return OperationsHelper.retrieveTextFromElement(elm)
});

let dataPromise = OperationsHelper.retrieveMatchingElementsByCSS('.resource-list', '.resource-container .data', 0)
.map((elm) => {
browser.executeScript(scrollMe, elm);
return OperationsHelper.retrieveTextFromElement(elm)
});

let promises = [idsPromise, dataPromise];

return Promise.all(promises)
.then((values) => {
let ids = values[0];
let data = values[1];
var result = ids.map(function(val, index){
return { id: val, data: data[index] };
});
return result;
})
}

static submitTransaction(transaction: string, type: string) {
return OperationsHelper.click(element(by.className('side-button')).all(by.className('button-item')).all(by.className('primary')).first())
.then(() => {
OperationsHelper.click(element(by.className('transaction-modal')).all(by.id('dropdownMenu1')).first());
})
.then(() => {
OperationsHelper.retrieveMatchingElementsByCSS('.transaction-modal', '.dropdown-item', 1)
.then((elements) => {
for (var i = 0; i < elements.length; i++) {
let elm = elements[i];
browser.executeScript(scrollMe, elm);
OperationsHelper.retrieveTextFromElement(elm)
.then((text) => {
if(text.toString() === type) {
return OperationsHelper.click(elm)
}
});
}
});
})
.then(() => {
return browser.executeScript(`
var editor = document.getElementsByClassName('CodeMirror')[0].CodeMirror;
editor.focus();
return editor.setValue('');
`)
})
.then(() => {
return element(by.css('.CodeMirror textarea')).sendKeys(transaction)
})
.then(() => {
return OperationsHelper.click(element(by.id('submitTransactionButton')));
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$class": "org.acme.mynetwork.Commodity",
"tradingSymbol": "ABC",
"description": "Test commodity",
"mainExchange": "Euronext",
"quantity": 72.297,
"owner": "resource:org.acme.mynetwork.Trader#TRADER1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$class": "org.acme.mynetwork.Trader",
"tradeId": "TRADER1",
"firstName": "Jenny",
"lastName": "Jones"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$class": "org.acme.mynetwork.Trader",
"tradeId": "TRADER2",
"firstName": "Amy",
"lastName": "Williams"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$class": "org.acme.mynetwork.Trade",
"commodity": "resource:org.acme.mynetwork.Commodity#ABC",
"newOwner": "resource:org.acme.mynetwork.Trader#TRADER2"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
rule NetworkAdminUser {
description: "Grant business network administrators full access to user resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "**"
action: ALLOW
}

rule NetworkAdminSystem {
description: "Grant business network administrators full access to system resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* My commodity trading network
*/
namespace org.acme.mynetwork
asset Commodity identified by tradingSymbol {
o String tradingSymbol
o String description
o String mainExchange
o Double quantity
--> Trader owner
}
participant Trader identified by tradeId {
o String tradeId
o String firstName
o String lastName
}
transaction Trade {
--> Commodity commodity
--> Trader newOwner
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Track the trade of a commodity from one trader to another
* @param {org.acme.mynetwork.Trade} trade - the trade to be processed
* @transaction
*/
function tradeCommodity(trade) {
trade.commodity.owner = trade.newOwner;
return getAssetRegistry('org.acme.mynetwork.Commodity')
.then(function (assetRegistry) {
return assetRegistry.update(trade.commodity);
});
}
Loading

0 comments on commit 4f2055a

Please sign in to comment.