Skip to content
This repository has been archived by the owner on Apr 15, 2019. It is now read-only.

Make e2e tests more stable - Closes #878 #890

Merged
merged 27 commits into from
Nov 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
6f5b4bd
Wait for modal dialog animation to finish in e2e tests
slaweet Oct 19, 2017
e18b152
Move wait for modal dialog animation to step_definitions
slaweet Oct 19, 2017
61c10dc
Wait for new account modal in e2e test
slaweet Oct 20, 2017
b78da40
Stabilize vote launch protocol e2e test
slaweet Oct 20, 2017
9fc4c4a
Wait in vote by URL e2e test
slaweet Oct 20, 2017
617ed4b
Refactor e2e waitForElem to use promise
slaweet Oct 20, 2017
162c3f4
Catch errors of click in e2e tests
slaweet Oct 20, 2017
457d0e1
Increase wait for main menu open in e2e tests
slaweet Oct 20, 2017
03a6cbf
Move screenshot code back to hooks.js
slaweet Oct 20, 2017
c1ae844
Increase wait time for select to open
slaweet Oct 20, 2017
bc83eb7
Move e2e setup to Before block
slaweet Oct 20, 2017
43c6a6c
Fix capitalization of "I refresh the page" e2e step
slaweet Oct 20, 2017
7e054ee
Double the timeout of "Given I'm logged it"
slaweet Nov 2, 2017
d9440b5
Stabilize "remeber network" e2e test
slaweet Nov 2, 2017
1482a3b
Handle undefined callbacks in e2e utils
slaweet Nov 2, 2017
be042ed
Fix alert dialog e2e step
slaweet Nov 2, 2017
431d53b
Fix message wordings in e2e tests
slaweet Nov 2, 2017
3623d6c
Add wait to repeat transaction e2e test
slaweet Nov 2, 2017
6f55fc5
Fix forging e2e test
slaweet Nov 2, 2017
351aab5
Change repeat transaction e2e test value
slaweet Nov 2, 2017
906b568
Fix login e2e step to wait for async event
slaweet Nov 3, 2017
149db61
Fix async e2e steps to wait for previous command
slaweet Nov 3, 2017
43bc18d
Run e2e tests in Jenkins on built index.html
slaweet Nov 3, 2017
6c390d8
Add wait for vote dialog to animate in
slaweet Nov 6, 2017
348dd54
Add e2e test hook to for @pending tag
slaweet Nov 6, 2017
4414e58
Make unstable e2e "repeat transaction" scenario @pending
slaweet Nov 6, 2017
7355143
Wait for `.votedListSearch input` in e2e tests voting
slaweet Nov 6, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,13 @@ node('lisk-nano') {
ansiColor('xterm') {
sh '''
N=${EXECUTOR_NUMBER:-0}
NODE_ENV= npm run --silent dev -- --port 808$N > .lisk-nano.log 2>&1 &
sleep 30

# End to End test configuration
export DISPLAY=:1$N
Xvfb :1$N -ac -screen 0 1280x1024x24 &

# Run end-to-end tests
npm run --silent e2e-test -- --params.baseURL http://127.0.0.1:808$N/ --params.liskCoreURL http://127.0.0.1:400$N
npm run --silent e2e-test -- --params.baseURL file://$WORKSPACE/app/build/index.html --params.liskCoreURL http://127.0.0.1:400$N
'''
}
} catch (err) {
Expand All @@ -143,8 +141,6 @@ node('lisk-nano') {
( cd ~/lisk-Linux-x86_64 && bash lisk.sh stop_node -p etc/pm2-lisk_$N.json ) || true
pgrep --list-full -f "Xvfb :1$N" || true
pkill --echo -f "Xvfb :1$N" -9 || echo "pkill returned code $?"
pgrep --list-full -f "webpack.*808$N" || true
pkill --echo -f "webpack.*808$N" -9 || echo "pkill returned code $?"
'''
dir('node_modules') {
deleteDir()
Expand Down
6 changes: 3 additions & 3 deletions features/accountManagement.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Feature: Account management
And I click "save account button"
And I wait 1 seconds
And I should see text "Account saved" in "toast" element
And I Refresh the page
And I refresh the page
And I wait 2 seconds
Then I should be logged in
And I click "send button"
Expand All @@ -26,12 +26,12 @@ Feature: Account management
Given I'm logged in as "any account"
When I click "save account" in main menu
And I click "save account button"
And I Refresh the page
And I refresh the page
And I wait 2 seconds
And I click "forget account" in main menu
And I wait 1 seconds
Then I should see text "Account was successfully forgotten." in "toast" element
And I Refresh the page
And I refresh the page
And I should be on login page

Scenario: should allow to exit save account dialog with "cancel button"
Expand Down
2 changes: 2 additions & 0 deletions features/login.feature
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Feature: Login page
When I fill in "wagon stock borrow episode laundry kitten salute link globe zero feed marble" to "passphrase" field
And I select option no. 2 from "network" select
And I click "login button"
And I wait 2 seconds
And I refresh the page
And I fill in "wagon stock borrow episode laundry kitten salute link globe zero feed marble" to "passphrase" field
And I click "login button"
Expand All @@ -45,6 +46,7 @@ Feature: Login page
Scenario: should allow to create a new account
Given I'm on login page
When I click "new account button"
And I wait 1 seconds
And I click "next button"
And I 250 times move mouse randomly
And I remember passphrase, click "next button", fill in missing word
Expand Down
4 changes: 2 additions & 2 deletions features/menu.feature
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Feature: Top right menu
When I click "register as delegate" in main menu
And I fill in "test" to "username" field
And I click "register button"
Then I should see alert dialog with title "Success" and text "Delegate registration was successfully submitted. It can take several seconds before it is processed."
Then I should see alert dialog with title "Success" and text "Delegate registration was successfully submitted with username: "test". It can take several seconds before it is processed."
And I click "ok button"
And I wait 15 seconds
And I should see text "test" in "delegate name" element
Expand All @@ -44,7 +44,7 @@ Feature: Top right menu
And I fill in "test2" to "username" field
And I fill in second passphrase of "second passphrase account" to "second passphrase" field
And I click "register button"
Then I should see alert dialog with title "Success" and text "Delegate registration was successfully submitted. It can take several seconds before it is processed."
Then I should see alert dialog with title "Success" and text "Delegate registration was successfully submitted with username: "test2". It can take several seconds before it is processed."

Scenario: should allow to exit delegate registration dialog
Given I'm logged in as "genesis"
Expand Down
3 changes: 2 additions & 1 deletion features/send.feature
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Feature: Send dialog
Scenario: should allow to exit send dialog
Given I'm logged in as "any account"
When I click "send button"
And I wait 1 seconds
And I click "cancel button"
Then I should see no "modal dialog"

Expand All @@ -33,7 +34,7 @@ Feature: Send dialog
And I fill in "537318935439898807L" to "recipient" field
And I click "send maximum amount" in "transaction amount" menu
And I click "submit button"
Then I should see alert dialog with title "Success" and text "Your transaction of 101 LSK to 537318935439898807L was accepted and will be processed in a few seconds."
Then I should see alert dialog with title "Success" and text "Your transaction of 100 LSK to 537318935439898807L was accepted and will be processed in a few seconds."

Scenario: should allow to send with second passphrase
Given I'm logged in as "second passphrase account"
Expand Down
2 changes: 1 addition & 1 deletion features/step_definitions/forging.step.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { waitForElemAndCheckItsText } = require('../support/util.js');

defineSupportCode(({ Then }) => {
Then('I should see forging center', (callback) => {
waitForElemAndCheckItsText('.delegate-name', 'genesis_17', callback);
waitForElemAndCheckItsText('.delegate-name', 'genesis_17');
waitForElemAndCheckItsText('.forged-blocks h5', 'Forged Blocks', callback);
});
});
61 changes: 28 additions & 33 deletions features/step_definitions/generic.step.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const {
waitForElemAndCheckItsText,
waitForElemAndMatchItsText,
waitForElemRemoved,
waitForElemAndClickIt,
waitForElemAndSendKeys,
Expand All @@ -12,7 +13,6 @@ const {
waitTime,
} = require('../support/util.js');
const accounts = require('../support/accounts.js');
const localStorage = require('../support/localStorage.js');

chai.use(chaiAsPromised);
const expect = chai.expect;
Expand Down Expand Up @@ -75,12 +75,12 @@ defineSupportCode(({ Given, When, Then, setDefaultTimeout }) => {

When('I select option no. {index} from "{selectName}" select', (index, selectName, callback) => {
waitForElemAndClickIt(`.${selectName}`);
browser.sleep(500);
browser.sleep(1000);
const selector = `.${selectName} ul li`;
const optionElem = element.all(by.css(selector)).get(index - 1);
browser.wait(EC.presenceOf(optionElem), waitTime)
.catch(error => console.error(`${error}`)); // eslint-disable-line no-console
optionElem.click().then(callback);
optionElem.click().then(callback).catch(callback);
});

Then('the option "{optionText}" is selected in "{selectName}" select', (optionText, selectName, callback) => {
Expand All @@ -101,7 +101,7 @@ defineSupportCode(({ Given, When, Then, setDefaultTimeout }) => {

Then('I should see no "{elementName}"', (elementName, callback) => {
const selector = `.${elementName.replace(/ /g, '-')}`;
waitForElemRemoved(selector, () => {
waitForElemRemoved(selector).then(() => {
expect(element.all(by.css(selector)).count()).to.eventually.equal(0)
.and.notify(callback);
});
Expand All @@ -123,9 +123,9 @@ defineSupportCode(({ Given, When, Then, setDefaultTimeout }) => {
waitForElemAndCheckItsText(selectorClass, text, callback);
});

Then('I should see "{elementName}" element with text:', (elementName, text, callback) => {
Then('I should see "{elementName}" element with text matching regexp:', (elementName, text, callback) => {
const selectorClass = `.${elementName.replace(/ /g, '-')}`;
waitForElemAndCheckItsText(selectorClass, text, callback);
waitForElemAndMatchItsText(selectorClass, text, callback);
});

Then('I should see element "{elementName}" that contains text:', (elementName, text, callback) => {
Expand All @@ -139,15 +139,10 @@ defineSupportCode(({ Given, When, Then, setDefaultTimeout }) => {
});

Given('I\'m logged in as "{accountName}"', { timeout: 2 * defaultTimeout }, (accountName, callback) => {
browser.ignoreSynchronization = true;
browser.driver.manage().window().setSize(1000, 1000);
browser.get(browser.params.baseURL);
localStorage.clear();
localStorage.setItem('address', browser.params.liskCoreURL);
localStorage.setItem('network', 2);
browser.get(browser.params.baseURL);
waitForElemAndSendKeys('.passphrase input', accounts[accountName].passphrase);
waitForElemAndClickIt('.login-button', callback);
waitForElemAndSendKeys('.passphrase input', accounts[accountName].passphrase, () => {
waitForElemAndClickIt('.login-button', callback);
});
});

When('I go to "{url}"', (url, callback) => {
Expand All @@ -171,29 +166,29 @@ defineSupportCode(({ Given, When, Then, setDefaultTimeout }) => {
});

When('I remember passphrase, click "{nextButtonSelector}", fill in missing word', { timeout: 2 * defaultTimeout }, (nextButtonSelector, callback) => {
waitForElemAndCheckItsText('.passphrase label', 'Save your passphrase in a safe place!');

waitForElem('.passphrase textarea', (textareaElem) => {
textareaElem.getText().then((passphrase) => {
// eslint-disable-next-line no-unused-expressions
expect(passphrase).to.not.be.undefined;
const passphraseWords = passphrase.split(' ');
expect(passphraseWords.length).to.equal(12);
waitForElemAndClickIt(`.${nextButtonSelector.replace(/ /g, '-')}`);

waitForElem('.passphrase-verifier p span', (elem) => {
elem.getText().then((firstPartOfPassphrase) => {
const missingWordIndex = firstPartOfPassphrase.length ?
firstPartOfPassphrase.split(' ').length :
0;
waitForElemAndSendKeys('.passphrase-verifier input', passphraseWords[missingWordIndex], callback);
waitForElemAndCheckItsText('.passphrase label', 'Save your passphrase in a safe place!', () => {
waitForElem('.passphrase textarea').then((textareaElem) => {
textareaElem.getText().then((passphrase) => {
// eslint-disable-next-line no-unused-expressions
expect(passphrase).to.not.be.undefined;
const passphraseWords = passphrase.split(' ');
expect(passphraseWords.length).to.equal(12);
waitForElemAndClickIt(`.${nextButtonSelector.replace(/ /g, '-')}`, () => {
waitForElem('.passphrase-verifier p span').then((elem) => {
elem.getText().then((firstPartOfPassphrase) => {
const missingWordIndex = firstPartOfPassphrase.length ?
firstPartOfPassphrase.split(' ').length :
0;
waitForElemAndSendKeys('.passphrase-verifier input', passphraseWords[missingWordIndex], callback);
}).catch(callback);
}).catch(callback);
});
});
});
}).catch(callback);
}).catch(callback);
});
});

When('I Refresh the page', (callback) => {
When('I refresh the page', (callback) => {
browser.refresh().then(callback);
});

Expand Down
48 changes: 46 additions & 2 deletions features/step_definitions/hooks.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,52 @@
/* eslint-disable import/no-extraneous-dependencies */
const { defineSupportCode } = require('cucumber');
const { takeScreenshot, slugify } = require('../support/util.js');
const fs = require('fs');
const localStorage = require('../support/localStorage.js');

function slugify(text) {
return text.toString().toLowerCase()
.replace(/\s+/g, '-') // Replace spaces with -
.replace(/[^\w-]+/g, '') // Remove all non-word chars
.replace(/--+/g, '-') // Replace multiple - with single -
.replace(/^-+/, '') // Trim - from start of text
.replace(/-+$/, ''); // Trim - from end of text
}

function writeScreenShot(data, filename) {
const stream = fs.createWriteStream(filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
}

function takeScreenshot(screnarioSlug, callback) {
browser.takeScreenshot().then((screenshotBuffer) => {
if (!fs.existsSync(browser.params.screenshotFolder)) {
fs.mkdirSync(browser.params.screenshotFolder);
}
const screenshotPath = `${browser.params.screenshotFolder}/${screnarioSlug}.png`;
writeScreenShot(screenshotBuffer, screenshotPath);
console.log(`Screenshot saved to ${screenshotPath}`); // eslint-disable-line no-console
if (callback) {
callback();
}
});
}

defineSupportCode(({ Before, After }) => {
Before((scenario, callback) => {
browser.ignoreSynchronization = true;
browser.driver.manage().window().setSize(1000, 1000);
browser.get(browser.params.baseURL);
localStorage.clear();
localStorage.setItem('address', browser.params.liskCoreURL);
localStorage.setItem('network', 2);
callback();
});

Before('@pending', (scenario, callback) => {
callback(null, 'pending');
});

defineSupportCode(({ After }) => {
After((scenario, callback) => {
if (scenario.isFailed()) {
const screnarioSlug = slugify([scenario.scenario.feature.name, scenario.scenario.name].join(' '));
Expand Down
9 changes: 1 addition & 8 deletions features/step_definitions/login.step.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@
const { defineSupportCode } = require('cucumber');
const { waitForElemAndCheckItsText } = require('../support/util.js');

defineSupportCode(({ Given, Then, When }) => {
defineSupportCode(({ Given, Then }) => {
Given('I\'m on login page', (callback) => {
browser.ignoreSynchronization = true;
browser.driver.manage().window().setSize(1000, 1000);
browser.driver.get('about:blank');
browser.get(browser.params.baseURL).then(callback);
});

When('I refresh the page', (callback) => {
browser.driver.navigate().refresh().then(callback);
});

Then('I should be logged in', (callback) => {
waitForElemAndCheckItsText('.logout-button', 'LOGOUT', callback);
});
Expand Down
5 changes: 3 additions & 2 deletions features/step_definitions/menu.step.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ defineSupportCode(({ When, Then }) => {
When('I click "{itemSelector}" in main menu', (itemSelector, callback) => {
waitForElemAndClickIt('.main-menu-icon-button');
browser.sleep(1000);
waitForElemAndClickIt(`.${itemSelector.replace(/ /g, '-')}`, callback);
waitForElemAndClickIt(`.${itemSelector.replace(/ /g, '-')}`);
browser.sleep(1000).then(callback);
});

Then('There is no "{itemSelector}" in main menu', (itemSelector, callback) => {
waitForElemAndClickIt('.main-menu-icon-button');
browser.sleep(1000);
browser.sleep(500);
expect(element.all(by.css(`md-menu-item .md-button.${itemSelector.replace(/ /g, '-')}`)).count()).to.eventually.equal(0)
.and.notify(callback);
});
Expand Down
17 changes: 11 additions & 6 deletions features/step_definitions/voting.step.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
const { defineSupportCode } = require('cucumber');
const chai = require('chai');
const chaiAsPromised = require('chai-as-promised');
const { waitForElemAndClickIt } = require('../support/util.js');
const {
waitForElemAndClickIt,
waitForElemAndSendKeys,
} = require('../support/util.js');

chai.use(chaiAsPromised);
const expect = chai.expect;
Expand All @@ -13,11 +16,13 @@ defineSupportCode(({ When, Then }) => {
});

When('Search twice for "{searchTerm}" in vote dialog', (searchTerm, callback) => {
element.all(by.css('.votedListSearch input')).get(0).sendKeys(searchTerm);
waitForElemAndClickIt('#votedResult ul li:nth-child(1)');
element.all(by.css('.votedListSearch input')).get(0).sendKeys(searchTerm);
browser.sleep(500);
waitForElemAndClickIt('#votedResult ul li:nth-child(1)', callback);
waitForElemAndSendKeys('.votedListSearch input', searchTerm, () => {
waitForElemAndClickIt('#votedResult ul li:nth-child(1)', () => {
element.all(by.css('.votedListSearch input')).get(0).sendKeys(searchTerm);
browser.sleep(500);
waitForElemAndClickIt('#votedResult ul li:nth-child(1)', callback);
});
});
});

Then('I should see delegates list with {count} lines', (count, callback) => {
Expand Down
Loading