Making tests truly idempotent to use reply: enc and broadcast

This commit is contained in:
Diego Mello 2023-02-22 10:06:16 -03:00
parent c79cef0465
commit e9721c8743
7 changed files with 121 additions and 55 deletions

View File

@ -1,5 +1,6 @@
// @ts-ignore
import account from './e2e_account';
import random from './helpers/random';
export interface IUser {
username: string;
@ -103,7 +104,15 @@ const data = {
password: `passwordfour${value}`,
email: `mobile+registeringfour${value}@rocket.chat`
},
random: value
random: value,
randomUser: (): { username: string; password: string; email: string } => {
const randomVal = random();
return {
username: `user${randomVal}`,
password: '123',
email: `mobile+${randomVal}@rocket.chat`
};
}
};
export default data;

View File

@ -2,5 +2,5 @@ import { setup } from './helpers/data_setup';
module.exports = async () => {
await require('detox/runners/jest/index').globalSetup();
await setup();
// await setup();
};

View File

@ -1,6 +1,7 @@
import { by, expect, element } from 'detox';
import data from '../data';
import random from './random';
export type TTextMatcher = keyof Pick<Detox.ByFacade, 'text' | 'label'>;
@ -109,6 +110,21 @@ async function mockMessage(message: string, isThread = false) {
.tap();
}
async function mockRandomMessage(messageEnd: string, isThread = false) {
const message = `${random(10)}${messageEnd}`;
const deviceType = device.getPlatform();
const { textMatcher } = platformTypes[deviceType];
const input = isThread ? 'messagebox-input-thread' : 'messagebox-input';
await element(by.id(input)).replaceText(message);
await sleep(300);
await element(by.id('messagebox-send-message')).tap();
await waitFor(element(by[textMatcher](message)))
.toExist()
.withTimeout(60000);
await element(by[textMatcher](message)).atIndex(0).tap();
return message;
}
async function dismissReviewNag() {
const deviceType = device.getPlatform();
const { textMatcher } = platformTypes[deviceType];
@ -234,6 +250,7 @@ export {
login,
logout,
mockMessage,
mockRandomMessage,
dismissReviewNag,
tapBack,
sleep,

View File

@ -1,6 +1,7 @@
import axios from 'axios';
import data, { TDataChannels, TDataGroups, TDataTeams, TDataUsers, TUserRegularChannels } from '../data';
import random from './random';
const TEAM_TYPE = {
PUBLIC: 0,
@ -28,6 +29,36 @@ const login = async (username: string, password: string) => {
return { authToken, userId };
};
export interface ICreateUser {
username: string;
password: string;
name: string;
email: string;
}
export const createRandomUser = async (): Promise<ICreateUser> => {
await login(data.adminUser, data.adminPassword);
const val = random(5);
console.log(`Creating user user${val}`);
try {
const username = `user${val}`;
const password = `pass${val}`;
const name = `name${val}`;
const email = `mobile+${val}@rocket.chat`;
await rocketchat.post('users.create', {
username,
password,
name,
email
});
return { username, password, name, email } as const;
} catch (error) {
console.log(JSON.stringify(error));
throw new Error('Failed to create user');
}
};
const createUser = async (username: string, password: string, name: string, email: string) => {
console.log(`Creating user ${username}`);
try {

View File

@ -1,4 +1,4 @@
function random(length: number) {
function random(length = 10) {
let text = '';
const possible = 'abcdefghijklmnopqrstuvwxyz';
for (let i = 0; i < length; i += 1) {

View File

@ -5,18 +5,17 @@ import {
login,
sleep,
tapBack,
mockMessage,
searchRoom,
logout,
platformTypes,
TTextMatcher,
tapAndWaitFor,
expectValidRegisterOrRetry
expectValidRegisterOrRetry,
mockRandomMessage
} from '../../helpers/app';
import data from '../../data';
const testuser = data.users.encryption;
const otheruser = data.users.alternate;
import { createRandomUser, ICreateUser } from '../../helpers/data_setup';
import random from '../../helpers/random';
const checkServer = async (server: string) => {
const label = `Connected to ${server}`;
@ -71,16 +70,22 @@ async function navigateSecurityPrivacy() {
}
describe('E2E Encryption', () => {
const room = `encrypted${data.random}`;
const room = `encrypted${random()}`;
let user: ICreateUser;
let otherUser: ICreateUser;
let mockedMessageText: string;
const newPassword = 'abc';
let alertButtonType: string;
let textMatcher: TTextMatcher;
beforeAll(async () => {
user = await createRandomUser();
otherUser = await createRandomUser();
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
await navigateToLogin();
await login(testuser.username, testuser.password);
await login(user.username, user.password);
});
describe('Banner', () => {
@ -123,12 +128,12 @@ describe('E2E Encryption', () => {
await waitFor(element(by.id('select-users-view')))
.toBeVisible()
.withTimeout(2000);
await element(by.id('select-users-view-search')).replaceText(otheruser.username);
await waitFor(element(by.id(`select-users-view-item-${otheruser.username}`)))
await element(by.id('select-users-view-search')).replaceText(otherUser.username);
await waitFor(element(by.id(`select-users-view-item-${otherUser.username}`)))
.toBeVisible()
.withTimeout(60000);
await element(by.id(`select-users-view-item-${otheruser.username}`)).tap();
await waitFor(element(by.id(`selected-user-${otheruser.username}`)))
await element(by.id(`select-users-view-item-${otherUser.username}`)).tap();
await waitFor(element(by.id(`selected-user-${otherUser.username}`)))
.toBeVisible()
.withTimeout(5000);
await element(by.id('selected-users-view-submit')).tap();
@ -148,7 +153,7 @@ describe('E2E Encryption', () => {
});
it('should send message and be able to read it', async () => {
await mockMessage('message');
mockedMessageText = await mockRandomMessage('message');
await tapBack();
});
});
@ -205,7 +210,7 @@ describe('E2E Encryption', () => {
describe('Change password', () => {
it('should change password', async () => {
await element(by.id('e2e-encryption-security-view-password')).typeText(newPassword);
await element(by.id('e2e-encryption-security-view-password')).replaceText(newPassword);
await element(by.id('e2e-encryption-security-view-change-password')).tap();
await waitFor(element(by[textMatcher]('Are you sure?')))
.toExist()
@ -236,7 +241,7 @@ describe('E2E Encryption', () => {
.toBeVisible()
.withTimeout(2000);
await navigateToRoom(room);
await waitFor(element(by[textMatcher](`${data.random}message`)).atIndex(0))
await waitFor(element(by[textMatcher](mockedMessageText)).atIndex(0))
.toExist()
.withTimeout(2000);
});
@ -248,9 +253,9 @@ describe('E2E Encryption', () => {
.withTimeout(2000);
await logout();
await navigateToLogin();
await login(testuser.username, testuser.password);
await login(user.username, user.password);
await navigateToRoom(room);
await waitFor(element(by[textMatcher](`${data.random}message`)).atIndex(0))
await waitFor(element(by[textMatcher](mockedMessageText)).atIndex(0))
.not.toExist()
.withTimeout(2000);
await expect(element(by.label('Encrypted message')).atIndex(0)).toExist();
@ -266,13 +271,13 @@ describe('E2E Encryption', () => {
.toBeVisible()
.withTimeout(2000);
await tapAndWaitFor(element(by.id('listheader-encryption')), element(by.id('e2e-enter-your-password-view')), 2000);
await element(by.id('e2e-enter-your-password-view-password')).typeText(newPassword);
await element(by.id('e2e-enter-your-password-view-password')).replaceText(newPassword);
await element(by.id('e2e-enter-your-password-view-confirm')).tap();
await waitFor(element(by.id('listheader-encryption')))
.not.toExist()
.withTimeout(10000);
await navigateToRoom(room);
await waitFor(element(by[textMatcher](`${data.random}message`)).atIndex(0))
await waitFor(element(by[textMatcher](mockedMessageText)).atIndex(0))
.toExist()
.withTimeout(2000);
});
@ -317,7 +322,7 @@ describe('E2E Encryption', () => {
await waitFor(element(by.id('login-view')))
.toBeVisible()
.withTimeout(2000);
await login(testuser.username, testuser.password);
await login(user.username, user.password);
// TODO: assert 'Save Your Encryption Password'
await waitFor(element(by.id('listheader-encryption')))
.toBeVisible()
@ -332,7 +337,7 @@ describe('E2E Encryption', () => {
if (device.getPlatform() === 'android') {
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
await navigateToLogin();
await login(testuser.username, testuser.password);
await login(user.username, user.password);
}
});
it('check save banner', async () => {
@ -352,7 +357,7 @@ describe('E2E Encryption', () => {
await waitFor(element(by.id('new-server-view')))
.toBeVisible()
.withTimeout(60000);
await element(by.id('new-server-view-input')).typeText(`${data.alternateServer}`);
await element(by.id('new-server-view-input')).replaceText(`${data.alternateServer}`);
await element(by.id('new-server-view-input')).tapReturnKey();
await waitFor(element(by.id('workspace-view')))
.toBeVisible()
@ -363,10 +368,11 @@ describe('E2E Encryption', () => {
.withTimeout(2000);
// Register new user
await element(by.id('register-view-name')).replaceText(data.registeringUser.username);
await element(by.id('register-view-username')).replaceText(data.registeringUser.username);
await element(by.id('register-view-email')).replaceText(data.registeringUser.email);
await element(by.id('register-view-password')).replaceText(data.registeringUser.password);
const randomUser = data.randomUser();
await element(by.id('register-view-name')).replaceText(randomUser.username);
await element(by.id('register-view-username')).replaceText(randomUser.username);
await element(by.id('register-view-email')).replaceText(randomUser.email);
await element(by.id('register-view-password')).replaceText(randomUser.password);
await element(by.id('register-view-password')).tapReturnKey();
await expectValidRegisterOrRetry(device.getPlatform());

View File

@ -5,26 +5,32 @@ import { expect } from 'detox';
import {
navigateToLogin,
login,
mockMessage,
tapBack,
searchRoom,
platformTypes,
TTextMatcher,
sleep,
checkRoomTitle
checkRoomTitle,
mockRandomMessage
} from '../../helpers/app';
import data from '../../data';
const testuser = data.users.regular;
const otheruser = data.users.alternate;
import { createRandomUser, ICreateUser } from '../../helpers/data_setup';
import random from '../../helpers/random';
describe('Broadcast room', () => {
let textMatcher: TTextMatcher;
let user: ICreateUser;
let otherUser: ICreateUser;
let message: string;
const room = `broadcast${random()}`;
beforeAll(async () => {
user = await createRandomUser();
otherUser = await createRandomUser();
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
({ textMatcher } = platformTypes[device.getPlatform()]);
await navigateToLogin();
await login(testuser.username, testuser.password);
await login(user.username, user.password);
});
it('should create broadcast room', async () => {
@ -39,23 +45,23 @@ describe('Broadcast room', () => {
await waitFor(element(by.id('select-users-view')))
.toBeVisible()
.withTimeout(2000);
await element(by.id('select-users-view-search')).replaceText(otheruser.username);
await waitFor(element(by.id(`select-users-view-item-${otheruser.username}`)))
await element(by.id('select-users-view-search')).replaceText(otherUser.username);
await waitFor(element(by.id(`select-users-view-item-${otherUser.username}`)))
.toBeVisible()
.withTimeout(60000);
await element(by.id(`select-users-view-item-${otheruser.username}`)).tap();
await waitFor(element(by.id(`selected-user-${otheruser.username}`)))
await element(by.id(`select-users-view-item-${otherUser.username}`)).tap();
await waitFor(element(by.id(`selected-user-${otherUser.username}`)))
.toBeVisible()
.withTimeout(5000);
await element(by.id('selected-users-view-submit')).tap();
await waitFor(element(by.id('create-channel-view')))
.toExist()
.withTimeout(5000);
await element(by.id('create-channel-name')).replaceText(`broadcast${data.random}`);
await element(by.id('create-channel-name')).replaceText(room);
await element(by.id('create-channel-name')).tapReturnKey();
await element(by.id('create-channel-broadcast')).tap();
await element(by.id('create-channel-submit')).tap();
await checkRoomTitle(`broadcast${data.random}`);
await checkRoomTitle(room);
await element(by.id('room-header')).tap();
await waitFor(element(by.id('room-actions-view')))
.toBeVisible()
@ -79,14 +85,14 @@ describe('Broadcast room', () => {
await waitFor(element(by.id('room-view')))
.toBeVisible()
.withTimeout(5000);
await mockMessage('message');
message = await mockRandomMessage('message');
await tapBack();
});
it('should login as user without write message authorization and enter room', async () => {
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
await navigateToLogin();
await login(otheruser.username, otheruser.password);
await login(otherUser.username, otherUser.password);
// await waitFor(element(by.id('two-factor'))).toBeVisible().withTimeout(5000);
// await expect(element(by.id('two-factor'))).toBeVisible();
@ -94,12 +100,12 @@ describe('Broadcast room', () => {
// await element(by.id('two-factor-input')).replaceText(code);
// await element(by.id('two-factor-send')).tap();
await searchRoom(`broadcast${data.random}`);
await element(by.id(`rooms-list-view-item-broadcast${data.random}`)).tap();
await searchRoom(room);
await element(by.id(`rooms-list-view-item-${room}`)).tap();
await waitFor(element(by.id('room-view')))
.toBeVisible()
.withTimeout(5000);
await waitFor(element(by.id(`room-view-title-broadcast${data.random}`)))
await waitFor(element(by.id(`room-view-title-${room}`)))
.toBeVisible()
.withTimeout(60000);
});
@ -113,7 +119,7 @@ describe('Broadcast room', () => {
});
it('should have the message created earlier', async () => {
await waitFor(element(by[textMatcher](`${data.random}message`)))
await waitFor(element(by[textMatcher](message)))
.toExist()
.withTimeout(60000);
});
@ -124,23 +130,20 @@ describe('Broadcast room', () => {
it('should tap on reply button and navigate to direct room', async () => {
await element(by.id('message-broadcast-reply')).tap();
await waitFor(element(by.id(`room-view-title-${testuser.username}`)))
await waitFor(element(by.id(`room-view-title-${user.username}`)))
.toBeVisible()
.withTimeout(5000);
});
it('should reply broadcasted message', async () => {
// Server is adding 2 spaces in front a reply message
await element(by.id('messagebox-input')).replaceText(`${data.random}broadcastreply`);
await element(by.id('messagebox-input')).replaceText(`${random()}broadcastreply`);
await sleep(300);
await element(by.id('messagebox-send-message')).tap();
await waitFor(element(by[textMatcher](`${data.random}message`)))
await waitFor(element(by[textMatcher](message)))
.toExist()
.withTimeout(10000);
await element(by[textMatcher](`${data.random}message`)).tap();
await sleep(600);
await waitFor(element(by.id(`room-view-title-broadcast${data.random}`)))
.toBeVisible()
.withTimeout(10000);
await element(by[textMatcher](message)).tap();
await sleep(300); // wait for animation
await checkRoomTitle(room);
});
});