UI test for MintedCapped

This commit is contained in:
dennis00010011b 2018-05-22 21:52:19 -07:00
parent 1849af177d
commit 22bd53d245
16 changed files with 1013 additions and 2209 deletions

144
README.md
View File

@ -1,11 +1,10 @@
### Automated tests for token-wizard
Start URL in ```config.json```
Test suite #1 , starts with command ```npm run -script test1```
Test suite for MintedCappedCrowdsale , starts with command ```npm run e2eMinted```
#### UI tests
```
- User is able to open wizard welcome page
- Welcome page: button NewCrowdsale present
- Welcome page: button ChooseContract present
@ -14,80 +13,87 @@ Test suite #1 , starts with command ```npm run -script test1```
- Wizard step#2: user able to fill Name field with valid data
- Wizard step#2: user able to fill Ticker field with valid data
- Wizard step#2: user able to fill Decimals field with valid data
- Wizard step#2: user is able to add reserved tokens
- Wizard step#2: user is able to remove one of reserved tokens
- Wizard step#2: button ClearAll present
- Wizard step#2: Alert present after clicking ClearAll, alert contains button No
- Wizard step#2: User able to click button No and warning disappear
- Wizard step#2: Alert present after clicking ClearAll, alert contains button Yse
- Wizard step#2: User is able to download CSV file with reserved addresses
- Wizard step#2: added only valid data from CSV file
- Wizard step#2: button ClearAll is displayed
- Wizard step#2: Alert present after clicking ClearAll
- Wizard step#2: user is able bulk delete of reserved tokens
- Wizard step#2: user is able to add one reserved tokens address after deletion
- Wizard step#2: button Continue present
- Wizard step#2: user is able to add reserved tokens one by one
- Wizard step#2: field Decimals is disabled if reserved tokens are added
- Wizard step#2: user is able to remove one of reserved tokens
- Wizard step#2: button Continue is displayed
- Wizard step#2: user is able to open Step3 by clicking button Continue
- Wizard step#3: field Wallet address contains the metamask account address
- Wizard step#3: User is able to set "Safe and cheap gasprice" checkbox
- Wizard step#3: User is able to set "Normal Gasprice" checkbox
- Wizard step#3: User is able to set "Fast Gasprice" checkbox
- Wizard step#3: User is able to set "Custom Gasprice" checkbox
- Wizard step#3: User is able to fill "Custom Gasprice" with valid value
- Wizard step#3: User is able to set checkbox "Whitelist disabled"
- Wizard step#3: User is able to set checkbox "Whitelist enabled"
- Wizard step#3: User is able to download CVS file with whitelisted addresses
- Wizard step#3: User is able to add several whitelisted addresses
- Wizard step#3: User is able to remove one whitelisted address
- Wizard step#3: Whitelist container present if checkbox "Whitelist enabled" is selected
- Wizard step#3: User is able to download CSV file with whitelisted addresses
- Wizard step#3: Number of added whitelisted addresses is correct,data is valid
- Wizard step#3: User is able to bulk delete all whitelisted addresses
- Wizard step#3: User is able to bulk delete all whitelisted addresses
- Wizard step#3: All whitelisted addresses are removed after deletion
- Wizard step#3: User is able to add several whitelisted addresses one by one
- Wizard step#3: User is able to remove one whitelisted address
- Wizard step#3: User is able to set "Custom Gasprice" checkbox
- Wizard step#3: User is able to fill out the CustomGasprice field with valid value
- Wizard step#3: User is able to set SafeAndCheapGasprice checkbox
- Wizard step#3:Tier#1: User is able to fill out field "Rate" with valid data
- Wizard step#3:Tier#1: User is able to fill out field "Supply" with valid data
- Wizard step#3: User is able to add tier
- Wizard step#3:Tier#2: User is able to fill out field "Rate" with valid data
- Wizard step#3:Tier#2: User is able to fill out field "Supply" with valid data
- Wizard step#3: user is able to proceed to Step4 by clicking button Continue
- Wizard step#4: alert present if user reload the page
- Wizard step#4: user is able to accept alert after reloading the page
- Wizard step#4: button SkipTransaction is presented if user reject a transaction
- Wizard step#4: user is able to skip transaction
- Wizard step#4: alert is displayed if user wants to leave the wizard
- Wizard step#4: User is able to stop deployment
```
#### Functional tests
```
1. Owner can create crowdsale(scenario testSuite1.json),1 tier, not modifiable, no whitelist,1 reserved
2. Disabled to modify the end time if crowdsale is not modifiable
3. Investor can NOT buy less than mincap in first transaction
4. Investor can buy amount equal mincap
5. Investor can buy less than mincap after first transaction
6. Disabled to buy after crowdsale time expired
7. Owner able to distribute if crowdsale time expired but not all tokens were sold
8. Reserved address has received correct quantity of tokens after distribution
9. Owner able to finalize ( if crowdsale time expired but not all tokens were sold)
10.Investor has received correct quantity of tokens after finalization
11.Owner can create crowdsale(scenario testSuite2.json): 1 tier,1 whitelist address,2 reserved addresses, modifiable
12.Whitelisted investor NOT able to buy before start of crowdsale
13.Disabled to modify the name of tier
14.Tier's name matches given value
15.Disabled to modify the wallet address
16.Tier's wallet address matches given value
17.Owner is able to add whitelisted address before start of crowdsale
18.Owner is able to modify the rate before start of crowdsale
19.Owner is able to modify the total supply before start of crowdsale
20.Owner is able to modify the start time before start of crowdsale
21.Owner is able to modify the end time before start of crowdsale
22.Warning present if end time earlier than start time
23.Not owner is NOT able to modify the start time of tier
24.Disabled to modify the start time if crowdsale has begun
25.Disabled to modify the total supply if crowdsale has begun
26.Disabled to modify the rate if crowdsale has begun
27.Owner is able to modify the end time after start of crowdsale
28.Owner is able to add whitelisted address if crowdsale has begun
29.Whitelisted investor is NOT able to buy less than min in first transaction
30.Whitelisted investor can buy amount equal min
31.Whitelisted investor is able to buy less than min after first transaction
32.Whitelisted investor is NOT able to buy more than assigned max
33.Whitelisted investor is able to buy assigned max
34.Whitelisted investor is NOT able to buy more than total supply in tier
35.Owner is NOT able to distribute before all tokens are sold and crowdsale is not finished
36.Owner is NOT able to finalize before all tokens are sold and crowdsale is not finished
37.Whitelisted investor able to buy total supply
38.Whitelisted investor is NOT able to buy if all tokens were sold
39.Owner able to distribute after all tokens were sold but crowdsale is not finished
40.Reserved address has received correct QUANTITY of tokens after distribution
41.Reserved address has received correct PERCENT of tokens after distribution
42.Not Owner is NOT able to finalize (after all tokens were sold)
43.Owner able to finalize (after all tokens were sold)
44.Disabled to buy after finalization of crowdsale
45.Investor #1 has received correct amount of tokens after finalization
46.Investor #2 has received correct amount of tokens after finalization
- Owner can create crowdsale:1 tier, modifiable, whitelist,2 reserved
- Whitelisted investor is not able to buy before start of crowdsale
- Manage page: owner is able to open the manage page
- Manage page: button 'Save' is disabled by default
- Manage page: button 'Save' is not clickable when disabled
- Manage page: owner is able to add whitelisted address before start of crowdsale
- Manage page: owner is able to modify the end time before start of crowdsale
- Manage page: end time changed accordingly after modifying
- Invest page: Countdown timer is displayed
- Tier starts as scheduled
- Manage page: owner is able to add whitelisted address if crowdsale has begun
- Manage page: owner is able to modify the end time after start of crowdsale
- Manage page: end time changed accordingly after modifying
- Whitelisted investor is NOT able to buy less than min in first transaction
- Whitelisted investor can buy amount equal mincap
- Invest page: Investors balance is changed accordingly after purchase
- Whitelisted investor is able to buy less than mincap after first transaction
- Whitelisted investor is able to buy not more than maxCap
- Whitelisted investor (which was added from Manage page) is able to buy maxCap
- Whitelisted investor is not able to buy more than remains even if individual maxCap is not reached
- Whitelisted investor is not able to buy if all tokens were sold
- Not owner is not able to finalize
- Owner is able to finalize (if crowdsale time expired but not all tokens were sold)
- Whitelisted investor is not able to buy if crowdsale finalized
- Reserved address has received correct quantity of tokens after distribution
- Investor has received correct quantity of tokens after finalization
- Owner can create crowdsale with minCap,1 tier, not modifiable, no whitelist,2 reserved
- Investor not able to buy before start of crowdsale
- Disabled to modify the end time if crowdsale is not modifiable
- Invest page: Countdown timer is displayed
- Tier starts as scheduled
- Investor is not able to buy less than mincap in first transaction
- Investor can buy amount equal mincap
- Invest page: Investor's balance is changed accordingly after purchase
- Investor is able to buy less than mincap after first transaction
- Owner is not able to finalize if all tokens were not sold and crowdsale is not finished
- Crowdsale is finished as scheduled
- Disabled to buy after crowdsale's time expired
- Owner is able to finalize (if crowdsale time expired but not all tokens were sold)
- Investor is not able to buy if crowdsale is finalized
- Reserved address has received correct quantity of tokens after distribution
- Investor has received correct quantity of tokens after finalization
```

26
bulkReservedAddresses.csv Normal file
View File

@ -0,0 +1,26 @@
0xf9180fF7650f808EB08C1EA1C9D0f85436d9a39D,percentage,100
0xd03ea8624c8c5987235048901fb614fdca89b117,tokens,50
0x95ced938f7991cd0dfcb48f0a06a40fa1af46ebc,tokens,3.1
0xBC4023Baef7B812c23f21bc0b108A188243b07Cb,tokens,45.12
0x2589bd7D8A58Ac9A4aC01d68A7c63315ef184c63,tokens,234.123
0xF3eA35DB8F0058b4e0aD45F883172E92fdCb4B82,tokens,1245.1234
0xb3b4F4b5568BB6dF78e4d96Ad30A5538C913D495,tokens,99999.12345
0x16926399BAF474Cd314E6425ace67A88EA5BeA11,tokens,999999.123456
0xE98055678d8e8724E5106b059e88557a99561007,tokens,9999999.1234567
0x06554522da78D90015a12C5caaf96be2999ea3F9,tokens,99999999.12345678
0x1894F11ddf864CA1de4eB339512a79e199cbf194,tokens,999999999.123456789
0xeec3B3A65E3157b19605911615218B33772d5da2,tokens,9999999999.0123456789
0xec8Af49612F4EdfcD069B8cfe95552740c6849e0,tokens,99999999999.01234567899
0x9613130348aC610732A391063CD70b5a8c186EfC,tokens,999999999999.012345678998
0x7Bc397b1F42bB521cEadE2509f8deAF477C7BEd6,tokens,9999999999999.0123456789987
0x8632cc8620f7aA794aC1a3b88e0D07E4BF133638,tokens,99999999999999.01234567899876
0xAAcd9926862A2ECC1F0D547aF9D9d6FcBD3928f6,tokens,999999999999999.012345678998765
0xa3e8A60f9dC18385e6215c1F2b04437Ca02F634c,tokens,9999999999999999.0123456789987654
0xAbDEeE7cdE25064b42E4A27B00cf53f01587520b,tokens,99999999999999999.01234567899876543
0x75B4a78b86523ef93CcE5cfC217cd3D99fc9ab18,tokens,999999999999999999.012345678998765432
0x2C683fE4dac1f28c51Aa710Ed74196CdFcb04E20,tokens,9999999999999999999.0123456789987654321
0xE743AaF851663e84D3Ec364863866,tokens,45
0xE743AaF851663e84D3Ec3648638662a6c41cEe2A,teté, 5.0505
0x5d2Bf1496242D32785d1A386410b7F157e17F42d,tokens,-50
0x1d765eB5AD7020BA8e006978930CeAd68b38012a,percentage,-3
0x94451A0A09f3aD57f3Af201dB183Ce89f5797e1F
Can't render this file because it has a wrong number of fields in line 26.

View File

@ -1,16 +1,19 @@
,,
0xBC4023Baef7B812c23f21bc0b108A1807Cb,2,100
0xBC4023Baef7B812c23f21bc0b108A188243b07Cb,,67
0x16926399BAF474Cd314E6425ace67A88EA5BeA11,4,
0xE98055678d8e8724E5106b059e88557a99561007,5,1
0x06554522da78D90015a12C5caaf96be2999ea3F9,0,1,2,3
0x1894F11ddf864CA1de4eB339512a79e199cbf194,0,0
0xeec3B3A65E3157b19605911615218B33772d5da2,9,9
0xec8Af49612F4EdfcD069B8cfe95552740c6849e0,-1,6
0x9613130348aC610732A391063CD70b5a8c186EfC,-1,-2
0x8632cc8620f7aA794aC1a3b88e0D07E4BF133638,13,9
0xd540257890329448fB721562Bb95BA0eb7,5-5,10
0x2589bd7D8A58Ac9A4aC01d68A7c63315ef184c63,1,68
0xF3eA35DB8F0058b4e0aD45F883172E92fdCb4B82,2,69
0xb3b4F4b5568BB6dF78e4d96Ad30A5538C913D495,3,70
0x16926399BAF474Cd314E6425ace67A88EA5BeA11,4,
0xE98055678d8e8724E5106b059e88557a99561007,5,1
0x06554522da78D90015a12C5caaf96be2999ea3F9,6,2
,7,3
0x1894F11ddf864CA1de4eB339512a79e199cbf194,8,4
0xeec3B3A65E3157b19605911615218B33772d5da2,9,5
0xec8Af49612F4EdfcD069B8cfe95552740c6849e0,10,6
0x9613130348aC610732A391063CD70b5a8c186EfC,11,7
0x7Bc397b1F42bB521cEadE2509f8deAF477C7BEd6,12,8
0x8632cc8620f7aA794aC1a3b88e0D07E4BF133638,13,9
0xd540257890329448fB721562Bb95BA0eb7,5-5,10
0x7Bc397b1F42bB521cEadE2509f8deAF477C7BEd6,0.0000001,8.35
1 ,,
2 0xBC4023Baef7B812c23f21bc0b108A1807Cb,2,100
3 0xBC4023Baef7B812c23f21bc0b108A188243b07Cb 0xBC4023Baef7B812c23f21bc0b108A188243b07Cb,,67 67
4 0x16926399BAF474Cd314E6425ace67A88EA5BeA11,4,
5 0xE98055678d8e8724E5106b059e88557a99561007,5,1
6 0x06554522da78D90015a12C5caaf96be2999ea3F9,0,1,2,3
7 0x1894F11ddf864CA1de4eB339512a79e199cbf194,0,0
8 0xeec3B3A65E3157b19605911615218B33772d5da2,9,9
9 0xec8Af49612F4EdfcD069B8cfe95552740c6849e0,-1,6
10 0x9613130348aC610732A391063CD70b5a8c186EfC,-1,-2
11 0x8632cc8620f7aA794aC1a3b88e0D07E4BF133638,13,9
12 0xd540257890329448fB721562Bb95BA0eb7,5-5,10
13 0x2589bd7D8A58Ac9A4aC01d68A7c63315ef184c63,1,68
14 0xF3eA35DB8F0058b4e0aD45F883172E92fdCb4B82,2,69
15 0xb3b4F4b5568BB6dF78e4d96Ad30A5538C913D495,3,70
16 0x2589bd7D8A58Ac9A4aC01d68A7c63315ef184c63 0x7Bc397b1F42bB521cEadE2509f8deAF477C7BEd6,0.0000001,8.35 1 68
17 0xF3eA35DB8F0058b4e0aD45F883172E92fdCb4B82 2 69
18 0xb3b4F4b5568BB6dF78e4d96Ad30A5538C913D495 3 70
19 0x16926399BAF474Cd314E6425ace67A88EA5BeA11 4
0xE98055678d8e8724E5106b059e88557a99561007 5 1
0x06554522da78D90015a12C5caaf96be2999ea3F9 6 2
7 3
0x1894F11ddf864CA1de4eB339512a79e199cbf194 8 4
0xeec3B3A65E3157b19605911615218B33772d5da2 9 5
0xec8Af49612F4EdfcD069B8cfe95552740c6849e0 10 6
0x9613130348aC610732A391063CD70b5a8c186EfC 11 7
0x7Bc397b1F42bB521cEadE2509f8deAF477C7BEd6 12 8
0x8632cc8620f7aA794aC1a3b88e0D07E4BF133638 13 9
0xd540257890329448fB721562Bb95BA0eb7 5-5 10

View File

@ -142,14 +142,13 @@ class User {
logger.info("fill whitelist for tier " + tier);
logger.info("Wh address=" + address + " , min=" + min + ", max=" + max);
let mngPage = new ManagePage(this.driver);
await mngPage.fillWhitelist(tier, address, min, max);
let metaMask = new MetaMask(this.driver);
let result = await metaMask.signTransaction(5);
if (!result) return false;
await mngPage.waitUntilLoaderGone();
result = await this.confirmPopup();
await mngPage.waitUntilLoaderGone();
return result;
return await mngPage.fillWhitelist(tier, address, min, max)
&& await metaMask.signTransaction(5)
&& await mngPage.waitUntilLoaderGone()
&& await this.confirmPopup()
&& await mngPage.waitUntilLoaderGone();
}
async changeSupply(tier, value) {
@ -258,7 +257,7 @@ class User {
async contribute(amount) {
logger.info("contribute " + amount);
const investPage = new InvestPage(this.driver);
return !await investPage.waitUntilShowUpWarning(10)
return !await investPage.waitUntilShowUpWarning(15)
&& await investPage.waitUntilLoaderGone()
&& await investPage.fillInvest(amount)
&& await investPage.clickButtonContribute()

View File

@ -33,8 +33,24 @@ class ManagePage extends Page {
this.fieldMaxTier = [];
this.buttonAddWh = [];
this.buttonFinalize;
this.buttonSave;
}
async initButtonSave() {
logger.info(this.name + "initButtonSave ");
try {
let locator = By.className("no_arrow");
let array = await super.findWithWait(locator);
this.buttonSave = array [0];
return array;
}
catch (err) {
logger.info("Error: " + err);
return null;
}
}
async initButtonFinalize() {
logger.info(this.name + "initButtonFinalize ");
try {
@ -170,7 +186,21 @@ class ManagePage extends Page {
async clickButtonSave() {
logger.info(this.name + "clickButtonSave ");
return await super.clickWithWait(buttonSave);
return (await this.initButtonSave() !== null)
&& await super.clickWithWait(this.buttonSave);
}
async isDisabledButtonSave() {
logger.info(this.name + " isDisabledButtonSave ");
await this.initButtonSave();
if (await super.getAttribute(this.buttonSave, "class") === "no_arrow button button_fill button_disabled") {
logger.info("present and disabled");
return true;
}
else {
logger.info("Error "+ err);
return false;
}
}
async isPresentWarningStartTimeTier1() {
@ -223,25 +253,14 @@ class ManagePage extends Page {
async fillWhitelist(tier, address, min, max) {
logger.info(this.name + "fillWhitelist ");
await this.initInputs();
try {
if (this.fieldWhAddressTier[tier - 1] == undefined) {
throw ("WhiteList address field not present");
}
logger.info(this.name + "add address in whitelist, tier #1 :");
await super.fillWithWait(this.fieldMinTier[tier - 1], min);
await super.fillWithWait(this.fieldMaxTier[tier - 1], max);
await super.fillWithWait(this.fieldWhAddressTier[tier - 1], address);
await this.initButtons();
await super.clickWithWait(this.buttonAddWh[tier - 1]);
return await this.clickButtonSave();
}
catch (err) {
logger.info("Can't fill out whitelist. Field DISABLED." + err);
return false;
}
return (await this.initInputs() !== null)
&& (this.fieldWhAddressTier[tier - 1] !== undefined)
&& await super.fillWithWait(this.fieldMinTier[tier - 1], min)
&& await super.fillWithWait(this.fieldMaxTier[tier - 1], max)
&& await super.fillWithWait(this.fieldWhAddressTier[tier - 1], address)
&& (await this.initButtons() !== null)
&& await super.clickWithWait(this.buttonAddWh[tier - 1])
&& await this.clickButtonSave();
}
async fillEndTimeTier(tier, date, time) {

View File

@ -1,35 +1,37 @@
const logger = require('../entity/Logger.js').logger;
const key = require('selenium-webdriver').Key;
const Page=require('./Page.js').Page;
const Page = require('./Page.js').Page;
const By = require('selenium-webdriver/lib/by').By;
const IDMetaMask="nkbihfbeogaeaoehlefnkodbefgpgknn";
const URL="chrome-extension://"+IDMetaMask+"//popup.html";
const buttonSubmit=By.className("confirm btn-green");
const buttonAccept=By.xpath('//*[@id="app-content"]/div/div[4]/div/button');
const agreement=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div/div/p[1]/strong");
const fieldNewPass=By.xpath("//*[@id=\"password-box\"]");
const fieldConfirmPass=By.xpath("//*[@id=\"password-box-confirm\"]");
const buttonCreate=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/button");
const buttonIveCopied=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/button[1]");
const popupNetwork=By.className("network-name");
const popupAccount=By.xpath("//*[@id=\"app-content\"]/div/div[1]/div/div[2]/span/div");
const fieldPrivateKey=By.xpath("//*[@id=\"private-key-box\"]");
const pass="qwerty12345";
const buttonImport=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[3]/button");
const fieldNewRPCURL=By.id("new_rpc");
const buttonSave=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[3]/div/div[2]/button");
const arrowBackRPCURL=By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[1]/i");
const iconChangeAccount=By.className("cursor-pointer color-orange accounts-selector");
const IDMetaMask = "nkbihfbeogaeaoehlefnkodbefgpgknn";
const URL = "chrome-extension://" + IDMetaMask + "//popup.html";
const buttonSubmit = By.className("confirm btn-green");
const buttonAccept = By.xpath('//*[@id="app-content"]/div/div[4]/div/button');
const agreement = By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div/div/p[1]/strong");
const fieldNewPass = By.xpath("//*[@id=\"password-box\"]");
const fieldConfirmPass = By.xpath("//*[@id=\"password-box-confirm\"]");
const buttonCreate = By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/button");
const buttonIveCopied = By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/button[1]");
const popupNetwork = By.className("network-name");
const popupAccount = By.xpath("//*[@id=\"app-content\"]/div/div[1]/div/div[2]/span/div");
const fieldPrivateKey = By.xpath("//*[@id=\"private-key-box\"]");
const pass = "qwerty12345";
const buttonImport = By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[3]/button");
const fieldNewRPCURL = By.id("new_rpc");
const buttonSave = By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[3]/div/div[2]/button");
const arrowBackRPCURL = By.xpath("//*[@id=\"app-content\"]/div/div[4]/div/div[1]/i");
const iconChangeAccount = By.className("cursor-pointer color-orange accounts-selector");
const buttonReject = By.className("cancel btn-red");
const buttonRejectAll = By.className("cancel btn-red");
var accountOrderNumber=1;
var networks=[0,3,42,4,8545];
var accountOrderNumber = 1;
var networks = [0, 3, 42, 4, 8545];
class MetaMask extends Page {
constructor(driver) {
super(driver);
this.driver=driver;
this.URL=URL;
this.driver = driver;
this.URL = URL;
this.name = "Metamask "
}
@ -38,37 +40,37 @@ class MetaMask extends Page {
}
async activate() {
logger.info(this.name+ "activate ");
return await this.switchToNextPage() &&
await this.open(this.URL) &&
await this.clickWithWait(buttonAccept) &&
await this.clickWithWait(agreement) &&
await this.pressKey(key.TAB,15) &&
await this.clickWithWait(buttonAccept) &&
await this.waitUntilLocated(fieldNewPass) &&
await this.clickWithWait(fieldNewPass) &&
await this.fillWithWait(fieldNewPass,pass) &&
await this.fillWithWait(fieldConfirmPass,pass) &&
await this.clickWithWait(buttonCreate) &&
await this.waitUntilDisplayed(buttonIveCopied) &&
await this.clickWithWait(buttonIveCopied) &&
await this.switchToNextPage();
logger.info(this.name + "activate ");
return await this.switchToNextPage() &&
await this.open(this.URL) &&
await this.clickWithWait(buttonAccept) &&
await this.clickWithWait(agreement) &&
await this.pressKey(key.TAB, 15) &&
await this.clickWithWait(buttonAccept) &&
await this.waitUntilLocated(fieldNewPass) &&
await this.clickWithWait(fieldNewPass) &&
await this.fillWithWait(fieldNewPass, pass) &&
await this.fillWithWait(fieldConfirmPass, pass) &&
await this.clickWithWait(buttonCreate) &&
await this.waitUntilDisplayed(buttonIveCopied) &&
await this.clickWithWait(buttonIveCopied) &&
await this.switchToNextPage();
}
async importAccount(user) {
logger.info(this.name+ "importAccount ");
logger.info(this.name + "importAccount ");
user.accountOrderInMetamask = accountOrderNumber;
return await this.switchToNextPage() &&
await this.setNetwork(user.networkID) &&
await this.clickImportAccount() &&
await this.fillWithWait(fieldPrivateKey,user.privateKey) &&
await this.fillWithWait(fieldPrivateKey, user.privateKey) &&
await this.waitUntilDisplayed(buttonImport) &&
await this.clickWithWait(buttonImport) &&
await this.switchToNextPage();
}
async selectAccount(user) {
logger.info(this.name+ "selectAccount ");
logger.info(this.name + "selectAccount ");
try {
await this.switchToNextPage();
await this.setNetwork(user.networkID);
@ -77,28 +79,30 @@ class MetaMask extends Page {
user.accountOrderInMetamask + "].click();");
await this.switchToNextPage();
return true;
} catch(err) {
}
catch (err) {
return false;
}
}
async clickImportAccount() {
logger.info(this.name+ "clickImportAccount ");
logger.info(this.name + "clickImportAccount ");
try {
await super.clickWithWait(popupAccount);
await this.driver.executeScript("document.getElementsByClassName('dropdown-menu-item')["
+ (accountOrderNumber + 1) + "].click();");
accountOrderNumber++;
return true;
} catch (err) {
}
catch (err) {
return false;
}
}
async signTransaction(refreshCount) {
logger.info(this.name+ "signTransaction ");
logger.info(this.name + "signTransaction ");
await this.switchToNextPage();
let counter=5;
let counter = 5;
if (refreshCount !== undefined) counter = refreshCount;
do {
await this.refresh();
@ -108,51 +112,77 @@ class MetaMask extends Page {
await this.switchToNextPage();
}
await this.driver.sleep(3000);
} while(counter-->=0);
} while (counter-- >= 0);
await this.switchToNextPage();
return false;
}
async setNetwork(provider) {
logger.info(this.name+ "setNetwork ");
logger.info(this.name + "setNetwork ");
try {
await super.clickWithWait(popupNetwork);
let orderNumber = networks.indexOf(provider);
let script = "document.getElementsByClassName('dropdown-menu-item')["+orderNumber + "].click();"
let script = "document.getElementsByClassName('dropdown-menu-item')[" + orderNumber + "].click();"
if (orderNumber < 0) await this.addNetwork(provider);
else await this.driver.executeScript(script);
return true;
} catch (err) {
}
catch (err) {
return false;
}
}
async addNetwork(provider) {
logger.info(this.name+ "addNetwork ");
logger.info(this.name + "addNetwork ");
let url;
switch(provider) {
switch (provider) {
case 77: {
url="https://sokol.poa.network";
url = "https://sokol.poa.network";
networks.push(77);
break;
}
case 99: {
url="https://core.poa.network";
url = "https://core.poa.network";
networks.push(99);
break;
}
default: {
url="https://sokol.poa.network";
url = "https://sokol.poa.network";
}
}
await this.driver.executeScript("document.getElementsByClassName('dropdown-menu-item')["+
(networks.length-1)+"].click();");
return await super.fillWithWait(fieldNewRPCURL,url) &&
await this.driver.executeScript("document.getElementsByClassName('dropdown-menu-item')[" +
(networks.length - 1) + "].click();");
return await super.fillWithWait(fieldNewRPCURL, url) &&
await super.clickWithWait(buttonSave) &&
await super.clickWithWait(arrowBackRPCURL);
}
async clickButtonReject() {
logger.info(this.name + "clickButtonReject ");
return await super.clickWithWait(buttonReject);
}
async rejectTransaction(refreshCount) {
logger.info(this.name + " rejectTransaction ");
let counter = 5;
if (refreshCount !== undefined) counter = refreshCount;
await this.switchToNextPage();
do {
await this.refresh();
await super.waitUntilLocated(iconChangeAccount);
if (await this.isElementDisplayed(buttonReject)) {
return await this.clickButtonReject()
&& await this.switchToNextPage();
}
await this.driver.sleep(1000);
} while (counter-- >= 0);
await this.switchToNextPage();
return false;
}
}
module.exports = {
MetaMask:MetaMask
MetaMask: MetaMask
};

View File

@ -1,27 +1,29 @@
const Logger= require('../entity/Logger.js');
const logger=Logger.logger;
const Logger = require('../entity/Logger.js');
const logger = Logger.logger;
const key = require('selenium-webdriver').Key;
const webdriver = require('selenium-webdriver');
const By = require('selenium-webdriver/lib/by').By;
const loader=By.className("loading-container");
const loader = By.className("loading-container");
const loaderNotDisplayed = By.className("loading-container notdisplayed");
const titles=By.className("title");
const titles = By.className("title");
class Page {
constructor(driver) {
this.driver=driver;
this.driver = driver;
this.titleElement;
}
async pressKey(key, times) {
logger.info("press key "+key+" "+times+" times")
logger.info("press key " + key + " " + times + " times")
try {
const action=this.driver.actions();
for (let i=0;i<times;i++)
const action = this.driver.actions();
for (let i = 0; i < times; i++)
await action.sendKeys(key).perform();
return true;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
@ -29,15 +31,16 @@ class Page {
async waitUntilDisplayed(element, Twaiting) {
logger.info("wait until displayed");
let counter = Twaiting;
if (counter === undefined) counter = 180;
if (counter === undefined) counter = 180;
try {
do {
await this.driver.sleep(333);
if (await this.isElementDisplayed(element)) return true;
} while (counter-- > 0);
return false;
} catch(err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
@ -45,7 +48,7 @@ class Page {
async waitUntilLocated(element, Twaiting) {
logger.info("wait until located");
let counter = Twaiting;
if (counter === undefined) counter = 180;
if (counter === undefined) counter = 180;
try {
do {
await this.driver.sleep(333);
@ -53,78 +56,83 @@ class Page {
} while (counter-- > 0);
return false;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async isElementLocated(element) {
logger.info("is element located: ");
return (await this.driver.findElements(element)).length >0;
return (await this.driver.findElements(element)).length > 0;
}
async isElementDisplayed(element) {
logger.info("is element displayed: ");
try {
if (element.constructor.name !== "WebElement") {
return await this.driver.findElement(element).isDisplayed();
return await this.driver.findElement(element).isDisplayed();
}
else
return element.isDisplayed();
} catch (err) {
return element.isDisplayed();
}
catch (err) {
logger.info("false");
return false;
}
}
async getElement(element,Twaiting ) {
async getElement(element, Twaiting) {
logger.info("getElement: " + element);
try {
if (Twaiting === undefined) Twaiting = 180;
if (element.constructor.name !== "WebElement")
return await this.driver.wait(webdriver.until.elementLocated(element), Twaiting * 333);
else return element;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async isElementDisabled(element) {
logger.info("is element disabled :" +element);
logger.info("is element disabled :" + element);
try {
let field = await this.getElement(element);
return await this.driver.wait(webdriver.until.elementIsDisabled(field), 100);
let field = await this.getElement(element);
return !await field.isEnabled()
}
catch(err) {
logger.info("element enabled or does not present");
return false;
catch (err) {
logger.info("element enabled or does not present");
return false;
}
}
async getAttribute(element,attr) {
logger.info("get attribute = "+attr+ "for element = "+element);
async getAttribute(element, attr) {
logger.info("get attribute = " + attr + "for element = " + element);
try {
let field = await this.getElement(element);
let result = await field.getAttribute(attr);
logger.info("received value= " + result);
return result;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async getTextForElement(element,Twaiting) {
async getTextForElement(element, Twaiting) {
logger.info("get text for element : ");
try {
let field = await this.getElement(element, Twaiting);
let result = await field.getText();
if (result.length < 100) logger.info("text received: " + result);
return result;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
@ -134,26 +142,27 @@ class Page {
return await this.driver.getCurrentUrl();
}
async open (url) {
logger.info("open: "+url);
async open(url) {
logger.info("open: " + url);
try {
await this.driver.get(url);
logger.info("Current URL: " + await this.driver.getCurrentUrl());
logger.info("Current HANDLE: " + await this.driver.getWindowHandle());
return true;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async isLocatedLoader() {
async isLocatedLoader() {
logger.info("is loader displayed :");
try {
return await this.isElementLocated(loader);
}
catch (err) {
logger.info("Error: "+err);
logger.info("Error: " + err);
return false;
}
}
@ -162,7 +171,7 @@ class Page {
logger.info("wait until loader gone :");
if (!await this.isLocatedLoader()) return true;
else
return await this.waitUntilLocated(loaderNotDisplayed);
return await this.waitUntilLocated(loaderNotDisplayed);
}
async refresh() {
@ -170,47 +179,48 @@ class Page {
try {
await this.driver.navigate().refresh();
return true;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async clickWithWait(element,Twaiting) {
logger.info("click with wait: " +element);
async clickWithWait(element, Twaiting) {
logger.info("click with wait: " + element);
try {
let field = await this.getElement(element,Twaiting);
let field = await this.getElement(element, Twaiting);
await field.click();
return true;
}
catch(err) {
logger.info("Error: "+ err);
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async fillWithWait(element,k, Twaiting) {
logger.info("fill with wait : value = "+k);
async fillWithWait(element, k, Twaiting) {
logger.info("fill with wait : value = " + k);
try {
let field = await this.getElement(element,Twaiting);
let field = await this.getElement(element, Twaiting);
await field.sendKeys(k);
return true;
}
catch(err) {
logger.info("Element "+ element+" has not appeared in"+ Twaiting*333/1000+" sec.");
catch (err) {
logger.info("Element " + element + " has not appeared in" + Twaiting * 333 / 1000 + " sec.");
return false;
}
}
async findWithWait(element,Twaiting) {
async findWithWait(element, Twaiting) {
logger.info("find with wait ");
try {
if (Twaiting === undefined) Twaiting = 180;
await this.driver.wait(webdriver.until.elementLocated(element), Twaiting*333);
await this.driver.wait(webdriver.until.elementLocated(element), Twaiting * 333);
return await this.driver.findElements(element);
}
catch(err) {
logger.info("Element "+ element+" have not appeared in"+ Twaiting*333/1000+" sec.");
catch (err) {
logger.info("Element " + element + " have not appeared in" + Twaiting * 333 / 1000 + " sec.");
return null;
}
}
@ -232,25 +242,26 @@ class Page {
if (content === "") return true;
} while (counter-- > 0);
return false;
} catch(err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async switchToNextPage() {
logger.info("switch to next tab :");
let allHandles=[];
let allHandles = [];
let curHandle;
try {
allHandles = await this.driver.getAllWindowHandles();
curHandle = await this.driver.getWindowHandle();
if (allHandles.length>2) {
let arr=[];
arr[0]=allHandles[0];
arr[1]=allHandles[1];
allHandles=arr;
logger.info("Browser has " + allHandles.length+" tabs");
if (allHandles.length > 2) {
let arr = [];
arr[0] = allHandles[0];
arr[1] = allHandles[1];
allHandles = arr;
logger.info("Browser has " + allHandles.length + " tabs");
}
let handle;
for (let i = 0; i < allHandles.length; i++) {
@ -260,14 +271,15 @@ class Page {
}
}
await this.driver.switchTo().window(handle);
logger.info("Current handle = "+ curHandle);
logger.info("Switch to handle = "+ handle);
logger.info("Current handle = " + curHandle);
logger.info("Switch to handle = " + handle);
await this.driver.sleep(500);
return true;
} catch (err) {
logger.info("can't switch to next tab "+err);
logger.info("current handle: "+curHandle);
}
catch (err) {
logger.info("can't switch to next tab " + err);
logger.info("current handle: " + curHandle);
return false;
}
}
@ -277,20 +289,77 @@ class Page {
try {
this.driver.navigate().back();
return true;
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return false;
}
}
async getChildFromElementByClassName (child,element) {
async getChildFromElementByClassName(child, element) {
logger.info("getChildFromElementByClassName");
try {
return await element.findElements(By.className(child));
} catch (err) {
logger.info("Error: "+err);
}
catch (err) {
logger.info("Error: " + err);
return null;
}
}
async initTitles() {
logger.info("initTitles ");
try {
let array = await this.findWithWait(titles);
this.titleElement = array[0];
}
catch (err) {
logger.info("Error: " + err);
return null;
}
}
async getPageTitleText() {
logger.info("getPageTitle ");
await this.initTitles();
return this.getTextForElement(this.titleElement);
}
async waitUntilDisplayedTitle(Twaiting) {
logger.info("waitUntilDisplayedTitle: ");
return (await this.initTitles() !== null)
&& await this.waitUntilDisplayed(this.titleElement, Twaiting);
}
async isPresentAlert() {
logger.info("isPresentAlert:")
try {
let result = await this.driver.switchTo().alert().getText();
logger.info("alert text: " + result);
return true;
}
catch (err) {
logger.info("Error "+err);
return false;
}
}
async acceptAlert() {
logger.info("acceptAlert:")
try {
this.driver.switchTo().alert().accept();
return true;
}
catch (err) {
logger.info("Error "+err);
return false;
}
}
}
module.exports.Page=Page;
module.exports.Page = Page;

View File

@ -1,12 +1,14 @@
const logger = require('../entity/Logger.js').logger;
const Page = require('./Page.js').Page;
const By = require('selenium-webdriver/lib/by').By;
const Utils = require('../utils/Utils.js').Utils;
const ReservedTokensContainer = By.className("reserved-tokens-item-container-inner");
const buttonAdd = By.className("button button_fill button_no_icon");//("button button_fill button_no_icon");
const itemsRemove = By.className("item-remove");
const buttonClearAll = By.className("fa fa-trash");
const buttonYesAlert = By.className("swal2-confirm swal2-styled");
const buttonNoAlert = By.className("swal2-cancel swal2-styled");
const buttonOK = By.className("swal2-confirm swal2-styled");
class ReservedTokensPage extends Page {
@ -54,7 +56,7 @@ class ReservedTokensPage extends Page {
async initReservedTokensContainer() {
logger.info(this.name + "initReservedTokensContainer warnings ");
return await super.findWithWait(ReservedTokensContainer);
return await super.findWithWait(ReservedTokensContainer,10);
}
async initInputFields() {
@ -90,11 +92,14 @@ class ReservedTokensPage extends Page {
async amountAddedReservedTokens() {
logger.info(this.name + "amountAddedReservedTokens ");
try {
let arr = await this.initReservedTokensContainer();
logger.info("Reserved tokens added=" + arr.length);
return arr.length;
let array = await this.initReservedTokensContainer();
let length = 0;
if (array !== null) length = array.length;
logger.info("Reserved tokens added=" + length);
return length;
}
catch (err) {
logger.info("Error " +err);
return 0;
}
}
@ -161,13 +166,20 @@ class ReservedTokensPage extends Page {
}
async clickButtonClearAll() {
logger.info(this.name + "clickButtonClearAll ");
return await super.clickWithWait(buttonClearAll);
logger.info(this.name + " clickButtonClearAll :");
try {
await this.driver.executeScript("document.getElementsByClassName('fa fa-trash')[0].click();");
return true;
}
catch (err) {
logger.info(err);
return false;
}
}
async isDisplayedButtonClearAll() {
logger.info(this.name + "isDisplayedButtonClearAll ");
return await super.isElementDisplayed(buttonClearAll);
async isLocatedButtonClearAll() {
logger.info(this.name + "isLocatedButtonClearAll ");
return await super.isElementLocated(buttonClearAll);
}
async isDisplayedButtonYesAlert() {
@ -218,6 +230,28 @@ class ReservedTokensPage extends Page {
return result;
}
async uploadReservedCSVFile() {
try {
const locator = By.xpath('//input[@type="file"]');
let element = await this.driver.findElement(locator);
let path = await Utils.getPathToFileInPWD("bulkReservedAddresses.csv");
logger.info(this.name + ": uploadReservedAddressesCSVFile: from path: " + path);
await element.sendKeys(path);
return true;
}
catch (err) {
logger.info("Error " + err);
return false;
}
}
async clickButtonOk() {
logger.info("clickButtonOk");
await super.clickWithWait(buttonOK);
}
}
module.exports.ReservedTokensPage = ReservedTokensPage;

View File

@ -169,15 +169,21 @@ class TierPage extends Page {
async initWhitelistFields() {
logger.info(this.name + "initWhitelistContainer ");
let element = (await this.findWithWait(whitelistContainer))[this.number];
let array = await this.getChildFromElementByClassName("input", element);
if (array === null) return null;
else {
this.fieldWhAddressTier = array[0];
this.fieldMinTier = array[1];
this.fieldMaxTier = array[2];
try {
let element = (await this.findWithWait(whitelistContainer))[this.number];
let array = await this.getChildFromElementByClassName("input", element);
if (array === null) return null;
else {
this.fieldWhAddressTier = array[0];
this.fieldMinTier = array[1];
this.fieldMaxTier = array[2];
}
return array;
}
catch (err) {
logger.info("Error: " + err);
return null;
}
return array;
}
async initCheckboxes() {
@ -196,26 +202,26 @@ class TierPage extends Page {
async fillAddress(address) {
logger.info(this.name + "fillAddress ");
await this.initWhitelistFields();
return (this.fieldWhAddressTier !== undefined) &&
return (await this.initWhitelistFields() !== null)
&& (this.fieldWhAddressTier !== undefined) &&
await super.clearField(this.fieldWhAddressTier) &&
await super.fillWithWait(this.fieldWhAddressTier, address);
}
async fillMin(value) {
logger.info(this.name + "fillMin ");
await this.initWhitelistFields();
return (this.fieldMinTier !== undefined) &&
return (await this.initWhitelistFields() !== null)
&& (this.fieldMinTier !== undefined) &&
await super.clearField(this.fieldMinTier) &&
await super.fillWithWait(this.fieldMinTier, value);
}
async fillMax(value) {
logger.info(this.name + "fillMax ");
await this.initWhitelistFields();
return (this.fieldMaxTier !== undefined) &&
await super.clearField(this.fieldMaxTier) &&
await super.fillWithWait(this.fieldMaxTier, value);
return (await this.initWhitelistFields() !== null)
&& (this.fieldMaxTier !== undefined)
&& await super.clearField(this.fieldMaxTier)
&& await super.fillWithWait(this.fieldMaxTier, value);
}
async clickButtonAdd() {
@ -240,12 +246,19 @@ class TierPage extends Page {
await super.clickWithWait(this.itemsRemove[number]);
}
async amountAddedWhitelist() {
async isDisplayedWhitelistContainer() {
logger.info(this.name + "isDisplayedWhitelistContainer ");
return (await this.initWhitelistFields() !== null)
}
async amountAddedWhitelist(Twaiting) {
logger.info(this.name + "amountAddedWhitelist ");
try {
let array = await this.findWithWait(whitelistContainerInner);
logger.info("Whitelisted addresses added=" + array.length);
return array.length;
let array = await super.findWithWait(whitelistContainerInner,Twaiting);
let length = 0;
if (array !== null) length = array.length;
logger.info("Whitelisted addresses added=" + length);
return length;
}
catch (err) {
return 0;
@ -253,13 +266,26 @@ class TierPage extends Page {
}
async clickButtonClearAll() {
return await super.clickWithWait(buttonClearAll);
logger.info(this.name + "clickButtonClearAll:");
try {
await this.driver.executeScript("document.getElementsByClassName('fa fa-trash')[0].click();");
return true;
}
catch (err) {
logger.info("Error "+err);
return false;
}
}
async clickButtonYesAlert() {
return await super.clickWithWait(buttonYesAlert);
}
async waitUntilShowUpPopupConfirm(Twaiting) {
logger.info("waitUntilShowUpPopupConfirm: ");
return await this.waitUntilDisplayed(buttonYesAlert, Twaiting);
}
async isPresentWarningName() {
logger.info(this.name + "isPresentWarningName");
return false;

View File

@ -79,7 +79,7 @@ class WizardStep2 extends Page {
async isDisplayedWarningName() {
logger.info(this.name+"isDisplayedWarningName ");
return false;
return (await this.initWarnings() !== null) &&
(await this.getTextForElement(this.warningName) !== "");
}
@ -93,7 +93,6 @@ class WizardStep2 extends Page {
async isDisplayedWarningDecimals() {
logger.info(this.name + "isDisplayedWarningDecimals ");
return false;
return (await this.initWarnings() !== null) &&
(await this.getTextForElement(this.warningDecimals) !== "");
}

View File

@ -223,6 +223,7 @@ class WizardStep3 extends Page {
return await super.clickWithWait(buttonAddTier);
}
}
module.exports.WizardStep3 = WizardStep3;

View File

@ -16,6 +16,7 @@ const modal = By.className("modal");
const buttonOK = By.className("swal2-confirm swal2-styled");
const buttonSkipTransaction = By.className("no_image button button_fill");
const buttonYes = By.className("swal2-confirm swal2-styled");
const buttonCancelDeployment = By.className("button button_outline");
class WizardStep4 extends page.Page {
@ -23,34 +24,6 @@ class WizardStep4 extends page.Page {
super(driver);
this.URL;
this.name = "WizardStep4 page: ";
this.tokenContractAddress;
this.fieldTokenABI;
}
async init() {
var locator = By.className("input");
var arr = await super.findWithWait(locator);
this.tokenContractAddress = arr[2];
}
async initFields() {
const fields = By.css("pre");
var arr = await super.findWithWait(fields);
this.fieldTokenABI = arr[1];
}
async getABI() {
//*[@id="root"]/div/section/div[2]/div[2]/div[7]/div[2]/pre
await this.initFields();
logger.info(this.name + ": get ABI: ");
let element = this.fieldTokenABI;
let abi = await super.getTextForElement(element);
abi = JSON.parse(abi);
return abi;
}
async isDisplayedModal() {
@ -58,6 +31,11 @@ class WizardStep4 extends page.Page {
return await super.isElementDisplayed(modal);
}
async waitUntilDisplayedModal() {
logger.info(this.name + "waitUntilDisplayedModal: ");
return await super.waitUntilDisplayed(modal);
}
async clickButtonContinue() {
logger.info(this.name + "buttonContinue: ");
return await super.clickWithWait(buttonContinue);
@ -87,13 +65,19 @@ class WizardStep4 extends page.Page {
async clickButtonSkipTransaction() {
logger.info(this.name + "buttonSkipTransaction: ");
await this.driver.executeScript("document.getElementsByClassName('no_image button button_fill')[0].click();");
try {
await this.driver.executeScript("document.getElementsByClassName('no_image button button_fill')[0].click();");
return true;
}
catch (err) {
logger.info("Error " + err);
return false;
}
}
async clickButtonYes() {
logger.info(this.name + "clickButtonYes: ");
await super.clickWithWait(buttonYes);
return await super.clickWithWait(buttonYes);
}
async deployContracts(crowdsale) {
@ -104,7 +88,6 @@ class WizardStep4 extends page.Page {
let skippedTransactions = 0;
let timeLimit = timeLimitTransactions * crowdsale.tiers.length;
let metaMask = new MetaMask(this.driver);
do {
logger.info("Transaction# " + allTransactions++);
if (await metaMask.signTransaction()) {
@ -130,6 +113,10 @@ class WizardStep4 extends page.Page {
await this.clickButtonOk();
}
async clickButtonCancelDeployment() {
logger.info(this.name + "clickButtonCancelDeployment ");
return await super.clickWithWait(buttonCancelDeployment);
}
}
module.exports = {WizardStep4: WizardStep4}

View File

@ -1,46 +1,59 @@
const logger = require('../entity/Logger.js').logger;
const Page =require('./Page.js').Page;
const Page = require('./Page.js').Page;
const By = require('selenium-webdriver/lib/by').By;
const buttonNewCrowdsale=By.className("button button_fill");
const buttonChooseContract=By.className("button button_outline");
const buttonNewCrowdsale = By.className("button button_fill");
const buttonChooseContract = By.className("button button_outline");
class WizardWelcome extends Page {
constructor(driver,URL) {
super(driver);
this.URL = URL;
this.name = "WizardWelcome page: ";
}
async clickButtonNewCrowdsale() {
logger.info(this.name + "clickButtonNewCrowdsale");
return await super.clickWithWait(buttonNewCrowdsale);
}
async clickButtonChooseContract() {
logger.info(this.name + "clickButtonChooseContract");
return await super.clickWithWait(buttonChooseContract);
}
async open() {
logger.info(this.name + ": open");
return await super.open(this.URL);
constructor(driver, URL) {
super(driver);
this.URL = URL;
this.name = "WizardWelcome page: ";
}
async isPresentButtonNewCrowdsale() {
logger.info(this.name + ": isPresentButtonNewCrowdsale:");
return await super.isElementDisplayed(buttonNewCrowdsale);
}
async clickButtonNewCrowdsale() {
logger.info(this.name + "clickButtonNewCrowdsale");
return await super.clickWithWait(buttonNewCrowdsale);
}
async isPresentButtonChooseContract() {
logger.info(this.name + ": isPresentButtonChooseContract");
async clickButtonChooseContract() {
logger.info(this.name + "clickButtonChooseContract");
return await super.clickWithWait(buttonChooseContract);
}
async open() {
logger.info(this.name + ": open");
return await super.open(this.URL);
}
async waitUntilDisplayedButtonNewCrowdsale(Twaiting) {
logger.info(this.name + "waitUntilDisplayedButtonNewCrowdsale: ");
return await super.waitUntilDisplayed(buttonNewCrowdsale, Twaiting);
}
async isDisplayedButtonNewCrowdsale() {
logger.info(this.name + ": isDisplayedButtonNewCrowdsale:");
return await super.isElementDisplayed(buttonNewCrowdsale);
}
async isDisplayedButtonChooseContract() {
logger.info(this.name + ": isDisplayedButtonChooseContract");
return await super.isElementDisplayed(buttonChooseContract);
}
async isPage() {
return await super.isElementDisplayed(buttonNewCrowdsale) &&
await super.isElementDisplayed(buttonChooseContract);
}
async openWithAlertConfirmation() {
logger.info(this.name + " openWithAlertConfirmation ");
try {
await this.open(this.URL);
return true;
}
catch (err) {
await super.acceptAlert();
return false;
}
}
}
module.exports.WizardWelcome=WizardWelcome;
module.exports.WizardWelcome = WizardWelcome;

File diff suppressed because it is too large Load Diff

View File

@ -1,141 +0,0 @@
const Logger= require('../entity/Logger.js');
const logger=Logger.logger;
const utils=require('../utils/Utils.js');
const Utils=utils.Utils;
const metaMask=require('../pages/MetaMask.js');
const MetaMask=metaMask.MetaMask;
const user=require("../entity/User.js");
const User=user.User;
const crowdsale=require('../entity/Crowdsale.js');
const Crowdsale=crowdsale.Crowdsale;
const acc=require('../entity/Account.js');
const Account=acc.Account;
const reservedTokens=require('../entity/ReservedTokens.js');
const ReservedTokens=reservedTokens.ReservedTokens;
const reservedTokensPage=require('../pages/ReservedTokensPage.js');
const ReservedTokensPage=reservedTokensPage.ReservedTokensPage;
webdriver = require('selenium-webdriver');
let test = require('selenium-webdriver/testing');
let assert = require('assert');
const fs = require('fs-extra');
const eth_wallet=require('ethereumjs-wallet');
const bundleRA=[];
const bundleAccounts=[];
const number=process.argv[2];
const network=process.argv[3];
testRA();
async function testRA() {
const tempOutputPath='./temp/';
fs.ensureDirSync(tempOutputPath);
const tempOutputFile=tempOutputPath+'resultReservedBundle'+Date.now()+'.json';
fs.ensureFileSync(tempOutputFile);
console.log(Date.now());
logger.info("Test: create crowdsale with bundle of reserved tokens");
let driver = await Utils.startBrowserWithMetamask();
let user3_F16AFile='./users/user3_F16A.json';//Rinkeby
let user4_F16AFile='./users/user4_F16A.json';//Rinkeby
let user8545_56B2File='./users/user8545_56B2.json';//Ganache
let user77_56B2File='./users/user77_56B2.json';//Sokol
let Owner;
switch(network)
{
case '3': { Owner = new User (driver,user3_F16AFile);break;}
case '4': { Owner = new User (driver,user4_F16AFile);break;}
case '8545':{Owner = new User (driver,user8545_56B2File);break;}
default: {Owner = new User (driver,user77_56B2File);break;}
}
await Utils.receiveEth(Owner,20);
logger.info("Owner = "+Owner.account);
logger.info("Owner's balance = :"+await Utils.getBalance(Owner)/1e18);
let mtMask = new MetaMask(driver);
await mtMask.activate();//return activated Metamask and empty page
await Owner.setMetaMaskAccount();
let scenario = './scenarios/testRA.json';
let crowdsale = await Utils.getCrowdsaleInstance(scenario);
crowdsale = await Owner.createMintedCappedCrowdsale(crowdsale,1,'reserved');
await Owner.openInvestPage(crowdsale);
await driver.sleep(15000);
await driver.sleep(180000);
//await Owner.contribute(crowdsale.tiers[0].supply);
await Owner.contribute(20);
//await Owner.distribute(crowdsale);
await Owner.finalize(crowdsale);
let obj;
let balance;
let shouldBe;
let isPass=true;
let user= Owner;
for (let i=0;i<bundleRA.length;i++) {
if (bundleRA[i].dimension === 'percentage')
shouldBe=bundleRA[i].value*crowdsale.tiers[0].supply/100;
else shouldBe=bundleRA[i].value;
user.account=bundleAccounts[i].address;
user.privateKey=bundleAccounts[i].privateKey;
user.networkID=Owner.networkID;
balance=await user.getTokenBalance(crowdsale)/1e18;
bundleAccounts[i].balance=balance;
isPass=isPass&&(shouldBe === balance);
logger.info("#"+i+" should be:"+ shouldBe+" balance: "+balance+" "+ (shouldBe === balance));
}
logger.info("RESULT: "+isPass);
obj={owner:Owner,crowdsale:crowdsale,accounts:bundleAccounts,isPassTest:isPass};
fs.appendFileSync(tempOutputFile,JSON.stringify(obj));
}
async function generateAccount() {
let obj = eth_wallet.generate();
let address="0x".concat(obj.getAddress().toString('hex'));
let privateKey="0x".concat(obj.getPrivateKey().toString('hex'));
logger.info("Address created: "+address +" ,private key: "+privateKey);
return new Account(address,privateKey);
}
async function fillReservedTokens(driver) {
let account;
let dimension;
let value;
let RA;
logger.info("fill reserved tokens for testRA")
const reservedTokensPage=new ReservedTokensPage(driver);
for (let i=0;i<number;i++) {
account=await generateAccount();
dimension=Math.round(Math.random());
if (dimension === 0) dimension='percentage';
else dimension='tokens';
value=Math.trunc(Math.random()*1000);
RA=new ReservedTokens(account.address,dimension,value);
await reservedTokensPage.fillOneReservedToken(RA);
await reservedTokensPage.clickButtonAddReservedTokens();
bundleRA[i]=RA;
bundleAccounts[i]=account;
logger.info("#"+i+" Address: "+bundleRA[i].address+" , dimension"+bundleRA[i].dimension+" , value: "+ bundleRA[i].value+" #"+i);
await driver.sleep(1000);
}
let check=await reservedTokensPage.amountAddedReservedTokens();
logger.info("Reserved tokens added: "+check);
logger.info("Reserved tokens should be: "+number);
//await driver.sleep(120000);
}
module.exports.fillReservedTokens=fillReservedTokens;

1122
ttt.js

File diff suppressed because it is too large Load Diff