Re-add previous tests
This commit is contained in:
parent
2e371131df
commit
b332bfecd4
|
@ -0,0 +1,101 @@
|
|||
/* eslint-disable import/extensions, import/no-unresolved */
|
||||
import random from './helpers/random';
|
||||
// @ts-ignore
|
||||
import account from './e2e_account';
|
||||
|
||||
export interface IUser {
|
||||
username: string;
|
||||
password: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export type TData = typeof data;
|
||||
export type TDataKeys = keyof TData;
|
||||
export type TDataUsers = keyof typeof data.users;
|
||||
export type TDataChannels = keyof typeof data.channels;
|
||||
export type TUserRegularChannels = keyof typeof data.userRegularChannels;
|
||||
export type TDataGroups = keyof typeof data.groups;
|
||||
export type TDataTeams = keyof typeof data.teams;
|
||||
|
||||
const value: string = random(20);
|
||||
const data = {
|
||||
server: 'https://mobile.rocket.chat',
|
||||
...account,
|
||||
alternateServer: 'https://stable.rocket.chat',
|
||||
users: {
|
||||
regular: {
|
||||
username: `userone${value}`,
|
||||
password: '123',
|
||||
email: `mobile+regular${value}@rocket.chat`
|
||||
},
|
||||
alternate: {
|
||||
username: `usertwo${value}`,
|
||||
password: '123',
|
||||
email: `mobile+alternate${value}@rocket.chat`,
|
||||
totpSecret: 'NA4GOMZGHBQSK6KEFRVT62DMGJJGSYZJFZIHO3ZOGVXWCYZ6MMZQ'
|
||||
},
|
||||
profileChanges: {
|
||||
username: `userthree${value}`,
|
||||
password: '123',
|
||||
email: `mobile+profileChanges${value}@rocket.chat`
|
||||
},
|
||||
existing: {
|
||||
username: `existinguser${value}`,
|
||||
password: '123',
|
||||
email: `mobile+existing${value}@rocket.chat`
|
||||
}
|
||||
},
|
||||
channels: {
|
||||
detoxpublic: {
|
||||
name: 'detox-public'
|
||||
},
|
||||
detoxpublicprotected: {
|
||||
name: 'detox-public-protected',
|
||||
joinCode: '123'
|
||||
}
|
||||
},
|
||||
userRegularChannels: {
|
||||
detoxpublic: {
|
||||
name: `detox-public-${value}`
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
private: {
|
||||
name: `detox-private-${value}`
|
||||
},
|
||||
alternate: {
|
||||
name: `detox-alternate-${value}`
|
||||
},
|
||||
alternate2: {
|
||||
name: `detox-alternate2-${value}`
|
||||
}
|
||||
},
|
||||
teams: {
|
||||
private: {
|
||||
name: `detox-team-${value}`
|
||||
}
|
||||
},
|
||||
registeringUser: {
|
||||
username: `newuser${value}`,
|
||||
password: `password${value}`,
|
||||
email: `mobile+registering${value}@rocket.chat`
|
||||
},
|
||||
registeringUser2: {
|
||||
username: `newusertwo${value}`,
|
||||
password: `passwordtwo${value}`,
|
||||
email: `mobile+registeringtwo${value}@rocket.chat`
|
||||
},
|
||||
registeringUser3: {
|
||||
username: `newuserthree${value}`,
|
||||
password: `passwordthree${value}`,
|
||||
email: `mobile+registeringthree${value}@rocket.chat`
|
||||
},
|
||||
registeringUser4: {
|
||||
username: `newuserfour${value}`,
|
||||
password: `passwordfour${value}`,
|
||||
email: `mobile+registeringfour${value}@rocket.chat`
|
||||
},
|
||||
random: value
|
||||
};
|
||||
|
||||
export default data;
|
|
@ -0,0 +1,96 @@
|
|||
/* eslint-disable import/extensions, import/no-unresolved */
|
||||
// @ts-ignore
|
||||
import random from './helpers/random';
|
||||
// @ts-ignore
|
||||
import account from './e2e_account';
|
||||
|
||||
export interface IUser {
|
||||
username: string;
|
||||
password: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export type TData = typeof data;
|
||||
export type TDataKeys = keyof TData;
|
||||
export type TDataUsers = keyof typeof data.users;
|
||||
export type TDataChannels = keyof typeof data.channels;
|
||||
export type TUserRegularChannels = keyof typeof data.userRegularChannels;
|
||||
export type TDataGroups = keyof typeof data.groups;
|
||||
export type TDataTeams = keyof typeof data.teams;
|
||||
|
||||
const value = random(20);
|
||||
const data = {
|
||||
server: 'https://mobile.rocket.chat',
|
||||
...account,
|
||||
alternateServer: 'https://stable.rocket.chat',
|
||||
users: {
|
||||
regular: {
|
||||
username: `userone${value}`,
|
||||
password: '123',
|
||||
email: `mobile+regular${value}@rocket.chat`
|
||||
},
|
||||
alternate: {
|
||||
username: `usertwo${value}`,
|
||||
password: '123',
|
||||
email: `mobile+alternate${value}@rocket.chat`,
|
||||
totpSecret: 'NA4GOMZGHBQSK6KEFRVT62DMGJJGSYZJFZIHO3ZOGVXWCYZ6MMZQ'
|
||||
},
|
||||
profileChanges: {
|
||||
username: `userthree${value}`,
|
||||
password: '123',
|
||||
email: `mobile+profileChanges${value}@rocket.chat`
|
||||
},
|
||||
existing: {
|
||||
username: `existinguser${value}`,
|
||||
password: '123',
|
||||
email: `mobile+existing${value}@rocket.chat`
|
||||
}
|
||||
},
|
||||
channels: {
|
||||
detoxpublic: {
|
||||
name: 'detox-public'
|
||||
},
|
||||
detoxpublicprotected: {
|
||||
name: 'detox-public-protected',
|
||||
joinCode: '123'
|
||||
}
|
||||
},
|
||||
userRegularChannels: {
|
||||
detoxpublic: {
|
||||
name: `detox-public-${value}`
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
private: {
|
||||
name: `detox-private-${value}`
|
||||
}
|
||||
},
|
||||
teams: {
|
||||
private: {
|
||||
name: `detox-team-${value}`
|
||||
}
|
||||
},
|
||||
registeringUser: {
|
||||
username: `newuser${value}`,
|
||||
password: `password${value}`,
|
||||
email: `mobile+registering${value}@rocket.chat`
|
||||
},
|
||||
registeringUser2: {
|
||||
username: `newusertwo${value}`,
|
||||
password: `passwordtwo${value}`,
|
||||
email: `mobile+registeringtwo${value}@rocket.chat`
|
||||
},
|
||||
registeringUser3: {
|
||||
username: `newuserthree${value}`,
|
||||
password: `passwordthree${value}`,
|
||||
email: `mobile+registeringthree${value}@rocket.chat`
|
||||
},
|
||||
registeringUser4: {
|
||||
username: `newuserfour${value}`,
|
||||
password: `passwordfour${value}`,
|
||||
email: `mobile+registeringfour${value}@rocket.chat`
|
||||
},
|
||||
random: value
|
||||
};
|
||||
|
||||
export default data;
|
|
@ -0,0 +1,101 @@
|
|||
/* eslint-disable import/extensions, import/no-unresolved */
|
||||
// @ts-ignore
|
||||
import random from './helpers/random';
|
||||
|
||||
export interface IUser {
|
||||
username: string;
|
||||
password: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export type TData = typeof data;
|
||||
export type TDataKeys = keyof TData;
|
||||
export type TDataUsers = keyof typeof data.users;
|
||||
export type TDataChannels = keyof typeof data.channels;
|
||||
export type TUserRegularChannels = keyof typeof data.userRegularChannels;
|
||||
export type TDataGroups = keyof typeof data.groups;
|
||||
export type TDataTeams = keyof typeof data.teams;
|
||||
|
||||
const value = random(20);
|
||||
const data = {
|
||||
server: 'http://localhost:3000',
|
||||
adminUser: 'admin',
|
||||
adminPassword: 'password',
|
||||
alternateServer: 'https://stable.rocket.chat',
|
||||
users: {
|
||||
regular: {
|
||||
username: `userone${value}`,
|
||||
password: '123',
|
||||
email: `mobile+regular${value}@rocket.chat`
|
||||
},
|
||||
alternate: {
|
||||
username: `usertwo${value}`,
|
||||
password: '123',
|
||||
email: `mobile+alternate${value}@rocket.chat`,
|
||||
totpSecret: 'NA4GOMZGHBQSK6KEFRVT62DMGJJGSYZJFZIHO3ZOGVXWCYZ6MMZQ'
|
||||
},
|
||||
profileChanges: {
|
||||
username: `userthree${value}`,
|
||||
password: '123',
|
||||
email: `mobile+profileChanges${value}@rocket.chat`
|
||||
},
|
||||
existing: {
|
||||
username: `existinguser${value}`,
|
||||
password: '123',
|
||||
email: `mobile+existing${value}@rocket.chat`
|
||||
}
|
||||
},
|
||||
channels: {
|
||||
detoxpublic: {
|
||||
name: 'detox-public'
|
||||
},
|
||||
detoxpublicprotected: {
|
||||
name: 'detox-public-protected',
|
||||
joinCode: '123'
|
||||
}
|
||||
},
|
||||
userRegularChannels: {
|
||||
detoxpublic: {
|
||||
name: `detox-public-${value}`
|
||||
}
|
||||
},
|
||||
groups: {
|
||||
private: {
|
||||
name: `detox-private-${value}`
|
||||
},
|
||||
alternate: {
|
||||
name: `detox-alternate-${value}`
|
||||
},
|
||||
alternate2: {
|
||||
name: `detox-alternate2-${value}`
|
||||
}
|
||||
},
|
||||
teams: {
|
||||
private: {
|
||||
name: `detox-team-${value}`
|
||||
}
|
||||
},
|
||||
registeringUser: {
|
||||
username: `newuser${value}`,
|
||||
password: `password${value}`,
|
||||
email: `mobile+registering${value}@rocket.chat`
|
||||
},
|
||||
registeringUser2: {
|
||||
username: `newusertwo${value}`,
|
||||
password: `passwordtwo${value}`,
|
||||
email: `mobile+registeringtwo${value}@rocket.chat`
|
||||
},
|
||||
registeringUser3: {
|
||||
username: `newuserthree${value}`,
|
||||
password: `passwordthree${value}`,
|
||||
email: `mobile+registeringthree${value}@rocket.chat`
|
||||
},
|
||||
registeringUser4: {
|
||||
username: `newuserfour${value}`,
|
||||
password: `passwordfour${value}`,
|
||||
email: `mobile+registeringfour${value}@rocket.chat`
|
||||
},
|
||||
random: value
|
||||
};
|
||||
|
||||
export default data;
|
|
@ -0,0 +1,6 @@
|
|||
const account = {
|
||||
adminUser: 'Change_here',
|
||||
adminPassword: 'Change_here'
|
||||
};
|
||||
|
||||
export default account;
|
|
@ -0,0 +1,248 @@
|
|||
import { exec } from 'child_process';
|
||||
|
||||
import { by, expect, element } from 'detox';
|
||||
|
||||
import data from '../data';
|
||||
|
||||
export type TTextMatcher = keyof Pick<Detox.ByFacade, 'text' | 'label'>;
|
||||
|
||||
const platformTypes = {
|
||||
android: {
|
||||
// Android types
|
||||
alertButtonType: 'android.widget.Button',
|
||||
scrollViewType: 'android.widget.ScrollView',
|
||||
textInputType: 'android.widget.EditText',
|
||||
textMatcher: 'text' as TTextMatcher
|
||||
},
|
||||
ios: {
|
||||
// iOS types
|
||||
alertButtonType: '_UIAlertControllerActionView',
|
||||
scrollViewType: 'UIScrollView',
|
||||
textInputType: '_UIAlertControllerTextField',
|
||||
textMatcher: 'label' as TTextMatcher
|
||||
}
|
||||
};
|
||||
|
||||
function sleep(ms: number) {
|
||||
return new Promise(res => setTimeout(res, ms));
|
||||
}
|
||||
|
||||
async function navigateToWorkspace(server = data.server) {
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('new-server-view-input')).replaceText(`${server}`);
|
||||
await element(by.id('new-server-view-input')).tapReturnKey();
|
||||
await waitFor(element(by.id('workspace-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('workspace-view'))).toBeVisible();
|
||||
}
|
||||
|
||||
async function navigateToLogin(server?: string) {
|
||||
await navigateToWorkspace(server);
|
||||
await element(by.id('workspace-view-login')).tap();
|
||||
await waitFor(element(by.id('login-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
|
||||
async function navigateToRegister(server?: string) {
|
||||
await navigateToWorkspace(server);
|
||||
await element(by.id('workspace-view-register')).tap();
|
||||
await waitFor(element(by.id('register-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
|
||||
async function login(username: string, password: string) {
|
||||
await waitFor(element(by.id('login-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('login-view-email')).replaceText(username);
|
||||
await element(by.id('login-view-password')).replaceText(password);
|
||||
await element(by.id('login-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
const deviceType = device.getPlatform();
|
||||
const { scrollViewType, textMatcher } = platformTypes[deviceType];
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-settings')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-settings')).tap();
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.type(scrollViewType)).atIndex(1).scrollTo('bottom');
|
||||
await element(by.id('settings-logout')).tap();
|
||||
const logoutAlertMessage = 'You will be logged out of this application.';
|
||||
await waitFor(element(by[textMatcher](logoutAlertMessage)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await expect(element(by[textMatcher](logoutAlertMessage)).atIndex(0)).toExist();
|
||||
await element(by[textMatcher]('Logout')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await expect(element(by.id('new-server-view'))).toBeVisible();
|
||||
}
|
||||
|
||||
async function mockMessage(message: string, isThread = false) {
|
||||
const deviceType = device.getPlatform();
|
||||
const { textMatcher } = platformTypes[deviceType];
|
||||
const input = isThread ? 'messagebox-input-thread' : 'messagebox-input';
|
||||
await element(by.id(input)).replaceText(`${data.random}${message}`);
|
||||
await sleep(300);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await waitFor(element(by[textMatcher](`${data.random}${message}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by[textMatcher](`${data.random}${message}`))
|
||||
.atIndex(0)
|
||||
.tap();
|
||||
}
|
||||
|
||||
async function starMessage(message: string) {
|
||||
const deviceType = device.getPlatform();
|
||||
const { textMatcher } = platformTypes[deviceType];
|
||||
const messageLabel = `${data.random}${message}`;
|
||||
await element(by[textMatcher](messageLabel)).atIndex(0).longPress();
|
||||
await expect(element(by.id('action-sheet'))).toExist();
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Star')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.not.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function pinMessage(message: string) {
|
||||
const deviceType = device.getPlatform();
|
||||
const { textMatcher } = platformTypes[deviceType];
|
||||
const messageLabel = `${data.random}${message}`;
|
||||
await waitFor(element(by[textMatcher](messageLabel)).atIndex(0)).toExist();
|
||||
await element(by[textMatcher](messageLabel)).atIndex(0).longPress();
|
||||
await expect(element(by.id('action-sheet'))).toExist();
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Pin')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.not.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function dismissReviewNag() {
|
||||
const deviceType = device.getPlatform();
|
||||
const { textMatcher } = platformTypes[deviceType];
|
||||
await waitFor(element(by[textMatcher]('Are you enjoying this app?')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by[textMatcher]('No')).atIndex(0).tap(); // Tap `no` on ask for review alert
|
||||
}
|
||||
|
||||
async function tapBack() {
|
||||
await element(by.id('header-back')).atIndex(0).tap();
|
||||
}
|
||||
|
||||
async function searchRoom(room: string) {
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(30000);
|
||||
await element(by.id('rooms-list-view-search')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view-search-input')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id('rooms-list-view-search-input'))).toExist();
|
||||
await sleep(300);
|
||||
await element(by.id('rooms-list-view-search-input')).typeText(room);
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
async function tryTapping(theElement: Detox.IndexableNativeElement, timeout: number, longtap = false) {
|
||||
try {
|
||||
if (longtap) {
|
||||
await theElement.longPress();
|
||||
} else {
|
||||
await theElement.tap();
|
||||
}
|
||||
} catch (e) {
|
||||
if (timeout <= 0) {
|
||||
// TODO: Maths. How closely has the timeout been honoured here?
|
||||
throw e;
|
||||
}
|
||||
await sleep(100);
|
||||
await tryTapping(theElement, timeout - 100);
|
||||
}
|
||||
}
|
||||
|
||||
const checkServer = async (server: string) => {
|
||||
const label = `Connected to ${server}`;
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.label(label)))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id('sidebar-close-drawer')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('sidebar-close-drawer')).tap();
|
||||
await waitFor(element(by.id('sidebar-close-drawer')))
|
||||
.not.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
};
|
||||
|
||||
function runCommand(command: string) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
exec(command, (error, _stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(new Error(`exec error: ${stderr}`));
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function prepareAndroid() {
|
||||
if (device.getPlatform() !== 'android') {
|
||||
return;
|
||||
}
|
||||
await runCommand('adb shell settings put secure spell_checker_enabled 0');
|
||||
await runCommand('adb shell settings put secure autofill_service null');
|
||||
await runCommand('adb shell settings put global window_animation_scale 0.0');
|
||||
await runCommand('adb shell settings put global transition_animation_scale 0.0');
|
||||
await runCommand('adb shell settings put global animator_duration_scale 0.0');
|
||||
}
|
||||
|
||||
export {
|
||||
navigateToWorkspace,
|
||||
navigateToLogin,
|
||||
navigateToRegister,
|
||||
login,
|
||||
logout,
|
||||
mockMessage,
|
||||
starMessage,
|
||||
pinMessage,
|
||||
dismissReviewNag,
|
||||
tapBack,
|
||||
sleep,
|
||||
searchRoom,
|
||||
tryTapping,
|
||||
checkServer,
|
||||
platformTypes,
|
||||
prepareAndroid
|
||||
};
|
|
@ -0,0 +1,193 @@
|
|||
import axios from 'axios';
|
||||
|
||||
import data, { TDataChannels, TDataGroups, TDataTeams, TDataUsers, TUserRegularChannels } from '../data';
|
||||
import random from './random';
|
||||
|
||||
const TEAM_TYPE = {
|
||||
PUBLIC: 0,
|
||||
PRIVATE: 1
|
||||
};
|
||||
|
||||
const { server } = data;
|
||||
|
||||
const rocketchat = axios.create({
|
||||
baseURL: `${server}/api/v1/`,
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
}
|
||||
});
|
||||
|
||||
const login = async (username: string, password: string) => {
|
||||
console.log(`Logging in as user ${username}`);
|
||||
const response = await rocketchat.post('login', {
|
||||
user: username,
|
||||
password
|
||||
});
|
||||
const { userId } = response.data.data;
|
||||
const { authToken } = response.data.data;
|
||||
rocketchat.defaults.headers.common['X-User-Id'] = userId;
|
||||
rocketchat.defaults.headers.common['X-Auth-Token'] = authToken;
|
||||
return { authToken, userId };
|
||||
};
|
||||
|
||||
const createUser = async (username: string, password: string, name: string, email: string) => {
|
||||
console.log(`Creating user ${username}`);
|
||||
try {
|
||||
await rocketchat.post('users.create', {
|
||||
username,
|
||||
password,
|
||||
name,
|
||||
email
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(JSON.stringify(error));
|
||||
throw new Error('Failed to create user');
|
||||
}
|
||||
};
|
||||
|
||||
const createChannelIfNotExists = async (channelname: string) => {
|
||||
console.log(`Creating public channel ${channelname}`);
|
||||
try {
|
||||
const room = await rocketchat.post('channels.create', {
|
||||
name: channelname
|
||||
});
|
||||
return room;
|
||||
} catch (createError) {
|
||||
try {
|
||||
// Maybe it exists already?
|
||||
const room = rocketchat.get(`channels.info?roomName=${channelname}`);
|
||||
return room;
|
||||
} catch (infoError) {
|
||||
console.log(JSON.stringify(createError));
|
||||
console.log(JSON.stringify(infoError));
|
||||
throw new Error('Failed to find or create public channel');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const createTeamIfNotExists = async (teamname: string) => {
|
||||
console.log(`Creating private team ${teamname}`);
|
||||
try {
|
||||
await rocketchat.post('teams.create', {
|
||||
name: teamname,
|
||||
type: TEAM_TYPE.PRIVATE
|
||||
});
|
||||
} catch (createError) {
|
||||
try {
|
||||
// Maybe it exists already?
|
||||
await rocketchat.get(`teams.info?teamName=${teamname}`);
|
||||
} catch (infoError) {
|
||||
console.log(JSON.stringify(createError));
|
||||
console.log(JSON.stringify(infoError));
|
||||
throw new Error('Failed to find or create private team');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const createGroupIfNotExists = async (groupname: string) => {
|
||||
console.log(`Creating private group ${groupname}`);
|
||||
try {
|
||||
await rocketchat.post('groups.create', {
|
||||
name: groupname
|
||||
});
|
||||
} catch (createError) {
|
||||
try {
|
||||
// Maybe it exists already?
|
||||
await rocketchat.get(`groups.info?roomName=${groupname}`);
|
||||
} catch (infoError) {
|
||||
console.log(JSON.stringify(createError));
|
||||
console.log(JSON.stringify(infoError));
|
||||
throw new Error('Failed to find or create private group');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const changeChannelJoinCode = async (roomId: string, joinCode: string) => {
|
||||
console.log(`Changing channel Join Code ${roomId}`);
|
||||
try {
|
||||
await rocketchat.post('method.call/saveRoomSettings', {
|
||||
message: JSON.stringify({
|
||||
msg: 'method',
|
||||
id: random(10),
|
||||
method: 'saveRoomSettings',
|
||||
params: [roomId, { joinCode }]
|
||||
})
|
||||
});
|
||||
} catch (createError) {
|
||||
console.log(JSON.stringify(createError));
|
||||
throw new Error('Failed to create protected channel');
|
||||
}
|
||||
};
|
||||
|
||||
const sendMessage = async (user: { username: string; password: string }, channel: string, msg: string, tmid?: string) => {
|
||||
console.log(`Sending message to ${channel}`);
|
||||
try {
|
||||
await login(user.username, user.password);
|
||||
const response = await rocketchat.post('chat.postMessage', { channel, msg, tmid });
|
||||
return response.data;
|
||||
} catch (infoError) {
|
||||
console.log(JSON.stringify(infoError));
|
||||
throw new Error('Failed to find or create private group');
|
||||
}
|
||||
};
|
||||
|
||||
const setup = async () => {
|
||||
await login(data.adminUser, data.adminPassword);
|
||||
|
||||
for (const userKey in data.users) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.users, userKey)) {
|
||||
const user = data.users[userKey as TDataUsers];
|
||||
await createUser(user.username, user.password, user.username, user.email);
|
||||
}
|
||||
}
|
||||
|
||||
for (const channelKey in data.channels) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.channels, channelKey)) {
|
||||
const channel = data.channels[channelKey as TDataChannels];
|
||||
const {
|
||||
data: {
|
||||
channel: { _id }
|
||||
}
|
||||
} = await createChannelIfNotExists(channel.name);
|
||||
|
||||
if ('joinCode' in channel) {
|
||||
await changeChannelJoinCode(_id, channel.joinCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
|
||||
for (const channelKey in data.userRegularChannels) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.userRegularChannels, channelKey)) {
|
||||
const channel = data.userRegularChannels[channelKey as TUserRegularChannels];
|
||||
await createChannelIfNotExists(channel.name);
|
||||
}
|
||||
}
|
||||
|
||||
for (const groupKey in data.groups) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.groups, groupKey)) {
|
||||
const group = data.groups[groupKey as TDataGroups];
|
||||
await createGroupIfNotExists(group.name);
|
||||
}
|
||||
}
|
||||
|
||||
for (const teamKey in data.teams) {
|
||||
if (Object.prototype.hasOwnProperty.call(data.teams, teamKey)) {
|
||||
const team = data.teams[teamKey as TDataTeams];
|
||||
await createTeamIfNotExists(team.name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const get = (endpoint: string) => {
|
||||
console.log(`GET /${endpoint}`);
|
||||
return rocketchat.get(endpoint);
|
||||
};
|
||||
|
||||
const post = (endpoint: string, body: any) => {
|
||||
console.log(`POST /${endpoint} ${JSON.stringify(body)}`);
|
||||
return rocketchat.post(endpoint, body);
|
||||
};
|
||||
|
||||
export { setup, sendMessage, get, post, login };
|
|
@ -0,0 +1,10 @@
|
|||
function random(length: number) {
|
||||
let text = '';
|
||||
const possible = 'abcdefghijklmnopqrstuvwxyz';
|
||||
for (let i = 0; i < length; i += 1) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
export default random;
|
|
@ -1,7 +1,8 @@
|
|||
/** @type {import('@jest/types').Config.InitialOptions} */
|
||||
module.exports = {
|
||||
rootDir: '..',
|
||||
testMatch: ['<rootDir>/e2e/**/*.test.js'],
|
||||
setupFilesAfterEnv: ['<rootDir>/e2e/tests/init.ts'],
|
||||
testMatch: ['<rootDir>/e2e/tests/**/*.spec.ts'],
|
||||
testTimeout: 120000,
|
||||
maxWorkers: 1,
|
||||
globalSetup: 'detox/runners/jest/globalSetup',
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
describe('Example', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp();
|
||||
});
|
||||
|
||||
// beforeEach(async () => {
|
||||
// await device.reloadReactNative();
|
||||
// });
|
||||
|
||||
it('should have welcome screen', async () => {
|
||||
await expect(element(by.id('welcome'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have onboarding screen', async () => {
|
||||
await expect(element(by.id('new-server-view'))).toBeVisible();
|
||||
});
|
||||
// it('should show hello screen after tap', async () => {
|
||||
// await element(by.id('hello_button')).tap();
|
||||
// await expect(element(by.text('Hello!!!'))).toBeVisible();
|
||||
// });
|
||||
|
||||
// it('should show world screen after tap', async () => {
|
||||
// await element(by.id('world_button')).tap();
|
||||
// await expect(element(by.text('World!!!'))).toBeVisible();
|
||||
// });
|
||||
});
|
|
@ -0,0 +1,401 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import {
|
||||
navigateToLogin,
|
||||
login,
|
||||
sleep,
|
||||
tapBack,
|
||||
mockMessage,
|
||||
searchRoom,
|
||||
logout,
|
||||
platformTypes,
|
||||
TTextMatcher
|
||||
} from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
const otheruser = data.users.alternate;
|
||||
|
||||
const checkServer = async (server: string) => {
|
||||
const label = `Connected to ${server}`;
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.label(label)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('sidebar-close-drawer')).tap();
|
||||
};
|
||||
|
||||
const checkBanner = async () => {
|
||||
// TODO: Assert 'Save Your Encryption Password'
|
||||
await waitFor(element(by.id('listheader-encryption')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
};
|
||||
|
||||
async function navigateToRoom(roomName: string) {
|
||||
await searchRoom(`${roomName}`);
|
||||
await element(by.id(`rooms-list-view-item-${roomName}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function waitForToast() {
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
async function navigateSecurityPrivacy() {
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-settings')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-settings')).tap();
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('settings-view-security-privacy')).tap();
|
||||
await waitFor(element(by.id('security-privacy-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
|
||||
describe('E2E Encryption', () => {
|
||||
const room = `encrypted${data.random}`;
|
||||
const newPassword = 'abc';
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
});
|
||||
|
||||
describe('Banner', () => {
|
||||
describe('Render', () => {
|
||||
it('should have encryption badge', async () => {
|
||||
await checkBanner();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should tap encryption badge and open save password modal', async () => {
|
||||
await element(by.id('listheader-encryption')).tap();
|
||||
await waitFor(element(by.id('e2e-save-password-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should tap "How it works" and navigate', async () => {
|
||||
await element(by.id('e2e-save-password-view-how-it-works').and(by.label('How It Works'))).tap();
|
||||
await waitFor(element(by.id('e2e-how-it-works-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should tap "Save my password" and close modal', async () => {
|
||||
await element(by.id('e2e-save-password-view-saved-password').and(by.label('I Saved My E2E Password'))).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should create encrypted room', async () => {
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('new-message-view-create-channel')).tap();
|
||||
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}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
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(room);
|
||||
await element(by.id('create-channel-encrypted')).longPress();
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await waitFor(element(by.id(`room-view-title-${room}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should send message and be able to read it', async () => {
|
||||
await mockMessage('message');
|
||||
await tapBack();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Security and Privacy', () => {
|
||||
it('should navigate to security privacy', async () => {
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-settings')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-settings')).tap();
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('settings-view-security-privacy')).tap();
|
||||
await waitFor(element(by.id('security-privacy-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('render', async () => {
|
||||
await expect(element(by.id('security-privacy-view-e2e-encryption'))).toExist();
|
||||
await expect(element(by.id('security-privacy-view-screen-lock'))).toExist();
|
||||
await expect(element(by.id('security-privacy-view-analytics-events'))).toExist();
|
||||
await expect(element(by.id('security-privacy-view-crash-report'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('E2E Encryption Security', () => {
|
||||
it('should navigate to e2e encryption security', async () => {
|
||||
await element(by.id('security-privacy-view-e2e-encryption')).tap();
|
||||
await waitFor(element(by.id('e2e-encryption-security-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have items', async () => {
|
||||
await waitFor(element(by.id('e2e-encryption-security-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('e2e-encryption-security-view-password'))).toExist();
|
||||
await expect(element(by.id('e2e-encryption-security-view-change-password').and(by.label('Save Changes')))).toExist();
|
||||
await expect(element(by.id('e2e-encryption-security-view-reset-key').and(by.label('Reset E2E Key')))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
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-change-password')).tap();
|
||||
await waitFor(element(by[textMatcher]('Are you sure?')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by[textMatcher]("Make sure you've saved it carefully somewhere else."))).toExist();
|
||||
await element(by[textMatcher]('Yes, change it')).atIndex(0).tap();
|
||||
await waitForToast();
|
||||
});
|
||||
|
||||
it('should navigate to the room and messages should remain decrypted', async () => {
|
||||
await waitFor(element(by.id('e2e-encryption-security-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('security-privacy-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('settings-view-drawer')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-chats')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await navigateToRoom(room);
|
||||
await waitFor(element(by[textMatcher](`${data.random}message`)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should logout, login and messages should be encrypted', async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await logout();
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
await navigateToRoom(room);
|
||||
await waitFor(element(by[textMatcher](`${data.random}message`)).atIndex(0))
|
||||
.not.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.label('Encrypted message')).atIndex(0)).toExist();
|
||||
});
|
||||
|
||||
it('should enter new e2e password and messages should be decrypted', async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
// TODO: assert 'Enter Your E2E Password'
|
||||
await waitFor(element(by.id('listheader-encryption')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('listheader-encryption')).tap();
|
||||
await waitFor(element(by.id('e2e-enter-your-password-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('e2e-enter-your-password-view-password')).typeText(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))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Reset E2E key', () => {
|
||||
beforeAll(async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
it('should reset e2e key', async () => {
|
||||
// FIXME: too flaky on Android for now... let's fix it later
|
||||
// It's also flaky on iOS, but it works from time to time
|
||||
if (device.getPlatform() === 'android') {
|
||||
return;
|
||||
}
|
||||
await navigateSecurityPrivacy();
|
||||
await element(by.id('security-privacy-view-e2e-encryption')).tap();
|
||||
await waitFor(element(by.id('e2e-encryption-security-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('e2e-encryption-security-view-reset-key').and(by.label('Reset E2E Key'))).tap();
|
||||
await waitFor(element(by[textMatcher]('Are you sure?')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by[textMatcher]("You're going to be logged out."))).toExist();
|
||||
await element(by[textMatcher]('Yes, reset it').and(by.type(alertButtonType))).tap();
|
||||
await sleep(2000);
|
||||
|
||||
// FIXME: The app isn't showing this alert anymore
|
||||
// await waitFor(element(by[textMatcher]("You've been logged out by the server. Please log in again.")))
|
||||
// .toExist()
|
||||
// .withTimeout(20000);
|
||||
// await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
// await waitFor(element(by.id('workspace-view')))
|
||||
// .toBeVisible()
|
||||
// .withTimeout(10000);
|
||||
// await element(by.id('workspace-view-login')).tap();
|
||||
await navigateToLogin();
|
||||
await waitFor(element(by.id('login-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await login(testuser.username, testuser.password);
|
||||
// TODO: assert 'Save Your Encryption Password'
|
||||
await waitFor(element(by.id('listheader-encryption')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Persist Banner', () => {
|
||||
beforeAll(async () => {
|
||||
// reinstall the app because of one flaky test above
|
||||
if (device.getPlatform() === 'android') {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
}
|
||||
});
|
||||
it('check save banner', async () => {
|
||||
await checkServer(data.server);
|
||||
await checkBanner();
|
||||
});
|
||||
|
||||
it('should add server and create new user', async () => {
|
||||
await sleep(5000);
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('rooms-list-header-server-add')).tap();
|
||||
|
||||
// TODO: refactor
|
||||
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')).tapReturnKey();
|
||||
await waitFor(element(by.id('workspace-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('workspace-view-register')).tap();
|
||||
await waitFor(element(by.id('register-view')))
|
||||
.toBeVisible()
|
||||
.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);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
|
||||
await checkServer(data.alternateServer);
|
||||
});
|
||||
|
||||
it('should change back', async () => {
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`rooms-list-header-server-${data.server}`)).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await checkServer(data.server);
|
||||
await checkBanner();
|
||||
});
|
||||
|
||||
it('should reopen the app and have banner', async () => {
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: true
|
||||
});
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await checkBanner();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,141 @@
|
|||
// const OTP = require('otp.js');
|
||||
// const GA = OTP.googleAuthenticator;
|
||||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToLogin, login, mockMessage, tapBack, searchRoom, platformTypes, TTextMatcher, sleep } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
const otheruser = data.users.alternate;
|
||||
|
||||
describe('Broadcast room', () => {
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
});
|
||||
|
||||
it('should create broadcast room', async () => {
|
||||
await waitFor(element(by.id('rooms-list-view-create-channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('new-message-view-create-channel')).tap();
|
||||
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}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
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-broadcast')).longPress(); // https://github.com/facebook/react-native/issues/28032
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await waitFor(element(by.id(`room-view-title-broadcast${data.random}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await sleep(500);
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-actions-info')).tap();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.label('Broadcast').withAncestor(by.id('room-info-view-broadcast')))).toBeVisible();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should send message', async () => {
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await mockMessage('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 waitFor(element(by.id('two-factor'))).toBeVisible().withTimeout(5000);
|
||||
// await expect(element(by.id('two-factor'))).toBeVisible();
|
||||
// const code = GA.gen(data.alternateUserTOTPSecret);
|
||||
// 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 waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`room-view-title-broadcast${data.random}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should not have messagebox', async () => {
|
||||
await expect(element(by.id('messagebox'))).toBeNotVisible();
|
||||
});
|
||||
|
||||
it('should be read only', async () => {
|
||||
await expect(element(by.label('This room is read only'))).toExist();
|
||||
});
|
||||
|
||||
it('should have the message created earlier', async () => {
|
||||
await waitFor(element(by[textMatcher](`${data.random}message`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should have reply button', async () => {
|
||||
await expect(element(by.id('message-broadcast-reply'))).toBeVisible();
|
||||
});
|
||||
|
||||
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}`)))
|
||||
.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 sleep(300);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await waitFor(element(by[textMatcher](`${data.random}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);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,130 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToLogin, login, sleep, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
const profileChangeUser = data.users.profileChanges;
|
||||
|
||||
const scrollDown = 200;
|
||||
|
||||
async function waitForToast() {
|
||||
// await waitFor(element(by.id('toast'))).toBeVisible().withTimeout(1000);
|
||||
// await expect(element(by.id('toast'))).toBeVisible();
|
||||
// await waitFor(element(by.id('toast'))).not.toBeNotVisible().withTimeout(1000);
|
||||
// await expect(element(by.id('toast'))).not.toBeVisible();
|
||||
await sleep(600);
|
||||
}
|
||||
|
||||
describe('Profile screen', () => {
|
||||
let scrollViewType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ scrollViewType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(profileChangeUser.username, profileChangeUser.password);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-profile')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-profile')).tap();
|
||||
await waitFor(element(by.id('profile-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have profile view', async () => {
|
||||
await expect(element(by.id('profile-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have avatar', async () => {
|
||||
await expect(element(by.id('profile-view-avatar')).atIndex(0)).toExist();
|
||||
});
|
||||
|
||||
it('should have name', async () => {
|
||||
await expect(element(by.id('profile-view-name'))).toExist();
|
||||
});
|
||||
|
||||
it('should have username', async () => {
|
||||
await expect(element(by.id('profile-view-username'))).toExist();
|
||||
});
|
||||
|
||||
it('should have email', async () => {
|
||||
await expect(element(by.id('profile-view-email'))).toExist();
|
||||
});
|
||||
|
||||
it('should have new password', async () => {
|
||||
await expect(element(by.id('profile-view-new-password'))).toExist();
|
||||
});
|
||||
|
||||
it('should have avatar url', async () => {
|
||||
await expect(element(by.id('profile-view-avatar-url'))).toExist();
|
||||
});
|
||||
|
||||
it('should have reset avatar button', async () => {
|
||||
await waitFor(element(by.id('profile-view-reset-avatar')))
|
||||
.toExist()
|
||||
.whileElement(by.id('profile-view-list'))
|
||||
.scroll(scrollDown, 'down');
|
||||
});
|
||||
|
||||
it('should have upload avatar button', async () => {
|
||||
await waitFor(element(by.id('profile-view-upload-avatar')))
|
||||
.toExist()
|
||||
.whileElement(by.id('profile-view-list'))
|
||||
.scroll(scrollDown, 'down');
|
||||
});
|
||||
|
||||
it('should have avatar url button', async () => {
|
||||
await waitFor(element(by.id('profile-view-avatar-url-button')))
|
||||
.toExist()
|
||||
.whileElement(by.id('profile-view-list'))
|
||||
.scroll(scrollDown, 'down');
|
||||
});
|
||||
|
||||
it('should have submit button', async () => {
|
||||
await waitFor(element(by.id('profile-view-submit')))
|
||||
.toExist()
|
||||
.whileElement(by.id('profile-view-list'))
|
||||
.scroll(scrollDown, 'down');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should change name and username', async () => {
|
||||
await element(by.id('profile-view-name')).replaceText(`${profileChangeUser.username}new`);
|
||||
await element(by.id('profile-view-username')).replaceText(`${profileChangeUser.username}new`);
|
||||
await element(by.type(scrollViewType)).atIndex(1).swipe('up');
|
||||
await element(by.id('profile-view-submit')).tap();
|
||||
await waitForToast();
|
||||
});
|
||||
|
||||
it('should change email and password', async () => {
|
||||
await element(by.id('profile-view-email')).replaceText(`mobile+profileChangesNew${data.random}@rocket.chat`);
|
||||
await element(by.id('profile-view-new-password')).replaceText(`${profileChangeUser.password}new`);
|
||||
await waitFor(element(by.id('profile-view-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('profile-view-submit')).tap();
|
||||
await waitFor(element(by.id('profile-view-enter-password-sheet')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('profile-view-enter-password-sheet')).replaceText(`${profileChangeUser.password}`);
|
||||
await element(by[textMatcher]('Save').withAncestor(by.id('action-sheet-content-with-input-and-submit')))
|
||||
.atIndex(0)
|
||||
.tap();
|
||||
await waitForToast();
|
||||
});
|
||||
|
||||
it('should reset avatar', async () => {
|
||||
await element(by.type(scrollViewType)).atIndex(1).swipe('up');
|
||||
await element(by.id('profile-view-reset-avatar')).tap();
|
||||
await waitForToast();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,92 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToLogin, login, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
|
||||
describe('Settings screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-settings')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-settings')).tap();
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have settings view', async () => {
|
||||
await expect(element(by.id('settings-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have language', async () => {
|
||||
await expect(element(by.id('settings-view-language'))).toExist();
|
||||
});
|
||||
|
||||
it('should have review app', async () => {
|
||||
await expect(element(by.id('settings-view-review-app'))).toExist();
|
||||
});
|
||||
|
||||
it('should have share app', async () => {
|
||||
await expect(element(by.id('settings-view-share-app'))).toExist();
|
||||
});
|
||||
|
||||
it('should have default browser', async () => {
|
||||
await expect(element(by.id('settings-view-default-browser'))).toExist();
|
||||
});
|
||||
|
||||
it('should have theme', async () => {
|
||||
await expect(element(by.id('settings-view-theme'))).toExist();
|
||||
});
|
||||
|
||||
it('should have security and privacy', async () => {
|
||||
await expect(element(by.id('settings-view-security-privacy'))).toExist();
|
||||
});
|
||||
|
||||
it('should have licence', async () => {
|
||||
await expect(element(by.id('settings-view-license'))).toExist();
|
||||
});
|
||||
|
||||
it('should have version no', async () => {
|
||||
await expect(element(by.id('settings-view-version'))).toExist();
|
||||
});
|
||||
|
||||
it('should have server version', async () => {
|
||||
await expect(element(by.id('settings-view-server-version'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should tap clear cache and navigate to roomslistview', async () => {
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('settings-view-clear-cache')).tap();
|
||||
await waitFor(element(by[textMatcher]('This will clear all your offline data.')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Clear').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,170 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, mockMessage, tapBack, searchRoom, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
const room = data.channels.detoxpublic.name;
|
||||
|
||||
async function navigateToRoom() {
|
||||
await searchRoom(room);
|
||||
await element(by.id(`rooms-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id('room-view')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function navigateToRoomActions() {
|
||||
await element(by.id(`room-view-title-${room}`)).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
describe('Join public room', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
await navigateToRoom();
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have room screen', async () => {
|
||||
await expect(element(by.id('room-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
// Render - Header
|
||||
describe('Header', () => {
|
||||
it('should have actions button ', async () => {
|
||||
await expect(element(by.id('room-header'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
// Render - Join
|
||||
describe('Join', () => {
|
||||
it('should have join', async () => {
|
||||
await expect(element(by.id('room-view-join'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have join text', async () => {
|
||||
await expect(element(by.label('You are in preview mode'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have join button', async () => {
|
||||
await expect(element(by.id('room-view-join-button'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should not have messagebox', async () => {
|
||||
await expect(element(by.id('messagebox'))).toBeNotVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Room Actions', () => {
|
||||
beforeAll(async () => {
|
||||
await navigateToRoomActions();
|
||||
});
|
||||
|
||||
it('should have room actions screen', async () => {
|
||||
await expect(element(by.id('room-actions-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have info', async () => {
|
||||
await expect(element(by.id('room-actions-info'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have members', async () => {
|
||||
await waitFor(element(by.id('room-actions-members')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should have files', async () => {
|
||||
await expect(element(by.id('room-actions-files'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have mentions', async () => {
|
||||
await expect(element(by.id('room-actions-mentioned'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have starred', async () => {
|
||||
await expect(element(by.id('room-actions-starred'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have share', async () => {
|
||||
await expect(element(by.id('room-actions-share'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have pinned', async () => {
|
||||
await expect(element(by.id('room-actions-pinned'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should not have notifications', async () => {
|
||||
await expect(element(by.id('room-actions-notifications'))).toBeNotVisible();
|
||||
});
|
||||
|
||||
it('should not have leave channel', async () => {
|
||||
await expect(element(by.id('room-actions-leave-channel'))).toBeNotVisible();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should join room', async () => {
|
||||
await element(by.id('room-view-join-button')).tap();
|
||||
await tapBack();
|
||||
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('messagebox')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('messagebox'))).toBeVisible();
|
||||
await expect(element(by.id('room-view-join'))).toBeNotVisible();
|
||||
});
|
||||
|
||||
it('should send message', async () => {
|
||||
await mockMessage('message');
|
||||
});
|
||||
|
||||
it('should have notifications and leave channel', async () => {
|
||||
await navigateToRoomActions();
|
||||
await expect(element(by.id('room-actions-view'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-info'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-members'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-files'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-mentioned'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-starred'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-share'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-pinned'))).toBeVisible();
|
||||
await expect(element(by.id('room-actions-notifications'))).toBeVisible();
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await expect(element(by.id('room-actions-leave-channel'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should leave room', async () => {
|
||||
await element(by.id('room-actions-leave-channel')).tap();
|
||||
await waitFor(element(by[textMatcher]('Yes, leave it!').and(by.type(alertButtonType))))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Yes, leave it!').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000); // flaky on Android
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,65 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToLogin, login, sleep } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
|
||||
describe('Status screen', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-custom-status-online')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
|
||||
await element(by.id('sidebar-custom-status-online')).tap();
|
||||
await waitFor(element(by.id('status-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have status input', async () => {
|
||||
await expect(element(by.id('status-view-input'))).toBeVisible();
|
||||
await expect(element(by.id('status-view-online'))).toExist();
|
||||
await expect(element(by.id('status-view-busy'))).toExist();
|
||||
await expect(element(by.id('status-view-away'))).toExist();
|
||||
await expect(element(by.id('status-view-offline'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should change status', async () => {
|
||||
await element(by.id('status-view-busy')).tap();
|
||||
await element(by.id('status-view-submit')).tap();
|
||||
await sleep(3000); // Wait until the loading hide
|
||||
await waitFor(element(by.id('rooms-list-view-sidebar')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-custom-status-busy')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-custom-status-busy')).tap();
|
||||
});
|
||||
|
||||
// TODO: flaky
|
||||
it('should change status text', async () => {
|
||||
await element(by.id('status-view-input')).replaceText('status-text-new');
|
||||
await element(by.id('status-view-submit')).tap();
|
||||
await sleep(3000); // Wait until the loading hide
|
||||
await waitFor(element(by.label('status-text-new')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,101 @@
|
|||
import data from '../../data';
|
||||
import { navigateToLogin, login, checkServer, sleep } from '../../helpers/app';
|
||||
|
||||
const reopenAndCheckServer = async (server: string) => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true });
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await checkServer(server);
|
||||
};
|
||||
|
||||
describe('Change server', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
it('should open the dropdown button, have the server add button and create workspace button', async () => {
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('rooms-list-header-server-add')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('rooms-list-header-create-workspace-button')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should login to server, add new server, close the app, open the app and show previous logged server', async () => {
|
||||
await element(by.id('rooms-list-header-server-add')).tap();
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(6000);
|
||||
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()
|
||||
.withTimeout(10000);
|
||||
await reopenAndCheckServer(data.server);
|
||||
});
|
||||
|
||||
it('should add server and create new user', async () => {
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`rooms-list-header-server-${data.alternateServer}`)).tap();
|
||||
await waitFor(element(by.id('workspace-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('workspace-view-register')).tap();
|
||||
await waitFor(element(by.id('register-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
|
||||
// Register new user
|
||||
await sleep(5000);
|
||||
await element(by.id('register-view-name')).replaceText(data.registeringUser2.username);
|
||||
await element(by.id('register-view-username')).replaceText(data.registeringUser2.username);
|
||||
await element(by.id('register-view-email')).replaceText(data.registeringUser2.email);
|
||||
await element(by.id('register-view-password')).replaceText(data.registeringUser2.password);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${data.groups.private.name}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
await checkServer(data.alternateServer);
|
||||
});
|
||||
|
||||
it('should reopen the app and show alternate server', async () => {
|
||||
await reopenAndCheckServer(data.alternateServer);
|
||||
});
|
||||
|
||||
it('should change back to main server', async () => {
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`rooms-list-header-server-${data.server}`)).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${data.groups.private.name}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await checkServer(data.server);
|
||||
});
|
||||
|
||||
it('should reopen the app and show main server', async () => {
|
||||
await reopenAndCheckServer(data.server);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,73 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, mockMessage, searchRoom } from '../../helpers/app';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
const room = data.channels.detoxpublicprotected.name;
|
||||
const { joinCode } = data.channels.detoxpublicprotected;
|
||||
|
||||
async function navigateToRoom() {
|
||||
await searchRoom(room);
|
||||
await element(by.id(`rooms-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function openJoinCode() {
|
||||
await waitFor(element(by.id('room-view-join-button')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
let n = 0;
|
||||
while (n < 3) {
|
||||
try {
|
||||
await element(by.id('room-view-join-button')).tap();
|
||||
await waitFor(element(by.id('join-code')))
|
||||
.toBeVisible()
|
||||
.withTimeout(500);
|
||||
} catch (error) {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe('Join protected room', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
await navigateToRoom();
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should tap join and ask for join code', async () => {
|
||||
await openJoinCode();
|
||||
});
|
||||
|
||||
it('should cancel join room', async () => {
|
||||
await element(by.id('join-code-cancel')).tap();
|
||||
await waitFor(element(by.id('join-code')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should join room', async () => {
|
||||
await openJoinCode();
|
||||
await element(by.id('join-code-input')).replaceText(joinCode);
|
||||
await element(by.id('join-code-submit')).tap();
|
||||
await waitFor(element(by.id('join-code')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('messagebox')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('messagebox'))).toBeVisible();
|
||||
await expect(element(by.id('room-view-join'))).toBeNotVisible();
|
||||
});
|
||||
|
||||
it('should send message', async () => {
|
||||
await mockMessage('message');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,86 @@
|
|||
import data from '../../data';
|
||||
import { navigateToLogin, login, tapBack, sleep } from '../../helpers/app';
|
||||
import { sendMessage } from '../../helpers/data_setup';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
|
||||
async function navigateToRoom(search: string) {
|
||||
await element(by.id('directory-view-search')).replaceText(search);
|
||||
await waitFor(element(by.id(`directory-view-item-${search}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await sleep(300); // app takes some time to animate
|
||||
await element(by.id(`directory-view-item-${search}`)).tap();
|
||||
await waitFor(element(by.id('room-view')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`room-view-title-${search}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
describe('Join room from directory', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
const threadMessage = `thread-${data.random}`;
|
||||
beforeAll(async () => {
|
||||
const result = await sendMessage(data.users.alternate, data.channels.detoxpublic.name, threadMessage);
|
||||
const threadId = result.message._id;
|
||||
await sendMessage(data.users.alternate, result.message.rid, data.random, threadId);
|
||||
});
|
||||
|
||||
it('should tap directory', async () => {
|
||||
await element(by.id('rooms-list-view-directory')).tap();
|
||||
await waitFor(element(by.id('directory-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should search public channel and navigate', async () => {
|
||||
await navigateToRoom(data.channels.detoxpublic.name);
|
||||
});
|
||||
|
||||
it('should navigate to thread messages view and load messages', async () => {
|
||||
await waitFor(element(by.id('room-view-header-threads')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-view-header-threads')).tap();
|
||||
await waitFor(element(by.id(`thread-messages-view-${threadMessage}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-view-header-threads')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should search user and navigate', async () => {
|
||||
await tapBack();
|
||||
await element(by.id('rooms-list-view-directory')).tap();
|
||||
await waitFor(element(by.id('directory-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('directory-view-dropdown')).tap();
|
||||
await element(by.label('Users')).atIndex(0).tap();
|
||||
await element(by.label('Search by')).atIndex(0).tap();
|
||||
await navigateToRoom(data.users.alternate.username);
|
||||
});
|
||||
|
||||
it('should search team and navigate', async () => {
|
||||
await tapBack();
|
||||
await element(by.id('rooms-list-view-directory')).tap();
|
||||
await waitFor(element(by.id('directory-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('directory-view-dropdown')).tap();
|
||||
await element(by.label('Teams')).atIndex(0).tap();
|
||||
await element(by.label('Search by')).atIndex(0).tap();
|
||||
await navigateToRoom(data.teams.private.name);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,67 @@
|
|||
import data from '../../data';
|
||||
import { sleep, navigateToLogin, login, checkServer, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
describe('Delete server', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
it('should be logged in main server', async () => {
|
||||
await checkServer(data.server);
|
||||
});
|
||||
|
||||
it('should add server', async () => {
|
||||
await sleep(5000);
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('rooms-list-header-server-add')).tap();
|
||||
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
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()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('workspace-view-register')).tap();
|
||||
await waitFor(element(by.id('register-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
|
||||
// Register new user
|
||||
await element(by.id('register-view-name')).replaceText(data.registeringUser3.username);
|
||||
await element(by.id('register-view-username')).replaceText(data.registeringUser3.username);
|
||||
await element(by.id('register-view-email')).replaceText(data.registeringUser3.email);
|
||||
await element(by.id('register-view-password')).replaceText(data.registeringUser3.password);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
|
||||
await checkServer(data.alternateServer);
|
||||
});
|
||||
|
||||
it('should delete server', async () => {
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`rooms-list-header-server-${data.server}`)).longPress(1500);
|
||||
await element(by[textMatcher]('Delete').and(by.type(alertButtonType))).tap();
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`rooms-list-header-server-${data.server}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,218 @@
|
|||
import EJSON from 'ejson';
|
||||
|
||||
import data from '../../data';
|
||||
import { tapBack, checkServer, navigateToRegister, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
import { get, login, sendMessage } from '../../helpers/data_setup';
|
||||
|
||||
const DEEPLINK_METHODS = { AUTH: 'auth', ROOM: 'room' };
|
||||
|
||||
let amp = '&';
|
||||
|
||||
const getDeepLink = (method: string, server: string, params?: string) => {
|
||||
const deeplink = `rocketchat://${method}?host=${server.replace(/^(http:\/\/|https:\/\/)/, '')}${amp}${params}`;
|
||||
console.log(`Deeplinking to: ${deeplink}`);
|
||||
return deeplink;
|
||||
};
|
||||
|
||||
describe('Deep linking', () => {
|
||||
let userId: string;
|
||||
let authToken: string;
|
||||
let scrollViewType: string;
|
||||
let threadId: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
const threadMessage = `to-thread-${data.random}`;
|
||||
beforeAll(async () => {
|
||||
const loginResult = await login(data.users.regular.username, data.users.regular.password);
|
||||
({ userId, authToken } = loginResult);
|
||||
const deviceType = device.getPlatform();
|
||||
amp = deviceType === 'android' ? '\\&' : '&';
|
||||
({ scrollViewType, textMatcher } = platformTypes[deviceType]);
|
||||
// create a thread with api
|
||||
const result = await sendMessage(data.users.regular, data.groups.alternate2.name, threadMessage);
|
||||
threadId = result.message._id;
|
||||
await sendMessage(data.users.regular, result.message.rid, data.random, threadId);
|
||||
});
|
||||
|
||||
describe('Authentication', () => {
|
||||
it('should run a deep link to an invalid account and raise error', async () => {
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
delete: true,
|
||||
url: getDeepLink(DEEPLINK_METHODS.AUTH, data.server, `userId=123${amp}token=abc`)
|
||||
});
|
||||
await waitFor(element(by[textMatcher]("You've been logged out by the server. Please log in again.")))
|
||||
.toExist()
|
||||
.withTimeout(30000); // TODO: we need to improve this message
|
||||
});
|
||||
|
||||
const authAndNavigate = async () => {
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: true,
|
||||
url: getDeepLink(
|
||||
DEEPLINK_METHODS.AUTH,
|
||||
data.server,
|
||||
`userId=${userId}${amp}token=${authToken}${amp}path=group/${data.groups.private.name}`
|
||||
)
|
||||
});
|
||||
await waitFor(element(by.id(`room-view-title-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await checkServer(data.server);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
};
|
||||
|
||||
it('should authenticate and navigate', async () => {
|
||||
await authAndNavigate();
|
||||
});
|
||||
|
||||
it('should authenticate while logged in another server', async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToRegister(data.alternateServer);
|
||||
await element(by.id('register-view-name')).replaceText(data.registeringUser4.username);
|
||||
await element(by.id('register-view-username')).replaceText(data.registeringUser4.username);
|
||||
await element(by.id('register-view-email')).replaceText(data.registeringUser4.email);
|
||||
await element(by.id('register-view-password')).replaceText(data.registeringUser4.password);
|
||||
await element(by.type(scrollViewType)).atIndex(0).scrollTo('bottom');
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await authAndNavigate();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Room', () => {
|
||||
describe('While logged in', () => {
|
||||
it('should navigate to the room using path', async () => {
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: true,
|
||||
url: getDeepLink(DEEPLINK_METHODS.ROOM, data.server, `path=group/${data.groups.private.name}`)
|
||||
});
|
||||
await waitFor(element(by.id(`room-view-title-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
});
|
||||
|
||||
it('should navigate to the thread using path', async () => {
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: true,
|
||||
url: getDeepLink(DEEPLINK_METHODS.ROOM, data.server, `path=group/${data.groups.alternate2.name}/thread/${threadId}`)
|
||||
});
|
||||
await waitFor(element(by.id(`room-view-title-${threadMessage}`)))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
});
|
||||
|
||||
it('should navigate to the room using rid', async () => {
|
||||
const roomResult = await get(`groups.info?roomName=${data.groups.private.name}`);
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: true,
|
||||
url: getDeepLink(DEEPLINK_METHODS.ROOM, data.server, `rid=${roomResult.data.group._id}`)
|
||||
});
|
||||
await waitFor(element(by.id(`room-view-title-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should resume from background and navigate to the room', async () => {
|
||||
await device.sendToHome();
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: false,
|
||||
url: getDeepLink(DEEPLINK_METHODS.ROOM, data.server, `path=group/${data.groups.private.name}`)
|
||||
});
|
||||
await waitFor(element(by.id(`room-view-title-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should simulate a tap on a push notification and navigate to the room', async () => {
|
||||
/**
|
||||
* Ideally, we would repeat this test to simulate a resume from background,
|
||||
* but for some reason it was not working as expected
|
||||
* This was always turning to false right before running the logic https://github.com/RocketChat/Rocket.Chat.ReactNative/blob/18f359a8ef9691144970c0c1fad990f82096b024/app/lib/notifications/push.ts#L58
|
||||
*/
|
||||
// await device.sendToHome();
|
||||
await device.launchApp({
|
||||
newInstance: true,
|
||||
userNotification: {
|
||||
trigger: {
|
||||
type: 'push'
|
||||
},
|
||||
title: 'From push',
|
||||
body: 'Body',
|
||||
badge: 1,
|
||||
payload: {
|
||||
ejson: EJSON.stringify({
|
||||
rid: null,
|
||||
host: data.server,
|
||||
name: data.groups.private.name,
|
||||
type: 'p'
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
await waitFor(element(by.id(`room-view-title-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Others', () => {
|
||||
it('should change server', async () => {
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('rooms-list-header-server-dropdown-button')).tap();
|
||||
await waitFor(element(by.id('rooms-list-header-server-dropdown')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`rooms-list-header-server-${data.alternateServer}`)).tap();
|
||||
await checkServer(data.alternateServer);
|
||||
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: true,
|
||||
url: getDeepLink(DEEPLINK_METHODS.ROOM, data.server, `path=group/${data.groups.private.name}`)
|
||||
});
|
||||
await waitFor(element(by.id(`room-view-title-${data.groups.private.name}`)))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
});
|
||||
|
||||
it('should add a not existing server and fallback to the previous one', async () => {
|
||||
await device.launchApp({
|
||||
permissions: { notifications: 'YES' },
|
||||
newInstance: true,
|
||||
url: getDeepLink(DEEPLINK_METHODS.ROOM, 'https://google.com')
|
||||
});
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(30000);
|
||||
await checkServer(data.server);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,140 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToLogin, login, sleep } from '../../helpers/app';
|
||||
import { post } from '../../helpers/data_setup';
|
||||
import data from '../../data';
|
||||
|
||||
const testuser = data.users.regular;
|
||||
const defaultLaunchArgs = { permissions: { notifications: 'YES' } } as Detox.DeviceLaunchAppConfig;
|
||||
|
||||
const navToLanguage = async () => {
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('sidebar-settings')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-settings')).tap();
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('settings-view-language')).tap();
|
||||
await waitFor(element(by.id('language-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
};
|
||||
|
||||
describe('i18n', () => {
|
||||
describe('OS language', () => {
|
||||
it("OS set to 'en' and proper translate to 'en'", async () => {
|
||||
if (device.getPlatform() === 'android') {
|
||||
return; // FIXME: Passing language with launch parameters doesn't work with Android
|
||||
}
|
||||
await device.launchApp({
|
||||
...defaultLaunchArgs,
|
||||
languageAndLocale: {
|
||||
language: 'en',
|
||||
locale: 'en'
|
||||
},
|
||||
delete: true
|
||||
});
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(20000);
|
||||
await expect(element(by.id('new-server-view-open').and(by.label('Join our open workspace')))).toBeVisible();
|
||||
});
|
||||
|
||||
it("OS set to unavailable language and fallback to 'en'", async () => {
|
||||
if (device.getPlatform() === 'android') {
|
||||
return; // FIXME: Passing language with launch parameters doesn't work with Android
|
||||
}
|
||||
await device.launchApp({
|
||||
...defaultLaunchArgs,
|
||||
languageAndLocale: {
|
||||
language: 'es-MX',
|
||||
locale: 'es-MX'
|
||||
}
|
||||
});
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(20000);
|
||||
await expect(element(by.id('new-server-view-open').and(by.label('Join our open workspace')))).toBeVisible();
|
||||
});
|
||||
|
||||
/**
|
||||
* This test might become outdated as soon as we support the language
|
||||
* Although this seems to be a bad approach, that's the intention for having fallback enabled
|
||||
*/
|
||||
// it('OS set to available language and fallback to \'en\' on strings missing translation', async() => {
|
||||
// await device.launchApp({
|
||||
// ...defaultLaunchArgs,
|
||||
// languageAndLocale: {
|
||||
// language: "nl",
|
||||
// locale: "nl"
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
});
|
||||
|
||||
describe('Rocket.Chat language', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ ...defaultLaunchArgs, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(testuser.username, testuser.password);
|
||||
});
|
||||
|
||||
it("should select 'en'", async () => {
|
||||
await navToLanguage();
|
||||
await element(by.id('language-view-en')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('sidebar-chats').withDescendant(by.label('Chats')))).toBeVisible();
|
||||
await expect(element(by.id('sidebar-profile').withDescendant(by.label('Profile')))).toBeVisible();
|
||||
await expect(element(by.id('sidebar-settings').withDescendant(by.label('Settings')))).toBeVisible();
|
||||
await element(by.id('sidebar-close-drawer')).tap();
|
||||
});
|
||||
|
||||
it("should select 'nl' and fallback to 'en'", async () => {
|
||||
await navToLanguage();
|
||||
await element(by.id('language-view-nl')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('sidebar-chats').withDescendant(by.label('Chats')))).toBeVisible(); // fallback to en
|
||||
await expect(element(by.id('sidebar-profile').withDescendant(by.label('Profiel')))).toBeVisible();
|
||||
await expect(element(by.id('sidebar-settings').withDescendant(by.label('Instellingen')))).toBeVisible();
|
||||
await element(by.id('sidebar-close-drawer')).tap();
|
||||
});
|
||||
|
||||
it("should set unsupported language and fallback to 'en'", async () => {
|
||||
await post('users.setPreferences', { data: { language: 'eo' } }); // Set language to Esperanto
|
||||
await device.launchApp({ ...defaultLaunchArgs, newInstance: true });
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
// give the app some time to apply new language
|
||||
await sleep(3000);
|
||||
await expect(element(by.id('sidebar-chats').withDescendant(by.label('Chats')))).toBeVisible();
|
||||
await expect(element(by.id('sidebar-profile').withDescendant(by.label('Profile')))).toBeVisible();
|
||||
await expect(element(by.id('sidebar-settings').withDescendant(by.label('Settings')))).toBeVisible();
|
||||
await post('users.setPreferences', { data: { language: 'en' } }); // Set back to english
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,102 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { login, navigateToLogin } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
const goToDisplayPref = async () => {
|
||||
await expect(element(by.id('rooms-list-view-sidebar'))).toBeVisible();
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await expect(element(by.id('sidebar-display'))).toBeVisible();
|
||||
await element(by.id('sidebar-display')).tap();
|
||||
};
|
||||
const goToRoomList = async () => {
|
||||
await expect(element(by.id('display-view-drawer'))).toBeVisible();
|
||||
await element(by.id('display-view-drawer')).tap();
|
||||
await expect(element(by.id('sidebar-chats'))).toBeVisible();
|
||||
await element(by.id('sidebar-chats')).tap();
|
||||
};
|
||||
|
||||
describe('Display prefs', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have rooms list screen', async () => {
|
||||
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have room item', async () => {
|
||||
await waitFor(element(by.id('rooms-list-view-item-general')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
// Render - Header
|
||||
describe('Header', () => {
|
||||
it('should have create channel button', async () => {
|
||||
await expect(element(by.id('rooms-list-view-create-channel'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have sidebar button', async () => {
|
||||
await expect(element(by.id('rooms-list-view-sidebar'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('DisplayPrefView', () => {
|
||||
it('should go to Display Preferences', async () => {
|
||||
await goToDisplayPref();
|
||||
});
|
||||
|
||||
it('should have Displays button, expanded, condensed, avatars', async () => {
|
||||
await expect(element(by.id('display-pref-view-expanded'))).toBeVisible();
|
||||
await expect(element(by.id('display-pref-view-condensed'))).toBeVisible();
|
||||
await expect(element(by.id('display-pref-view-avatars'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have Sort By button', async () => {
|
||||
await expect(element(by.id('display-pref-view-activity'))).toBeVisible();
|
||||
await expect(element(by.id('display-pref-view-name'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have Group by button', async () => {
|
||||
await expect(element(by.id('display-pref-view-unread'))).toBeVisible();
|
||||
await expect(element(by.id('display-pref-view-favorites'))).toBeVisible();
|
||||
await expect(element(by.id('display-pref-view-types'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Change display', () => {
|
||||
it('should appear the last message in RoomList when is Expanded', async () => {
|
||||
await element(by.id('display-pref-view-expanded')).tap();
|
||||
await goToRoomList();
|
||||
await expect(element(by.id('room-item-last-message')).atIndex(0)).toBeVisible();
|
||||
});
|
||||
|
||||
it('should not appear the last message in RoomList when is Condensed', async () => {
|
||||
await goToDisplayPref();
|
||||
await element(by.id('display-pref-view-condensed')).tap();
|
||||
await goToRoomList();
|
||||
await expect(element(by.id('room-item-last-message'))).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Change the avatar visible', () => {
|
||||
it('should have avatar as default in room list', async () => {
|
||||
await expect(element(by.id('avatar')).atIndex(0)).toExist();
|
||||
});
|
||||
|
||||
it('should hide the avatar', async () => {
|
||||
await goToDisplayPref();
|
||||
await expect(element(by.id('display-pref-view-avatar-switch'))).toBeVisible();
|
||||
await element(by.id('display-pref-view-avatar-switch')).tap();
|
||||
await goToRoomList();
|
||||
await waitFor(element(by.id('avatar').withAncestor(by.id('rooms-list-view-item-general'))))
|
||||
.not.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,72 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, sleep, tapBack } from '../../helpers/app';
|
||||
import { sendMessage, post } from '../../helpers/data_setup';
|
||||
|
||||
describe('InApp Notification', () => {
|
||||
let dmCreatedRid: string;
|
||||
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
const result = await post(`im.create`, { username: data.users.alternate.username });
|
||||
dmCreatedRid = result.data.room.rid;
|
||||
});
|
||||
|
||||
describe('receive in RoomsListView', () => {
|
||||
const text = 'Message in DM';
|
||||
it('should have rooms list screen', async () => {
|
||||
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should send direct message from user alternate to user regular', async () => {
|
||||
await sleep(1000);
|
||||
await sendMessage(data.users.alternate, dmCreatedRid, text);
|
||||
});
|
||||
|
||||
it('should tap on InApp Notification', async () => {
|
||||
await waitFor(element(by.id(`in-app-notification-${text}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await sleep(500);
|
||||
await element(by.id(`in-app-notification-${text}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id(`room-view-title-${data.users.alternate.username}`))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('receive in another room', () => {
|
||||
const text = 'Another msg';
|
||||
it('should back to RoomsListView and open the channel Detox Public', async () => {
|
||||
await tapBack();
|
||||
await sleep(500);
|
||||
await element(by.id(`rooms-list-view-item-${data.userRegularChannels.detoxpublic.name}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id(`room-view-title-${data.userRegularChannels.detoxpublic.name}`))).toExist();
|
||||
});
|
||||
|
||||
it('should receive and tap InAppNotification in another room', async () => {
|
||||
await sendMessage(data.users.alternate, dmCreatedRid, text);
|
||||
await waitFor(element(by.id(`in-app-notification-${text}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await sleep(500);
|
||||
await element(by.id(`in-app-notification-${text}`)).tap();
|
||||
await sleep(500);
|
||||
await expect(element(by.id('room-header'))).toExist();
|
||||
await expect(element(by.id(`room-view-title-${data.users.alternate.username}`))).toExist();
|
||||
});
|
||||
|
||||
it('should back to RoomsListView', async () => {
|
||||
await tapBack();
|
||||
await sleep(500);
|
||||
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,29 @@
|
|||
// import detox from 'detox';
|
||||
// import adapter from 'detox/runners/mocha/adapter';
|
||||
|
||||
// import { detox as config } from '../../package.json';
|
||||
import { setup } from '../helpers/data_setup';
|
||||
// import { prepareAndroid } from '../helpers/app';
|
||||
|
||||
beforeAll(async () => {
|
||||
await setup();
|
||||
// await Promise.all([setup(), detox.init(config, { launchApp: false })]);
|
||||
// await prepareAndroid(); // Make Android less flaky
|
||||
// await dataSetup()
|
||||
// await detox.init(config, { launchApp: false });
|
||||
// await device.launchApp({ permissions: { notifications: 'YES' } });
|
||||
});
|
||||
|
||||
// beforeEach(async function () {
|
||||
// // @ts-ignore
|
||||
// await adapter.beforeEach(this);
|
||||
// });
|
||||
|
||||
// afterEach(async function () {
|
||||
// // @ts-ignore
|
||||
// await adapter.afterEach(this);
|
||||
// });
|
||||
|
||||
// afterAll(async () => {
|
||||
// await detox.cleanup();
|
||||
// });
|
|
@ -0,0 +1,56 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { TTextMatcher, platformTypes } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
describe('Onboarding', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(20000);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have onboarding screen', async () => {
|
||||
await expect(element(by.id('new-server-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have "Join our open workspace"', async () => {
|
||||
await expect(element(by.id('new-server-view-open'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should enter an invalid server and get error', async () => {
|
||||
await element(by.id('new-server-view-input')).replaceText('invalidtest');
|
||||
await element(by.id('new-server-view-input')).tapReturnKey();
|
||||
await waitFor(element(by[textMatcher]('Oops!')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
});
|
||||
|
||||
it('should tap on "Join our open workspace" and navigate', async () => {
|
||||
await element(by.id('new-server-view-open')).tap();
|
||||
await waitFor(element(by.id('workspace-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should enter a valid server without login services and navigate to login', async () => {
|
||||
await device.launchApp({ newInstance: true });
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('new-server-view-input')).replaceText(data.server);
|
||||
await element(by.id('new-server-view-input')).tapReturnKey();
|
||||
await waitFor(element(by.id('workspace-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,71 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToRegister, navigateToLogin } from '../../helpers/app';
|
||||
|
||||
describe('Legal screen', () => {
|
||||
describe('From Login', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
});
|
||||
|
||||
it('should have legal button on login', async () => {
|
||||
await waitFor(element(by.id('login-view-more')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should navigate to legal from login', async () => {
|
||||
await expect(element(by.id('login-view-more'))).toBeVisible();
|
||||
await element(by.id('login-view-more')).tap();
|
||||
await waitFor(element(by.id('legal-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(4000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('From Register', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToRegister();
|
||||
});
|
||||
|
||||
it('should have legal button on register', async () => {
|
||||
await waitFor(element(by.id('register-view-more')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should navigate to legal from register', async () => {
|
||||
await expect(element(by.id('register-view-more'))).toBeVisible();
|
||||
await element(by.id('register-view-more')).tap();
|
||||
await waitFor(element(by.id('legal-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(4000);
|
||||
});
|
||||
|
||||
it('should have terms of service button', async () => {
|
||||
await expect(element(by.id('legal-terms-button'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have privacy policy button', async () => {
|
||||
await expect(element(by.id('legal-privacy-button'))).toBeVisible();
|
||||
});
|
||||
|
||||
// We can't simulate how webview behaves, so I had to disable :(
|
||||
/*
|
||||
it('should navigate to terms', async() => {
|
||||
await element(by.id('legal-terms-button')).tap();
|
||||
await waitFor(element(by.id('terms-view'))).toBeVisible().withTimeout(2000);
|
||||
await expect(element(by.id('terms-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should navigate to privacy', async() => {
|
||||
await tapBack();
|
||||
await element(by.id('legal-privacy-button')).tap();
|
||||
await waitFor(element(by.id('privacy-view'))).toBeVisible().withTimeout(2000);
|
||||
await expect(element(by.id('privacy-view'))).toBeVisible();
|
||||
});
|
||||
*/
|
||||
});
|
||||
});
|
|
@ -0,0 +1,46 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
describe('Forgot password screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await element(by.id('login-view-forgot-password')).tap();
|
||||
await waitFor(element(by.id('forgot-password-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have forgot password screen', async () => {
|
||||
await expect(element(by.id('forgot-password-view'))).toExist();
|
||||
});
|
||||
|
||||
it('should have email input', async () => {
|
||||
await expect(element(by.id('forgot-password-view-email'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have submit button', async () => {
|
||||
await expect(element(by.id('forgot-password-view-submit'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should reset password and navigate to login', async () => {
|
||||
await element(by.id('forgot-password-view-email')).replaceText(data.users.existing.email);
|
||||
await element(by.id('forgot-password-view-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('OK')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('login-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,91 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToRegister, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
describe('Create user screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToRegister();
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have create user screen', async () => {
|
||||
await waitFor(element(by.id('register-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should have name input', async () => {
|
||||
await expect(element(by.id('register-view-name'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have email input', async () => {
|
||||
await expect(element(by.id('register-view-email'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have password input', async () => {
|
||||
await expect(element(by.id('register-view-password'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have submit button', async () => {
|
||||
await element(by.id('register-view')).atIndex(0).swipe('up', 'fast', 0.5);
|
||||
await expect(element(by.id('register-view-submit'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have legal button', async () => {
|
||||
await expect(element(by.id('register-view-more'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
// FIXME: Detox isn't able to check if it's tappable: https://github.com/wix/Detox/issues/246
|
||||
// it('should submit invalid email and do nothing', async() => {
|
||||
// const invalidEmail = 'invalidemail';
|
||||
// await element(by.id('register-view-name')).replaceText(data.user);
|
||||
// await element(by.id('register-view-username')).replaceText(data.user);
|
||||
// await element(by.id('register-view-email')).replaceText(invalidEmail);
|
||||
// await element(by.id('register-view-password')).replaceText(data.password);
|
||||
// await element(by.id('register-view-submit')).tap();
|
||||
// });
|
||||
|
||||
// TODO: When server handle two errors in sequence, the server return Too many requests and force to wait for some time.
|
||||
// it('should submit email already taken and raise error', async () => {
|
||||
// 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.users.existing.email);
|
||||
// await element(by.id('register-view-password')).replaceText(data.registeringUser.password);
|
||||
// await element(by.id('register-view-submit')).tap();
|
||||
// await waitFor(element(by[textMatcher]('Email already exists. [403]')).atIndex(0))
|
||||
// .toExist()
|
||||
// .withTimeout(10000);
|
||||
// await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
// });
|
||||
|
||||
it('should submit username already taken and raise error', async () => {
|
||||
await element(by.id('register-view-name')).replaceText(data.registeringUser.username);
|
||||
await element(by.id('register-view-username')).replaceText(data.users.existing.username);
|
||||
await element(by.id('register-view-email')).replaceText(data.registeringUser.email);
|
||||
await element(by.id('register-view-password')).replaceText(data.registeringUser.password);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('Username is already in use')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
});
|
||||
|
||||
it('should register', async () => {
|
||||
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);
|
||||
await element(by.id('register-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,88 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { navigateToLogin, tapBack, platformTypes, navigateToWorkspace, login, TTextMatcher } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
describe('Login screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have login screen', async () => {
|
||||
await expect(element(by.id('login-view'))).toExist();
|
||||
});
|
||||
|
||||
it('should have email input', async () => {
|
||||
await expect(element(by.id('login-view-email'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have password input', async () => {
|
||||
await expect(element(by.id('login-view-password'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have submit button', async () => {
|
||||
await expect(element(by.id('login-view-submit'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have register button', async () => {
|
||||
await expect(element(by.id('login-view-register'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have forgot password button', async () => {
|
||||
await expect(element(by.id('login-view-forgot-password'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have legal button', async () => {
|
||||
await expect(element(by.id('login-view-more'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should navigate to register', async () => {
|
||||
await element(by.id('login-view-register')).tap();
|
||||
await waitFor(element(by.id('register-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should navigate to forgot password', async () => {
|
||||
await element(by.id('login-view-forgot-password')).tap();
|
||||
await waitFor(element(by.id('forgot-password-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should insert wrong password and get error', async () => {
|
||||
await element(by.id('login-view-email')).replaceText(data.users.regular.username);
|
||||
await element(by.id('login-view-password')).replaceText('NotMyActualPassword');
|
||||
await element(by.id('login-view-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('Your credentials were rejected! Please try again.')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
});
|
||||
|
||||
it('should login with success', async () => {
|
||||
await element(by.id('login-view-password')).replaceText(data.users.regular.password);
|
||||
await element(by.id('login-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should connect, go back, connect to the same server and login', async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true });
|
||||
await navigateToWorkspace();
|
||||
await tapBack();
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,59 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { login, navigateToLogin, logout, tapBack, searchRoom } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
describe('Rooms list screen', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have rooms list screen', async () => {
|
||||
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have room item', async () => {
|
||||
await waitFor(element(by.id('rooms-list-view-item-general')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
// Render - Header
|
||||
describe('Header', () => {
|
||||
it('should have create channel button', async () => {
|
||||
await expect(element(by.id('rooms-list-view-create-channel'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have sidebar button', async () => {
|
||||
await expect(element(by.id('rooms-list-view-sidebar'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should search room and navigate', async () => {
|
||||
await searchRoom('rocket.cat');
|
||||
await element(by.id('rooms-list-view-item-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id('room-view-title-rocket.cat')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(6000);
|
||||
await waitFor(element(by.id('rooms-list-view-item-rocket.cat')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should logout', async () => {
|
||||
await logout();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,56 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { login, navigateToLogin, logout, tapBack } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
describe('Server history', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should login, save server as history and logout', async () => {
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
await logout();
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should show servers history', async () => {
|
||||
await element(by.id('new-server-view-input')).tap();
|
||||
await waitFor(element(by.id(`server-history-${data.server}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should tap on a server history and navigate to login', async () => {
|
||||
await element(by.id(`server-history-${data.server}`)).tap();
|
||||
await waitFor(element(by.id('login-view-email')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.label(data.users.regular.username).withAncestor(by.id('login-view-email'))));
|
||||
});
|
||||
|
||||
it('should delete server from history', async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('workspace-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('new-server-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('new-server-view-input')).tap();
|
||||
await waitFor(element(by.id(`server-history-${data.server}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id(`server-history-delete-${data.server}`)).tap();
|
||||
await element(by.id('new-server-view-input')).tap();
|
||||
await waitFor(element(by.id(`server-history-${data.server}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,257 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { tapBack, navigateToLogin, login, tryTapping, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
describe('Create room screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('New Message', () => {
|
||||
beforeAll(async () => {
|
||||
await waitFor(element(by.id('rooms-list-view-create-channel')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have new message screen', async () => {
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should have search input', async () => {
|
||||
await waitFor(element(by.id('new-message-view-search')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should back to rooms list', async () => {
|
||||
await waitFor(element(by.id('new-message-view-close')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('new-message-view-close')).tap();
|
||||
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
|
||||
await tryTapping(element(by.id('rooms-list-view-create-channel')), 3000);
|
||||
// await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should search user and navigate', async () => {
|
||||
await element(by.id('new-message-view-search')).replaceText('rocket.cat');
|
||||
await waitFor(element(by.id('new-message-view-item-rocket.cat')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('new-message-view-item-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id('room-view-title-rocket.cat')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should navigate to select users', async () => {
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('new-message-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('select-users-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Select Users', () => {
|
||||
it('should search users', async () => {
|
||||
await element(by.id('select-users-view-search')).replaceText('rocket.cat');
|
||||
await waitFor(element(by.id('select-users-view-item-rocket.cat')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
it('should select/unselect user', async () => {
|
||||
// Spotlight issues
|
||||
await element(by.id('select-users-view-item-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('selected-user-rocket.cat')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('selected-user-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('selected-user-rocket.cat')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(10000);
|
||||
// Spotlight issues
|
||||
await element(by.id('select-users-view-item-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('selected-user-rocket.cat')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
it('should navigate to create channel view', async () => {
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
await waitFor(element(by.id('create-channel-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Create Channel', () => {
|
||||
describe('Render', () => {
|
||||
it('should render all fields', async () => {
|
||||
await expect(element(by.id('create-channel-name'))).toBeVisible();
|
||||
await expect(element(by.id('create-channel-type'))).toBeVisible();
|
||||
await expect(element(by.id('create-channel-readonly'))).toBeVisible();
|
||||
await expect(element(by.id('create-channel-broadcast'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should get invalid room', async () => {
|
||||
await element(by.id('create-channel-name')).replaceText('general');
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('A channel with name general exists')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by[textMatcher]('A channel with name general exists'))).toExist();
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
});
|
||||
|
||||
it('should create public room', async () => {
|
||||
const room = `public${data.random}`;
|
||||
await element(by.id('create-channel-name')).replaceText('');
|
||||
await element(by.id('create-channel-name')).replaceText(room);
|
||||
await element(by.id('create-channel-type')).tap();
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await expect(element(by.id('room-view'))).toExist();
|
||||
await waitFor(element(by.id(`room-view-title-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await expect(element(by.id(`room-view-title-${room}`))).toExist();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await expect(element(by.id(`rooms-list-view-item-${room}`))).toExist();
|
||||
});
|
||||
|
||||
it('should create private room', async () => {
|
||||
const room = `private${data.random}`;
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('new-message-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('select-users-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('select-users-view-item-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('selected-user-rocket.cat')))
|
||||
.toExist()
|
||||
.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(room);
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('room-view'))).toExist();
|
||||
await waitFor(element(by.id(`room-view-title-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id(`room-view-title-${room}`))).toExist();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id(`rooms-list-view-item-${room}`))).toExist();
|
||||
});
|
||||
|
||||
it('should create empty room', async () => {
|
||||
const room = `empty${data.random}`;
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
// await device.launchApp({ newInstance: true });
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('new-message-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('select-users-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
await waitFor(element(by.id('create-channel-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('create-channel-name')).replaceText(room);
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('room-view'))).toExist();
|
||||
await waitFor(element(by.id(`room-view-title-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id(`room-view-title-${room}`))).toExist();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id(`rooms-list-view-item-${room}`))).toExist();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,536 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import {
|
||||
navigateToLogin,
|
||||
login,
|
||||
mockMessage,
|
||||
tapBack,
|
||||
sleep,
|
||||
searchRoom,
|
||||
dismissReviewNag,
|
||||
tryTapping,
|
||||
platformTypes,
|
||||
TTextMatcher
|
||||
} from '../../helpers/app';
|
||||
import { sendMessage } from '../../helpers/data_setup';
|
||||
|
||||
async function navigateToRoom(roomName: string) {
|
||||
await searchRoom(`${roomName}`);
|
||||
await element(by.id(`rooms-list-view-item-${roomName}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
describe('Room screen', () => {
|
||||
const mainRoom = data.groups.private.name;
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
await navigateToRoom(mainRoom);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have room screen', async () => {
|
||||
await expect(element(by.id('room-view'))).toExist();
|
||||
await waitFor(element(by.id(`room-view-title-${mainRoom}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
// Render - Header
|
||||
describe('Header', () => {
|
||||
it('should have actions button ', async () => {
|
||||
await expect(element(by.id('room-header'))).toExist();
|
||||
});
|
||||
|
||||
it('should have threads button ', async () => {
|
||||
await expect(element(by.id('room-view-header-threads'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
// Render - Messagebox
|
||||
describe('Messagebox', () => {
|
||||
it('should have messagebox', async () => {
|
||||
await expect(element(by.id('messagebox'))).toExist();
|
||||
});
|
||||
|
||||
it('should have open emoji button', async () => {
|
||||
await expect(element(by.id('messagebox-open-emoji'))).toExist();
|
||||
});
|
||||
|
||||
it('should have message input', async () => {
|
||||
await expect(element(by.id('messagebox-input'))).toExist();
|
||||
});
|
||||
|
||||
it('should have audio button', async () => {
|
||||
await expect(element(by.id('messagebox-send-audio'))).toExist();
|
||||
});
|
||||
|
||||
it('should have actions button', async () => {
|
||||
await expect(element(by.id('messagebox-actions'))).toExist();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
describe('Messagebox', () => {
|
||||
it('should send message', async () => {
|
||||
await mockMessage('message');
|
||||
await expect(element(by[textMatcher](`${data.random}message`)).atIndex(0)).toExist();
|
||||
});
|
||||
|
||||
describe('Emoji Keyboard', () => {
|
||||
it('should open emoji keyboard, select an emoji and send it', async () => {
|
||||
await element(by.id('messagebox-open-emoji')).tap();
|
||||
await waitFor(element(by.id('messagebox-keyboard-emoji')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id('emoji-picker-tab-emoji')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('emoji-picker-tab-emoji')).tap();
|
||||
await expect(element(by.id('emoji-blush'))).toExist();
|
||||
await element(by.id('emoji-blush')).tap();
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText('😊');
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await waitFor(element(by[textMatcher]('😊')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by[textMatcher]('😊')).atIndex(0).tap();
|
||||
});
|
||||
|
||||
it('should open emoji keyboard, select an emoji and delete it using emoji keyboards backspace', async () => {
|
||||
await element(by.id('messagebox-open-emoji')).tap();
|
||||
await waitFor(element(by.id('messagebox-keyboard-emoji')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await expect(element(by.id('emoji-picker-tab-emoji'))).toExist();
|
||||
await element(by.id('emoji-picker-tab-emoji')).tap();
|
||||
await expect(element(by.id('emoji-upside_down'))).toExist();
|
||||
await element(by.id('emoji-upside_down')).tap();
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText('🙃');
|
||||
await waitFor(element(by.id('emoji-picker-backspace')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('emoji-picker-backspace')).tap();
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText('');
|
||||
await element(by.id('messagebox-close-emoji')).tap();
|
||||
await waitFor(element(by.id('messagebox-keyboard-emoji')))
|
||||
.not.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
it('should search emoji and send it', async () => {
|
||||
await element(by.id('messagebox-open-emoji')).tap();
|
||||
await waitFor(element(by.id('emoji-picker-search')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('emoji-picker-search')).tap();
|
||||
await waitFor(element(by.id('emoji-searchbar-input')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('emoji-searchbar-input')).replaceText('no_mouth');
|
||||
await waitFor(element(by.id('emoji-no_mouth')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('emoji-no_mouth')).tap();
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText('😶');
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await waitFor(element(by[textMatcher]('😶')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by[textMatcher]('😶')).atIndex(0).tap();
|
||||
});
|
||||
|
||||
it('should search emojis, go back to Emoji keyboard and then close the Emoji keyboard', async () => {
|
||||
await element(by.id('messagebox-open-emoji')).tap();
|
||||
await waitFor(element(by.id('emoji-picker-search')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('emoji-picker-search')).tap();
|
||||
await waitFor(element(by.id('emoji-searchbar-input')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('openback-emoji-keyboard')).tap();
|
||||
await waitFor(element(by.id('emoji-searchbar-input')))
|
||||
.not.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('messagebox-close-emoji'))).toExist();
|
||||
await element(by.id('messagebox-close-emoji')).tap();
|
||||
await waitFor(element(by.id('messagebox-keyboard-emoji')))
|
||||
.not.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
it('frequently used emojis should contain the recently used emojis', async () => {
|
||||
await element(by.id('messagebox-open-emoji')).tap();
|
||||
await waitFor(element(by.id('emoji-picker-tab-clock')));
|
||||
await element(by.id('emoji-picker-tab-clock')).tap();
|
||||
await waitFor(element(by.id('emoji-blush')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('emoji-upside_down')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('emoji-no_mouth')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('messagebox-close-emoji'))).toExist();
|
||||
await element(by.id('messagebox-close-emoji')).tap();
|
||||
await waitFor(element(by.id('messagebox-keyboard-emoji')))
|
||||
.not.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show/hide emoji autocomplete', async () => {
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
await element(by.id('messagebox-input')).typeText(':joy');
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id('messagebox-container')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
await waitFor(element(by.id('messagebox-container')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
it('should show and tap on emoji autocomplete', async () => {
|
||||
await element(by.id('messagebox-input')).typeText(':joy');
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id('messagebox-container')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id('mention-item-joy')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('mention-item-joy')).tap();
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText(':joy: ');
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
});
|
||||
|
||||
it('should not show emoji autocomplete on semicolon in middle of a string', async () => {
|
||||
await element(by.id('messagebox-input')).typeText('name:is');
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id('messagebox-container')))
|
||||
.toNotExist()
|
||||
.withTimeout(20000);
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
});
|
||||
|
||||
it('should show and tap on user autocomplete and send mention', async () => {
|
||||
const { username } = data.users.regular;
|
||||
const messageMention = `@${username}`;
|
||||
const message = `${data.random}mention`;
|
||||
const fullMessage = `${messageMention} ${message}`;
|
||||
await element(by.id('messagebox-input')).typeText(`@${username}`);
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id('messagebox-container')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await waitFor(element(by.id(`mention-item-${username}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(4000);
|
||||
await tryTapping(element(by.id(`mention-item-${username}`)), 2000, true);
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText(`${messageMention} `);
|
||||
await tryTapping(element(by.id('messagebox-input')), 2000);
|
||||
if (device.getPlatform() === 'ios') {
|
||||
await element(by.id('messagebox-input')).typeText(message);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
const fullMessageMatcher = fullMessage.substr(1); // removes `@`
|
||||
await waitFor(element(by[textMatcher](fullMessageMatcher)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by[textMatcher](fullMessageMatcher))).toExist();
|
||||
await element(by[textMatcher](fullMessageMatcher)).atIndex(0).tap();
|
||||
} else {
|
||||
await element(by.id('messagebox-input')).replaceText(fullMessage);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
}
|
||||
});
|
||||
|
||||
it('should not show user autocomplete on @ in the middle of a string', async () => {
|
||||
await element(by.id('messagebox-input')).typeText('email@gmail');
|
||||
await waitFor(element(by.id('messagebox-container')))
|
||||
.toNotExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
});
|
||||
|
||||
it('should show and tap on room autocomplete', async () => {
|
||||
await element(by.id('messagebox-input')).typeText('#general');
|
||||
await waitFor(element(by.id('mention-item-general')))
|
||||
.toBeVisible()
|
||||
.withTimeout(4000);
|
||||
await tryTapping(element(by.id('mention-item-general')), 2000, true);
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText('#general ');
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
});
|
||||
|
||||
it('should not show room autocomplete on # in middle of a string', async () => {
|
||||
await element(by.id('messagebox-input')).tap();
|
||||
await element(by.id('messagebox-input')).typeText('te#gen');
|
||||
await waitFor(element(by.id('messagebox-container')))
|
||||
.toNotExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
});
|
||||
it('should draft message', async () => {
|
||||
await element(by.id('messagebox-input')).typeText(`${data.random}draft`);
|
||||
await tapBack();
|
||||
|
||||
await navigateToRoom(mainRoom);
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText(`${data.random}draft`);
|
||||
await element(by.id('messagebox-input')).clearText();
|
||||
await tapBack();
|
||||
|
||||
await navigateToRoom(mainRoom);
|
||||
await expect(element(by.id('messagebox-input'))).toHaveText('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Message', () => {
|
||||
it('should copy link', async () => {
|
||||
await element(by[textMatcher](`${data.random}message`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Get Link')).atIndex(0).tap();
|
||||
// TODO: test clipboard
|
||||
});
|
||||
it('should copy message', async () => {
|
||||
await element(by[textMatcher](`${data.random}message`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Copy')).atIndex(0).tap();
|
||||
// TODO: test clipboard
|
||||
});
|
||||
|
||||
it('should react to message', async () => {
|
||||
await waitFor(element(by[textMatcher](`${data.random}message`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by[textMatcher](`${data.random}message`))
|
||||
.atIndex(0)
|
||||
.tap();
|
||||
await element(by[textMatcher](`${data.random}message`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('add-reaction')).tap();
|
||||
await waitFor(element(by.id('emoji-picker-tab-emoji')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 1);
|
||||
await element(by.id('emoji-picker-tab-emoji')).tap();
|
||||
await waitFor(element(by.id('emoji-grinning')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('emoji-grinning')).tap();
|
||||
await waitFor(element(by.id('message-reaction-:grinning:')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should ask for review', async () => {
|
||||
await dismissReviewNag(); // TODO: Create a proper test for this elsewhere.
|
||||
});
|
||||
|
||||
it('should search emojis in the reaction picker and react', async () => {
|
||||
await element(by[textMatcher](`${data.random}message`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('add-reaction')).tap();
|
||||
await waitFor(element(by.id('emoji-searchbar-input')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('emoji-searchbar-input')).typeText('laughing');
|
||||
await waitFor(element(by.id('emoji-laughing')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('emoji-laughing')).tap();
|
||||
await waitFor(element(by.id('message-reaction-:laughing:')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should react to message with frequently used emoji', async () => {
|
||||
await element(by[textMatcher](`${data.random}message`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await waitFor(element(by.id('message-actions-emoji-upside_down')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('message-actions-emoji-upside_down')).tap();
|
||||
await waitFor(element(by.id('message-reaction-:upside_down:')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should show reaction picker on add reaction button pressed and have frequently used emoji', async () => {
|
||||
await element(by.id('message-add-reaction')).tap();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 1);
|
||||
await waitFor(element(by.id('emoji-upside_down')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await waitFor(element(by.id('emoji-picker-tab-emoji')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('emoji-picker-tab-emoji')).tap();
|
||||
await waitFor(element(by.id('emoji-wink')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('emoji-wink')).tap();
|
||||
await waitFor(element(by.id('message-reaction-:wink:')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should open/close reactions list', async () => {
|
||||
await element(by.id('message-reaction-:grinning:')).longPress();
|
||||
await waitFor(element(by.id('reactionsList')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('down', 'fast', 0.5);
|
||||
});
|
||||
|
||||
it('should remove reaction', async () => {
|
||||
await element(by.id('message-reaction-:grinning:')).tap();
|
||||
await waitFor(element(by.id('message-reaction-:grinning:')))
|
||||
.not.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should edit message', async () => {
|
||||
await mockMessage('edit');
|
||||
await element(by[textMatcher](`${data.random}edit`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Edit')).atIndex(0).tap();
|
||||
await element(by.id('messagebox-input')).replaceText(`${data.random}edited`);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await waitFor(element(by[textMatcher](`${data.random}edited`)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await waitFor(element(by.id(`${data.random}edited-edited`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
it('should quote message', async () => {
|
||||
await mockMessage('quote');
|
||||
await element(by[textMatcher](`${data.random}quote`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Quote')).atIndex(0).tap();
|
||||
await element(by.id('messagebox-input')).replaceText(`${data.random}quoted`);
|
||||
await waitFor(element(by.id('messagebox-send-message')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
// TODO: test if quote was sent
|
||||
});
|
||||
|
||||
it('should delete message', async () => {
|
||||
await mockMessage('delete');
|
||||
await waitFor(element(by[textMatcher](`${data.random}delete`)).atIndex(0)).toBeVisible();
|
||||
await element(by[textMatcher](`${data.random}delete`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await waitFor(element(by[textMatcher]('Delete')))
|
||||
.toExist()
|
||||
.withTimeout(1000);
|
||||
await element(by[textMatcher]('Delete')).atIndex(0).tap();
|
||||
const deleteAlertMessage = 'You will not be able to recover this message!';
|
||||
await waitFor(element(by[textMatcher](deleteAlertMessage)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by[textMatcher]('Delete').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by[textMatcher](`${data.random}delete`)).atIndex(0))
|
||||
.toNotExist()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should reply in DM to another user', async () => {
|
||||
const channelName = data.userRegularChannels.detoxpublic.name;
|
||||
const stringToReply = 'Message to reply in DM';
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await navigateToRoom(channelName);
|
||||
await sendMessage(data.users.alternate, channelName, stringToReply);
|
||||
await waitFor(element(by[textMatcher](stringToReply)).atIndex(0))
|
||||
.toBeVisible()
|
||||
.withTimeout(3000);
|
||||
await element(by[textMatcher](stringToReply)).atIndex(0).longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await waitFor(element(by[textMatcher]('Reply in Direct Message')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await element(by[textMatcher]('Reply in Direct Message')).atIndex(0).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${data.users.alternate.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await element(by.id('messagebox-input')).replaceText(`${data.random} replied in dm`);
|
||||
await waitFor(element(by.id('messagebox-send-message')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,659 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import {
|
||||
navigateToLogin,
|
||||
login,
|
||||
tapBack,
|
||||
sleep,
|
||||
searchRoom,
|
||||
mockMessage,
|
||||
starMessage,
|
||||
pinMessage,
|
||||
platformTypes,
|
||||
TTextMatcher
|
||||
} from '../../helpers/app';
|
||||
|
||||
const { sendMessage } = require('../../helpers/data_setup');
|
||||
|
||||
async function navigateToRoomActions(type: string) {
|
||||
let room;
|
||||
if (type === 'd') {
|
||||
room = 'rocket.cat';
|
||||
} else {
|
||||
room = data.groups.private.name;
|
||||
}
|
||||
await searchRoom(room);
|
||||
await element(by.id(`rooms-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function backToActions() {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
|
||||
async function backToRoomsList() {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
|
||||
async function waitForToast() {
|
||||
await sleep(1000);
|
||||
}
|
||||
|
||||
describe('Room actions screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
describe('Direct', () => {
|
||||
beforeAll(async () => {
|
||||
await navigateToRoomActions('d');
|
||||
});
|
||||
|
||||
it('should have room actions screen', async () => {
|
||||
await expect(element(by.id('room-actions-view'))).toExist();
|
||||
});
|
||||
|
||||
it('should have info', async () => {
|
||||
await expect(element(by.id('room-actions-info'))).toExist();
|
||||
});
|
||||
|
||||
// it('should have voice', async() => {
|
||||
// await expect(element(by.id('room-actions-voice'))).toExist();
|
||||
// });
|
||||
|
||||
// it('should have video', async() => {
|
||||
// await expect(element(by.id('room-actions-video'))).toExist();
|
||||
// });
|
||||
|
||||
it('should have files', async () => {
|
||||
await expect(element(by.id('room-actions-files'))).toExist();
|
||||
});
|
||||
|
||||
it('should have mentions', async () => {
|
||||
await expect(element(by.id('room-actions-mentioned'))).toExist();
|
||||
});
|
||||
|
||||
it('should have starred', async () => {
|
||||
await expect(element(by.id('room-actions-starred'))).toExist();
|
||||
});
|
||||
|
||||
it('should have share', async () => {
|
||||
await waitFor(element(by.id('room-actions-share'))).toExist();
|
||||
await expect(element(by.id('room-actions-share'))).toExist();
|
||||
});
|
||||
|
||||
it('should have pinned', async () => {
|
||||
await waitFor(element(by.id('room-actions-pinned'))).toExist();
|
||||
await expect(element(by.id('room-actions-pinned'))).toExist();
|
||||
});
|
||||
|
||||
it('should have notifications', async () => {
|
||||
await waitFor(element(by.id('room-actions-notifications'))).toExist();
|
||||
await expect(element(by.id('room-actions-notifications'))).toExist();
|
||||
});
|
||||
|
||||
it('should have block user', async () => {
|
||||
await waitFor(element(by.id('room-actions-block-user'))).toExist();
|
||||
await expect(element(by.id('room-actions-block-user'))).toExist();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await backToRoomsList();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Channel/Group', () => {
|
||||
beforeAll(async () => {
|
||||
await navigateToRoomActions('c');
|
||||
});
|
||||
|
||||
it('should have room actions screen', async () => {
|
||||
await expect(element(by.id('room-actions-view'))).toExist();
|
||||
});
|
||||
|
||||
it('should have info', async () => {
|
||||
await expect(element(by.id('room-actions-info'))).toExist();
|
||||
});
|
||||
|
||||
// it('should have voice', async() => {
|
||||
// await expect(element(by.id('room-actions-voice'))).toExist();
|
||||
// });
|
||||
|
||||
// it('should have video', async() => {
|
||||
// await expect(element(by.id('room-actions-video'))).toExist();
|
||||
// });
|
||||
|
||||
it('should have members', async () => {
|
||||
await expect(element(by.id('room-actions-members'))).toExist();
|
||||
});
|
||||
|
||||
it('should have files', async () => {
|
||||
await expect(element(by.id('room-actions-files'))).toExist();
|
||||
});
|
||||
|
||||
it('should have mentions', async () => {
|
||||
await expect(element(by.id('room-actions-mentioned'))).toExist();
|
||||
});
|
||||
|
||||
it('should have starred', async () => {
|
||||
await expect(element(by.id('room-actions-starred'))).toExist();
|
||||
});
|
||||
|
||||
it('should have share', async () => {
|
||||
await waitFor(element(by.id('room-actions-share'))).toExist();
|
||||
await expect(element(by.id('room-actions-share'))).toExist();
|
||||
});
|
||||
|
||||
it('should have pinned', async () => {
|
||||
await waitFor(element(by.id('room-actions-pinned'))).toExist();
|
||||
await expect(element(by.id('room-actions-pinned'))).toExist();
|
||||
});
|
||||
|
||||
it('should have notifications', async () => {
|
||||
await waitFor(element(by.id('room-actions-notifications'))).toExist();
|
||||
await expect(element(by.id('room-actions-notifications'))).toExist();
|
||||
});
|
||||
|
||||
it('should have leave channel', async () => {
|
||||
await waitFor(element(by.id('room-actions-leave-channel'))).toExist();
|
||||
await expect(element(by.id('room-actions-leave-channel'))).toExist();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
describe('Common', () => {
|
||||
it('should show mentioned messages', async () => {
|
||||
await element(by.id('room-actions-mentioned')).tap();
|
||||
await waitFor(element(by.id('mentioned-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await backToActions();
|
||||
});
|
||||
|
||||
it('should show starred message and unstar it', async () => {
|
||||
// Go back to room and send a message
|
||||
await tapBack();
|
||||
await mockMessage('messageToStar');
|
||||
|
||||
// Star the message
|
||||
await starMessage('messageToStar');
|
||||
|
||||
// Back into Room Actions
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
|
||||
// Go to starred messages
|
||||
await element(by.id('room-actions-view')).swipe('up');
|
||||
await waitFor(element(by.id('room-actions-starred'))).toExist();
|
||||
await element(by.id('room-actions-starred')).tap();
|
||||
await waitFor(element(by.id('starred-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by[textMatcher](`${data.random}messageToStar`).withAncestor(by.id('starred-messages-view'))))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
|
||||
// Unstar message
|
||||
await element(by[textMatcher](`${data.random}messageToStar`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await expect(element(by.id('action-sheet'))).toExist();
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by[textMatcher]('Unstar')).atIndex(0).tap();
|
||||
|
||||
await waitFor(element(by[textMatcher](`${data.random}messageToStar`).withAncestor(by.id('starred-messages-view'))))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
await backToActions();
|
||||
});
|
||||
|
||||
it('should show pinned message and unpin it', async () => {
|
||||
// Go back to room and send a message
|
||||
await tapBack();
|
||||
await mockMessage('messageToPin');
|
||||
|
||||
// Pin the message
|
||||
await pinMessage('messageToPin');
|
||||
|
||||
// Back into Room Actions
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-pinned'))).toExist();
|
||||
await element(by.id('room-actions-pinned')).tap();
|
||||
await waitFor(element(by.id('pinned-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by[textMatcher](`${data.random}messageToPin`).withAncestor(by.id('pinned-messages-view'))))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await element(by[textMatcher](`${data.random}messageToPin`).withAncestor(by.id('pinned-messages-view')))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
|
||||
await expect(element(by.id('action-sheet'))).toExist();
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by[textMatcher]('Unpin')).atIndex(0).tap();
|
||||
|
||||
await waitFor(element(by[textMatcher](`${data.random}messageToPin`).withAncestor(by.id('pinned-messages-view'))))
|
||||
.not.toExist()
|
||||
.withTimeout(6000);
|
||||
await backToActions();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Notification', () => {
|
||||
it('should navigate to notification preference view', async () => {
|
||||
await waitFor(element(by.id('room-actions-scrollview')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-notifications')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-notifications')).tap();
|
||||
await waitFor(element(by.id('notification-preference-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should have receive notification option', async () => {
|
||||
await expect(element(by.id('notification-preference-view-receive-notification'))).toExist();
|
||||
});
|
||||
|
||||
it('should have show unread count option', async () => {
|
||||
await expect(element(by.id('notification-preference-view-mark-as-unread'))).toExist();
|
||||
});
|
||||
|
||||
it('should have notification alert option', async () => {
|
||||
await expect(element(by.id('notification-preference-view-alert'))).toExist();
|
||||
});
|
||||
|
||||
it('should have push notification option', async () => {
|
||||
await waitFor(element(by.id('notification-preference-view-push-notification')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
});
|
||||
|
||||
it('should have notification sound option', async () => {
|
||||
await waitFor(element(by.id('notification-preference-view-sound')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
});
|
||||
|
||||
it('should have email alert option', async () => {
|
||||
await waitFor(element(by.id('notification-preference-view-email-alert')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await backToActions();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Channel/Group', () => {
|
||||
// Currently, there's no way to add more owners to the room
|
||||
// So we test only for the 'You are the last owner...' message
|
||||
|
||||
const user = data.users.alternate;
|
||||
|
||||
it('should tap on leave channel and raise alert', async () => {
|
||||
await waitFor(element(by.id('room-actions-scrollview')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-leave-channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-leave-channel')).tap();
|
||||
await waitFor(element(by[textMatcher]('Yes, leave it!')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Yes, leave it!').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by[textMatcher]('You are the last owner. Please set new owner before leaving the room.')))
|
||||
.toExist()
|
||||
.withTimeout(8000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should add users to the room', async () => {
|
||||
await waitFor(element(by.id('room-actions-members')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-members')).tap();
|
||||
await waitFor(element(by.id('room-members-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
|
||||
await waitFor(element(by.id('room-actions-add-user')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('room-actions-add-user')).tap();
|
||||
|
||||
// add rocket.cat
|
||||
const rocketCat = 'rocket.cat';
|
||||
await waitFor(element(by.id(`select-users-view-item-${rocketCat}`)))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id(`select-users-view-item-${rocketCat}`)).tap();
|
||||
await waitFor(element(by.id(`selected-user-${rocketCat}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
|
||||
await waitFor(element(by.id('select-users-view-search')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('select-users-view-search')).tap();
|
||||
await element(by.id('select-users-view-search')).replaceText(user.username);
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id(`select-users-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id(`select-users-view-item-${user.username}`)).tap();
|
||||
await waitFor(element(by.id(`selected-user-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
await sleep(300);
|
||||
await backToActions();
|
||||
});
|
||||
|
||||
describe('Room Members', () => {
|
||||
beforeAll(async () => {
|
||||
await waitFor(element(by.id('room-actions-members')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-members')).tap();
|
||||
await waitFor(element(by.id('room-members-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
const openActionSheet = async (username: string) => {
|
||||
await waitFor(element(by.id(`room-members-view-item-${username}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
let n = 0;
|
||||
while (n < 3) {
|
||||
// Max tries three times, in case it does not register the click
|
||||
try {
|
||||
await element(by.id(`room-members-view-item-${username}`)).tap();
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up');
|
||||
return;
|
||||
} catch (e) {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const closeActionSheet = async () => {
|
||||
await element(by.id('action-sheet-handle')).swipe('down', 'fast', 0.6);
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(1000);
|
||||
await sleep(100);
|
||||
};
|
||||
|
||||
it('should show all users', async () => {
|
||||
await waitFor(element(by.id('room-members-view-filter')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-members-view-filter')).tap();
|
||||
await waitFor(element(by.id('room-members-view-toggle-status-all')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-members-view-toggle-status-all')).tap();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should filter user', async () => {
|
||||
await waitFor(element(by.id('room-actions-members')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-members')).tap();
|
||||
await element(by.id('room-members-view-filter')).tap();
|
||||
await waitFor(element(by.id('room-members-view-toggle-status-all')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-members-view-toggle-status-all')).tap();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('room-members-view-search')).replaceText('rocket');
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('room-members-view-search')).tap();
|
||||
await element(by.id('room-members-view-search')).clearText();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should remove user from room', async () => {
|
||||
await openActionSheet('rocket.cat');
|
||||
await waitFor(element(by[textMatcher]('Remove from room')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Remove from room')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('Are you sure?')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Yes, remove user!').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('room-members-view-item-rocket.cat')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should clear search', async () => {
|
||||
await element(by.id('room-members-view-search')).tap();
|
||||
await element(by.id('room-members-view-search')).clearText();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should set/remove as owner', async () => {
|
||||
await openActionSheet(user.username);
|
||||
await element(by.id('action-sheet-set-owner')).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await waitFor(element(by.id('action-sheet-set-owner-checked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(6000);
|
||||
await element(by.id('action-sheet-set-owner')).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await waitFor(element(by.id('action-sheet-set-owner-unchecked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await closeActionSheet();
|
||||
});
|
||||
|
||||
it('should set/remove as leader', async () => {
|
||||
await openActionSheet(user.username);
|
||||
await element(by.id('action-sheet-set-leader')).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await waitFor(element(by.id('action-sheet-set-leader-checked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(6000);
|
||||
await element(by.id('action-sheet-set-leader')).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await waitFor(element(by.id('action-sheet-set-owner-unchecked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await closeActionSheet();
|
||||
});
|
||||
|
||||
it('should set/remove as moderator', async () => {
|
||||
await openActionSheet(user.username);
|
||||
await element(by.id('action-sheet-set-moderator')).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await waitFor(element(by.id('action-sheet-set-moderator-checked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(6000);
|
||||
await element(by.id('action-sheet-set-moderator')).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await waitFor(element(by.id('action-sheet-set-moderator-unchecked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await closeActionSheet();
|
||||
});
|
||||
|
||||
it('should set/remove as mute', async () => {
|
||||
await openActionSheet(user.username);
|
||||
await element(by[textMatcher]('Mute')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('Are you sure?')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Mute').and(by.type(alertButtonType))).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await element(by[textMatcher]('Unmute')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('Are you sure?')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Unmute').and(by.type(alertButtonType))).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
// Tests if Remove as mute worked
|
||||
await waitFor(element(by[textMatcher]('Mute')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await closeActionSheet();
|
||||
});
|
||||
|
||||
it('should ignore user', async () => {
|
||||
const message = `${data.random}ignoredmessagecontent`;
|
||||
const channelName = `#${data.groups.private.name}`;
|
||||
await sendMessage(user, channelName, message);
|
||||
await openActionSheet(user.username);
|
||||
await element(by[textMatcher]('Ignore')).atIndex(0).tap();
|
||||
await waitForToast();
|
||||
await backToActions();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await waitFor(element(by[textMatcher]('Message ignored. Tap to display it.')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by[textMatcher]('Message ignored. Tap to display it.')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher](message)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by[textMatcher](message)).atIndex(0).tap();
|
||||
});
|
||||
|
||||
it('should navigate to direct message', async () => {
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('room-actions-members')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-members')).tap();
|
||||
await waitFor(element(by.id('room-members-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('room-members-view-filter')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-members-view-filter')).tap();
|
||||
await waitFor(element(by.id('room-members-view-toggle-status-all')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-members-view-toggle-status-all')).tap();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await openActionSheet(user.username);
|
||||
await element(by[textMatcher]('Direct message')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await waitFor(element(by.id(`room-view-title-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Direct', () => {
|
||||
beforeAll(async () => {
|
||||
await navigateToRoomActions('d');
|
||||
});
|
||||
|
||||
it('should block/unblock user', async () => {
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-block-user'))).toExist();
|
||||
await element(by.id('room-actions-block-user')).tap();
|
||||
await waitFor(element(by[textMatcher]('Unblock user')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('room-actions-block-user')).tap();
|
||||
await waitFor(element(by[textMatcher]('Block user')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,225 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import { TTextMatcher, navigateToLogin, login, mockMessage, tapBack, searchRoom, platformTypes } from '../../helpers/app';
|
||||
import data from '../../data';
|
||||
|
||||
const channel = data.groups.private.name;
|
||||
|
||||
const navigateToRoom = async () => {
|
||||
await searchRoom(channel);
|
||||
await element(by.id(`rooms-list-view-item-${channel}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
};
|
||||
|
||||
describe('Discussion', () => {
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true });
|
||||
({ textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
it('should create discussion from NewMessageView', async () => {
|
||||
const discussionName = `${data.random} Discussion NewMessageView`;
|
||||
await waitFor(element(by.id('rooms-list-view-create-channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Discussion')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('create-discussion-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('create-discussion-view'))).toExist();
|
||||
await element(by[textMatcher]('Select a Channel...')).tap();
|
||||
await element(by.id('multi-select-search')).replaceText(`${channel}`);
|
||||
await waitFor(element(by.id(`multi-select-item-${channel}`)))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id(`multi-select-item-${channel}`)).tap();
|
||||
await element(by.id('multi-select-discussion-name')).replaceText(discussionName);
|
||||
await waitFor(element(by.id('create-discussion-submit')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('create-discussion-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`room-view-title-${discussionName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${discussionName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should create discussion from action button', async () => {
|
||||
const discussionName = `${data.random} Discussion Action Button`;
|
||||
await navigateToRoom();
|
||||
await element(by.id('messagebox-actions')).tap();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Create Discussion')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('create-discussion-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('multi-select-discussion-name')).replaceText(discussionName);
|
||||
await waitFor(element(by.id('create-discussion-submit')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('create-discussion-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`room-view-title-${discussionName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
describe('Create Discussion from action sheet', () => {
|
||||
it('should send a message', async () => {
|
||||
await waitFor(element(by.id('messagebox')))
|
||||
.toBeVisible()
|
||||
.withTimeout(60000);
|
||||
await mockMessage('message');
|
||||
});
|
||||
|
||||
it('should create discussion', async () => {
|
||||
const discussionName = `${data.random}message`;
|
||||
await element(by[textMatcher](discussionName)).atIndex(0).longPress();
|
||||
await waitFor(element(by.id('action-sheet')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Start a Discussion')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('create-discussion-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('create-discussion-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`room-view-title-${discussionName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Check RoomActionsView render', () => {
|
||||
it('should navigate to RoomActionsView', async () => {
|
||||
await waitFor(element(by.id('room-header')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should have room actions screen', async () => {
|
||||
await expect(element(by.id('room-actions-view'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have info', async () => {
|
||||
await expect(element(by.id('room-actions-info'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have members', async () => {
|
||||
await expect(element(by.id('room-actions-members'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have files', async () => {
|
||||
await expect(element(by.id('room-actions-files'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have mentions', async () => {
|
||||
await expect(element(by.id('room-actions-mentioned'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have starred', async () => {
|
||||
await element(by.id('room-actions-scrollview')).swipe('up', 'slow', 0.5);
|
||||
await expect(element(by.id('room-actions-starred'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have share', async () => {
|
||||
await element(by.id('room-actions-scrollview')).swipe('up');
|
||||
await expect(element(by.id('room-actions-share'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should have pinned', async () => {
|
||||
await expect(element(by.id('room-actions-pinned'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should not have notifications', async () => {
|
||||
await expect(element(by.id('room-actions-notifications'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should not have leave channel', async () => {
|
||||
await expect(element(by.id('room-actions-leave-channel'))).toBeVisible();
|
||||
});
|
||||
|
||||
it('should navigate to RoomActionView', async () => {
|
||||
await element(by.id('room-actions-scrollview')).swipe('down');
|
||||
await expect(element(by.id('room-actions-info'))).toBeVisible();
|
||||
await element(by.id('room-actions-info')).tap();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('room-info-view'))).toExist();
|
||||
});
|
||||
|
||||
it('should have edit button', async () => {
|
||||
await expect(element(by.id('room-info-view-edit-button'))).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Open Discussion from DiscussionsView', () => {
|
||||
const discussionName = `${data.random}message`;
|
||||
it('should go back to main room', async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id(`room-view-title-${discussionName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await tapBack();
|
||||
await navigateToRoom();
|
||||
});
|
||||
|
||||
it('should navigate to DiscussionsView', async () => {
|
||||
await waitFor(element(by.id(`room-view-title-${channel}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('room-header')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-discussions')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-actions-discussions')).tap();
|
||||
await waitFor(element(by.id('discussions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should navigate to discussion', async () => {
|
||||
const discussionName = `${data.random} Discussion NewMessageView`;
|
||||
await waitFor(element(by.label(discussionName)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.label(discussionName)).atIndex(0).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${discussionName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,240 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import {
|
||||
navigateToLogin,
|
||||
login,
|
||||
mockMessage,
|
||||
tapBack,
|
||||
sleep,
|
||||
searchRoom,
|
||||
platformTypes,
|
||||
dismissReviewNag,
|
||||
TTextMatcher
|
||||
} from '../../helpers/app';
|
||||
|
||||
async function navigateToRoom(roomName: string) {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
await searchRoom(`${roomName}`);
|
||||
await element(by.id(`rooms-list-view-item-${roomName}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${roomName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
describe('Threads', () => {
|
||||
const mainRoom = data.groups.private.name;
|
||||
let textMatcher: TTextMatcher;
|
||||
|
||||
beforeAll(async () => {
|
||||
({ textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToRoom(mainRoom);
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have room screen', async () => {
|
||||
await waitFor(element(by.id(`room-view-title-${mainRoom}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
// Render - Header
|
||||
describe('Header', () => {
|
||||
it('should have actions button ', async () => {
|
||||
await expect(element(by.id('room-header'))).toExist();
|
||||
});
|
||||
|
||||
it('should have threads button ', async () => {
|
||||
await expect(element(by.id('room-view-header-threads'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
// Render - Messagebox
|
||||
describe('Messagebox', () => {
|
||||
it('should have messagebox', async () => {
|
||||
await expect(element(by.id('messagebox'))).toExist();
|
||||
});
|
||||
|
||||
it('should have open emoji button', async () => {
|
||||
if (device.getPlatform() === 'android') {
|
||||
await expect(element(by.id('messagebox-open-emoji'))).toExist();
|
||||
}
|
||||
});
|
||||
|
||||
it('should have message input', async () => {
|
||||
await expect(element(by.id('messagebox-input'))).toExist();
|
||||
});
|
||||
|
||||
it('should have audio button', async () => {
|
||||
await expect(element(by.id('messagebox-send-audio'))).toExist();
|
||||
});
|
||||
|
||||
it('should have actions button', async () => {
|
||||
await expect(element(by.id('messagebox-actions'))).toExist();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
describe('Thread', () => {
|
||||
const thread = `${data.random}thread`;
|
||||
it('should create thread', async () => {
|
||||
await mockMessage('thread');
|
||||
await element(by[textMatcher](thread)).atIndex(0).longPress();
|
||||
await expect(element(by.id('action-sheet'))).toExist();
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Reply in Thread')).atIndex(0).tap();
|
||||
await element(by.id('messagebox-input')).replaceText('replied');
|
||||
await waitFor(element(by.id('messagebox-send-message')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await waitFor(element(by.id(`message-thread-button-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id(`message-thread-button-${thread}`))).toExist();
|
||||
});
|
||||
|
||||
it('should navigate to thread from button', async () => {
|
||||
await element(by.id(`message-thread-button-${thread}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id(`room-view-title-${thread}`))).toExist();
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should toggle follow thread', async () => {
|
||||
await element(by.id(`message-thread-button-${thread}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-view-header-unfollow')).tap();
|
||||
await waitFor(element(by.id('room-view-header-follow')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('room-view-header-follow'))).toExist();
|
||||
await element(by.id('room-view-header-follow')).tap();
|
||||
await waitFor(element(by.id('room-view-header-unfollow')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id('room-view-header-unfollow'))).toExist();
|
||||
});
|
||||
|
||||
it('should send message in thread only', async () => {
|
||||
const messageText = 'threadonly';
|
||||
await mockMessage(messageText, true);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id(`room-view-title-${data.random}thread`)))
|
||||
.not.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`room-view-title-${mainRoom}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by[textMatcher](`${data.random}${messageText}`)).atIndex(0))
|
||||
.toNotExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should mark send to channel and show on main channel', async () => {
|
||||
const messageText = 'sendToChannel';
|
||||
await element(by.id(`message-thread-button-${thread}`)).tap();
|
||||
await waitFor(element(by.id('messagebox-input-thread')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('messagebox-input-thread')).replaceText(messageText);
|
||||
await element(by.id('messagebox-send-to-channel')).tap();
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id(`room-view-title-${data.random}thread`)))
|
||||
.not.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`room-view-title-${mainRoom}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by[textMatcher](messageText)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should navigate to thread from thread name', async () => {
|
||||
const messageText = 'navthreadname';
|
||||
await mockMessage('dummymessagebetweenthethread'); // TODO: Create a proper test for this elsewhere.
|
||||
await dismissReviewNag();
|
||||
await element(by.id(`message-thread-button-${thread}`)).tap();
|
||||
await waitFor(element(by.id('messagebox-input-thread')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('messagebox-input-thread')).replaceText(messageText);
|
||||
await element(by.id('messagebox-send-to-channel')).tap();
|
||||
await element(by.id('messagebox-send-message')).tap();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id(`room-view-title-${data.random}thread`)))
|
||||
.not.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`room-view-title-${mainRoom}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`message-thread-replied-on-${thread}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id(`message-thread-replied-on-${thread}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id(`room-view-title-${thread}`))).toExist();
|
||||
await sleep(2000);
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should navigate to thread from threads view', async () => {
|
||||
await waitFor(element(by.id('room-view-header-threads')))
|
||||
.toExist()
|
||||
.withTimeout(1000);
|
||||
await element(by.id('room-view-header-threads')).tap();
|
||||
await waitFor(element(by.id('thread-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`thread-messages-view-${thread}`))
|
||||
.atIndex(0)
|
||||
.tap();
|
||||
await waitFor(element(by.id(`room-view-title-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id(`room-view-title-${thread}`))).toExist();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('thread-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id('thread-messages-view'))).toExist();
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should draft thread message', async () => {
|
||||
await element(by.id(`message-thread-button-${thread}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('messagebox-input-thread')).replaceText(`${thread}draft`);
|
||||
await tapBack();
|
||||
|
||||
await element(by.id(`message-thread-button-${thread}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id('messagebox-input-thread'))).toHaveText(`${thread}draft`);
|
||||
await element(by.id('messagebox-input-thread')).clearText();
|
||||
await tapBack();
|
||||
|
||||
await element(by.id(`message-thread-button-${thread}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${thread}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id('messagebox-input-thread'))).toHaveText('');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,61 @@
|
|||
import data from '../../data';
|
||||
import { navigateToLogin, login, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
describe('Group DM', () => {
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('Create Group DM', () => {
|
||||
beforeAll(async () => {
|
||||
await waitFor(element(by.id('rooms-list-view-create-channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have new message screen', async () => {
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should have search input', async () => {
|
||||
await waitFor(element(by.id('new-message-view-search')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should navigate to create DM', async () => {
|
||||
await element(by[textMatcher]('Direct message')).atIndex(0).tap();
|
||||
});
|
||||
|
||||
it('should add users', async () => {
|
||||
await element(by.id('select-users-view-search')).replaceText('rocket.cat');
|
||||
await waitFor(element(by.id('select-users-view-item-rocket.cat')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('select-users-view-item-rocket.cat')).tap();
|
||||
await element(by.id('select-users-view-search')).replaceText(data.users.existing.username);
|
||||
await waitFor(element(by.id(`select-users-view-item-${data.users.existing.username}`)))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id(`select-users-view-item-${data.users.existing.username}`)).tap();
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
});
|
||||
|
||||
it('check Group DM exist', async () => {
|
||||
await waitFor(element(by.id(`room-view-title-${data.users.existing.username}, rocket.cat`)))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,50 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, searchRoom, sleep, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
import { sendMessage } from '../../helpers/data_setup';
|
||||
|
||||
async function navigateToRoom(user: string) {
|
||||
await searchRoom(`${user}`);
|
||||
await element(by.id(`rooms-list-view-item-${user}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
describe('Mark as unread', () => {
|
||||
const user = data.users.alternate.username;
|
||||
let textMatcher: TTextMatcher;
|
||||
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
await navigateToRoom(user);
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
describe('Mark message as unread', () => {
|
||||
it('should mark message as unread', async () => {
|
||||
const message = `${data.random}message-mark-as-unread`;
|
||||
const channelName = `@${data.users.regular.username}`;
|
||||
await sendMessage(data.users.alternate, channelName, message);
|
||||
await waitFor(element(by[textMatcher](message)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await sleep(300);
|
||||
await element(by[textMatcher](message)).atIndex(0).longPress();
|
||||
await waitFor(element(by.id('action-sheet-handle')))
|
||||
.toBeVisible()
|
||||
.withTimeout(3000);
|
||||
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
|
||||
await element(by[textMatcher]('Mark Unread')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by.id(`rooms-list-view-item-${data.users.alternate.username}`))).toExist();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,324 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, tapBack, sleep, searchRoom, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
const privateRoomName = data.groups.private.name;
|
||||
|
||||
async function navigateToRoomInfo(type: string) {
|
||||
let room;
|
||||
if (type === 'd') {
|
||||
room = 'rocket.cat';
|
||||
} else {
|
||||
room = privateRoomName;
|
||||
}
|
||||
await searchRoom(room);
|
||||
await element(by.id(`rooms-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-actions-info')).tap();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
|
||||
async function swipe(direction: Detox.Direction) {
|
||||
await element(by.id('room-info-edit-view-list')).swipe(direction, 'fast', 0.8);
|
||||
}
|
||||
|
||||
async function waitForToast() {
|
||||
await sleep(300);
|
||||
}
|
||||
|
||||
describe('Room info screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('Direct', () => {
|
||||
beforeAll(async () => {
|
||||
await navigateToRoomInfo('d');
|
||||
});
|
||||
|
||||
it('should navigate to room info', async () => {
|
||||
await expect(element(by.id('room-info-view'))).toExist();
|
||||
await expect(element(by.id('room-info-view-name'))).toExist();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await tapBack();
|
||||
await tapBack();
|
||||
await tapBack();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Channel/Group', () => {
|
||||
beforeAll(async () => {
|
||||
await navigateToRoomInfo('c');
|
||||
});
|
||||
|
||||
describe('Render', () => {
|
||||
it('should have room info view', async () => {
|
||||
await expect(element(by.id('room-info-view'))).toExist();
|
||||
});
|
||||
|
||||
it('should have name', async () => {
|
||||
await expect(element(by.id('room-info-view-name'))).toExist();
|
||||
});
|
||||
|
||||
it('should have description', async () => {
|
||||
await expect(element(by[textMatcher]('Description'))).toExist();
|
||||
});
|
||||
|
||||
it('should have topic', async () => {
|
||||
await expect(element(by[textMatcher]('Topic'))).toExist();
|
||||
});
|
||||
|
||||
it('should have announcement', async () => {
|
||||
await expect(element(by[textMatcher]('Announcement'))).toExist();
|
||||
});
|
||||
|
||||
it('should have edit button', async () => {
|
||||
await expect(element(by.id('room-info-view-edit-button'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Render Edit', () => {
|
||||
beforeAll(async () => {
|
||||
await waitFor(element(by.id('room-info-view-edit-button')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-info-view-edit-button')).tap();
|
||||
await waitFor(element(by.id('room-info-edit-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should have room info edit view', async () => {
|
||||
await expect(element(by.id('room-info-edit-view'))).toExist();
|
||||
});
|
||||
|
||||
it('should have name input', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-name'))).toExist();
|
||||
});
|
||||
|
||||
it('should have description input', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-description'))).toExist();
|
||||
});
|
||||
|
||||
it('should have topic input', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-topic'))).toExist();
|
||||
});
|
||||
|
||||
it('should have announcement input', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-announcement'))).toExist();
|
||||
});
|
||||
|
||||
it('should have password input', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-password'))).toExist();
|
||||
});
|
||||
|
||||
it('should have type switch', async () => {
|
||||
await swipe('up');
|
||||
await expect(element(by.id('room-info-edit-view-t'))).toExist();
|
||||
});
|
||||
|
||||
it('should have ready only switch', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-ro'))).toExist();
|
||||
});
|
||||
|
||||
it('should have submit button', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-submit'))).toExist();
|
||||
});
|
||||
|
||||
it('should have reset button', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-reset'))).toExist();
|
||||
});
|
||||
|
||||
it('should have archive button', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-archive'))).toExist();
|
||||
});
|
||||
|
||||
it('should have delete button', async () => {
|
||||
await expect(element(by.id('room-info-edit-view-delete'))).toExist();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await swipe('down');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
it('should change room name', async () => {
|
||||
await element(by.id('room-info-edit-view-name')).replaceText(`${privateRoomName}new`);
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await swipe('up');
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
const matcher = device.getPlatform() === 'android' ? 'toHaveText' : 'toHaveLabel';
|
||||
await expect(element(by.id('room-info-view-name')))[matcher](`${privateRoomName}new`);
|
||||
// change name to original
|
||||
await element(by.id('room-info-view-edit-button')).tap();
|
||||
await waitFor(element(by.id('room-info-edit-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await sleep(2000);
|
||||
await element(by.id('room-info-edit-view-name')).replaceText(`${privateRoomName}`);
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
await swipe('down');
|
||||
});
|
||||
|
||||
it('should reset form', async () => {
|
||||
await sleep(2000);
|
||||
await element(by.id('room-info-edit-view-name')).replaceText('abc');
|
||||
await element(by.id('room-info-edit-view-description')).replaceText('abc');
|
||||
await element(by.id('room-info-edit-view-topic')).replaceText('abc');
|
||||
await element(by.id('room-info-edit-view-announcement')).replaceText('abc');
|
||||
await element(by.id('room-info-edit-view-password')).replaceText('abc');
|
||||
await element(by.id('room-info-edit-view-t')).tap();
|
||||
await swipe('up');
|
||||
await element(by.id('room-info-edit-view-ro')).longPress(); // https://github.com/facebook/react-native/issues/28032
|
||||
await element(by.id('room-info-edit-view-react-when-ro')).tap();
|
||||
await swipe('up');
|
||||
await element(by.id('room-info-edit-view-reset')).tap();
|
||||
// after reset
|
||||
await element(by.id('room-info-edit-view-list')).swipe('down', 'fast', 0.5);
|
||||
await expect(element(by.id('room-info-edit-view-name'))).toHaveText(privateRoomName);
|
||||
await expect(element(by.id('room-info-edit-view-description'))).toHaveText('');
|
||||
await expect(element(by.id('room-info-edit-view-topic'))).toHaveText('');
|
||||
await expect(element(by.id('room-info-edit-view-announcement'))).toHaveText('');
|
||||
await expect(element(by.id('room-info-edit-view-password'))).toHaveText('');
|
||||
// await swipe('down');
|
||||
await expect(element(by.id('room-info-edit-view-t'))).toHaveToggleValue(true);
|
||||
await expect(element(by.id('room-info-edit-view-ro'))).toHaveToggleValue(false);
|
||||
await expect(element(by.id('room-info-edit-view-react-when-ro'))).toBeNotVisible();
|
||||
await swipe('down');
|
||||
});
|
||||
|
||||
it('should change room description', async () => {
|
||||
await element(by.id('room-info-edit-view-description')).replaceText('new description');
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by[textMatcher]('new description').withAncestor(by.id('room-info-view-description')))).toExist();
|
||||
});
|
||||
|
||||
it('should change room topic', async () => {
|
||||
await waitFor(element(by.id('room-info-view-edit-button')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-info-view-edit-button')).tap();
|
||||
await waitFor(element(by.id('room-info-edit-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await sleep(2000);
|
||||
await element(by.id('room-info-edit-view-topic')).replaceText('new topic');
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by[textMatcher]('new topic').withAncestor(by.id('room-info-view-topic')))).toExist();
|
||||
});
|
||||
|
||||
it('should change room announcement', async () => {
|
||||
await waitFor(element(by.id('room-info-view-edit-button')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-info-view-edit-button')).tap();
|
||||
await waitFor(element(by.id('room-info-edit-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await sleep(2000);
|
||||
await element(by.id('room-info-edit-view-announcement')).replaceText('new announcement');
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await expect(element(by[textMatcher]('new announcement').withAncestor(by.id('room-info-view-announcement')))).toExist();
|
||||
});
|
||||
|
||||
it('should change room password', async () => {
|
||||
await waitFor(element(by.id('room-info-view-edit-button')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-info-view-edit-button')).tap();
|
||||
await waitFor(element(by.id('room-info-edit-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await sleep(2000);
|
||||
await element(by.id('room-info-edit-view-password')).replaceText('password');
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
});
|
||||
|
||||
it('should change room type', async () => {
|
||||
await swipe('down');
|
||||
await element(by.id('room-info-edit-view-t')).tap();
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
await swipe('down');
|
||||
await element(by.id('room-info-edit-view-t')).tap();
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-submit')).tap();
|
||||
await waitForToast();
|
||||
});
|
||||
|
||||
it('should archive room', async () => {
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-archive')).tap();
|
||||
await waitFor(element(by[textMatcher]('Yes, archive it!')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Yes, archive it!').and(by.type(alertButtonType))).tap();
|
||||
await waitForToast();
|
||||
// await waitFor(element(by.id('room-info-edit-view-unarchive')))
|
||||
// .toExist()
|
||||
// .withTimeout(60000);
|
||||
// await expect(element(by.id('room-info-edit-view-archive'))).toBeNotVisible();
|
||||
});
|
||||
|
||||
it('should delete room', async () => {
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-delete')).tap();
|
||||
await waitFor(element(by[textMatcher]('Yes, delete it!')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Yes, delete it!').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${privateRoomName}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,266 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, tapBack, login, searchRoom, sleep, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
async function navigateToRoom(roomName: string) {
|
||||
await searchRoom(`${roomName}`);
|
||||
await element(by.id(`rooms-list-view-item-${roomName}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`room-view-title-${roomName}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
let textMatcher: TTextMatcher;
|
||||
let alertButtonType: string;
|
||||
|
||||
async function clearCache() {
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('rooms-list-view-sidebar')).tap();
|
||||
await waitFor(element(by.id('sidebar-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('sidebar-settings')).tap();
|
||||
await waitFor(element(by.id('settings-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('settings-view-clear-cache')).tap();
|
||||
await waitFor(element(by[textMatcher]('This will clear all your offline data.')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Clear').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('rooms-list-view-item-jumping')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
}
|
||||
|
||||
async function waitForLoading() {
|
||||
if (device.getPlatform() === 'android') {
|
||||
await sleep(10000);
|
||||
return; // FIXME: Loading indicator doesn't animate properly on android
|
||||
}
|
||||
await waitFor(element(by.id('loading-image')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('loading-image')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(10000);
|
||||
}
|
||||
|
||||
describe('Room', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.adminUser, data.adminPassword);
|
||||
});
|
||||
|
||||
it('should jump to an old message and load its surroundings', async () => {
|
||||
await navigateToRoom('jumping');
|
||||
await waitFor(element(by[textMatcher]('295')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await sleep(2000);
|
||||
await element(by[textMatcher]('1')).atIndex(0).tap();
|
||||
await waitForLoading();
|
||||
await waitFor(element(by[textMatcher]('1')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await expect(element(by[textMatcher]('2'))).toExist();
|
||||
});
|
||||
|
||||
it('should tap FAB and scroll to bottom', async () => {
|
||||
await waitFor(element(by.id('nav-jump-to-bottom')))
|
||||
.toExist()
|
||||
.withTimeout(15000);
|
||||
await element(by.id('nav-jump-to-bottom')).tap();
|
||||
await waitFor(element(by[textMatcher]("Go to jumping-thread's thread")))
|
||||
.toExist()
|
||||
.withTimeout(15000);
|
||||
await clearCache();
|
||||
});
|
||||
|
||||
it('should load messages on scroll', async () => {
|
||||
await navigateToRoom('jumping');
|
||||
await waitFor(element(by.id('room-view-messages')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by[textMatcher]('300')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
let found = false;
|
||||
while (!found) {
|
||||
try {
|
||||
const direction = device.getPlatform() === 'android' ? 'down' : 'up';
|
||||
await element(by.id('room-view-messages')).scroll(500, direction);
|
||||
await expect(element(by[textMatcher]('249'))).toExist();
|
||||
found = true;
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
}
|
||||
await clearCache();
|
||||
});
|
||||
|
||||
it('should search for old message and load its surroundings', async () => {
|
||||
await navigateToRoom('jumping');
|
||||
await sleep(1000); // wait for proper load the room
|
||||
await element(by.id('room-view-search')).tap();
|
||||
await waitFor(element(by.id('search-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('search-message-view-input')).replaceText('30');
|
||||
await waitFor(element(by[textMatcher]('30')).atIndex(1))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await sleep(1000);
|
||||
await element(by[textMatcher]('30')).atIndex(1).tap();
|
||||
await waitForLoading();
|
||||
await waitFor(element(by[textMatcher]('30')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await expect(element(by[textMatcher]('31'))).toExist();
|
||||
await expect(element(by[textMatcher]('32'))).toExist();
|
||||
});
|
||||
|
||||
it('should load newer and older messages', async () => {
|
||||
// TODO: couldn't make it work on Android :(
|
||||
if (device.getPlatform() === 'android') {
|
||||
return;
|
||||
}
|
||||
let found = false;
|
||||
while (!found) {
|
||||
try {
|
||||
// it doesn't recognize this list
|
||||
await element(by.id('room-view-messages')).scroll(500, 'up');
|
||||
await expect(element(by[textMatcher]('Load Older'))).toBeVisible();
|
||||
await expect(element(by[textMatcher]('5'))).toExist();
|
||||
found = true;
|
||||
} catch {
|
||||
//
|
||||
}
|
||||
}
|
||||
await element(by[textMatcher]('Load Older')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('4')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-view-messages')).atIndex(0).swipe('down', 'fast', 0.5);
|
||||
await waitFor(element(by[textMatcher]('1')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-view-messages')).atIndex(0).swipe('up', 'fast', 0.5);
|
||||
await waitFor(element(by[textMatcher]('25')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-view-messages')).atIndex(0).swipe('up', 'fast', 0.5);
|
||||
await waitFor(element(by[textMatcher]('50')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-view-messages')).atIndex(0).swipe('up', 'slow', 0.4);
|
||||
await waitFor(element(by[textMatcher]('Load Newer')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Load Newer')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('104')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by[textMatcher]('Load Newer')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Load Newer')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('154')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by[textMatcher]('Load Newer')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Load Newer')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('Load Newer')))
|
||||
.toNotExist()
|
||||
.withTimeout(5000);
|
||||
await expect(element(by[textMatcher]('Load More'))).toNotExist();
|
||||
await expect(element(by[textMatcher]('201'))).toExist();
|
||||
await expect(element(by[textMatcher]('202'))).toExist();
|
||||
await tapBack();
|
||||
});
|
||||
});
|
||||
|
||||
const expectThreadMessages = async (message: string) => {
|
||||
await waitFor(element(by.id('room-view-title-thread 1')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by[textMatcher](message)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by[textMatcher](message)).atIndex(0).tap();
|
||||
};
|
||||
|
||||
describe('Threads', () => {
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true });
|
||||
});
|
||||
|
||||
it('should navigate to a thread from another room', async () => {
|
||||
await navigateToRoom('jumping');
|
||||
await waitFor(element(by[textMatcher]("Go to jumping-thread's thread")).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]("Go to jumping-thread's thread")).atIndex(0).tap();
|
||||
await expectThreadMessages("Go to jumping-thread's thread");
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should tap on thread message from main room', async () => {
|
||||
await waitFor(element(by.id('room-view-title-jumping-thread')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by[textMatcher]('thread message sent to main room')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by[textMatcher]('thread message sent to main room')).atIndex(0).tap();
|
||||
await expectThreadMessages('thread message sent to main room');
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should tap on quote', async () => {
|
||||
await waitFor(element(by.id('room-view-title-jumping-thread')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by[textMatcher]('quoted')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('quoted')).atIndex(0).tap();
|
||||
await expectThreadMessages('quoted');
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should jump from search message', async () => {
|
||||
await waitFor(element(by.id('room-view-title-jumping-thread')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-view-search')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('search-messages-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('search-message-view-input')).replaceText('to be searched');
|
||||
await waitFor(element(by[textMatcher]('to be searched')).atIndex(1))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await element(by[textMatcher]('to be searched')).atIndex(1).tap();
|
||||
await expectThreadMessages('to be searched');
|
||||
});
|
||||
|
||||
// TODO: Threads pagination
|
||||
});
|
|
@ -0,0 +1,104 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, searchRoom, sleep, platformTypes, TTextMatcher, tapBack } from '../../helpers/app';
|
||||
import { sendMessage } from '../../helpers/data_setup';
|
||||
|
||||
async function navigateToRoom(user: string) {
|
||||
await searchRoom(`${user}`);
|
||||
await element(by.id(`rooms-list-view-item-${user}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function navigateToInfoView() {
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-actions-info')).tap();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
|
||||
describe('Ignore/Block User', () => {
|
||||
const user = data.users.alternate.username;
|
||||
let textMatcher: TTextMatcher;
|
||||
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('Usage', () => {
|
||||
describe('Block user from DM', () => {
|
||||
it('should go to user info view', async () => {
|
||||
await navigateToRoom(user);
|
||||
await navigateToInfoView();
|
||||
});
|
||||
it('should block user', async () => {
|
||||
await waitFor(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Block user'))))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-info-view-ignore')).tap();
|
||||
await waitFor(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Unblock user'))))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await tapBack();
|
||||
await expect(element(by[textMatcher]('This room is blocked'))).toExist();
|
||||
});
|
||||
|
||||
it('should unblock user', async () => {
|
||||
await navigateToInfoView();
|
||||
await element(by.id('room-info-view-ignore')).tap();
|
||||
await expect(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Block user')))).toExist();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await tapBack();
|
||||
await expect(element(by.id('messagebox'))).toBeVisible();
|
||||
await tapBack();
|
||||
});
|
||||
});
|
||||
describe('Ignore user from Message', () => {
|
||||
it('should ignore user from message', async () => {
|
||||
const channelName = data.userRegularChannels.detoxpublic.name;
|
||||
await navigateToRoom(channelName);
|
||||
await sleep(300);
|
||||
await sendMessage(data.users.alternate, channelName, 'message-01');
|
||||
await sendMessage(data.users.alternate, channelName, 'message-02');
|
||||
await waitFor(element(by[textMatcher](user)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(30000);
|
||||
await sleep(300);
|
||||
await element(by[textMatcher](user)).atIndex(0).tap();
|
||||
await expect(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Ignore')))).toExist();
|
||||
await element(by.id('room-info-view-ignore')).tap();
|
||||
await expect(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Unignore')))).toExist();
|
||||
await tapBack();
|
||||
});
|
||||
it('should tap to display message', async () => {
|
||||
await expect(element(by[textMatcher]('Message ignored. Tap to display it.')).atIndex(0)).toExist();
|
||||
await element(by[textMatcher]('Message ignored. Tap to display it.')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher](user)))
|
||||
.toBeVisible()
|
||||
.withTimeout(1000);
|
||||
await element(by[textMatcher](user)).atIndex(0).tap();
|
||||
await expect(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Unignore')))).toExist();
|
||||
await element(by.id('room-info-view-ignore')).tap();
|
||||
await expect(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Ignore')))).toExist();
|
||||
await tapBack();
|
||||
await expect(element(by[textMatcher]('message-02')).atIndex(0)).toBeVisible();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,110 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
const teamName = `team-${data.random}`;
|
||||
|
||||
describe('Create team screen', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('New Message', () => {
|
||||
beforeAll(async () => {
|
||||
await waitFor(element(by.id('rooms-list-view-create-channel')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
});
|
||||
|
||||
it('should have team button', async () => {
|
||||
await waitFor(element(by.id('new-message-view-create-team')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should navigate to select users', async () => {
|
||||
await element(by.id('new-message-view-create-team')).tap();
|
||||
await waitFor(element(by.id('select-users-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Select Users', () => {
|
||||
it('should nav to create team', async () => {
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
await waitFor(element(by.id('create-channel-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Create Team', () => {
|
||||
describe('Usage', () => {
|
||||
it('should get invalid team name', async () => {
|
||||
await element(by.id('create-channel-name')).replaceText(`${data.teams.private.name}`);
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('OK').and(by.type(alertButtonType))))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
});
|
||||
|
||||
it('should create private team', async () => {
|
||||
await element(by.id('create-channel-name')).replaceText('');
|
||||
await element(by.id('create-channel-name')).replaceText(teamName);
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(20000);
|
||||
await expect(element(by.id('room-view'))).toExist();
|
||||
await waitFor(element(by.id(`room-view-title-${teamName}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await expect(element(by.id(`room-view-title-${teamName}`))).toExist();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Delete Team', () => {
|
||||
it('should navigate to room info edit view', async () => {
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-actions-info')).tap();
|
||||
await waitFor(element(by.id('room-info-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should delete team', async () => {
|
||||
await element(by.id('room-info-view-edit-button')).tap();
|
||||
await element(by.id('room-info-edit-view-list')).swipe('up', 'fast', 0.5);
|
||||
await element(by.id('room-info-edit-view-delete')).tap();
|
||||
await waitFor(element(by[textMatcher]('Yes, delete it!')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by[textMatcher]('Yes, delete it!').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${teamName}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,491 @@
|
|||
import { expect } from 'detox';
|
||||
|
||||
import data from '../../data';
|
||||
import { navigateToLogin, login, tapBack, sleep, searchRoom, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
async function navigateToRoom(roomName: string) {
|
||||
await searchRoom(`${roomName}`);
|
||||
await element(by.id(`rooms-list-view-item-${roomName}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function openActionSheet(username: string) {
|
||||
await waitFor(element(by.id(`room-members-view-item-${username}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`room-members-view-item-${username}`)).tap();
|
||||
await sleep(300);
|
||||
await expect(element(by.id('action-sheet'))).toExist();
|
||||
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
|
||||
await element(by.id('action-sheet-handle')).swipe('up');
|
||||
}
|
||||
|
||||
async function navigateToRoomActions() {
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function backToActions() {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
}
|
||||
async function closeActionSheet() {
|
||||
await element(by.id('action-sheet-handle')).swipe('down', 'fast', 0.6);
|
||||
await waitFor(element(by.id('action-sheet-handle')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(3000);
|
||||
await sleep(200);
|
||||
}
|
||||
|
||||
async function waitForToast() {
|
||||
await sleep(1000);
|
||||
}
|
||||
|
||||
async function swipeTillVisible(
|
||||
container: Detox.NativeMatcher,
|
||||
find: Detox.NativeMatcher,
|
||||
direction: Detox.Direction = 'up',
|
||||
delta = 0.3,
|
||||
speed: Detox.Speed = 'slow'
|
||||
) {
|
||||
let found = false;
|
||||
while (!found) {
|
||||
try {
|
||||
await element(container).swipe(direction, speed, delta);
|
||||
await sleep(200);
|
||||
await expect(element(find)).toBeVisible();
|
||||
found = true;
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe('Team', () => {
|
||||
const team = data.teams.private.name;
|
||||
const user = data.users.alternate;
|
||||
const room = `private${data.random}-channel-team`;
|
||||
const existingRoom = data.groups.alternate.name;
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
await navigateToRoom(team);
|
||||
});
|
||||
|
||||
describe('Team Room', () => {
|
||||
describe('Team Header', () => {
|
||||
it('should have actions button ', async () => {
|
||||
await expect(element(by.id('room-header'))).toExist();
|
||||
});
|
||||
|
||||
it('should have team channels button ', async () => {
|
||||
await expect(element(by.id('room-view-header-team-channels'))).toExist();
|
||||
});
|
||||
|
||||
it('should have threads button ', async () => {
|
||||
await expect(element(by.id('room-view-header-threads'))).toExist();
|
||||
});
|
||||
|
||||
it('should have threads button ', async () => {
|
||||
await expect(element(by.id('room-view-search'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Team Header Usage', () => {
|
||||
it('should navigate to team channels view', async () => {
|
||||
await element(by.id('room-view-header-team-channels')).tap();
|
||||
await waitFor(element(by.id('team-channels-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Team Channels Header', () => {
|
||||
it('should have actions button ', async () => {
|
||||
await expect(element(by.id('room-header')).atIndex(0)).toExist();
|
||||
});
|
||||
|
||||
it('should have team channels button ', async () => {
|
||||
await expect(element(by.id('team-channels-view-create'))).toExist();
|
||||
});
|
||||
|
||||
it('should have threads button ', async () => {
|
||||
await expect(element(by.id('team-channels-view-search'))).toExist();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Team Channels Header Usage', () => {
|
||||
it('should navigate to add team channels view', async () => {
|
||||
await element(by.id('team-channels-view-create')).tap();
|
||||
await waitFor(element(by.id('add-channel-team-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should have create new button', async () => {
|
||||
await waitFor(element(by.id('add-channel-team-view-create-channel')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
|
||||
it('should add existing button', async () => {
|
||||
await waitFor(element(by.id('add-channel-team-view-add-existing')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Channels', () => {
|
||||
it('should create new channel for team', async () => {
|
||||
await element(by.id('add-channel-team-view-create-channel')).tap();
|
||||
|
||||
await element(by.id('select-users-view-search')).replaceText('rocket.cat');
|
||||
await waitFor(element(by.id('select-users-view-item-rocket.cat')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('select-users-view-item-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('selected-user-rocket.cat')))
|
||||
.toBeVisible()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
|
||||
await waitFor(element(by.id('create-channel-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('create-channel-name')).replaceText('');
|
||||
await element(by.id('create-channel-name')).replaceText(room);
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(20000);
|
||||
await expect(element(by.id('room-view'))).toExist();
|
||||
await expect(element(by.id('room-view-header-team-channels'))).toExist();
|
||||
await element(by.id('room-view-header-team-channels')).tap();
|
||||
|
||||
await waitFor(element(by.id('team-channels-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await expect(element(by.id(`rooms-list-view-item-${room}`))).toExist();
|
||||
await element(by.id(`rooms-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id(`room-view-title-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id(`room-view-title-${room}`))).toExist();
|
||||
await expect(element(by.id('room-view-header-team-channels')).atIndex(0)).toExist();
|
||||
await expect(element(by.id('room-view-header-threads')).atIndex(0)).toExist();
|
||||
await expect(element(by.id('room-view-search')).atIndex(0)).toExist();
|
||||
await tapBack();
|
||||
});
|
||||
|
||||
it('should add existing channel to team', async () => {
|
||||
await navigateToRoom(team);
|
||||
await waitFor(element(by.id('room-view-header-team-channels')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('room-view-header-team-channels')).tap();
|
||||
await waitFor(element(by.id('team-channels-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('team-channels-view-create')).tap();
|
||||
await waitFor(element(by.id('add-channel-team-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
|
||||
await element(by.id('add-channel-team-view-add-existing')).tap();
|
||||
await waitFor(element(by.id('add-existing-channel-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await expect(element(by.id(`add-existing-channel-view-item-${existingRoom}`))).toExist();
|
||||
await element(by.id(`add-existing-channel-view-item-${existingRoom}`)).tap();
|
||||
await waitFor(element(by.id('add-existing-channel-view-submit')))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await element(by.id('add-existing-channel-view-submit')).tap();
|
||||
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(20000);
|
||||
await expect(element(by.id('room-view'))).toExist();
|
||||
await expect(element(by.id('room-view-header-team-channels'))).toExist();
|
||||
await element(by.id('room-view-header-team-channels')).tap();
|
||||
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${existingRoom}`)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
it('should activate/deactivate auto-join to channel', async () => {
|
||||
await element(by.id(`rooms-list-view-item-${existingRoom}`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
await sleep(500);
|
||||
await swipeTillVisible(by.id('action-sheet-remove-from-team'), by.id('action-sheet-delete'));
|
||||
await waitFor(element(by.id('action-sheet-auto-join')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('auto-join-unchecked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('action-sheet-remove-from-team')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id('action-sheet-delete')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
|
||||
await element(by.id('auto-join-unchecked')).tap();
|
||||
await waitFor(element(by.id('auto-join-tag')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`rooms-list-view-item-${existingRoom}`))
|
||||
.atIndex(0)
|
||||
.longPress();
|
||||
|
||||
await waitFor(element(by.id('auto-join-checked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('auto-join-checked')).tap();
|
||||
await waitFor(element(by.id('auto-join-tag')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${existingRoom}`)).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Team actions', () => {
|
||||
beforeAll(async () => {
|
||||
await tapBack();
|
||||
await navigateToRoomActions();
|
||||
});
|
||||
|
||||
it('should add users to the team', async () => {
|
||||
await element(by.id('room-actions-members')).tap();
|
||||
await waitFor(element(by.id('room-members-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
|
||||
await waitFor(element(by.id('room-actions-add-user')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-actions-add-user')).tap();
|
||||
|
||||
const rocketCat = 'rocket.cat';
|
||||
await element(by.id('select-users-view-search')).replaceText('rocket.cat');
|
||||
await waitFor(element(by.id(`select-users-view-item-${rocketCat}`)))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id(`select-users-view-item-${rocketCat}`)).tap();
|
||||
await waitFor(element(by.id(`selected-user-${rocketCat}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
|
||||
await waitFor(element(by.id('select-users-view-search')))
|
||||
.toExist()
|
||||
.withTimeout(4000);
|
||||
await element(by.id('select-users-view-search')).tap();
|
||||
await element(by.id('select-users-view-search')).replaceText(user.username);
|
||||
await waitFor(element(by.id(`select-users-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id(`select-users-view-item-${user.username}`)).tap();
|
||||
await waitFor(element(by.id(`selected-user-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
await sleep(300);
|
||||
await tapBack();
|
||||
await sleep(300);
|
||||
await waitFor(element(by.id('room-actions-members')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('room-actions-members')).tap();
|
||||
await element(by.id('room-members-view-filter')).tap();
|
||||
await waitFor(element(by.id('room-members-view-toggle-status-all')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-members-view-toggle-status-all')).tap();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await backToActions();
|
||||
});
|
||||
|
||||
it('should try to leave to leave team and raise alert', async () => {
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-leave-channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-leave-channel')).tap();
|
||||
|
||||
await waitFor(element(by.id('select-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`select-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`select-list-view-item-${existingRoom}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id(`select-list-view-item-${room}`)).tap();
|
||||
|
||||
await waitFor(
|
||||
element(
|
||||
by[textMatcher](
|
||||
'You are the last owner of this channel. Once you leave the team, the channel will be kept inside the team but you will be managing it from outside.'
|
||||
)
|
||||
)
|
||||
)
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('select-list-view-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('select-list-view-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('Last owner cannot be removed')))
|
||||
.toExist()
|
||||
.withTimeout(8000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
describe('Room Members', () => {
|
||||
beforeAll(async () => {
|
||||
await element(by.id('room-actions-members')).tap();
|
||||
await waitFor(element(by.id('room-members-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
|
||||
it('should show all users', async () => {
|
||||
await element(by.id('room-members-view-filter')).tap();
|
||||
await waitFor(element(by.id('room-members-view-toggle-status-all')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-members-view-toggle-status-all')).tap();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should filter user', async () => {
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('room-members-view-search')).replaceText('rocket');
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
await element(by.id('room-members-view-search')).tap();
|
||||
await element(by.id('room-members-view-search')).clearText();
|
||||
await waitFor(element(by.id(`room-members-view-item-${user.username}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should remove member from team', async () => {
|
||||
await openActionSheet('rocket.cat');
|
||||
await waitFor(element(by.id('action-sheet-remove-from-team')))
|
||||
.toBeVisible()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('action-sheet-remove-from-team')).tap();
|
||||
await waitFor(element(by.id('select-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await waitFor(element(by.id(`select-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`select-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id(`${room}-checked`)))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id(`select-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id(`${room}-checked`)))
|
||||
.toNotExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('select-list-view-submit')).tap();
|
||||
await waitFor(element(by.id('room-members-view-item-rocket.cat')))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
|
||||
it('should set member as owner', async () => {
|
||||
await openActionSheet(user.username);
|
||||
await element(by.id('action-sheet-set-owner')).tap();
|
||||
await waitForToast();
|
||||
|
||||
await openActionSheet(user.username);
|
||||
await waitFor(element(by.id('action-sheet-set-owner-checked')))
|
||||
.toBeVisible()
|
||||
.withTimeout(6000);
|
||||
await closeActionSheet();
|
||||
});
|
||||
|
||||
it('should leave team', async () => {
|
||||
await tapBack();
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-leave-channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-leave-channel')).tap();
|
||||
|
||||
await waitFor(element(by.id('select-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`select-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`select-list-view-item-${existingRoom}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id(`select-list-view-item-${room}`)).tap();
|
||||
|
||||
await waitFor(
|
||||
element(
|
||||
by[textMatcher](
|
||||
'You are the last owner of this channel. Once you leave the team, the channel will be kept inside the team but you will be managing it from outside.'
|
||||
)
|
||||
)
|
||||
)
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('OK').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('select-list-view-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('select-list-view-submit')).tap();
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${team}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,189 @@
|
|||
import data from '../../data';
|
||||
import { navigateToLogin, login, tapBack, searchRoom, platformTypes, TTextMatcher } from '../../helpers/app';
|
||||
|
||||
const toBeConverted = `to-be-converted-${data.random}`;
|
||||
const toBeMoved = `to-be-moved-${data.random}`;
|
||||
|
||||
const createChannel = async (room: string) => {
|
||||
await waitFor(element(by.id('rooms-list-view-create-channel')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('rooms-list-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('new-message-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('new-message-view-create-channel')).tap();
|
||||
await waitFor(element(by.id('select-users-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
await element(by.id('selected-users-view-submit')).tap();
|
||||
await waitFor(element(by.id('create-channel-view')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('create-channel-name')).replaceText(room);
|
||||
await waitFor(element(by.id('create-channel-submit')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
await element(by.id('create-channel-submit')).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await waitFor(element(by.id(`room-view-title-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
|
||||
.toExist()
|
||||
.withTimeout(60000);
|
||||
};
|
||||
|
||||
async function navigateToRoom(room: string) {
|
||||
await searchRoom(`${room}`);
|
||||
await element(by.id(`rooms-list-view-item-${room}`)).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toBeVisible()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
async function navigateToRoomActions(room: string) {
|
||||
await navigateToRoom(room);
|
||||
await element(by.id('room-header')).tap();
|
||||
await waitFor(element(by.id('room-actions-view')))
|
||||
.toExist()
|
||||
.withTimeout(5000);
|
||||
}
|
||||
|
||||
describe('Move/Convert Team', () => {
|
||||
let alertButtonType: string;
|
||||
let textMatcher: TTextMatcher;
|
||||
beforeAll(async () => {
|
||||
await device.launchApp({ permissions: { notifications: 'YES' }, delete: true });
|
||||
({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]);
|
||||
await navigateToLogin();
|
||||
await login(data.users.regular.username, data.users.regular.password);
|
||||
});
|
||||
|
||||
describe('Convert', () => {
|
||||
beforeAll(async () => {
|
||||
await createChannel(toBeConverted);
|
||||
});
|
||||
|
||||
it('should convert channel to a team', async () => {
|
||||
await navigateToRoomActions(toBeConverted);
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-convert-to-team')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-convert-to-team')).tap();
|
||||
await waitFor(element(by[textMatcher]('You are converting this Channel to a Team. All Members will be kept.')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Convert').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(20000);
|
||||
await waitFor(element(by.id(`room-view-title-${toBeConverted}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Move', () => {
|
||||
beforeAll(async () => {
|
||||
await createChannel(toBeMoved);
|
||||
});
|
||||
|
||||
it('should move channel to a team', async () => {
|
||||
await navigateToRoomActions(toBeMoved);
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by.id('room-actions-move-to-team')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('room-actions-move-to-team')).tap();
|
||||
await waitFor(element(by[textMatcher]('Move to Team')).atIndex(0))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id('select-list-view-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('select-list-view-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('Select Team')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`select-list-view-item-${toBeConverted}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id(`select-list-view-item-${toBeConverted}`)).tap();
|
||||
await element(by.id('select-list-view-submit')).atIndex(0).tap();
|
||||
await waitFor(
|
||||
element(
|
||||
by[textMatcher](
|
||||
'After reading the previous intructions about this behavior, do you still want to move this channel to the selected team?'
|
||||
)
|
||||
)
|
||||
)
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Yes, move it!').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('room-view-header-team-channels')))
|
||||
.toExist()
|
||||
.withTimeout(10000);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Convert Team to Channel and Delete toBeMoved channel within the Converted', () => {
|
||||
it('should convert a team to a channel', async () => {
|
||||
await navigateToRoomActions(toBeConverted);
|
||||
await element(by.id('room-actions-scrollview')).scrollTo('bottom');
|
||||
await waitFor(element(by[textMatcher]('Convert to Channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Convert to Channel')).atIndex(0).tap();
|
||||
await waitFor(element(by[textMatcher]('Converting Team to Channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`select-list-view-item-${toBeMoved}`)))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id(`select-list-view-item-${toBeMoved}`)).tap();
|
||||
await waitFor(element(by.id('select-list-view-submit')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by.id('select-list-view-submit')).tap();
|
||||
await waitFor(element(by[textMatcher]('You are converting this Team to a Channel')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await element(by[textMatcher]('Convert').and(by.type(alertButtonType))).tap();
|
||||
await waitFor(element(by.id('room-view')))
|
||||
.toExist()
|
||||
.withTimeout(20000);
|
||||
await waitFor(element(by.id(`room-view-title-${toBeConverted}`)))
|
||||
.toExist()
|
||||
.withTimeout(6000);
|
||||
await tapBack();
|
||||
await waitFor(element(by.id('rooms-list-view')))
|
||||
.toExist()
|
||||
.withTimeout(2000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-${toBeMoved}`)))
|
||||
.toBeNotVisible()
|
||||
.withTimeout(60000);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"target": "es2018",
|
||||
"module": "commonjs",
|
||||
"importHelpers": true,
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"types": ["node", "detox", "mocha"]
|
||||
},
|
||||
"include": ["./**/*.ts"],
|
||||
"exclude": ["../node_modules"]
|
||||
}
|
Loading…
Reference in New Issue