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} */
|
/** @type {import('@jest/types').Config.InitialOptions} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
rootDir: '..',
|
rootDir: '..',
|
||||||
testMatch: ['<rootDir>/e2e/**/*.test.js'],
|
setupFilesAfterEnv: ['<rootDir>/e2e/tests/init.ts'],
|
||||||
|
testMatch: ['<rootDir>/e2e/tests/**/*.spec.ts'],
|
||||||
testTimeout: 120000,
|
testTimeout: 120000,
|
||||||
maxWorkers: 1,
|
maxWorkers: 1,
|
||||||
globalSetup: 'detox/runners/jest/globalSetup',
|
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