Merge pull request #1044 from neuroscr/fix-int-tests

Integration tests: Support slower computers/network
pull/1047/head
Ryan Tharp 5 years ago committed by GitHub
commit 996d7c9844
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -38,7 +38,7 @@ describe('Add friends', function() {
await common.stopStubSnodeServer(); await common.stopStubSnodeServer();
}); });
it('can add a friend by sessionID', async () => { it('addFriends: can add a friend by sessionID', async () => {
const textMessage = common.generateSendMessageText(); const textMessage = common.generateSendMessageText();
await app.client.element(ConversationPage.contactsButtonSection).click(); await app.client.element(ConversationPage.contactsButtonSection).click();
@ -46,13 +46,16 @@ describe('Add friends', function() {
await app.client.isExisting(ConversationPage.leftPaneOverlay).should await app.client.isExisting(ConversationPage.leftPaneOverlay).should
.eventually.be.true; .eventually.be.true;
await app.client await common.setValueWrapper(
.element(ConversationPage.sessionIDInput) app,
.setValue(common.TEST_PUBKEY2); ConversationPage.sessionIDInput,
common.TEST_PUBKEY2
);
await app.client await app.client
.element(ConversationPage.sessionIDInput) .element(ConversationPage.sessionIDInput)
.getValue() .getValue()
.should.eventually.equal(common.TEST_PUBKEY2); .should.eventually.equal(common.TEST_PUBKEY2);
await app.client.element(ConversationPage.nextButton).click(); await app.client.element(ConversationPage.nextButton).click();
await app.client.waitForExist( await app.client.waitForExist(
ConversationPage.sendFriendRequestTextarea, ConversationPage.sendFriendRequestTextarea,
@ -68,6 +71,7 @@ describe('Add friends', function() {
ConversationPage.existingFriendRequestText(textMessage), ConversationPage.existingFriendRequestText(textMessage),
1000 1000
); );
// assure friend request message has been sent // assure friend request message has been sent
await common.timeout(3000); await common.timeout(3000);
await app.client.isExisting(ConversationPage.retrySendButton).should await app.client.isExisting(ConversationPage.retrySendButton).should

@ -23,14 +23,16 @@ describe('Closed groups', function() {
await common.stopStubSnodeServer(); await common.stopStubSnodeServer();
}); });
it('can create a closed group with a friend and send/receive a message', async () => { it('closedGroup: can create a closed group with a friend and send/receive a message', async () => {
await app.client.element(ConversationPage.globeButtonSection).click(); await app.client.element(ConversationPage.globeButtonSection).click();
await app.client.element(ConversationPage.createClosedGroupButton).click(); await app.client.element(ConversationPage.createClosedGroupButton).click();
// fill the groupname // fill the groupname
await app.client await common.setValueWrapper(
.element(ConversationPage.closedGroupNameTextarea) app,
.setValue(common.VALID_CLOSED_GROUP_NAME1); ConversationPage.closedGroupNameTextarea,
common.VALID_CLOSED_GROUP_NAME1
);
await app.client await app.client
.element(ConversationPage.closedGroupNameTextarea) .element(ConversationPage.closedGroupNameTextarea)
.getValue() .getValue()

@ -50,6 +50,38 @@ module.exports = {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
}, },
// a wrapper to work around electron/spectron bug
async setValueWrapper(app, selector, value) {
await app.client.element(selector).click();
// keys, setValue and addValue hang on certain platforms
// could put a branch here to use one of those
// if we know what platforms are good and which ones are broken
await app.client.execute(
(slctr, val) => {
// eslint-disable-next-line no-undef
const iter = document.evaluate(
slctr,
// eslint-disable-next-line no-undef
document,
null,
// eslint-disable-next-line no-undef
XPathResult.UNORDERED_NODE_ITERATOR_TYPE,
null
);
const elem = iter.iterateNext();
if (elem) {
elem.value = val;
} else {
console.error('Cant find', slctr, elem, iter);
}
},
selector,
value
);
// let session js detect the text change
await app.client.element(selector).click();
},
async startApp(environment = 'test-integration-session') { async startApp(environment = 'test-integration-session') {
const env = environment.startsWith('test-integration') const env = environment.startsWith('test-integration')
? 'test-integration' ? 'test-integration'
@ -92,16 +124,16 @@ module.exports = {
async stopApp(app1) { async stopApp(app1) {
if (app1 && app1.isRunning()) { if (app1 && app1.isRunning()) {
await app1.stop(); await app1.stop();
return Promise.resolve();
} }
return Promise.resolve();
}, },
async killallElectron() { async killallElectron() {
// rtharp - my 2nd client on MacOs needs: pkill -f "node_modules/.bin/electron"
// node_modules/electron/dist/electron is node_modules/electron/dist/Electron.app on MacOS
const killStr = const killStr =
process.platform === 'win32' process.platform === 'win32'
? 'taskkill /im electron.exe /t /f' ? 'taskkill /im electron.exe /t /f'
: 'pkill -f "node_modules/electron/dist/electron"'; : 'pkill -f "node_modules/electron/dist/electron" | pkill -f "node_modules/.bin/electron"';
return new Promise(resolve => { return new Promise(resolve => {
exec(killStr, (err, stdout, stderr) => { exec(killStr, (err, stdout, stderr) => {
if (err) { if (err) {
@ -145,23 +177,24 @@ module.exports = {
stubOpenGroups = false, stubOpenGroups = false,
env = 'test-integration-session', env = 'test-integration-session',
}) { }) {
const app1 = await this.startAndAssureCleanedApp(env); const app = await this.startAndAssureCleanedApp(env);
if (stubSnode) { if (stubSnode) {
await this.startStubSnodeServer(); await this.startStubSnodeServer();
this.stubSnodeCalls(app1); this.stubSnodeCalls(app);
} }
if (stubOpenGroups) { if (stubOpenGroups) {
this.stubOpenGroupsCalls(app1); this.stubOpenGroupsCalls(app);
} }
if (mnemonic && displayName) { if (mnemonic && displayName) {
await this.restoreFromMnemonic(app1, mnemonic, displayName); await this.restoreFromMnemonic(app, mnemonic, displayName);
// not sure we need this - rtharp.
await this.timeout(2000); await this.timeout(2000);
} }
return app1; return app;
}, },
async startAndStub2(props) { async startAndStub2(props) {
@ -173,18 +206,23 @@ module.exports = {
return app2; return app2;
}, },
async restoreFromMnemonic(app1, mnemonic, displayName) { async restoreFromMnemonic(app, mnemonic, displayName) {
await app1.client.element(RegistrationPage.registrationTabSignIn).click(); await app.client.element(RegistrationPage.registrationTabSignIn).click();
await app1.client.element(RegistrationPage.restoreFromSeedMode).click(); await app.client.element(RegistrationPage.restoreFromSeedMode).click();
await app1.client await this.setValueWrapper(
.element(RegistrationPage.recoveryPhraseInput) app,
.setValue(mnemonic); RegistrationPage.recoveryPhraseInput,
await app1.client mnemonic
.element(RegistrationPage.displayNameInput) );
.setValue(displayName);
await this.setValueWrapper(
await app1.client.element(RegistrationPage.continueSessionButton).click(); app,
await app1.client.waitForExist( RegistrationPage.displayNameInput,
displayName
);
await app.client.element(RegistrationPage.continueSessionButton).click();
await app.client.waitForExist(
RegistrationPage.conversationListContainer, RegistrationPage.conversationListContainer,
4000 4000
); );
@ -214,9 +252,11 @@ module.exports = {
await app1.client.element(ConversationPage.contactsButtonSection).click(); await app1.client.element(ConversationPage.contactsButtonSection).click();
await app1.client.element(ConversationPage.addContactButton).click(); await app1.client.element(ConversationPage.addContactButton).click();
await app1.client await this.setValueWrapper(
.element(ConversationPage.sessionIDInput) app1,
.setValue(this.TEST_PUBKEY2); ConversationPage.sessionIDInput,
this.TEST_PUBKEY2
);
await app1.client.element(ConversationPage.nextButton).click(); await app1.client.element(ConversationPage.nextButton).click();
await app1.client.waitForExist( await app1.client.waitForExist(
ConversationPage.sendFriendRequestTextarea, ConversationPage.sendFriendRequestTextarea,
@ -224,9 +264,11 @@ module.exports = {
); );
// send a text message to that user (will be a friend request) // send a text message to that user (will be a friend request)
await app1.client await this.setValueWrapper(
.element(ConversationPage.sendFriendRequestTextarea) app1,
.setValue(textMessage); ConversationPage.sendFriendRequestTextarea,
textMessage
);
await app1.client.keys('Enter'); await app1.client.keys('Enter');
await app1.client.waitForExist( await app1.client.waitForExist(
ConversationPage.existingFriendRequestText(textMessage), ConversationPage.existingFriendRequestText(textMessage),
@ -284,9 +326,12 @@ module.exports = {
// next trigger the link request from the app2 with the app1 pubkey // next trigger the link request from the app2 with the app1 pubkey
await app2.client.element(RegistrationPage.registrationTabSignIn).click(); await app2.client.element(RegistrationPage.registrationTabSignIn).click();
await app2.client.element(RegistrationPage.linkDeviceMode).click(); await app2.client.element(RegistrationPage.linkDeviceMode).click();
await app2.client
.element(RegistrationPage.textareaLinkDevicePubkey) await this.setValueWrapper(
.setValue(this.TEST_PUBKEY1); app2,
RegistrationPage.textareaLinkDevicePubkey,
this.TEST_PUBKEY1
);
await app2.client.element(RegistrationPage.linkDeviceTriggerButton).click(); await app2.client.element(RegistrationPage.linkDeviceTriggerButton).click();
await app1.client.waitForExist(RegistrationPage.toastWrapper, 7000); await app1.client.waitForExist(RegistrationPage.toastWrapper, 7000);
let secretWordsapp1 = await app1.client let secretWordsapp1 = await app1.client

@ -36,11 +36,11 @@ describe('Link Device', function() {
await common.stopStubSnodeServer(); await common.stopStubSnodeServer();
}); });
it('link two desktop devices', async () => { it('linkDevice: link two desktop devices', async () => {
await common.linkApp2ToApp(app, app2); await common.linkApp2ToApp(app, app2);
}); });
it('unlink two devices', async () => { it('linkDevice: unlink two devices', async () => {
await common.linkApp2ToApp(app, app2); await common.linkApp2ToApp(app, app2);
await common.timeout(1000); await common.timeout(1000);
await common.triggerUnlinkApp2FromApp(app, app2); await common.triggerUnlinkApp2FromApp(app, app2);

@ -23,25 +23,25 @@ describe('Open groups', function() {
await common.killallElectron(); await common.killallElectron();
}); });
it('works with valid group url', async () => { // reduce code duplication to get the initial join
async function joinOpenGroup(url, name) {
await app.client.element(ConversationPage.globeButtonSection).click(); await app.client.element(ConversationPage.globeButtonSection).click();
await app.client.element(ConversationPage.joinOpenGroupButton).click(); await app.client.element(ConversationPage.joinOpenGroupButton).click();
await app.client await common.setValueWrapper(app, ConversationPage.openGroupInputUrl, url);
.element(ConversationPage.openGroupInputUrl)
.setValue(common.VALID_GROUP_URL);
await app.client await app.client
.element(ConversationPage.openGroupInputUrl) .element(ConversationPage.openGroupInputUrl)
.getValue() .getValue()
.should.eventually.equal(common.VALID_GROUP_URL); .should.eventually.equal(url);
await app.client.element(ConversationPage.joinOpenGroupButton).click(); await app.client.element(ConversationPage.joinOpenGroupButton).click();
// validate session loader is shown // validate session loader is shown
await app.client.isExisting(ConversationPage.sessionLoader).should await app.client.isExisting(ConversationPage.sessionLoader).should
.eventually.be.true; .eventually.be.true;
// account for slow home internet connection delays...
await app.client.waitForExist( await app.client.waitForExist(
ConversationPage.sessionToastJoinOpenGroupSuccess, ConversationPage.sessionToastJoinOpenGroupSuccess,
9000 60 * 1000
); );
// validate overlay is closed // validate overlay is closed
@ -50,35 +50,27 @@ describe('Open groups', function() {
// validate open chat has been added // validate open chat has been added
await app.client.waitForExist( await app.client.waitForExist(
ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME), ConversationPage.rowOpenGroupConversationName(name),
4000 4000
); );
}
await common.timeout(1000); it('openGroup: works with valid open group url', async () => {
await joinOpenGroup(common.VALID_GROUP_URL, common.VALID_GROUP_NAME);
}); });
it('cannot join two times the same open group', async () => { it('openGroup: cannot join two times the same open group', async () => {
await app.client.element(ConversationPage.globeButtonSection).click(); await joinOpenGroup(common.VALID_GROUP_URL2, common.VALID_GROUP_NAME2);
await app.client.element(ConversationPage.joinOpenGroupButton).click();
await app.client
.element(ConversationPage.openGroupInputUrl)
.setValue(common.VALID_GROUP_URL2);
await app.client.element(ConversationPage.joinOpenGroupButton).click();
// first add is a success
await common.timeout(2000);
await app.client.waitForExist(
ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME2),
8000
);
// adding a second time the same open group // adding a second time the same open group
await app.client.element(ConversationPage.globeButtonSection).click(); await app.client.element(ConversationPage.globeButtonSection).click();
await app.client.element(ConversationPage.joinOpenGroupButton).click(); await app.client.element(ConversationPage.joinOpenGroupButton).click();
await app.client await common.setValueWrapper(
.element(ConversationPage.openGroupInputUrl) app,
.setValue(common.VALID_GROUP_URL2); ConversationPage.openGroupInputUrl,
common.VALID_GROUP_URL2
);
await app.client.element(ConversationPage.joinOpenGroupButton).click(); await app.client.element(ConversationPage.joinOpenGroupButton).click();
// validate session loader is not shown // validate session loader is not shown
await app.client.isExisting(ConversationPage.sessionLoader).should await app.client.isExisting(ConversationPage.sessionLoader).should
@ -86,7 +78,7 @@ describe('Open groups', function() {
await app.client.waitForExist( await app.client.waitForExist(
ConversationPage.sessionToastJoinOpenGroupAlreadyExist, ConversationPage.sessionToastJoinOpenGroupAlreadyExist,
1000 1 * 1000
); );
// validate overlay is still opened // validate overlay is still opened
@ -94,20 +86,28 @@ describe('Open groups', function() {
.eventually.be.true; .eventually.be.true;
}); });
it('can send message to open group', async () => { it('openGroup: can send message to open group', async () => {
// join dev-chat group // join dev-chat group
await app.client.element(ConversationPage.globeButtonSection).click(); await app.client.element(ConversationPage.globeButtonSection).click();
await app.client.element(ConversationPage.joinOpenGroupButton).click(); await app.client.element(ConversationPage.joinOpenGroupButton).click();
await app.client await common.setValueWrapper(
.element(ConversationPage.openGroupInputUrl) app,
.setValue(common.VALID_GROUP_URL2); ConversationPage.openGroupInputUrl,
common.VALID_GROUP_URL2
);
await app.client.element(ConversationPage.joinOpenGroupButton).click(); await app.client.element(ConversationPage.joinOpenGroupButton).click();
// first add is a success
await common.timeout(2000); // wait for toast to appear
await app.client.waitForExist(
ConversationPage.sessionToastJoinOpenGroupSuccess,
30 * 1000
);
await common.timeout(5 * 1000); // wait for toast to clear
await app.client.waitForExist( await app.client.waitForExist(
ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME2), ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME2),
8000 10 * 1000
); );
// generate a message containing the current timestamp so we can find it in the list of messages // generate a message containing the current timestamp so we can find it in the list of messages
const textMessage = common.generateSendMessageText(); const textMessage = common.generateSendMessageText();
@ -118,14 +118,18 @@ describe('Open groups', function() {
await app.client.isExisting( await app.client.isExisting(
ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME2) ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME2)
); );
await app.client await app.client
.element( .element(
ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME2) ConversationPage.rowOpenGroupConversationName(common.VALID_GROUP_NAME2)
) )
.click(); .click();
await app.client
.element(ConversationPage.sendMessageTextarea) await common.setValueWrapper(
.setValue(textMessage); app,
ConversationPage.sendMessageTextarea,
textMessage
);
await app.client await app.client
.element(ConversationPage.sendMessageTextarea) .element(ConversationPage.sendMessageTextarea)
.getValue() .getValue()
@ -139,7 +143,7 @@ describe('Open groups', function() {
// validate that the message has been added to the message list view // validate that the message has been added to the message list view
await app.client.waitForExist( await app.client.waitForExist(
ConversationPage.existingSendMessageText(textMessage), ConversationPage.existingSendMessageText(textMessage),
3000 3 * 1000
); );
// we should validate that the message has been added effectively sent // we should validate that the message has been added effectively sent
// (checking the check icon on the metadata part of the message?) // (checking the check icon on the metadata part of the message?)

@ -13,6 +13,7 @@ module.exports = {
`//input[contains(@placeholder, "${placeholder}")]`, `//input[contains(@placeholder, "${placeholder}")]`,
textAreaWithPlaceholder: placeholder => textAreaWithPlaceholder: placeholder =>
`//textarea[contains(@placeholder, "${placeholder}")]`, `//textarea[contains(@placeholder, "${placeholder}")]`,
byId: id => `//*[@id="${id}"]`,
divWithClass: classname => `//div[contains(@class, "${classname}")]`, divWithClass: classname => `//div[contains(@class, "${classname}")]`,
divWithClassAndText: (classname, text) => divWithClassAndText: (classname, text) =>
module.exports.objWithClassAndText('div', classname, text), module.exports.objWithClassAndText('div', classname, text),

@ -21,12 +21,12 @@ describe('Window Test and Login', function() {
await common.killallElectron(); await common.killallElectron();
}); });
it('opens one window', async () => { it('registration: opens one window', async () => {
app = await common.startAndAssureCleanedApp(); app = await common.startAndAssureCleanedApp();
app.client.getWindowCount().should.eventually.be.equal(1); app.client.getWindowCount().should.eventually.be.equal(1);
}); });
it('window title is correct', async () => { it('registration: window title is correct', async () => {
app = await common.startAndAssureCleanedApp(); app = await common.startAndAssureCleanedApp();
app.client app.client
@ -34,7 +34,7 @@ describe('Window Test and Login', function() {
.should.eventually.be.equal('Session - test-integration-session'); .should.eventually.be.equal('Session - test-integration-session');
}); });
it('can restore from seed', async () => { it('registration: can restore from seed', async () => {
app = await common.startAndAssureCleanedApp(); app = await common.startAndAssureCleanedApp();
await app.client.element(RegistrationPage.registrationTabSignIn).click(); await app.client.element(RegistrationPage.registrationTabSignIn).click();
@ -70,7 +70,7 @@ describe('Window Test and Login', function() {
.should.eventually.be.equal(common.TEST_PUBKEY1); .should.eventually.be.equal(common.TEST_PUBKEY1);
}); });
it('can create new account', async () => { it('registration: can create new account', async () => {
app = await common.startAndAssureCleanedApp(); app = await common.startAndAssureCleanedApp();
await app.client.element(RegistrationPage.createSessionIDButton).click(); await app.client.element(RegistrationPage.createSessionIDButton).click();
// wait for the animation of generated pubkey to finish // wait for the animation of generated pubkey to finish
@ -98,7 +98,7 @@ describe('Window Test and Login', function() {
.should.eventually.be.equal(pubkeyGenerated); .should.eventually.be.equal(pubkeyGenerated);
}); });
it('can delete account when logged in', async () => { it('registration: can delete account when logged in', async () => {
// login as user1 // login as user1
const login = { const login = {
mnemonic: common.TEST_MNEMONIC1, mnemonic: common.TEST_MNEMONIC1,

@ -35,7 +35,8 @@
"test-lib-view": "NODE_ENV=test-lib yarn run start", "test-lib-view": "NODE_ENV=test-lib yarn run start",
"test-loki-view": "NODE_ENV=test-loki yarn run start", "test-loki-view": "NODE_ENV=test-loki yarn run start",
"test-electron": "yarn grunt test", "test-electron": "yarn grunt test",
"test-integration": "ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 5000 integration_test/integration_test.js", "test-integration": "ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 10000 integration_test/integration_test.js",
"test-integration-parts": "ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 10000 integration_test/integration_test.js --grep 'registration' && ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 10000 integration_test/integration_test.js --grep 'openGroup' && ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 10000 integration_test/integration_test.js --grep 'addFriends' && ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 10000 integration_test/integration_test.js --grep 'linkDevice' && ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 10000 integration_test/integration_test.js --grep 'closedGroup'",
"test-node": "mocha --recursive --exit test/app test/modules ts/test libloki/test/node", "test-node": "mocha --recursive --exit test/app test/modules ts/test libloki/test/node",
"eslint": "eslint --cache .", "eslint": "eslint --cache .",
"eslint-fix": "eslint --fix .", "eslint-fix": "eslint --fix .",

Loading…
Cancel
Save