Message & settings tests

This commit is contained in:
Vincent 2020-04-15 04:26:50 +10:00
parent d2364ba529
commit c1dcac1b84
8 changed files with 145 additions and 21 deletions

View file

@ -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

View file

@ -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');

View file

@ -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;
});
});

View file

@ -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',
};

View file

@ -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?'

View file

@ -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' : ''}']`,
};

View file

@ -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
);
});
});

View file

@ -141,17 +141,18 @@ export class SessionPasswordModal extends React.Component<Props, State> {
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;
}