From 2f13afdd3fbd612604fa805313b5592a8e2533b3 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 26 Mar 2020 12:52:08 +1100 Subject: [PATCH 01/14] vince integration test setup --- integration_test/integration_test.js | 4 ++- integration_test/test_test.js | 45 ++++++++++++++++++++++++++++ package.json | 2 +- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 integration_test/test_test.js diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index 87eee0fcc..f465b5e65 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -12,11 +12,13 @@ require('./add_friends_test'); require('./link_device_test'); require('./closed_group_test'); +// require('./test_test'); + before(async () => { // start the app once before all tests to get the platform-dependent // path of user data and store it to common.USER_DATA_ROOT_FOLDER const app1 = await common.startApp(); - common.USER_DATA_ROOT_FOLDER = await app1.electron.remote.app.getPath( + common.USER_DATA_ROOT_FOLDER = app1.electron.remote.app.getPath( 'appData' ); await common.stopApp(app1); diff --git a/integration_test/test_test.js b/integration_test/test_test.js new file mode 100644 index 000000000..c024d7bd8 --- /dev/null +++ b/integration_test/test_test.js @@ -0,0 +1,45 @@ +/* eslint-disable func-names */ +/* eslint-disable import/no-extraneous-dependencies */ +const common = require('./common'); +const { afterEach, beforeEach, describe, it } = require('mocha'); + + +describe('Do Vince test', function() { + let app; + let app2; + this.timeout(60000); + this.slow(15000); + + beforeEach(async () => { + await common.killallElectron(); + await common.stopStubSnodeServer(); + + const app1Props = { + mnemonic: common.TEST_MNEMONIC1, + displayName: common.TEST_DISPLAY_NAME1, + stubSnode: true, + }; + + const app2Props = { + mnemonic: common.TEST_MNEMONIC2, + displayName: common.TEST_DISPLAY_NAME2, + stubSnode: true, + }; + + [app, app2] = await Promise.all([ + common.startAndStub(app1Props), + common.startAndStub2(app2Props), + ]); + }); + + afterEach(async () => { + await common.stopApp(app); + await common.killallElectron(); + await common.stopStubSnodeServer(); + }); + + it('Can do first check', async () => { + app = await common.startAndAssureCleanedApp(); + return app; + }); +}); \ No newline at end of file diff --git a/package.json b/package.json index e6bfcf6ca..439221662 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "test-lib-view": "NODE_ENV=test-lib yarn run start", "test-loki-view": "NODE_ENV=test-loki yarn run start", "test-electron": "yarn grunt test", - "test-integration-session": "ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 5000 integration_test/integration_test.js", + "test-integration-session": "ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 5000000 integration_test/integration_test.js", "test-node": "mocha --recursive --exit test/app test/modules ts/test libloki/test/node", "test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test libloki/test/node", "test-node-coverage-html": "nyc --reporter=lcov --reporter=html mocha --recursive test/a/* */pp test/modules ts/test libloki/test/node", From aac18cd683cf3c79827425700f3f3ccbe75ab8d2 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 26 Mar 2020 13:00:46 +1100 Subject: [PATCH 02/14] await reversion --- integration_test/integration_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index f465b5e65..1315d7a8f 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -18,7 +18,7 @@ before(async () => { // start the app once before all tests to get the platform-dependent // path of user data and store it to common.USER_DATA_ROOT_FOLDER const app1 = await common.startApp(); - common.USER_DATA_ROOT_FOLDER = app1.electron.remote.app.getPath( + common.USER_DATA_ROOT_FOLDER = await app1.electron.remote.app.getPath( 'appData' ); await common.stopApp(app1); From 553713c31147c32a776ea6319a1fb2a3bfc3c0d8 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 26 Mar 2020 13:03:46 +1100 Subject: [PATCH 03/14] revert --- integration_test/test_test.js | 74 +++++++++++++++++------------------ package.json | 2 +- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/integration_test/test_test.js b/integration_test/test_test.js index c024d7bd8..caa2b33b4 100644 --- a/integration_test/test_test.js +++ b/integration_test/test_test.js @@ -1,45 +1,45 @@ -/* eslint-disable func-names */ -/* eslint-disable import/no-extraneous-dependencies */ -const common = require('./common'); -const { afterEach, beforeEach, describe, it } = require('mocha'); +// /* eslint-disable func-names */ +// /* eslint-disable import/no-extraneous-dependencies */ +// const common = require('./common'); +// const { afterEach, beforeEach, describe, it } = require('mocha'); -describe('Do Vince test', function() { - let app; - let app2; - this.timeout(60000); - this.slow(15000); +// describe('Do Vince test', function() { +// let app; +// let app2; +// this.timeout(60000); +// this.slow(15000); - beforeEach(async () => { - await common.killallElectron(); - await common.stopStubSnodeServer(); +// beforeEach(async () => { +// await common.killallElectron(); +// await common.stopStubSnodeServer(); - const app1Props = { - mnemonic: common.TEST_MNEMONIC1, - displayName: common.TEST_DISPLAY_NAME1, - stubSnode: true, - }; +// const app1Props = { +// mnemonic: common.TEST_MNEMONIC1, +// displayName: common.TEST_DISPLAY_NAME1, +// stubSnode: true, +// }; - const app2Props = { - mnemonic: common.TEST_MNEMONIC2, - displayName: common.TEST_DISPLAY_NAME2, - stubSnode: true, - }; +// const app2Props = { +// mnemonic: common.TEST_MNEMONIC2, +// displayName: common.TEST_DISPLAY_NAME2, +// stubSnode: true, +// }; - [app, app2] = await Promise.all([ - common.startAndStub(app1Props), - common.startAndStub2(app2Props), - ]); - }); +// [app, app2] = await Promise.all([ +// common.startAndStub(app1Props), +// common.startAndStub2(app2Props), +// ]); +// }); - afterEach(async () => { - await common.stopApp(app); - await common.killallElectron(); - await common.stopStubSnodeServer(); - }); +// afterEach(async () => { +// await common.stopApp(app); +// await common.killallElectron(); +// await common.stopStubSnodeServer(); +// }); - it('Can do first check', async () => { - app = await common.startAndAssureCleanedApp(); - return app; - }); -}); \ No newline at end of file +// it('Can do first check', async () => { +// app = await common.startAndAssureCleanedApp(); +// return app; +// }); +// }); \ No newline at end of file diff --git a/package.json b/package.json index 439221662..e6bfcf6ca 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "test-lib-view": "NODE_ENV=test-lib yarn run start", "test-loki-view": "NODE_ENV=test-loki yarn run start", "test-electron": "yarn grunt test", - "test-integration-session": "ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 5000000 integration_test/integration_test.js", + "test-integration-session": "ELECTRON_DISABLE_SANDBOX=1 mocha --exit --timeout 5000 integration_test/integration_test.js", "test-node": "mocha --recursive --exit test/app test/modules ts/test libloki/test/node", "test-node-coverage": "nyc --reporter=lcov --reporter=text mocha --recursive test/app test/modules ts/test libloki/test/node", "test-node-coverage-html": "nyc --reporter=lcov --reporter=html mocha --recursive test/a/* */pp test/modules ts/test libloki/test/node", From 9d7d3bbe6ec1b5e29688eb789f19e3705779307e Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 27 Mar 2020 11:29:50 +1100 Subject: [PATCH 04/14] message functions init --- config/test-integration-session-2.json | 6 --- config/test-integration-session-3.json | 6 +++ integration_test/common.js | 28 ++++++----- integration_test/integration_test.js | 8 +-- integration_test/link_device_test.js | 2 +- integration_test/message_functions_test.js | 48 ++++++++++++++++++ integration_test/message_sync_test.js | 58 ++++++++++++++++++++++ integration_test/test_test.js | 45 ----------------- 8 files changed, 134 insertions(+), 67 deletions(-) delete mode 100644 config/test-integration-session-2.json create mode 100644 config/test-integration-session-3.json create mode 100644 integration_test/message_functions_test.js create mode 100644 integration_test/message_sync_test.js delete mode 100644 integration_test/test_test.js diff --git a/config/test-integration-session-2.json b/config/test-integration-session-2.json deleted file mode 100644 index e6a66e69d..000000000 --- a/config/test-integration-session-2.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "storageProfile": "testIntegration2Profile", - "openDevTools": false, - "updatesEnabled": false, - "localServerPort": "8082" -} diff --git a/config/test-integration-session-3.json b/config/test-integration-session-3.json new file mode 100644 index 000000000..9165effd6 --- /dev/null +++ b/config/test-integration-session-3.json @@ -0,0 +1,6 @@ +{ + "storageProfile": "testIntegration3Profile", + "openDevTools": false, + "updatesEnabled": false, + "localServerPort": "8489" +} diff --git a/integration_test/common.js b/integration_test/common.js index 5bcc7e40e..562afebe3 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -35,6 +35,13 @@ module.exports = { '054e1ca8681082dbd9aad1cf6fc89a32254e15cba50c75b5a73ac10a0b96bcbd2a', TEST_DISPLAY_NAME2: 'integration_tester_2', + TEST_MNEMONIC3: + 'alpine lukewarm oncoming blender kiwi fuel lobster upkeep vogue simplest gasp fully simplest', + TEST_PUBKEY3: + '05f8662b6e83da5a31007cc3ded44c601f191e07999acb6db2314a896048d9036c', + TEST_DISPLAY_NAME3: 'integration_tester_3', + + /* ************** OPEN GROUPS ****************** */ VALID_GROUP_URL: 'https://chat.getsession.org', VALID_GROUP_URL2: 'https://chat-dev.lokinet.org', @@ -98,14 +105,10 @@ module.exports = { const killStr = process.platform === 'win32' ? 'taskkill /im electron.exe /t /f' - : 'killall -9 electron'; + : 'pkill -f "node_modules/.bin/electron"'; return new Promise(resolve => { - exec(killStr, (err, stdout, stderr) => { - if (err) { - resolve({ stdout, stderr }); - } else { - resolve({ stdout, stderr }); - } + exec(killStr, (_err, stdout, stderr) => { + resolve({ stdout, stderr }); }); }); }, @@ -166,13 +169,14 @@ module.exports = { return app1; }, - async startAndStub2(props) { - const app2 = await this.startAndStub({ - env: 'test-integration-session-2', + async startAndStubN(props, n) { + // Make app with stub as number n + const appN = await this.startAndStub({ + env: `test-integration-session-${n}`, ...props, }); - return app2; + return appN; }, async restoreFromMnemonic(app1, mnemonic, displayName) { @@ -207,7 +211,7 @@ module.exports = { const [app1, app2] = await Promise.all([ this.startAndStub(app1Props), - this.startAndStub2(app2Props), + this.startAndStubN(app2Props, 2), ]); /** add each other as friends */ diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index 1315d7a8f..6e557ecd3 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -9,10 +9,12 @@ const common = require('./common'); require('./registration_test'); require('./open_group_test'); require('./add_friends_test'); -require('./link_device_test'); -require('./closed_group_test'); +// require('./link_device_test'); +// require('./closed_group_test'); + + +require('./message_sync_test'); -// require('./test_test'); before(async () => { // start the app once before all tests to get the platform-dependent diff --git a/integration_test/link_device_test.js b/integration_test/link_device_test.js index 14e60af03..d0fd66a36 100644 --- a/integration_test/link_device_test.js +++ b/integration_test/link_device_test.js @@ -27,7 +27,7 @@ describe('Link Device', function() { [app, app2] = await Promise.all([ common.startAndStub(app1Props), - common.startAndStub2(app2Props), + common.startAndStubN(app2Props, 2), ]); }); diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js new file mode 100644 index 000000000..d0fd66a36 --- /dev/null +++ b/integration_test/message_functions_test.js @@ -0,0 +1,48 @@ +/* eslint-disable prefer-destructuring */ +/* eslint-disable more/no-then */ +/* eslint-disable func-names */ +/* eslint-disable import/no-extraneous-dependencies */ +const common = require('./common'); +const { afterEach, beforeEach, describe, it } = require('mocha'); + +describe('Link Device', function() { + let app; + let app2; + this.timeout(60000); + this.slow(15000); + + beforeEach(async () => { + await common.killallElectron(); + await common.stopStubSnodeServer(); + + const app1Props = { + mnemonic: common.TEST_MNEMONIC1, + displayName: common.TEST_DISPLAY_NAME1, + stubSnode: true, + }; + + const app2Props = { + stubSnode: true, + }; + + [app, app2] = await Promise.all([ + common.startAndStub(app1Props), + common.startAndStubN(app2Props, 2), + ]); + }); + + afterEach(async () => { + await common.killallElectron(); + await common.stopStubSnodeServer(); + }); + + it('link two desktop devices', async () => { + await common.linkApp2ToApp(app, app2); + }); + + it('unlink two devices', async () => { + await common.linkApp2ToApp(app, app2); + await common.timeout(1000); + await common.triggerUnlinkApp2FromApp(app, app2); + }); +}); diff --git a/integration_test/message_sync_test.js b/integration_test/message_sync_test.js new file mode 100644 index 000000000..3d1b340ce --- /dev/null +++ b/integration_test/message_sync_test.js @@ -0,0 +1,58 @@ +/* eslint-disable func-names */ +/* eslint-disable import/no-extraneous-dependencies */ +const common = require('./common'); +const { afterEach, beforeEach, describe, it } = require('mocha'); + + +describe('Message Syncing', function() { + let app; + let app2; + let app3; + this.timeout(60000); + this.slow(15000); + + beforeEach(async () => { + // await common.killallElectron(); + await common.stopStubSnodeServer(); + + const app1Props = { + mnemonic: common.TEST_MNEMONIC1, + displayName: common.TEST_DISPLAY_NAME1, + stubSnode: true, + }; + + const app2Props = { + mnemonic: common.TEST_MNEMONIC2, + displayName: common.TEST_DISPLAY_NAME2, + stubSnode: true, + }; + + const app3Props = { + mnemonic: common.TEST_MNEMONIC3, + displayName: common.TEST_DISPLAY_NAME3, + stubSnode: true, + }; + + [app, app2, app3] = await Promise.all([ + common.startAndStub(app1Props), + common.startAndStubN(app2Props, 2), + common.startAndStubN(app3Props, 3), + ]); + }); + + afterEach(async () => { + await common.killallElectron(); + await common.stopStubSnodeServer(); + }); + + it('message syncing between linked devices', async () => { + await common.linkApp2ToApp(app, app2); + }); + + it('unlink two devices', async () => { + await common.linkApp2ToApp(app, app2); + await common.timeout(1000); + await common.triggerUnlinkApp2FromApp(app, app2); + }); + +}); \ No newline at end of file diff --git a/integration_test/test_test.js b/integration_test/test_test.js deleted file mode 100644 index caa2b33b4..000000000 --- a/integration_test/test_test.js +++ /dev/null @@ -1,45 +0,0 @@ -// /* eslint-disable func-names */ -// /* eslint-disable import/no-extraneous-dependencies */ -// const common = require('./common'); -// const { afterEach, beforeEach, describe, it } = require('mocha'); - - -// describe('Do Vince test', function() { -// let app; -// let app2; -// this.timeout(60000); -// this.slow(15000); - -// beforeEach(async () => { -// await common.killallElectron(); -// await common.stopStubSnodeServer(); - -// const app1Props = { -// mnemonic: common.TEST_MNEMONIC1, -// displayName: common.TEST_DISPLAY_NAME1, -// stubSnode: true, -// }; - -// const app2Props = { -// mnemonic: common.TEST_MNEMONIC2, -// displayName: common.TEST_DISPLAY_NAME2, -// stubSnode: true, -// }; - -// [app, app2] = await Promise.all([ -// common.startAndStub(app1Props), -// common.startAndStub2(app2Props), -// ]); -// }); - -// afterEach(async () => { -// await common.stopApp(app); -// await common.killallElectron(); -// await common.stopStubSnodeServer(); -// }); - -// it('Can do first check', async () => { -// app = await common.startAndAssureCleanedApp(); -// return app; -// }); -// }); \ No newline at end of file From d3c934e119022f79e0b1108df5ce941646e11991 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 31 Mar 2020 13:35:48 +1100 Subject: [PATCH 05/14] attachment sending test complete --- integration_test/closed_group_test.js | 75 +------------- integration_test/common.js | 96 ++++++++++++++++++ integration_test/integration_test.js | 9 +- integration_test/message_functions_test.js | 76 +++++++++----- .../page-objects/conversation.page.js | 9 +- integration_test/test_attachment | Bin 0 -> 1024 bytes stylesheets/_global.scss | 7 +- 7 files changed, 162 insertions(+), 110 deletions(-) create mode 100644 integration_test/test_attachment diff --git a/integration_test/closed_group_test.js b/integration_test/closed_group_test.js index 414e81bfb..1f49e1d14 100644 --- a/integration_test/closed_group_test.js +++ b/integration_test/closed_group_test.js @@ -27,79 +27,8 @@ describe('Closed groups', function() { await app.client.element(ConversationPage.globeButtonSection).click(); await app.client.element(ConversationPage.createClosedGroupButton).click(); - // fill the groupname - await app.client - .element(ConversationPage.closedGroupNameTextarea) - .setValue(common.VALID_CLOSED_GROUP_NAME1); - await app.client - .element(ConversationPage.closedGroupNameTextarea) - .getValue() - .should.eventually.equal(common.VALID_CLOSED_GROUP_NAME1); - - await app.client - .element(ConversationPage.createClosedGroupMemberItem) - .isVisible(); - - // select the first friend as a member of the groups being created - await app.client - .element(ConversationPage.createClosedGroupMemberItem) - .click(); - await app.client - .element(ConversationPage.createClosedGroupMemberItemSelected) - .isVisible(); - - // trigger the creation of the group - await app.client - .element(ConversationPage.validateCreationClosedGroupButton) - .click(); - - await app.client.waitForExist( - ConversationPage.sessionToastGroupCreatedSuccess, - 1000 - ); - await app.client.isExisting( - ConversationPage.headerTitleGroupName(common.VALID_CLOSED_GROUP_NAME1) - ); - await app.client - .element(ConversationPage.headerTitleMembers(2)) - .isVisible(); - - // validate overlay is closed - await app.client - .isExisting(ConversationPage.leftPaneOverlay) - .should.eventually.be.equal(false); - - // move back to the conversation section - await app.client - .element(ConversationPage.conversationButtonSection) - .click(); - - // validate open chat has been added - await app.client.isExisting( - ConversationPage.rowOpenGroupConversationName( - common.VALID_CLOSED_GROUP_NAME1 - ) - ); - - // next check app2 has been invited and has the group in its conversations - await app2.client.waitForExist( - ConversationPage.rowOpenGroupConversationName( - common.VALID_CLOSED_GROUP_NAME1 - ), - 6000 - ); - // open the closed group conversation on app2 - await app2.client - .element(ConversationPage.conversationButtonSection) - .click(); - await common.timeout(500); - await app2.client - .element( - ConversationPage.rowOpenGroupConversationName( - common.VALID_CLOSED_GROUP_NAME1 - ) - ) - .click(); + // create group and add new friend + await common.addFriendToNewClosedGroup(app, app2); // send a message from app and validate it is received on app2 const textMessage = common.generateSendMessageText(); diff --git a/integration_test/common.js b/integration_test/common.js index 182c9f7fa..81fc49b59 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -269,6 +269,81 @@ module.exports = { return [app1, app2]; }, + async addFriendToNewClosedGroup(app, app2) { + await app.client + .element(ConversationPage.closedGroupNameTextarea) + .setValue(this.VALID_CLOSED_GROUP_NAME1); + await app.client + .element(ConversationPage.closedGroupNameTextarea) + .getValue() + .should.eventually.equal(this.VALID_CLOSED_GROUP_NAME1); + + await app.client + .element(ConversationPage.createClosedGroupMemberItem) + .isVisible(); + + // select the first friend as a member of the groups being created + await app.client + .element(ConversationPage.createClosedGroupMemberItem) + .click(); + await app.client + .element(ConversationPage.createClosedGroupMemberItemSelected) + .isVisible(); + + // trigger the creation of the group + await app.client + .element(ConversationPage.validateCreationClosedGroupButton) + .click(); + + await app.client.waitForExist( + ConversationPage.sessionToastGroupCreatedSuccess, + 1000 + ); + await app.client.isExisting( + ConversationPage.headerTitleGroupName(this.VALID_CLOSED_GROUP_NAME1) + ); + await app.client + .element(ConversationPage.headerTitleMembers(2)) + .isVisible(); + + // validate overlay is closed + await app.client + .isExisting(ConversationPage.leftPaneOverlay) + .should.eventually.be.equal(false); + + // move back to the conversation section + await app.client + .element(ConversationPage.conversationButtonSection) + .click(); + + // validate open chat has been added + await app.client.isExisting( + ConversationPage.rowOpenGroupConversationName( + this.VALID_CLOSED_GROUP_NAME1 + ) + ); + + // next check app2 has been invited and has the group in its conversations + await app2.client.waitForExist( + ConversationPage.rowOpenGroupConversationName( + this.VALID_CLOSED_GROUP_NAME1 + ), + 6000 + ); + // open the closed group conversation on app2 + await app2.client + .element(ConversationPage.conversationButtonSection) + .click(); + await this.timeout(500); + await app2.client + .element( + ConversationPage.rowOpenGroupConversationName( + this.VALID_CLOSED_GROUP_NAME1 + ) + ) + .click(); + }, + async linkApp2ToApp(app1, app2) { // app needs to be logged in as user1 and app2 needs to be logged out // start the pairing dialog for the first app @@ -367,6 +442,27 @@ module.exports = { } }, + async sendMessage(app, messageText, fileLocation = undefined){ + await app.client + .element(ConversationPage.sendMessageTextarea) + .setValue(messageText); + await app.client + .element(ConversationPage.sendMessageTextarea) + .getValue() + .should.eventually.equal(messageText); + + // attach a file + if (fileLocation) { + await app.client + .element(ConversationPage.attachmentInput) + .setValue(fileLocation); + } + + // send message + await app.client.element(ConversationPage.sendMessageTextarea).click(); + await app.client.keys('Enter'); + }, + generateSendMessageText: () => `Test message from integration tests ${Date.now()}`, diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index 6e557ecd3..0b178aea7 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -6,14 +6,13 @@ const { before } = require('mocha'); const common = require('./common'); -require('./registration_test'); -require('./open_group_test'); -require('./add_friends_test'); +// require('./registration_test'); +// require('./open_group_test'); +// require('./add_friends_test'); // require('./link_device_test'); // require('./closed_group_test'); - -require('./message_sync_test'); +require('./message_functions_test'); before(async () => { diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js index d0fd66a36..5601ddee9 100644 --- a/integration_test/message_functions_test.js +++ b/integration_test/message_functions_test.js @@ -3,46 +3,70 @@ /* eslint-disable func-names */ /* eslint-disable import/no-extraneous-dependencies */ const common = require('./common'); -const { afterEach, beforeEach, describe, it } = require('mocha'); +const path = require('path'); -describe('Link Device', function() { +const { after, before, describe, it } = require('mocha'); +const ConversationPage = require('./page-objects/conversation.page'); + +describe('Message Functions', function() { let app; let app2; this.timeout(60000); this.slow(15000); - beforeEach(async () => { + before(async () => { await common.killallElectron(); await common.stopStubSnodeServer(); - const app1Props = { - mnemonic: common.TEST_MNEMONIC1, - displayName: common.TEST_DISPLAY_NAME1, - stubSnode: true, - }; - - const app2Props = { - stubSnode: true, - }; - - [app, app2] = await Promise.all([ - common.startAndStub(app1Props), - common.startAndStubN(app2Props, 2), - ]); + [app, app2] = await common.startAppsAsFriends(); }); - afterEach(async () => { - await common.killallElectron(); - await common.stopStubSnodeServer(); + after(async () => { + // await common.stopApp(app); + // await common.killallElectron(); + // await common.stopStubSnodeServer(); }); - it('link two desktop devices', async () => { - await common.linkApp2ToApp(app, app2); + it('can send attachment', async () => { + await app.client.element(ConversationPage.globeButtonSection).click(); + await app.client.element(ConversationPage.createClosedGroupButton).click(); + + // create group and add new friend + await common.addFriendToNewClosedGroup(app, app2); + + // send attachment from app1 to closed group + const fileLocation = path.join(__dirname, '/test_attachment'); + const messageText = 'test_attachment'; + + common.sendMessage(app, messageText, fileLocation); + + // validate attachment sent + await app.client.waitForExist( + ConversationPage.existingSendMessageText(messageText), + 3000 + ); + // validate attachment recieved + await app2.client.waitForExist( + ConversationPage.existingReceivedMessageText(messageText), + 5000 + ); }); + + it('can delete message', async () => { + const messageText = 'delete me'; + common.sendMessage(app, messageText); + + await app.client.waitForExist( + ConversationPage.existingSendMessageText(messageText), + 3000 + ); + await app2.client.waitForExist( + ConversationPage.existingReceivedMessageText(messageText), + 5000 + ); + + - it('unlink two devices', async () => { - await common.linkApp2ToApp(app, app2); - await common.timeout(1000); - await common.triggerUnlinkApp2FromApp(app, app2); }); + }); diff --git a/integration_test/page-objects/conversation.page.js b/integration_test/page-objects/conversation.page.js index df879c66c..40cdd932b 100644 --- a/integration_test/page-objects/conversation.page.js +++ b/integration_test/page-objects/conversation.page.js @@ -9,11 +9,11 @@ module.exports = { 'Send your first message' ), existingSendMessageText: textMessage => - `//*[contains(@class, "module-message__text--outgoing")and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, + `//*[contains(@class, "module-message__text--outgoing") and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, existingFriendRequestText: textMessage => `//*[contains(@class, "module-message-friend-request__container")and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, existingReceivedMessageText: textMessage => - `//*[contains(@class, "module-message__text--incoming")and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, + `//*[contains(@class, "module-message__text--incoming") and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, // conversations conversationButtonSection: @@ -28,6 +28,9 @@ module.exports = { `${number} members` ), + attachmentInput: '//*[contains(@class, "choose-file")]/input[@type="file"]', + attachmentButton: '//*[contains(@class, "choose-file")]/button', + // channels globeButtonSection: '//*[contains(@class,"session-icon-button") and .//*[contains(@class, "globe")]]', @@ -77,7 +80,7 @@ module.exports = { oneNotificationFriendRequestLeft: '//*[contains(@class,"session-icon-button") and .//*[contains(@class, "users")] and .//*[contains(@class, "notification-count") and contains(string(), "1")] ]', oneNotificationFriendRequestTop: - '//*[contains(@class,"contact-notification-count-bubble") and contains(string(), "1")]', + '//*[contains(@class,"module-left-pane__header")] //*[contains(@class, "notification-count") and contains(string(), "1")]', friendRequestFromUser: (displayName, pubkey) => `//*[contains(@class,"module-left-pane__list-popup") and .//*[contains(@class, "module-conversation__user") and .//*[contains(string(), "${displayName}")] and .//*[contains(string(), "(...${pubkey.substring( 60 diff --git a/integration_test/test_attachment b/integration_test/test_attachment new file mode 100644 index 0000000000000000000000000000000000000000..06d7405020018ddf3cacee90fd4af10487da3d20 GIT binary patch literal 1024 ScmZQz7zLvtFd70QH3R?z00031 literal 0 HcmV?d00001 diff --git a/stylesheets/_global.scss b/stylesheets/_global.scss index 8c8a04c8a..8c9b9e818 100644 --- a/stylesheets/_global.scss +++ b/stylesheets/_global.scss @@ -140,15 +140,16 @@ a { } input[type='file'] { - display: none; + // Must be displayed in order to programmatically + // insert file paths) position: absolute; width: 100%; height: 100%; - opacity: 0; top: 0; left: 0; cursor: pointer; - z-index: 1; + z-index: -100; + } } From 0c935b66f21d3cc983dc6e212338917b95901df9 Mon Sep 17 00:00:00 2001 From: Vincent Date: Fri, 3 Apr 2020 16:12:04 +1100 Subject: [PATCH 06/14] deleting messages init --- integration_test/add_friends_test.js | 3 ++- integration_test/closed_group_test.js | 3 ++- integration_test/common.js | 9 +++++---- integration_test/integration_test.js | 2 +- integration_test/link_device_test.js | 2 +- integration_test/message_functions_test.js | 18 +++++++++++++++--- integration_test/message_sync_test.js | 3 ++- integration_test/open_group_test.js | 3 ++- .../page-objects/conversation.page.js | 6 +++++- integration_test/registration_test.js | 3 ++- yarn.lock | 11 +++-------- 11 files changed, 40 insertions(+), 23 deletions(-) diff --git a/integration_test/add_friends_test.js b/integration_test/add_friends_test.js index a86dbf1ec..6b1d73670 100644 --- a/integration_test/add_friends_test.js +++ b/integration_test/add_friends_test.js @@ -1,7 +1,8 @@ /* eslint-disable func-names */ /* eslint-disable import/no-extraneous-dependencies */ -const common = require('./common'); const { afterEach, beforeEach, describe, it } = require('mocha'); + +const common = require('./common'); const ConversationPage = require('./page-objects/conversation.page'); describe('Add friends', function() { diff --git a/integration_test/closed_group_test.js b/integration_test/closed_group_test.js index 1f49e1d14..fec80c64a 100644 --- a/integration_test/closed_group_test.js +++ b/integration_test/closed_group_test.js @@ -1,7 +1,8 @@ /* eslint-disable func-names */ /* eslint-disable import/no-extraneous-dependencies */ -const common = require('./common'); const { afterEach, beforeEach, describe, it } = require('mocha'); +const common = require('./common'); + const ConversationPage = require('./page-objects/conversation.page'); describe('Closed groups', function() { diff --git a/integration_test/common.js b/integration_test/common.js index a81f4072c..5bf1c579e 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -4,15 +4,16 @@ const { Application } = require('spectron'); const path = require('path'); +const url = require('url'); +const http = require('http'); +const fse = require('fs-extra'); +const { exec } = require('child_process'); const chai = require('chai'); const chaiAsPromised = require('chai-as-promised'); const RegistrationPage = require('./page-objects/registration.page'); const ConversationPage = require('./page-objects/conversation.page'); -const { exec } = require('child_process'); -const url = require('url'); -const http = require('http'); -const fse = require('fs-extra'); + chai.should(); chai.use(chaiAsPromised); diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index 0b178aea7..911ed4985 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -6,12 +6,12 @@ const { before } = require('mocha'); const common = require('./common'); + // require('./registration_test'); // require('./open_group_test'); // require('./add_friends_test'); // require('./link_device_test'); // require('./closed_group_test'); - require('./message_functions_test'); diff --git a/integration_test/link_device_test.js b/integration_test/link_device_test.js index d0fd66a36..9cc8ca74a 100644 --- a/integration_test/link_device_test.js +++ b/integration_test/link_device_test.js @@ -2,8 +2,8 @@ /* eslint-disable more/no-then */ /* eslint-disable func-names */ /* eslint-disable import/no-extraneous-dependencies */ -const common = require('./common'); const { afterEach, beforeEach, describe, it } = require('mocha'); +const common = require('./common'); describe('Link Device', function() { let app; diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js index 81e7906d8..d92ad9bbc 100644 --- a/integration_test/message_functions_test.js +++ b/integration_test/message_functions_test.js @@ -53,18 +53,30 @@ describe('Message Functions', function() { }); it('can delete message', async () => { - const messageText = 'delete me'; + const messageText = 'delete_me'; common.sendMessage(app, messageText); await app.client.waitForExist( ConversationPage.existingSendMessageText(messageText), - 3000 + 5000 ); await app2.client.waitForExist( ConversationPage.existingReceivedMessageText(messageText), - 5000 + 7000 ); + + // delete message in context menu + await app.client.element(ConversationPage.messageCtxMenu(messageText)).click(); + await app.client.element(ConversationPage.deleteMessageCtxButton).click(); + // delete messaage from modal + await app.client.waitForExist( + ConversationPage.deleteMessageModalButton, + 3000 + ); + await app.client.element(ConversationPage.deleteMessageModalButton).click(); + + // verify the message is actually deleted }); diff --git a/integration_test/message_sync_test.js b/integration_test/message_sync_test.js index 3d1b340ce..44676a280 100644 --- a/integration_test/message_sync_test.js +++ b/integration_test/message_sync_test.js @@ -1,8 +1,9 @@ /* eslint-disable func-names */ /* eslint-disable import/no-extraneous-dependencies */ -const common = require('./common'); const { afterEach, beforeEach, describe, it } = require('mocha'); +const common = require('./common'); + describe('Message Syncing', function() { let app; diff --git a/integration_test/open_group_test.js b/integration_test/open_group_test.js index 486a5256b..9f3d21fd9 100644 --- a/integration_test/open_group_test.js +++ b/integration_test/open_group_test.js @@ -1,7 +1,8 @@ /* eslint-disable func-names */ /* eslint-disable import/no-extraneous-dependencies */ -const common = require('./common'); const { afterEach, beforeEach, describe, it } = require('mocha'); + +const common = require('./common'); const ConversationPage = require('./page-objects/conversation.page'); describe('Open groups', function() { diff --git a/integration_test/page-objects/conversation.page.js b/integration_test/page-objects/conversation.page.js index 51b44b4ef..c8b358634 100644 --- a/integration_test/page-objects/conversation.page.js +++ b/integration_test/page-objects/conversation.page.js @@ -11,7 +11,7 @@ module.exports = { existingSendMessageText: textMessage => `//*[contains(@class, "module-message__text--outgoing") and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, existingFriendRequestText: textMessage => - `//*[contains(@class, "module-message-friend-request__container")and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, + `//*[contains(@class, "module-message-friend-request__container") and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, existingReceivedMessageText: textMessage => `//*[contains(@class, "module-message__text--incoming") and .//span[contains(@class, "text-selectable")][contains(string(), '${textMessage}')]]`, @@ -31,6 +31,10 @@ module.exports = { attachmentInput: '//*[contains(@class, "choose-file")]/input[@type="file"]', attachmentButton: '//*[contains(@class, "choose-file")]/button', + messageCtxMenu: message => `//div[contains(@class, "message-wrapper") and .//span[contains(@class, "text-selectable")][contains(string(), ${message})]]//div[contains(@class, 'module-message__buttons__menu')]`, + deleteMessageCtxButton: '//*[contains(@class, "react-contextmenu--visible")]/div[contains(string(), "Delete Message")]', + deleteMessageModalButton: '//*[contains(@class, "session-modal")]//div[contains(string(), "Delete") and contains(@class, "session-button")]', + // channels globeButtonSection: '//*[contains(@class,"session-icon-button") and .//*[contains(@class, "globe")]]', diff --git a/integration_test/registration_test.js b/integration_test/registration_test.js index 3e0a57aa7..595ead8e8 100644 --- a/integration_test/registration_test.js +++ b/integration_test/registration_test.js @@ -2,8 +2,9 @@ /* eslint-disable func-names */ /* eslint-disable import/no-extraneous-dependencies */ -const common = require('./common'); const { afterEach, beforeEach, describe, it } = require('mocha'); + +const common = require('./common'); const RegistrationPage = require('./page-objects/registration.page'); const ConversationPage = require('./page-objects/conversation.page'); diff --git a/yarn.lock b/yarn.lock index 6a4f27191..7a4aa95c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6077,11 +6077,6 @@ lodash-es@^4.2.1: resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== -lodash-es@^4.2.1: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78" - integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ== - lodash.assign@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" @@ -8763,8 +8758,8 @@ redent@^1.0.0: resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" + indent-string "^2.1.0" + strip-indent "^1.0.1" reduce-css-calc@^1.2.6: version "1.3.0" @@ -11230,7 +11225,7 @@ write-file-atomic@^1.1.4: dependencies: graceful-fs "^4.1.11" imurmurhash "^0.1.4" - signal-exit "^3.0.2" + slide "^1.1.5" write-file-atomic@^3.0.0: version "3.0.3" From f7f4cc521819e2c3cbb8566ab8f0f743e9f586c0 Mon Sep 17 00:00:00 2001 From: Vincent Date: Sun, 12 Apr 2020 19:11:42 +1000 Subject: [PATCH 07/14] reverted_ looking for settings_text --- integration_test/integration_test.js | 3 ++- integration_test/page-objects/settings.page.js | 11 +++++++++++ ts/components/session/SessionPasswordModal.tsx | 9 +++++---- 3 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 integration_test/page-objects/settings.page.js diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index 911ed4985..f4a7233a5 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -12,7 +12,8 @@ const common = require('./common'); // require('./add_friends_test'); // require('./link_device_test'); // require('./closed_group_test'); -require('./message_functions_test'); +// require('./message_functions_test'); +require('./settings_test'); before(async () => { diff --git a/integration_test/page-objects/settings.page.js b/integration_test/page-objects/settings.page.js new file mode 100644 index 000000000..0acc0a485 --- /dev/null +++ b/integration_test/page-objects/settings.page.js @@ -0,0 +1,11 @@ +module.exports = { + // settings view + leftPaneSettingsButton: `//*[contains(@class,"session-icon-button") and .//*[contains(@class, "gear")]]`, + + settingToggleWithText: text => `//div[contains(@class, 'session-settings-item') and contains(string(), '${text}')]//*[contains(@class, 'session-toggle')]`, + settingButtonWithText: text => `//div[contains(@class, 'session-settings-item')]//*[contains(@class, 'session-button') and contains(string(), '${text}')]`, + settingCategoryWithText: text => `//div[contains(@class, 'left-pane-setting-category-list-item') and contains(string(), '${text}')]`, + + // Confirm is a boolean. Selects confirmation input + passwordSetModalInput: _confirm => `//input[@id = 'password-modal-input${_confirm ? '-confirm' : ''}']`, +}; diff --git a/ts/components/session/SessionPasswordModal.tsx b/ts/components/session/SessionPasswordModal.tsx index 4d7091057..30d3b1175 100644 --- a/ts/components/session/SessionPasswordModal.tsx +++ b/ts/components/session/SessionPasswordModal.tsx @@ -139,14 +139,15 @@ export class SessionPasswordModal extends React.Component { ); } - private async setPassword(onSuccess: any) { - if (!this.passwordInput.current || !this.passwordInputConfirm.current) { + private async setPassword(onSuccess?: any) { + // Only initial input required for PasswordAction.Remove + if (!this.passwordInput.current || (!this.passwordInputConfirm.current && this.props.action !== PasswordAction.Remove)) { return; } // Trim leading / trailing whitespace for UX const enteredPassword = String(this.passwordInput.current.value).trim(); - const enteredPasswordConfirm = String( + const enteredPasswordConfirm = this.passwordInputConfirm.current && String( this.passwordInputConfirm.current.value ).trim(); @@ -178,7 +179,7 @@ export class SessionPasswordModal extends React.Component { // Check if password match, when setting, changing or removing const valid = this.props.action !== PasswordAction.Set - ? !!await this.validatePasswordHash(oldPassword) + ? Boolean(await this.validatePasswordHash(oldPassword)) : enteredPassword === enteredPasswordConfirm; if (!valid) { From c1dcac1b84ffaa5bbe2f0f4d171d16affa389b8e Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 15 Apr 2020 04:26:50 +1000 Subject: [PATCH 08/14] Message & settings tests --- integration_test/common.js | 12 +- integration_test/integration_test.js | 1 + integration_test/message_functions_test.js | 11 +- integration_test/page-objects/common.page.js | 3 + .../page-objects/conversation.page.js | 12 +- .../page-objects/settings.page.js | 6 + integration_test/settings_test.js | 112 ++++++++++++++++++ .../session/SessionPasswordModal.tsx | 9 +- 8 files changed, 145 insertions(+), 21 deletions(-) create mode 100644 integration_test/settings_test.js diff --git a/integration_test/common.js b/integration_test/common.js index ddf4c1788..e3cd9f9e5 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -11,8 +11,10 @@ const { exec } = require('child_process'); const chai = require('chai'); const chaiAsPromised = require('chai-as-promised'); +const CommonPage = require('./page-objects/common.page'); const RegistrationPage = require('./page-objects/registration.page'); const ConversationPage = require('./page-objects/conversation.page'); +const SettingsPage = require('./page-objects/settings.page'); chai.should(); @@ -58,6 +60,10 @@ module.exports = { return new Promise(resolve => setTimeout(resolve, ms)); }, + async closeToast(app) { + app.client.element(CommonPage.toastCloseButton).click(); + }, + // a wrapper to work around electron/spectron bug async setValueWrapper(app, selector, value) { await app.client.element(selector).click(); @@ -399,8 +405,8 @@ module.exports = { async linkApp2ToApp(app1, app2) { // app needs to be logged in as user1 and app2 needs to be logged out // start the pairing dialog for the first app - await app1.client.element(ConversationPage.settingsButtonSection).click(); - await app1.client.element(ConversationPage.deviceSettingsRow).click(); + await app1.client.element(SettingsPage.settingsButtonSection).click(); + await app1.client.element(SettingsPage.settingsRowWithText('Devices')).click(); await app1.client.isVisible(ConversationPage.noPairedDeviceMessage); // we should not find the linkDeviceButtonDisabled button (as DISABLED) @@ -464,7 +470,7 @@ module.exports = { .should.eventually.be.true; await app1.client.element(ConversationPage.settingsButtonSection).click(); - await app1.client.element(ConversationPage.deviceSettingsRow).click(); + await app1.client.element(ConversationPage.settingsRowWithText('Devices')).click(); await app1.client.isExisting(ConversationPage.linkDeviceButtonDisabled) .should.eventually.be.true; // click the unlink button diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index f4a7233a5..efe2d9080 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -12,6 +12,7 @@ const common = require('./common'); // require('./add_friends_test'); // require('./link_device_test'); // require('./closed_group_test'); + // require('./message_functions_test'); require('./settings_test'); diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js index d92ad9bbc..8cd9bdcae 100644 --- a/integration_test/message_functions_test.js +++ b/integration_test/message_functions_test.js @@ -22,9 +22,9 @@ describe('Message Functions', function() { }); after(async () => { - // await common.stopApp(app); - // await common.killallElectron(); - // await common.stopStubSnodeServer(); + await common.stopApp(app); + await common.killallElectron(); + await common.stopStubSnodeServer(); }); it('can send attachment', async () => { @@ -77,8 +77,9 @@ describe('Message Functions', function() { await app.client.element(ConversationPage.deleteMessageModalButton).click(); // verify the message is actually deleted - - + await app.client.isExisting( + ConversationPage.existingSendMessageText(messageText) + ).should.eventually.be.false; }); }); diff --git a/integration_test/page-objects/common.page.js b/integration_test/page-objects/common.page.js index e5374f6d6..3e4bcd508 100644 --- a/integration_test/page-objects/common.page.js +++ b/integration_test/page-objects/common.page.js @@ -11,6 +11,7 @@ module.exports = { `${module.exports.divRoleButtonWithText(text)}[contains(@class, "danger")]`, inputWithPlaceholder: placeholder => `//input[contains(@placeholder, "${placeholder}")]`, + inputWithId: id => `//input[contains(@id, '${id}')]`, textAreaWithPlaceholder: placeholder => `//textarea[contains(@placeholder, "${placeholder}")]`, byId: id => `//*[@id="${id}"]`, @@ -21,4 +22,6 @@ module.exports = { module.exports.objWithClassAndText('span', classname, text), toastWithText: text => module.exports.divWithClassAndText('session-toast-wrapper', text), + toastCloseButton: '//div[contains(@class, "session-toast-wrapper")]//div[contains(@class, "toast-close")]/div', }; + diff --git a/integration_test/page-objects/conversation.page.js b/integration_test/page-objects/conversation.page.js index 1720274bb..aa7441bb9 100644 --- a/integration_test/page-objects/conversation.page.js +++ b/integration_test/page-objects/conversation.page.js @@ -31,10 +31,9 @@ module.exports = { attachmentInput: '//*[contains(@class, "choose-file")]/input[@type="file"]', attachmentButton: '//*[contains(@class, "choose-file")]/button', - messageCtxMenu: message => `//div[contains(@class, "message-wrapper")]//span[contains(@class, "text-selectable")][contains(string(), '${message}')]/ancestor::div//div[contains(@class, 'module-message__buttons__menu')]`, - //div[contains(@class, "message-wrapper")]//span[contains(@class, "text-selectable")][contains(string(), 'delete_me')]/ancestor::div//div[contains(@class, 'module-message__buttons__menu')] + messageCtxMenu: message => `//div[contains(@class, 'message-wrapper')]//span[contains(string(), '${message}')]/parent::div/parent::div/parent::div/parent::div//div[contains(@class, 'module-message__buttons__menu')]`, - deleteMessageCtxButton: '//*[contains(@class, "react-contextmenu--visible")]/div[contains(string(), "Delete Message")]', + deleteMessageCtxButton: '//*[contains(@class, "react-contextmenu--visible")]/div[contains(string(), "Delete")]', deleteMessageModalButton: '//*[contains(@class, "session-modal")]//div[contains(string(), "Delete") and contains(@class, "session-button")]', // channels @@ -96,12 +95,7 @@ module.exports = { acceptedFriendRequestMessage: '//*[contains(@class, "module-friend-request__title")][contains(string(), "Friend request accepted")]', - // settings - settingsButtonSection: - '//*[contains(@class,"session-icon-button") and .//*[contains(@class, "gear")]]', - deviceSettingsRow: - '//*[contains(@class, "left-pane-setting-category-list-item")][contains(string(), "Devices")]', - + descriptionDeleteAccount: commonPage.spanWithClassAndText( 'session-confirm-main-message', 'Are you sure you want to delete your account?' diff --git a/integration_test/page-objects/settings.page.js b/integration_test/page-objects/settings.page.js index 0acc0a485..64f51e7af 100644 --- a/integration_test/page-objects/settings.page.js +++ b/integration_test/page-objects/settings.page.js @@ -1,5 +1,10 @@ module.exports = { // settings view + settingsButtonSection: + '//*[contains(@class,"session-icon-button") and .//*[contains(@class, "gear")]]', + settingsRowWithText: text => + `//*[contains(@class, "left-pane-setting-category-list-item")][contains(string(), '${text}')]`, + leftPaneSettingsButton: `//*[contains(@class,"session-icon-button") and .//*[contains(@class, "gear")]]`, settingToggleWithText: text => `//div[contains(@class, 'session-settings-item') and contains(string(), '${text}')]//*[contains(@class, 'session-toggle')]`, @@ -9,3 +14,4 @@ module.exports = { // Confirm is a boolean. Selects confirmation input passwordSetModalInput: _confirm => `//input[@id = 'password-modal-input${_confirm ? '-confirm' : ''}']`, }; + diff --git a/integration_test/settings_test.js b/integration_test/settings_test.js new file mode 100644 index 000000000..19ef18d7d --- /dev/null +++ b/integration_test/settings_test.js @@ -0,0 +1,112 @@ +/* eslint-disable prefer-destructuring */ +/* eslint-disable more/no-then */ +/* eslint-disable func-names */ +/* eslint-disable import/no-extraneous-dependencies */ + +const { after, before, describe, it } = require('mocha'); +const common = require('./common'); + +const SettingsPage = require('./page-objects/settings.page'); +const CommonPage = require('./page-objects/common.page'); + +// Generate random password +const password = Math.random().toString(36).substr(2, 8); +const passwordInputID = 'password-modal-input'; + +describe('Settings', function() { + let app; + this.timeout(60000); + this.slow(15000); + + before(async () => { + await common.killallElectron(); + await common.stopStubSnodeServer(); + + const appProps = { + mnemonic: common.TEST_MNEMONIC1, + displayName: common.TEST_DISPLAY_NAME1, + stubSnode: true, + }; + + app = await common.startAndStub(appProps); + }); + + after(async () => { + // await common.stopApp(app); + // await common.killallElectron(); + // await common.stopStubSnodeServer(); + }); + + it('can toggle menubar', async () => { + const menuBarVisible = await app.browserWindow.isMenuBarVisible(); + + await app.client.element(SettingsPage.settingsButtonSection).click(); + await app.client.element(SettingsPage.settingToggleWithText('Hide Menu Bar')).click(); + + // Confirm that toggling works + const menuBarToggled = await app.browserWindow.isMenuBarVisible(); + menuBarToggled.should.equal(!menuBarVisible); + }); + + it('can set password', async () => { + + await app.client.element(SettingsPage.settingsRowWithText('Privacy')).click(); + + await app.client.element( + SettingsPage.settingButtonWithText('Set Password') + ).click(); + + await common.setValueWrapper( + app, + CommonPage.inputWithId(passwordInputID), + password + ); + await common.setValueWrapper( + app, + CommonPage.inputWithId(`${passwordInputID}-confirm`), + password + ); + + await app.client.keys('Enter'); + + // Verify password set + await app.client.waitForExist( + CommonPage.toastWithText('Set Password'), + 2000 + ); + + await common.closeToast(app); + + }); + + it('can remove password', async () => { + + // Enter password to unlock settings + await common.setValueWrapper( + app, + CommonPage.inputWithId('password-lock-input'), + password + ); + + await app.client.keys('Enter'); + + // Remove password + await app.client.element( + SettingsPage.settingButtonWithText('Remove Password') + ).click(); + + await common.setValueWrapper( + app, + CommonPage.inputWithId(passwordInputID), + password + ); + + await app.client.keys('Enter'); + + // Verify password removed + await app.client.waitForExist( + CommonPage.toastWithText('Removed Password'), + 2000 + ); + }); +}); diff --git a/ts/components/session/SessionPasswordModal.tsx b/ts/components/session/SessionPasswordModal.tsx index 30d3b1175..826e83ed7 100644 --- a/ts/components/session/SessionPasswordModal.tsx +++ b/ts/components/session/SessionPasswordModal.tsx @@ -141,17 +141,18 @@ export class SessionPasswordModal extends React.Component { private async setPassword(onSuccess?: any) { // Only initial input required for PasswordAction.Remove - if (!this.passwordInput.current || (!this.passwordInputConfirm.current && this.props.action !== PasswordAction.Remove)) { - return; + if (!this.passwordInput.current + || (!this.passwordInputConfirm.current && this.props.action !== PasswordAction.Remove)) { + return; } // Trim leading / trailing whitespace for UX const enteredPassword = String(this.passwordInput.current.value).trim(); const enteredPasswordConfirm = this.passwordInputConfirm.current && String( this.passwordInputConfirm.current.value - ).trim(); + ).trim() || ''; - if (enteredPassword.length === 0 || enteredPasswordConfirm.length === 0) { + if (enteredPassword.length === 0 || (enteredPasswordConfirm.length === 0 && this.props.action !== PasswordAction.Remove)) { return; } From e6fdf95dcba654b039507928884fe6e96e6cedf6 Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 15 Apr 2020 04:32:46 +1000 Subject: [PATCH 09/14] Run all tests --- integration_test/integration_test.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index efe2d9080..62dc03d62 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -7,13 +7,12 @@ const { before } = require('mocha'); const common = require('./common'); -// require('./registration_test'); -// require('./open_group_test'); -// require('./add_friends_test'); -// require('./link_device_test'); -// require('./closed_group_test'); - -// require('./message_functions_test'); +require('./registration_test'); +require('./open_group_test'); +require('./add_friends_test'); +require('./link_device_test'); +require('./closed_group_test'); +require('./message_functions_test'); require('./settings_test'); From 958a4c8594056b55e5f850630eb6662c6f8d12a3 Mon Sep 17 00:00:00 2001 From: Vincent Date: Thu, 16 Apr 2020 21:24:11 +1000 Subject: [PATCH 10/14] Linted --- integration_test/common.js | 29 ++++++++++--------- integration_test/integration_test.js | 2 -- integration_test/message_functions_test.js | 11 +++---- integration_test/message_sync_test.js | 6 ++-- integration_test/page-objects/common.page.js | 4 +-- .../page-objects/conversation.page.js | 10 ++++--- .../page-objects/settings.page.js | 13 +++++---- integration_test/settings_test.js | 29 ++++++++++--------- stylesheets/_global.scss | 1 - .../session/SessionPasswordModal.tsx | 22 +++++++++----- 10 files changed, 70 insertions(+), 57 deletions(-) diff --git a/integration_test/common.js b/integration_test/common.js index e3cd9f9e5..704322079 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -16,7 +16,6 @@ const RegistrationPage = require('./page-objects/registration.page'); const ConversationPage = require('./page-objects/conversation.page'); const SettingsPage = require('./page-objects/settings.page'); - chai.should(); chai.use(chaiAsPromised); chai.config.includeStack = true; @@ -44,7 +43,6 @@ module.exports = { '05f8662b6e83da5a31007cc3ded44c601f191e07999acb6db2314a896048d9036c', TEST_DISPLAY_NAME3: 'integration_tester_3', - /* ************** OPEN GROUPS ****************** */ VALID_GROUP_URL: 'https://chat.getsession.org', VALID_GROUP_URL2: 'https://chat-dev.lokinet.org', @@ -71,7 +69,7 @@ module.exports = { // could put a branch here to use one of those // if we know what platforms are good and which ones are broken - if (process.platform === 'darwin'){ + if (process.platform === 'darwin') { await app.client.execute( (slctr, val) => { // eslint-disable-next-line no-undef @@ -100,7 +98,6 @@ module.exports = { // Linux & Windows don't require wrapper await app.client.element(selector).setValue(value); } - }, async startApp(environment = 'test-integration-session') { @@ -329,8 +326,8 @@ module.exports = { async addFriendToNewClosedGroup(app, app2) { await app.client - .element(ConversationPage.closedGroupNameTextarea) - .setValue(this.VALID_CLOSED_GROUP_NAME1); + .element(ConversationPage.closedGroupNameTextarea) + .setValue(this.VALID_CLOSED_GROUP_NAME1); await app.client .element(ConversationPage.closedGroupNameTextarea) .getValue() @@ -364,10 +361,10 @@ module.exports = { .element(ConversationPage.headerTitleMembers(2)) .isVisible(); - // validate overlay is closed + // validate overlay is closed await app.client - .isExisting(ConversationPage.leftPaneOverlay) - .should.eventually.be.equal(false); + .isExisting(ConversationPage.leftPaneOverlay) + .should.eventually.be.equal(false); // move back to the conversation section await app.client @@ -406,7 +403,9 @@ module.exports = { // app needs to be logged in as user1 and app2 needs to be logged out // start the pairing dialog for the first app await app1.client.element(SettingsPage.settingsButtonSection).click(); - await app1.client.element(SettingsPage.settingsRowWithText('Devices')).click(); + await app1.client + .element(SettingsPage.settingsRowWithText('Devices')) + .click(); await app1.client.isVisible(ConversationPage.noPairedDeviceMessage); // we should not find the linkDeviceButtonDisabled button (as DISABLED) @@ -470,7 +469,9 @@ module.exports = { .should.eventually.be.true; await app1.client.element(ConversationPage.settingsButtonSection).click(); - await app1.client.element(ConversationPage.settingsRowWithText('Devices')).click(); + await app1.client + .element(ConversationPage.settingsRowWithText('Devices')) + .click(); await app1.client.isExisting(ConversationPage.linkDeviceButtonDisabled) .should.eventually.be.true; // click the unlink button @@ -506,10 +507,10 @@ module.exports = { } }, - async sendMessage(app, messageText, fileLocation = undefined){ + async sendMessage(app, messageText, fileLocation = undefined) { await app.client - .element(ConversationPage.sendMessageTextarea) - .setValue(messageText); + .element(ConversationPage.sendMessageTextarea) + .setValue(messageText); await app.client .element(ConversationPage.sendMessageTextarea) .getValue() diff --git a/integration_test/integration_test.js b/integration_test/integration_test.js index 62dc03d62..f5a78e070 100644 --- a/integration_test/integration_test.js +++ b/integration_test/integration_test.js @@ -6,7 +6,6 @@ const { before } = require('mocha'); const common = require('./common'); - require('./registration_test'); require('./open_group_test'); require('./add_friends_test'); @@ -15,7 +14,6 @@ require('./closed_group_test'); require('./message_functions_test'); require('./settings_test'); - before(async () => { // start the app once before all tests to get the platform-dependent // path of user data and store it to common.USER_DATA_ROOT_FOLDER diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js index 8cd9bdcae..e533592e0 100644 --- a/integration_test/message_functions_test.js +++ b/integration_test/message_functions_test.js @@ -51,7 +51,7 @@ describe('Message Functions', function() { 5000 ); }); - + it('can delete message', async () => { const messageText = 'delete_me'; common.sendMessage(app, messageText); @@ -64,9 +64,11 @@ describe('Message Functions', function() { ConversationPage.existingReceivedMessageText(messageText), 7000 ); - + // delete message in context menu - await app.client.element(ConversationPage.messageCtxMenu(messageText)).click(); + await app.client + .element(ConversationPage.messageCtxMenu(messageText)) + .click(); await app.client.element(ConversationPage.deleteMessageCtxButton).click(); // delete messaage from modal @@ -75,11 +77,10 @@ describe('Message Functions', function() { 3000 ); await app.client.element(ConversationPage.deleteMessageModalButton).click(); - + // verify the message is actually deleted await app.client.isExisting( ConversationPage.existingSendMessageText(messageText) ).should.eventually.be.false; }); - }); diff --git a/integration_test/message_sync_test.js b/integration_test/message_sync_test.js index 44676a280..e422bc52d 100644 --- a/integration_test/message_sync_test.js +++ b/integration_test/message_sync_test.js @@ -4,7 +4,6 @@ const { afterEach, beforeEach, describe, it } = require('mocha'); const common = require('./common'); - describe('Message Syncing', function() { let app; let app2; @@ -21,7 +20,7 @@ describe('Message Syncing', function() { displayName: common.TEST_DISPLAY_NAME1, stubSnode: true, }; - + const app2Props = { mnemonic: common.TEST_MNEMONIC2, displayName: common.TEST_DISPLAY_NAME2, @@ -55,5 +54,4 @@ describe('Message Syncing', function() { await common.timeout(1000); await common.triggerUnlinkApp2FromApp(app, app2); }); - -}); \ No newline at end of file +}); diff --git a/integration_test/page-objects/common.page.js b/integration_test/page-objects/common.page.js index 3e4bcd508..6d249ff02 100644 --- a/integration_test/page-objects/common.page.js +++ b/integration_test/page-objects/common.page.js @@ -22,6 +22,6 @@ module.exports = { module.exports.objWithClassAndText('span', classname, text), toastWithText: text => module.exports.divWithClassAndText('session-toast-wrapper', text), - toastCloseButton: '//div[contains(@class, "session-toast-wrapper")]//div[contains(@class, "toast-close")]/div', + toastCloseButton: + '//div[contains(@class, "session-toast-wrapper")]//div[contains(@class, "toast-close")]/div', }; - diff --git a/integration_test/page-objects/conversation.page.js b/integration_test/page-objects/conversation.page.js index aa7441bb9..bffb5d405 100644 --- a/integration_test/page-objects/conversation.page.js +++ b/integration_test/page-objects/conversation.page.js @@ -31,10 +31,13 @@ module.exports = { attachmentInput: '//*[contains(@class, "choose-file")]/input[@type="file"]', attachmentButton: '//*[contains(@class, "choose-file")]/button', - messageCtxMenu: message => `//div[contains(@class, 'message-wrapper')]//span[contains(string(), '${message}')]/parent::div/parent::div/parent::div/parent::div//div[contains(@class, 'module-message__buttons__menu')]`, + messageCtxMenu: message => + `//div[contains(@class, 'message-wrapper')]//span[contains(string(), '${message}')]/parent::div/parent::div/parent::div/parent::div//div[contains(@class, 'module-message__buttons__menu')]`, - deleteMessageCtxButton: '//*[contains(@class, "react-contextmenu--visible")]/div[contains(string(), "Delete")]', - deleteMessageModalButton: '//*[contains(@class, "session-modal")]//div[contains(string(), "Delete") and contains(@class, "session-button")]', + deleteMessageCtxButton: + '//*[contains(@class, "react-contextmenu--visible")]/div[contains(string(), "Delete")]', + deleteMessageModalButton: + '//*[contains(@class, "session-modal")]//div[contains(string(), "Delete") and contains(@class, "session-button")]', // channels globeButtonSection: @@ -95,7 +98,6 @@ module.exports = { acceptedFriendRequestMessage: '//*[contains(@class, "module-friend-request__title")][contains(string(), "Friend request accepted")]', - descriptionDeleteAccount: commonPage.spanWithClassAndText( 'session-confirm-main-message', 'Are you sure you want to delete your account?' diff --git a/integration_test/page-objects/settings.page.js b/integration_test/page-objects/settings.page.js index 64f51e7af..3adf33f05 100644 --- a/integration_test/page-objects/settings.page.js +++ b/integration_test/page-objects/settings.page.js @@ -7,11 +7,14 @@ module.exports = { leftPaneSettingsButton: `//*[contains(@class,"session-icon-button") and .//*[contains(@class, "gear")]]`, - settingToggleWithText: text => `//div[contains(@class, 'session-settings-item') and contains(string(), '${text}')]//*[contains(@class, 'session-toggle')]`, - settingButtonWithText: text => `//div[contains(@class, 'session-settings-item')]//*[contains(@class, 'session-button') and contains(string(), '${text}')]`, - settingCategoryWithText: text => `//div[contains(@class, 'left-pane-setting-category-list-item') and contains(string(), '${text}')]`, + settingToggleWithText: text => + `//div[contains(@class, 'session-settings-item') and contains(string(), '${text}')]//*[contains(@class, 'session-toggle')]`, + settingButtonWithText: text => + `//div[contains(@class, 'session-settings-item')]//*[contains(@class, 'session-button') and contains(string(), '${text}')]`, + settingCategoryWithText: text => + `//div[contains(@class, 'left-pane-setting-category-list-item') and contains(string(), '${text}')]`, // Confirm is a boolean. Selects confirmation input - passwordSetModalInput: _confirm => `//input[@id = 'password-modal-input${_confirm ? '-confirm' : ''}']`, + passwordSetModalInput: _confirm => + `//input[@id = 'password-modal-input${_confirm ? '-confirm' : ''}']`, }; - diff --git a/integration_test/settings_test.js b/integration_test/settings_test.js index 19ef18d7d..2477c8b34 100644 --- a/integration_test/settings_test.js +++ b/integration_test/settings_test.js @@ -10,7 +10,9 @@ const SettingsPage = require('./page-objects/settings.page'); const CommonPage = require('./page-objects/common.page'); // Generate random password -const password = Math.random().toString(36).substr(2, 8); +const password = Math.random() + .toString(36) + .substr(2, 8); const passwordInputID = 'password-modal-input'; describe('Settings', function() { @@ -41,20 +43,23 @@ describe('Settings', function() { const menuBarVisible = await app.browserWindow.isMenuBarVisible(); await app.client.element(SettingsPage.settingsButtonSection).click(); - await app.client.element(SettingsPage.settingToggleWithText('Hide Menu Bar')).click(); + await app.client + .element(SettingsPage.settingToggleWithText('Hide Menu Bar')) + .click(); // Confirm that toggling works const menuBarToggled = await app.browserWindow.isMenuBarVisible(); menuBarToggled.should.equal(!menuBarVisible); }); - - it('can set password', async () => { - await app.client.element(SettingsPage.settingsRowWithText('Privacy')).click(); + it('can set password', async () => { + await app.client + .element(SettingsPage.settingsRowWithText('Privacy')) + .click(); - await app.client.element( - SettingsPage.settingButtonWithText('Set Password') - ).click(); + await app.client + .element(SettingsPage.settingButtonWithText('Set Password')) + .click(); await common.setValueWrapper( app, @@ -76,11 +81,9 @@ describe('Settings', function() { ); await common.closeToast(app); - }); it('can remove password', async () => { - // Enter password to unlock settings await common.setValueWrapper( app, @@ -91,9 +94,9 @@ describe('Settings', function() { await app.client.keys('Enter'); // Remove password - await app.client.element( - SettingsPage.settingButtonWithText('Remove Password') - ).click(); + await app.client + .element(SettingsPage.settingButtonWithText('Remove Password')) + .click(); await common.setValueWrapper( app, diff --git a/stylesheets/_global.scss b/stylesheets/_global.scss index 8c9b9e818..89c8983bb 100644 --- a/stylesheets/_global.scss +++ b/stylesheets/_global.scss @@ -149,7 +149,6 @@ a { left: 0; cursor: pointer; z-index: -100; - } } diff --git a/ts/components/session/SessionPasswordModal.tsx b/ts/components/session/SessionPasswordModal.tsx index 826e83ed7..ef1a4c38d 100644 --- a/ts/components/session/SessionPasswordModal.tsx +++ b/ts/components/session/SessionPasswordModal.tsx @@ -141,18 +141,26 @@ export class SessionPasswordModal extends React.Component { private async setPassword(onSuccess?: any) { // Only initial input required for PasswordAction.Remove - if (!this.passwordInput.current - || (!this.passwordInputConfirm.current && this.props.action !== PasswordAction.Remove)) { - return; + if ( + !this.passwordInput.current || + (!this.passwordInputConfirm.current && + this.props.action !== PasswordAction.Remove) + ) { + return; } // Trim leading / trailing whitespace for UX const enteredPassword = String(this.passwordInput.current.value).trim(); - const enteredPasswordConfirm = this.passwordInputConfirm.current && String( - this.passwordInputConfirm.current.value - ).trim() || ''; + const enteredPasswordConfirm = + (this.passwordInputConfirm.current && + String(this.passwordInputConfirm.current.value).trim()) || + ''; - if (enteredPassword.length === 0 || (enteredPasswordConfirm.length === 0 && this.props.action !== PasswordAction.Remove)) { + if ( + enteredPassword.length === 0 || + (enteredPasswordConfirm.length === 0 && + this.props.action !== PasswordAction.Remove) + ) { return; } From e2c73f2fe5907462a2db3e065b1937a37fbfd8c1 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 28 Apr 2020 11:59:12 +1000 Subject: [PATCH 11/14] fixups --- config/test-integration-session-3.json | 6 ---- integration_test/common.js | 39 +++++++++++++--------- integration_test/message_functions_test.js | 2 +- integration_test/settings_test.js | 6 ++-- 4 files changed, 27 insertions(+), 26 deletions(-) delete mode 100644 config/test-integration-session-3.json diff --git a/config/test-integration-session-3.json b/config/test-integration-session-3.json deleted file mode 100644 index 9165effd6..000000000 --- a/config/test-integration-session-3.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "storageProfile": "testIntegration3Profile", - "openDevTools": false, - "updatesEnabled": false, - "localServerPort": "8489" -} diff --git a/integration_test/common.js b/integration_test/common.js index 704322079..8eb506349 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -66,8 +66,6 @@ module.exports = { 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 if (process.platform === 'darwin') { await app.client.execute( @@ -325,9 +323,11 @@ module.exports = { }, async addFriendToNewClosedGroup(app, app2) { - await app.client - .element(ConversationPage.closedGroupNameTextarea) - .setValue(this.VALID_CLOSED_GROUP_NAME1); + await this.setValueWrapper( + app, + ConversationPage.closedGroupNameTextarea, + this.VALID_CLOSED_GROUP_NAME1 + ); await app.client .element(ConversationPage.closedGroupNameTextarea) .getValue() @@ -335,7 +335,8 @@ module.exports = { await app.client .element(ConversationPage.createClosedGroupMemberItem) - .isVisible(); + .isVisible() + .should.eventually.be.true; // select the first friend as a member of the groups being created await app.client @@ -343,7 +344,8 @@ module.exports = { .click(); await app.client .element(ConversationPage.createClosedGroupMemberItemSelected) - .isVisible(); + .isVisible() + .should.eventually.be.true; // trigger the creation of the group await app.client @@ -356,10 +358,11 @@ module.exports = { ); await app.client.isExisting( ConversationPage.headerTitleGroupName(this.VALID_CLOSED_GROUP_NAME1) - ); + ).should.eventually.be.true; await app.client .element(ConversationPage.headerTitleMembers(2)) - .isVisible(); + .isVisible() + .should.eventually.be.true; // validate overlay is closed await app.client @@ -376,7 +379,7 @@ module.exports = { ConversationPage.rowOpenGroupConversationName( this.VALID_CLOSED_GROUP_NAME1 ) - ); + ).should.eventually.be.true; // next check app2 has been invited and has the group in its conversations await app2.client.waitForExist( @@ -508,9 +511,11 @@ module.exports = { }, async sendMessage(app, messageText, fileLocation = undefined) { - await app.client - .element(ConversationPage.sendMessageTextarea) - .setValue(messageText); + await this.setValueWrapper( + app, + ConversationPage.sendMessageTextarea, + messageText + ); await app.client .element(ConversationPage.sendMessageTextarea) .getValue() @@ -518,9 +523,11 @@ module.exports = { // attach a file if (fileLocation) { - await app.client - .element(ConversationPage.attachmentInput) - .setValue(fileLocation); + await this.setValueWrapper( + app, + ConversationPage.attachmentInput, + fileLocation + ); } // send message diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js index e533592e0..73296d1a7 100644 --- a/integration_test/message_functions_test.js +++ b/integration_test/message_functions_test.js @@ -35,7 +35,7 @@ describe('Message Functions', function() { await common.addFriendToNewClosedGroup(app, app2); // send attachment from app1 to closed group - const fileLocation = path.join(__dirname, '/test_attachment'); + const fileLocation = path.join(__dirname, 'test_attachment'); const messageText = 'test_attachment'; common.sendMessage(app, messageText, fileLocation); diff --git a/integration_test/settings_test.js b/integration_test/settings_test.js index 2477c8b34..6772d90aa 100644 --- a/integration_test/settings_test.js +++ b/integration_test/settings_test.js @@ -34,9 +34,9 @@ describe('Settings', function() { }); after(async () => { - // await common.stopApp(app); - // await common.killallElectron(); - // await common.stopStubSnodeServer(); + await common.stopApp(app); + await common.killallElectron(); + await common.stopStubSnodeServer(); }); it('can toggle menubar', async () => { From 5eb49764b3b9ce2a8fa55ee55d384aedd4cccc27 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 28 Apr 2020 12:12:06 +1000 Subject: [PATCH 12/14] lint --- integration_test/common.js | 10 +++------- integration_test/message_sync_test.js | 12 ++---------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/integration_test/common.js b/integration_test/common.js index 8eb506349..a6e1d8b14 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -335,8 +335,7 @@ module.exports = { await app.client .element(ConversationPage.createClosedGroupMemberItem) - .isVisible() - .should.eventually.be.true; + .isVisible().should.eventually.be.true; // select the first friend as a member of the groups being created await app.client @@ -344,8 +343,7 @@ module.exports = { .click(); await app.client .element(ConversationPage.createClosedGroupMemberItemSelected) - .isVisible() - .should.eventually.be.true; + .isVisible().should.eventually.be.true; // trigger the creation of the group await app.client @@ -359,9 +357,7 @@ module.exports = { await app.client.isExisting( ConversationPage.headerTitleGroupName(this.VALID_CLOSED_GROUP_NAME1) ).should.eventually.be.true; - await app.client - .element(ConversationPage.headerTitleMembers(2)) - .isVisible() + await app.client.element(ConversationPage.headerTitleMembers(2)).isVisible() .should.eventually.be.true; // validate overlay is closed diff --git a/integration_test/message_sync_test.js b/integration_test/message_sync_test.js index e422bc52d..4d40c97a9 100644 --- a/integration_test/message_sync_test.js +++ b/integration_test/message_sync_test.js @@ -7,12 +7,11 @@ const common = require('./common'); describe('Message Syncing', function() { let app; let app2; - let app3; this.timeout(60000); this.slow(15000); beforeEach(async () => { - // await common.killallElectron(); + await common.killallElectron(); await common.stopStubSnodeServer(); const app1Props = { @@ -27,16 +26,9 @@ describe('Message Syncing', function() { stubSnode: true, }; - const app3Props = { - mnemonic: common.TEST_MNEMONIC3, - displayName: common.TEST_DISPLAY_NAME3, - stubSnode: true, - }; - - [app, app2, app3] = await Promise.all([ + [app, app2] = await Promise.all([ common.startAndStub(app1Props), common.startAndStubN(app2Props, 2), - common.startAndStubN(app3Props, 3), ]); }); From cc3e03c5e4084ba7b3cde3b0255f4098482e6706 Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 29 Apr 2020 12:17:53 +1000 Subject: [PATCH 13/14] tests finalise --- integration_test/common.js | 1 - integration_test/message_functions_test.js | 4 ++-- integration_test/open_group_test.js | 7 +++---- integration_test/settings_test.js | 7 ++++++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/integration_test/common.js b/integration_test/common.js index a6e1d8b14..cac5a9526 100644 --- a/integration_test/common.js +++ b/integration_test/common.js @@ -64,7 +64,6 @@ module.exports = { // 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 if (process.platform === 'darwin') { diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js index 73296d1a7..c15f64621 100644 --- a/integration_test/message_functions_test.js +++ b/integration_test/message_functions_test.js @@ -58,7 +58,7 @@ describe('Message Functions', function() { await app.client.waitForExist( ConversationPage.existingSendMessageText(messageText), - 5000 + 6000 ); await app2.client.waitForExist( ConversationPage.existingReceivedMessageText(messageText), @@ -74,7 +74,7 @@ describe('Message Functions', function() { // delete messaage from modal await app.client.waitForExist( ConversationPage.deleteMessageModalButton, - 3000 + 5000 ); await app.client.element(ConversationPage.deleteMessageModalButton).click(); diff --git a/integration_test/open_group_test.js b/integration_test/open_group_test.js index e61f6047a..dba3d13e7 100644 --- a/integration_test/open_group_test.js +++ b/integration_test/open_group_test.js @@ -50,10 +50,9 @@ describe('Open groups', function() { .eventually.be.false; // validate open chat has been added - await app.client.waitForExist( - ConversationPage.rowOpenGroupConversationName(name), - 4000 - ); + await app.client.isExisting( + ConversationPage.rowOpenGroupConversationName(name) + ).should.eventually.be.true; } it('openGroup: works with valid open group url', async () => { diff --git a/integration_test/settings_test.js b/integration_test/settings_test.js index 6772d90aa..b166592b3 100644 --- a/integration_test/settings_test.js +++ b/integration_test/settings_test.js @@ -106,10 +106,15 @@ describe('Settings', function() { await app.client.keys('Enter'); - // Verify password removed + // Verify password removed with toast await app.client.waitForExist( CommonPage.toastWithText('Removed Password'), 2000 ); + + // Verify password actully removed + await app.client.isExisting( + CommonPage.divWithClass('session-settings__password-lock') + ).should.eventually.be.false; }); }); From 7763baba7a6ed341b05396e7bb26de00d7c17a58 Mon Sep 17 00:00:00 2001 From: Vincent Date: Wed, 29 Apr 2020 12:20:48 +1000 Subject: [PATCH 14/14] Send message async --- integration_test/message_functions_test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration_test/message_functions_test.js b/integration_test/message_functions_test.js index c15f64621..469171f2d 100644 --- a/integration_test/message_functions_test.js +++ b/integration_test/message_functions_test.js @@ -38,7 +38,7 @@ describe('Message Functions', function() { const fileLocation = path.join(__dirname, 'test_attachment'); const messageText = 'test_attachment'; - common.sendMessage(app, messageText, fileLocation); + await common.sendMessage(app, messageText, fileLocation); // validate attachment sent await app.client.waitForExist( @@ -54,7 +54,7 @@ describe('Message Functions', function() { it('can delete message', async () => { const messageText = 'delete_me'; - common.sendMessage(app, messageText); + await common.sendMessage(app, messageText); await app.client.waitForExist( ConversationPage.existingSendMessageText(messageText),