From bb880f01ad18b07b96415eaa6694f297f3124f88 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:51:33 -0300 Subject: [PATCH] Chore: Migrate E2E tests from JS to TS (#4475) * Migrate E2E tests from JS to TS * fixed type mocha into tsconfig * migration data.cloud and data.docker * migrate team folder and fix Detox namescpace * add type TTextMatcher and start the room folder migration * room / 02 and 03 * room's folder * onboarding's folder * assorted/ 01 * assorted/ 02, 03, 04 * assorted/ 05, 06, 07 * folder assorted * fix lint * fix device --- .eslintrc.js | 33 +++---- .gitignore | 1 + e2e/.mocharc.json | 4 +- e2e/README.md | 4 +- e2e/{data.js => data.ts} | 25 ++++-- e2e/data/{data.cloud.js => data.cloud.ts} | 25 ++++-- e2e/data/{data.docker.js => data.docker.ts} | 21 ++++- ...ount.example.js => e2e_account.example.ts} | 2 +- e2e/helpers/{app.js => app.ts} | 49 +++++----- e2e/helpers/{data_setup.js => data_setup.ts} | 42 ++++----- e2e/helpers/{random.js => random.ts} | 5 +- ...ption.spec.js => 01-e2eencryption.spec.ts} | 46 ++++++---- ...broadcast.spec.js => 02-broadcast.spec.ts} | 21 ++++- ...{03-profile.spec.js => 03-profile.spec.ts} | 15 ++-- ...{04-setting.spec.js => 04-setting.spec.ts} | 9 +- ...room.spec.js => 05-joinpublicroom.spec.ts} | 10 ++- .../{06-status.spec.js => 06-status.spec.ts} | 6 +- ...server.spec.js => 07-changeserver.spec.ts} | 6 +- ...m.spec.js => 08-joinprotectedroom.spec.ts} | 6 +- ...y.spec.js => 09-joinfromdirectory.spec.ts} | 6 +- ...server.spec.js => 10-deleteserver.spec.ts} | 8 +- ...linking.spec.js => 11-deeplinking.spec.ts} | 21 +++-- .../{12-i18n.spec.js => 12-i18n.spec.ts} | 10 ++- ...y-pref.spec.js => 13-display-pref.spec.ts} | 6 +- e2e/tests/{init.js => init.ts} | 13 +-- ...boarding.spec.js => 01-onboarding.spec.ts} | 10 ++- .../{02-legal.spec.js => 02-legal.spec.ts} | 4 +- ...word.spec.js => 03-forgotpassword.spec.ts} | 10 ++- ...eateuser.spec.js => 04-createuser.spec.ts} | 33 +++---- .../{05-login.spec.js => 05-login.spec.ts} | 10 ++- ...roomslist.spec.js => 06-roomslist.spec.ts} | 6 +- ...tory.spec.js => 07-server-history.spec.ts} | 6 +- ...eateroom.spec.js => 01-createroom.spec.ts} | 10 ++- .../room/{02-room.spec.js => 02-room.spec.ts} | 17 ++-- ...actions.spec.js => 03-roomactions.spec.ts} | 24 ++--- ...scussion.spec.js => 04-discussion.spec.ts} | 8 +- ...{05-threads.spec.js => 05-threads.spec.ts} | 15 ++-- ...group.spec.js => 06-createdmgroup.spec.ts} | 6 +- ...unread.spec.js => 07-markasunread.spec.ts} | 12 +-- ...8-roominfo.spec.js => 08-roominfo.spec.ts} | 20 +++-- ...ssage.spec.js => 09-jumptomessage.spec.ts} | 15 ++-- ...eateteam.spec.js => 01-createteam.spec.ts} | 10 ++- .../team/{02-team.spec.js => 02-team.spec.ts} | 24 +++-- ...convert.spec.js => 03-moveconvert.spec.ts} | 14 +-- e2e/tsconfig.json | 23 +++++ package.json | 3 + yarn.lock | 90 ++++++++++++++++++- 47 files changed, 508 insertions(+), 256 deletions(-) rename e2e/{data.js => data.ts} (74%) rename e2e/data/{data.cloud.js => data.cloud.ts} (74%) rename e2e/data/{data.docker.js => data.docker.ts} (77%) rename e2e/{e2e_account.example.js => e2e_account.example.ts} (75%) rename e2e/helpers/{app.js => app.ts} (86%) rename e2e/helpers/{data_setup.js => data_setup.ts} (79%) rename e2e/helpers/{random.js => random.ts} (76%) rename e2e/tests/assorted/{01-e2eencryption.spec.js => 01-e2eencryption.spec.ts} (93%) rename e2e/tests/assorted/{02-broadcast.spec.js => 02-broadcast.spec.ts} (85%) rename e2e/tests/assorted/{03-profile.spec.js => 03-profile.spec.ts} (92%) rename e2e/tests/assorted/{04-setting.spec.js => 04-setting.spec.ts} (92%) rename e2e/tests/assorted/{05-joinpublicroom.spec.js => 05-joinpublicroom.spec.ts} (95%) rename e2e/tests/assorted/{06-status.spec.js => 06-status.spec.ts} (93%) rename e2e/tests/assorted/{07-changeserver.spec.js => 07-changeserver.spec.ts} (95%) rename e2e/tests/assorted/{08-joinprotectedroom.spec.js => 08-joinprotectedroom.spec.ts} (92%) rename e2e/tests/assorted/{09-joinfromdirectory.spec.js => 09-joinfromdirectory.spec.ts} (92%) rename e2e/tests/assorted/{10-deleteserver.spec.js => 10-deleteserver.spec.ts} (92%) rename e2e/tests/assorted/{11-deeplinking.spec.js => 11-deeplinking.spec.ts} (92%) rename e2e/tests/assorted/{12-i18n.spec.js => 12-i18n.spec.ts} (95%) rename e2e/tests/assorted/{13-display-pref.spec.js => 13-display-pref.spec.ts} (96%) rename e2e/tests/{init.js => init.ts} (63%) rename e2e/tests/onboarding/{01-onboarding.spec.js => 01-onboarding.spec.ts} (90%) rename e2e/tests/onboarding/{02-legal.spec.js => 02-legal.spec.ts} (95%) rename e2e/tests/onboarding/{03-forgotpassword.spec.js => 03-forgotpassword.spec.ts} (86%) rename e2e/tests/onboarding/{04-createuser.spec.js => 04-createuser.spec.ts} (74%) rename e2e/tests/onboarding/{05-login.spec.js => 05-login.spec.ts} (91%) rename e2e/tests/onboarding/{06-roomslist.spec.js => 06-roomslist.spec.ts} (91%) rename e2e/tests/onboarding/{07-server-history.spec.js => 07-server-history.spec.ts} (92%) rename e2e/tests/room/{01-createroom.spec.js => 01-createroom.spec.ts} (97%) rename e2e/tests/room/{02-room.spec.js => 02-room.spec.ts} (98%) rename e2e/tests/room/{03-roomactions.spec.js => 03-roomactions.spec.ts} (98%) rename e2e/tests/room/{04-discussion.spec.js => 04-discussion.spec.ts} (97%) rename e2e/tests/room/{05-threads.spec.js => 05-threads.spec.ts} (97%) rename e2e/tests/room/{06-createdmgroup.spec.js => 06-createdmgroup.spec.ts} (92%) rename e2e/tests/room/{07-markasunread.spec.js => 07-markasunread.spec.ts} (83%) rename e2e/tests/room/{08-roominfo.spec.js => 08-roominfo.spec.ts} (95%) rename e2e/tests/room/{09-jumptomessage.spec.js => 09-jumptomessage.spec.ts} (95%) rename e2e/tests/team/{01-createteam.spec.js => 01-createteam.spec.ts} (94%) rename e2e/tests/team/{02-team.spec.js => 02-team.spec.ts} (96%) rename e2e/tests/team/{03-moveconvert.spec.js => 03-moveconvert.spec.ts} (94%) create mode 100644 e2e/tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index 6451c266..1f0105d1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -156,22 +156,6 @@ module.exports = { __DEV__: true }, overrides: [ - { - files: ['e2e/**'], - globals: { - by: true, - detox: true, - device: true, - element: true, - expect: true, - waitFor: true - }, - rules: { - 'import/no-extraneous-dependencies': 0, - 'no-await-in-loop': 0, - 'no-restricted-syntax': 0 - } - }, { files: ['**/*.ts', '**/*.tsx'], extends: [ @@ -253,6 +237,23 @@ module.exports = { } } } + }, + { + files: ['e2e/**'], + globals: { + by: true, + detox: true, + device: true, + element: true, + waitFor: true + }, + rules: { + 'import/no-extraneous-dependencies': 0, + 'no-await-in-loop': 0, + 'no-restricted-syntax': 0, + // TODO: remove this rule when update Detox to 20 and test if the namespace Detox is available + 'no-undef': 1 + } } ] }; diff --git a/.gitignore b/.gitignore index 19f2bcab..003abcfb 100644 --- a/.gitignore +++ b/.gitignore @@ -66,5 +66,6 @@ artifacts e2e/docker/rc_test_env/docker-compose.yml e2e/docker/data/db e2e/e2e_account.js +e2e/e2e_account.ts *.p8 \ No newline at end of file diff --git a/e2e/.mocharc.json b/e2e/.mocharc.json index 8c4277c7..4471b1c0 100644 --- a/e2e/.mocharc.json +++ b/e2e/.mocharc.json @@ -2,5 +2,7 @@ "timeout": 300000, "recursive": true, "bail": true, - "file": "e2e/tests/init.js" + "require": ["ts-node/register"], + "file": "e2e/tests/init.ts", + "extension": ["ts"] } diff --git a/e2e/README.md b/e2e/README.md index f95f9983..53379ff4 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -26,9 +26,9 @@ Or ### 2. Prepare test data * If you're running your own Rocket.Chat server, ensure it's started (e.g. `meteor npm start` in the server project directory). -* Edit `e2e/data.js`: +* Edit `e2e/data.ts`: * Set the `server` to the address of the server under test - * Create a file called `e2e_account.js`, in the same folder as `data.js`. Set the `adminUser` and `adminPassword` to an admin user on that environment (or a user with at least `create-user` and `create-c` permissions). The example of how to create this file is on `e2e/e2e_account.example.js` + * Create a file called `e2e_account.ts`, in the same folder as `data.ts`. Set the `adminUser` and `adminPassword` to an admin user on that environment (or a user with at least `create-user` and `create-c` permissions). The example of how to create this file is on `e2e/e2e_account.example.ts` * Working example configs exist in `./e2e/data/`. Setting `FORCE_DEFAULT_DOCKER_DATA` to `1` in the `runTestsInDocker.sh` script will use the example config automatically ### 3. Running tests diff --git a/e2e/data.js b/e2e/data.ts similarity index 74% rename from e2e/data.js rename to e2e/data.ts index 7436a3ef..5947a86d 100644 --- a/e2e/data.js +++ b/e2e/data.ts @@ -1,8 +1,22 @@ -const random = require('./helpers/random'); -// eslint-disable-next-line import/no-unresolved, import/extensions -const account = require('./e2e_account'); +/* eslint-disable import/extensions, import/no-unresolved */ +import random from './helpers/random'; +// @ts-ignore +import account from './e2e_account'; -const value = random(20); +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 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, @@ -77,4 +91,5 @@ const data = { }, random: value }; -module.exports = data; + +export default data; diff --git a/e2e/data/data.cloud.js b/e2e/data/data.cloud.ts similarity index 74% rename from e2e/data/data.cloud.js rename to e2e/data/data.cloud.ts index 85b7de50..56c5f502 100644 --- a/e2e/data/data.cloud.js +++ b/e2e/data/data.cloud.ts @@ -1,7 +1,21 @@ -// eslint-disable-next-line import/no-unresolved, import/extensions -const random = require('./helpers/random'); -// eslint-disable-next-line import/no-unresolved, import/extensions -const account = require('./e2e_account'); +/* 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 TDataGroups = keyof typeof data.groups; +export type TDataTeams = keyof typeof data.teams; const value = random(20); const data = { @@ -72,4 +86,5 @@ const data = { }, random: value }; -module.exports = data; + +export default data; diff --git a/e2e/data/data.docker.js b/e2e/data/data.docker.ts similarity index 77% rename from e2e/data/data.docker.js rename to e2e/data/data.docker.ts index 40407206..82360c20 100644 --- a/e2e/data/data.docker.js +++ b/e2e/data/data.docker.ts @@ -1,5 +1,19 @@ -// eslint-disable-next-line import/no-unresolved, import/extensions -const random = require('./helpers/random'); +/* 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 TDataGroups = keyof typeof data.groups; +export type TDataTeams = keyof typeof data.teams; const value = random(20); const data = { @@ -77,4 +91,5 @@ const data = { }, random: value }; -module.exports = data; + +export default data; diff --git a/e2e/e2e_account.example.js b/e2e/e2e_account.example.ts similarity index 75% rename from e2e/e2e_account.example.js rename to e2e/e2e_account.example.ts index 4294d6b0..cd0ee2c1 100644 --- a/e2e/e2e_account.example.js +++ b/e2e/e2e_account.example.ts @@ -3,4 +3,4 @@ const account = { adminPassword: 'Change_here' }; -module.exports = account; +export default account; diff --git a/e2e/helpers/app.js b/e2e/helpers/app.ts similarity index 86% rename from e2e/helpers/app.js rename to e2e/helpers/app.ts index 50e2d703..2bfda548 100644 --- a/e2e/helpers/app.js +++ b/e2e/helpers/app.ts @@ -1,5 +1,10 @@ -const { exec } = require('child_process'); -const data = require('../data'); +import { exec } from 'child_process'; + +import { by, expect, element } from 'detox'; + +import data from '../data'; + +export type TTextMatcher = keyof Pick; const platformTypes = { android: { @@ -7,18 +12,18 @@ const platformTypes = { alertButtonType: 'android.widget.Button', scrollViewType: 'android.widget.ScrollView', textInputType: 'android.widget.EditText', - textMatcher: 'text' + textMatcher: 'text' as TTextMatcher }, ios: { // iOS types alertButtonType: '_UIAlertControllerActionView', scrollViewType: 'UIScrollView', textInputType: '_UIAlertControllerTextField', - textMatcher: 'label' + textMatcher: 'label' as TTextMatcher } }; -function sleep(ms) { +function sleep(ms: number) { return new Promise(res => setTimeout(res, ms)); } @@ -34,7 +39,7 @@ async function navigateToWorkspace(server = data.server) { await expect(element(by.id('workspace-view'))).toBeVisible(); } -async function navigateToLogin(server) { +async function navigateToLogin(server?: string) { await navigateToWorkspace(server); await element(by.id('workspace-view-login')).tap(); await waitFor(element(by.id('login-view'))) @@ -42,7 +47,7 @@ async function navigateToLogin(server) { .withTimeout(2000); } -async function navigateToRegister(server) { +async function navigateToRegister(server?: string) { await navigateToWorkspace(server); await element(by.id('workspace-view-register')).tap(); await waitFor(element(by.id('register-view'))) @@ -50,7 +55,7 @@ async function navigateToRegister(server) { .withTimeout(2000); } -async function login(username, password) { +async function login(username: string, password: string) { await waitFor(element(by.id('login-view'))) .toExist() .withTimeout(2000); @@ -90,23 +95,22 @@ async function logout() { await expect(element(by.id('new-server-view'))).toBeVisible(); } -async function mockMessage(message, isThread = false) { +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 sleep(500); await waitFor(element(by[textMatcher](`${data.random}${message}`))) .toExist() - .withTimeout(10000); + .withTimeout(60000); await element(by[textMatcher](`${data.random}${message}`)) .atIndex(0) .tap(); } -async function starMessage(message) { +async function starMessage(message: string) { const deviceType = device.getPlatform(); const { textMatcher } = platformTypes[deviceType]; const messageLabel = `${data.random}${message}`; @@ -120,7 +124,7 @@ async function starMessage(message) { .withTimeout(5000); } -async function pinMessage(message) { +async function pinMessage(message: string) { const deviceType = device.getPlatform(); const { textMatcher } = platformTypes[deviceType]; const messageLabel = `${data.random}${message}`; @@ -148,24 +152,25 @@ async function tapBack() { await element(by.id('header-back')).atIndex(0).tap(); } -async function searchRoom(room) { +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 expect(element(by.id('rooms-list-view-search-input'))).toExist(); 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')).replaceText(room); + 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); } -async function tryTapping(theElement, timeout, longtap = false) { +// eslint-disable-next-line no-undef +async function tryTapping(theElement: Detox.IndexableNativeElement, timeout: number, longtap = false) { try { if (longtap) { await theElement.longPress(); @@ -182,7 +187,7 @@ async function tryTapping(theElement, timeout, longtap = false) { } } -const checkServer = async server => { +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'))) @@ -200,9 +205,9 @@ const checkServer = async server => { .withTimeout(10000); }; -function runCommand(command) { - return new Promise((resolve, reject) => { - exec(command, (error, stdout, stderr) => { +function runCommand(command: string) { + return new Promise((resolve, reject) => { + exec(command, (error, _stdout, stderr) => { if (error) { reject(new Error(`exec error: ${stderr}`)); return; @@ -223,7 +228,7 @@ async function prepareAndroid() { await runCommand('adb shell settings put global animator_duration_scale 0.0'); } -module.exports = { +export { navigateToWorkspace, navigateToLogin, navigateToRegister, diff --git a/e2e/helpers/data_setup.js b/e2e/helpers/data_setup.ts similarity index 79% rename from e2e/helpers/data_setup.js rename to e2e/helpers/data_setup.ts index b8459f18..b8cb9b4b 100644 --- a/e2e/helpers/data_setup.js +++ b/e2e/helpers/data_setup.ts @@ -1,7 +1,7 @@ -const axios = require('axios').default; +import axios from 'axios'; -const data = require('../data'); -const random = require('./random'); +import data, { TDataChannels, TDataGroups, TDataTeams, TDataUsers } from '../data'; +import random from './random'; const TEAM_TYPE = { PUBLIC: 0, @@ -17,7 +17,7 @@ const rocketchat = axios.create({ } }); -const login = async (username, password) => { +const login = async (username: string, password: string) => { console.log(`Logging in as user ${username}`); const response = await rocketchat.post('login', { user: username, @@ -30,7 +30,7 @@ const login = async (username, password) => { return { authToken, userId }; }; -const createUser = async (username, password, name, email) => { +const createUser = async (username: string, password: string, name: string, email: string) => { console.log(`Creating user ${username}`); try { await rocketchat.post('users.create', { @@ -45,7 +45,7 @@ const createUser = async (username, password, name, email) => { } }; -const createChannelIfNotExists = async channelname => { +const createChannelIfNotExists = async (channelname: string) => { console.log(`Creating public channel ${channelname}`); try { const room = await rocketchat.post('channels.create', { @@ -65,7 +65,7 @@ const createChannelIfNotExists = async channelname => { } }; -const createTeamIfNotExists = async teamname => { +const createTeamIfNotExists = async (teamname: string) => { console.log(`Creating private team ${teamname}`); try { await rocketchat.post('teams.create', { @@ -84,7 +84,7 @@ const createTeamIfNotExists = async teamname => { } }; -const createGroupIfNotExists = async groupname => { +const createGroupIfNotExists = async (groupname: string) => { console.log(`Creating private group ${groupname}`); try { await rocketchat.post('groups.create', { @@ -102,7 +102,7 @@ const createGroupIfNotExists = async groupname => { } }; -const changeChannelJoinCode = async (roomId, joinCode) => { +const changeChannelJoinCode = async (roomId: string, joinCode: string) => { console.log(`Changing channel Join Code ${roomId}`); try { await rocketchat.post('method.call/saveRoomSettings', { @@ -119,7 +119,7 @@ const changeChannelJoinCode = async (roomId, joinCode) => { } }; -const sendMessage = async (user, channel, msg, tmid) => { +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); @@ -136,21 +136,21 @@ const setup = async () => { for (const userKey in data.users) { if (Object.prototype.hasOwnProperty.call(data.users, userKey)) { - const user = 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]; + const channel = data.channels[channelKey as TDataChannels]; const { data: { channel: { _id } } } = await createChannelIfNotExists(channel.name); - if (channel.joinCode) { + if ('joinCode' in channel) { await changeChannelJoinCode(_id, channel.joinCode); } } @@ -160,33 +160,27 @@ const setup = async () => { for (const groupKey in data.groups) { if (Object.prototype.hasOwnProperty.call(data.groups, groupKey)) { - const group = 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]; + const team = data.teams[teamKey as TDataTeams]; await createTeamIfNotExists(team.name); } } }; -const get = endpoint => { +const get = (endpoint: string) => { console.log(`GET /${endpoint}`); return rocketchat.get(endpoint); }; -const post = (endpoint, body) => { +const post = (endpoint: string, body: any) => { console.log(`POST /${endpoint} ${JSON.stringify(body)}`); return rocketchat.post(endpoint, body); }; -module.exports = { - setup, - sendMessage, - get, - post, - login -}; +export { setup, sendMessage, get, post, login }; diff --git a/e2e/helpers/random.js b/e2e/helpers/random.ts similarity index 76% rename from e2e/helpers/random.js rename to e2e/helpers/random.ts index d41575c0..70a5a90b 100644 --- a/e2e/helpers/random.js +++ b/e2e/helpers/random.ts @@ -1,4 +1,4 @@ -function random(length) { +function random(length: number) { let text = ''; const possible = 'abcdefghijklmnopqrstuvwxyz'; for (let i = 0; i < length; i += 1) { @@ -6,4 +6,5 @@ function random(length) { } return text; } -module.exports = random; + +export default random; diff --git a/e2e/tests/assorted/01-e2eencryption.spec.js b/e2e/tests/assorted/01-e2eencryption.spec.ts similarity index 93% rename from e2e/tests/assorted/01-e2eencryption.spec.js rename to e2e/tests/assorted/01-e2eencryption.spec.ts index c8ba4c4d..f422e271 100644 --- a/e2e/tests/assorted/01-e2eencryption.spec.js +++ b/e2e/tests/assorted/01-e2eencryption.spec.ts @@ -1,11 +1,22 @@ -const { navigateToLogin, login, sleep, tapBack, mockMessage, searchRoom, logout, platformTypes } = require('../../helpers/app'); +import { expect } from 'detox'; -const data = require('../../data'); +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 => { +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'))) @@ -24,7 +35,7 @@ const checkBanner = async () => { .withTimeout(10000); }; -async function navigateToRoom(roomName) { +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'))) @@ -60,13 +71,12 @@ async function navigateSecurityPrivacy() { describe('E2E Encryption', () => { const room = `encrypted${data.random}`; const newPassword = 'abc'; - let alertButtonType; - let scrollViewType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); - ({ alertButtonType, scrollViewType, textMatcher } = platformTypes[device.getPlatform()]); + ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); await navigateToLogin(); await login(testuser.username, testuser.password); }); @@ -293,14 +303,16 @@ describe('E2E Encryption', () => { await element(by[textMatcher]('Yes, reset it').and(by.type(alertButtonType))).tap(); await sleep(2000); - 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(); + // 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); @@ -308,7 +320,7 @@ describe('E2E Encryption', () => { // TODO: assert 'Save Your Encryption Password' await waitFor(element(by.id('listheader-encryption'))) .toBeVisible() - .withTimeout(2000); + .withTimeout(5000); }); }); }); diff --git a/e2e/tests/assorted/02-broadcast.spec.js b/e2e/tests/assorted/02-broadcast.spec.ts similarity index 85% rename from e2e/tests/assorted/02-broadcast.spec.js rename to e2e/tests/assorted/02-broadcast.spec.ts index 06ebc9d4..695b09f5 100644 --- a/e2e/tests/assorted/02-broadcast.spec.js +++ b/e2e/tests/assorted/02-broadcast.spec.ts @@ -1,14 +1,15 @@ // const OTP = require('otp.js'); // const GA = OTP.googleAuthenticator; +import { expect } from 'detox'; -const { navigateToLogin, login, mockMessage, tapBack, searchRoom, platformTypes } = require('../../helpers/app'); -const data = require('../../data'); +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; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ textMatcher } = platformTypes[device.getPlatform()]); @@ -49,6 +50,7 @@ describe('Broadcast room', () => { 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() @@ -123,6 +125,17 @@ describe('Broadcast room', () => { }); it('should reply broadcasted message', async () => { - await mockMessage('broadcastreply'); + // 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); }); }); diff --git a/e2e/tests/assorted/03-profile.spec.js b/e2e/tests/assorted/03-profile.spec.ts similarity index 92% rename from e2e/tests/assorted/03-profile.spec.js rename to e2e/tests/assorted/03-profile.spec.ts index facec3a4..b7c13496 100644 --- a/e2e/tests/assorted/03-profile.spec.js +++ b/e2e/tests/assorted/03-profile.spec.ts @@ -1,5 +1,7 @@ -const { navigateToLogin, login, sleep, platformTypes } = require('../../helpers/app'); -const data = require('../../data'); +import { expect } from 'detox'; + +import { navigateToLogin, login, sleep, platformTypes, TTextMatcher } from '../../helpers/app'; +import data from '../../data'; const profileChangeUser = data.users.profileChanges; @@ -14,14 +16,12 @@ async function waitForToast() { } describe('Profile screen', () => { - let textInputType; - let scrollViewType; - let alertButtonType; - let textMatcher; + let scrollViewType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); - ({ textInputType, scrollViewType, alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); + ({ scrollViewType, textMatcher } = platformTypes[device.getPlatform()]); await navigateToLogin(); await login(profileChangeUser.username, profileChangeUser.password); await element(by.id('rooms-list-view-sidebar')).tap(); @@ -107,6 +107,7 @@ describe('Profile screen', () => { 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 sleep(300); await element(by.id('profile-view-submit')).tap(); await waitFor(element(by.id('profile-view-enter-password-sheet'))) .toBeVisible() diff --git a/e2e/tests/assorted/04-setting.spec.js b/e2e/tests/assorted/04-setting.spec.ts similarity index 92% rename from e2e/tests/assorted/04-setting.spec.js rename to e2e/tests/assorted/04-setting.spec.ts index 50c39b1a..25ce0c7f 100644 --- a/e2e/tests/assorted/04-setting.spec.js +++ b/e2e/tests/assorted/04-setting.spec.ts @@ -1,12 +1,13 @@ -const { navigateToLogin, login, platformTypes } = require('../../helpers/app'); +import { expect } from 'detox'; -const data = require('../../data'); +import { navigateToLogin, login, platformTypes, TTextMatcher } from '../../helpers/app'; +import data from '../../data'; const testuser = data.users.regular; describe('Settings screen', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/assorted/05-joinpublicroom.spec.js b/e2e/tests/assorted/05-joinpublicroom.spec.ts similarity index 95% rename from e2e/tests/assorted/05-joinpublicroom.spec.js rename to e2e/tests/assorted/05-joinpublicroom.spec.ts index 877ab426..81d7630c 100644 --- a/e2e/tests/assorted/05-joinpublicroom.spec.js +++ b/e2e/tests/assorted/05-joinpublicroom.spec.ts @@ -1,5 +1,7 @@ -const data = require('../../data'); -const { navigateToLogin, login, mockMessage, tapBack, searchRoom, platformTypes } = require('../../helpers/app'); +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; @@ -20,8 +22,8 @@ async function navigateToRoomActions() { } describe('Join public room', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/assorted/06-status.spec.js b/e2e/tests/assorted/06-status.spec.ts similarity index 93% rename from e2e/tests/assorted/06-status.spec.js rename to e2e/tests/assorted/06-status.spec.ts index e903f97e..9feadc19 100644 --- a/e2e/tests/assorted/06-status.spec.js +++ b/e2e/tests/assorted/06-status.spec.ts @@ -1,5 +1,7 @@ -const { navigateToLogin, login, sleep } = require('../../helpers/app'); -const data = require('../../data'); +import { expect } from 'detox'; + +import { navigateToLogin, login, sleep } from '../../helpers/app'; +import data from '../../data'; const testuser = data.users.regular; diff --git a/e2e/tests/assorted/07-changeserver.spec.js b/e2e/tests/assorted/07-changeserver.spec.ts similarity index 95% rename from e2e/tests/assorted/07-changeserver.spec.js rename to e2e/tests/assorted/07-changeserver.spec.ts index cd9d858f..7c7175a1 100644 --- a/e2e/tests/assorted/07-changeserver.spec.js +++ b/e2e/tests/assorted/07-changeserver.spec.ts @@ -1,7 +1,7 @@ -const data = require('../../data'); -const { navigateToLogin, login, checkServer, platformTypes, sleep } = require('../../helpers/app'); +import data from '../../data'; +import { navigateToLogin, login, checkServer, sleep } from '../../helpers/app'; -const reopenAndCheckServer = async server => { +const reopenAndCheckServer = async (server: string) => { await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true }); await waitFor(element(by.id('rooms-list-view'))) .toBeVisible() diff --git a/e2e/tests/assorted/08-joinprotectedroom.spec.js b/e2e/tests/assorted/08-joinprotectedroom.spec.ts similarity index 92% rename from e2e/tests/assorted/08-joinprotectedroom.spec.js rename to e2e/tests/assorted/08-joinprotectedroom.spec.ts index 375b9ff1..21c1d9bd 100644 --- a/e2e/tests/assorted/08-joinprotectedroom.spec.js +++ b/e2e/tests/assorted/08-joinprotectedroom.spec.ts @@ -1,5 +1,7 @@ -const data = require('../../data'); -const { navigateToLogin, login, mockMessage, searchRoom, sleep } = require('../../helpers/app'); +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; diff --git a/e2e/tests/assorted/09-joinfromdirectory.spec.js b/e2e/tests/assorted/09-joinfromdirectory.spec.ts similarity index 92% rename from e2e/tests/assorted/09-joinfromdirectory.spec.js rename to e2e/tests/assorted/09-joinfromdirectory.spec.ts index 1126264f..ab181b9e 100644 --- a/e2e/tests/assorted/09-joinfromdirectory.spec.js +++ b/e2e/tests/assorted/09-joinfromdirectory.spec.ts @@ -1,9 +1,9 @@ -const data = require('../../data'); -const { navigateToLogin, login, tapBack, sleep } = require('../../helpers/app'); +import data from '../../data'; +import { navigateToLogin, login, tapBack, sleep } from '../../helpers/app'; const testuser = data.users.regular; -async function navigateToRoom(search) { +async function navigateToRoom(search: string) { await element(by.id('directory-view-search')).replaceText(search); await waitFor(element(by.id(`directory-view-item-${search}`))) .toBeVisible() diff --git a/e2e/tests/assorted/10-deleteserver.spec.js b/e2e/tests/assorted/10-deleteserver.spec.ts similarity index 92% rename from e2e/tests/assorted/10-deleteserver.spec.js rename to e2e/tests/assorted/10-deleteserver.spec.ts index d917f298..8947bdb1 100644 --- a/e2e/tests/assorted/10-deleteserver.spec.js +++ b/e2e/tests/assorted/10-deleteserver.spec.ts @@ -1,9 +1,9 @@ -const data = require('../../data'); -const { sleep, navigateToLogin, login, checkServer, platformTypes } = require('../../helpers/app'); +import data from '../../data'; +import { sleep, navigateToLogin, login, checkServer, platformTypes, TTextMatcher } from '../../helpers/app'; describe('Delete server', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/assorted/11-deeplinking.spec.js b/e2e/tests/assorted/11-deeplinking.spec.ts similarity index 92% rename from e2e/tests/assorted/11-deeplinking.spec.js rename to e2e/tests/assorted/11-deeplinking.spec.ts index 00862f1b..4b9de777 100644 --- a/e2e/tests/assorted/11-deeplinking.spec.js +++ b/e2e/tests/assorted/11-deeplinking.spec.ts @@ -1,31 +1,30 @@ -const data = require('../../data'); -const { tapBack, checkServer, navigateToRegister, platformTypes } = require('../../helpers/app'); -const { get, login, sendMessage } = require('../../helpers/data_setup'); +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, server, params) => { +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; - let authToken; - let scrollViewType; - let threadId; - let textMatcher; - let alertButtonType; + let userId: string; + let authToken: string; + let scrollViewType: string; + let threadId: string; + let textMatcher: TTextMatcher; const threadMessage = `to-thread-${data.random}`; before(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, alertButtonType } = platformTypes[deviceType]); + ({ 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; diff --git a/e2e/tests/assorted/12-i18n.spec.js b/e2e/tests/assorted/12-i18n.spec.ts similarity index 95% rename from e2e/tests/assorted/12-i18n.spec.js rename to e2e/tests/assorted/12-i18n.spec.ts index 75caea9e..ce7c8379 100644 --- a/e2e/tests/assorted/12-i18n.spec.js +++ b/e2e/tests/assorted/12-i18n.spec.ts @@ -1,9 +1,11 @@ -const { navigateToLogin, login, sleep } = require('../../helpers/app'); -const { post } = require('../../helpers/data_setup'); -const data = require('../../data'); +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' } }; +const defaultLaunchArgs = { permissions: { notifications: 'YES' } } as Detox.DeviceLaunchAppConfig; const navToLanguage = async () => { await waitFor(element(by.id('rooms-list-view'))) diff --git a/e2e/tests/assorted/13-display-pref.spec.js b/e2e/tests/assorted/13-display-pref.spec.ts similarity index 96% rename from e2e/tests/assorted/13-display-pref.spec.js rename to e2e/tests/assorted/13-display-pref.spec.ts index 4bded3fa..f7b1f934 100644 --- a/e2e/tests/assorted/13-display-pref.spec.js +++ b/e2e/tests/assorted/13-display-pref.spec.ts @@ -1,5 +1,7 @@ -const { login, navigateToLogin, sleep } = require('../../helpers/app'); -const data = require('../../data'); +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(); diff --git a/e2e/tests/init.js b/e2e/tests/init.ts similarity index 63% rename from e2e/tests/init.js rename to e2e/tests/init.ts index fd2b7345..2106c1cc 100644 --- a/e2e/tests/init.js +++ b/e2e/tests/init.ts @@ -1,11 +1,12 @@ -const detox = require('detox'); -const adapter = require('detox/runners/mocha/adapter'); +import detox from 'detox'; +import adapter from 'detox/runners/mocha/adapter'; -const config = require('../../package.json').detox; -const { setup } = require('../helpers/data_setup'); -const { prepareAndroid } = require('../helpers/app'); +import { detox as config } from '../../package.json'; +import { setup } from '../helpers/data_setup'; +import { prepareAndroid } from '../helpers/app'; before(async () => { + // @ts-ignore await Promise.all([setup(), detox.init(config, { launchApp: false })]); await prepareAndroid(); // Make Android less flaky // await dataSetup() @@ -14,10 +15,12 @@ before(async () => { }); beforeEach(async function () { + // @ts-ignore await adapter.beforeEach(this); }); afterEach(async function () { + // @ts-ignore await adapter.afterEach(this); }); diff --git a/e2e/tests/onboarding/01-onboarding.spec.js b/e2e/tests/onboarding/01-onboarding.spec.ts similarity index 90% rename from e2e/tests/onboarding/01-onboarding.spec.js rename to e2e/tests/onboarding/01-onboarding.spec.ts index c82f2fa2..af77b69f 100644 --- a/e2e/tests/onboarding/01-onboarding.spec.js +++ b/e2e/tests/onboarding/01-onboarding.spec.ts @@ -1,9 +1,11 @@ -const data = require('../../data'); -const { platformTypes } = require('../../helpers/app'); +import { expect } from 'detox'; + +import { TTextMatcher, platformTypes } from '../../helpers/app'; +import data from '../../data'; describe('Onboarding', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/onboarding/02-legal.spec.js b/e2e/tests/onboarding/02-legal.spec.ts similarity index 95% rename from e2e/tests/onboarding/02-legal.spec.js rename to e2e/tests/onboarding/02-legal.spec.ts index c4574442..81039595 100644 --- a/e2e/tests/onboarding/02-legal.spec.js +++ b/e2e/tests/onboarding/02-legal.spec.ts @@ -1,4 +1,6 @@ -const { navigateToRegister, navigateToLogin } = require('../../helpers/app'); +import { expect } from 'detox'; + +import { navigateToRegister, navigateToLogin } from '../../helpers/app'; describe('Legal screen', () => { describe('From Login', () => { diff --git a/e2e/tests/onboarding/03-forgotpassword.spec.js b/e2e/tests/onboarding/03-forgotpassword.spec.ts similarity index 86% rename from e2e/tests/onboarding/03-forgotpassword.spec.js rename to e2e/tests/onboarding/03-forgotpassword.spec.ts index b3408bd2..198d2d3a 100644 --- a/e2e/tests/onboarding/03-forgotpassword.spec.js +++ b/e2e/tests/onboarding/03-forgotpassword.spec.ts @@ -1,9 +1,11 @@ -const data = require('../../data'); -const { navigateToLogin, platformTypes } = require('../../helpers/app'); +import { expect } from 'detox'; + +import data from '../../data'; +import { navigateToLogin, platformTypes, TTextMatcher } from '../../helpers/app'; describe('Forgot password screen', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/onboarding/04-createuser.spec.js b/e2e/tests/onboarding/04-createuser.spec.ts similarity index 74% rename from e2e/tests/onboarding/04-createuser.spec.js rename to e2e/tests/onboarding/04-createuser.spec.ts index c797e9dd..4f2dba5d 100644 --- a/e2e/tests/onboarding/04-createuser.spec.js +++ b/e2e/tests/onboarding/04-createuser.spec.ts @@ -1,9 +1,11 @@ -const { navigateToRegister, platformTypes } = require('../../helpers/app'); -const data = require('../../data'); +import { expect } from 'detox'; + +import { navigateToRegister, platformTypes, TTextMatcher } from '../../helpers/app'; +import data from '../../data'; describe('Create user screen', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); @@ -50,17 +52,18 @@ describe('Create user screen', () => { // await element(by.id('register-view-submit')).tap(); // }); - 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(); - }); + // 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); diff --git a/e2e/tests/onboarding/05-login.spec.js b/e2e/tests/onboarding/05-login.spec.ts similarity index 91% rename from e2e/tests/onboarding/05-login.spec.js rename to e2e/tests/onboarding/05-login.spec.ts index 88623d90..6bdb08c2 100644 --- a/e2e/tests/onboarding/05-login.spec.js +++ b/e2e/tests/onboarding/05-login.spec.ts @@ -1,9 +1,11 @@ -const { navigateToLogin, tapBack, platformTypes, navigateToWorkspace, login } = require('../../helpers/app'); -const data = require('../../data'); +import { expect } from 'detox'; + +import { navigateToLogin, tapBack, platformTypes, navigateToWorkspace, login, TTextMatcher } from '../../helpers/app'; +import data from '../../data'; describe('Login screen', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/onboarding/06-roomslist.spec.js b/e2e/tests/onboarding/06-roomslist.spec.ts similarity index 91% rename from e2e/tests/onboarding/06-roomslist.spec.js rename to e2e/tests/onboarding/06-roomslist.spec.ts index 38806c3f..7049e21a 100644 --- a/e2e/tests/onboarding/06-roomslist.spec.js +++ b/e2e/tests/onboarding/06-roomslist.spec.ts @@ -1,5 +1,7 @@ -const { login, navigateToLogin, logout, tapBack, searchRoom } = require('../../helpers/app'); -const data = require('../../data'); +import { expect } from 'detox'; + +import { login, navigateToLogin, logout, tapBack, searchRoom } from '../../helpers/app'; +import data from '../../data'; describe('Rooms list screen', () => { before(async () => { diff --git a/e2e/tests/onboarding/07-server-history.spec.js b/e2e/tests/onboarding/07-server-history.spec.ts similarity index 92% rename from e2e/tests/onboarding/07-server-history.spec.js rename to e2e/tests/onboarding/07-server-history.spec.ts index 879f4883..d6203ccb 100644 --- a/e2e/tests/onboarding/07-server-history.spec.js +++ b/e2e/tests/onboarding/07-server-history.spec.ts @@ -1,5 +1,7 @@ -const { login, navigateToLogin, logout, tapBack } = require('../../helpers/app'); -const data = require('../../data'); +import { expect } from 'detox'; + +import { login, navigateToLogin, logout, tapBack } from '../../helpers/app'; +import data from '../../data'; describe('Server history', () => { before(async () => { diff --git a/e2e/tests/room/01-createroom.spec.js b/e2e/tests/room/01-createroom.spec.ts similarity index 97% rename from e2e/tests/room/01-createroom.spec.js rename to e2e/tests/room/01-createroom.spec.ts index 017d471f..efd9fbf0 100644 --- a/e2e/tests/room/01-createroom.spec.js +++ b/e2e/tests/room/01-createroom.spec.ts @@ -1,9 +1,11 @@ -const data = require('../../data'); -const { tapBack, navigateToLogin, login, tryTapping, platformTypes } = require('../../helpers/app'); +import { expect } from 'detox'; + +import data from '../../data'; +import { tapBack, navigateToLogin, login, tryTapping, platformTypes, TTextMatcher } from '../../helpers/app'; describe('Create room screen', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/room/02-room.spec.js b/e2e/tests/room/02-room.spec.ts similarity index 98% rename from e2e/tests/room/02-room.spec.js rename to e2e/tests/room/02-room.spec.ts index 2f39cf37..266da5e2 100644 --- a/e2e/tests/room/02-room.spec.js +++ b/e2e/tests/room/02-room.spec.ts @@ -1,5 +1,7 @@ -const data = require('../../data'); -const { +import { expect } from 'detox'; + +import data from '../../data'; +import { navigateToLogin, login, mockMessage, @@ -10,10 +12,11 @@ const { pinMessage, dismissReviewNag, tryTapping, - platformTypes -} = require('../../helpers/app'); + platformTypes, + TTextMatcher +} from '../../helpers/app'; -async function navigateToRoom(roomName) { +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'))) @@ -23,8 +26,8 @@ async function navigateToRoom(roomName) { describe('Room screen', () => { const mainRoom = data.groups.private.name; - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); diff --git a/e2e/tests/room/03-roomactions.spec.js b/e2e/tests/room/03-roomactions.spec.ts similarity index 98% rename from e2e/tests/room/03-roomactions.spec.js rename to e2e/tests/room/03-roomactions.spec.ts index 5acb56f0..0b9774a3 100644 --- a/e2e/tests/room/03-roomactions.spec.js +++ b/e2e/tests/room/03-roomactions.spec.ts @@ -1,5 +1,7 @@ -const data = require('../../data'); -const { +import { expect } from 'detox'; + +import data from '../../data'; +import { navigateToLogin, login, tapBack, @@ -8,11 +10,13 @@ const { mockMessage, starMessage, pinMessage, - platformTypes -} = require('../../helpers/app'); + platformTypes, + TTextMatcher +} from '../../helpers/app'; + const { sendMessage } = require('../../helpers/data_setup'); -async function navigateToRoomActions(type) { +async function navigateToRoomActions(type: string) { let room; if (type === 'd') { room = 'rocket.cat'; @@ -53,8 +57,8 @@ async function waitForToast() { } describe('Room actions screen', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); await navigateToLogin(); @@ -398,7 +402,7 @@ describe('Room actions screen', () => { .withTimeout(2000); }); - const openActionSheet = async username => { + const openActionSheet = async (username: string) => { await waitFor(element(by.id(`room-members-view-item-${username}`))) .toExist() .withTimeout(5000); @@ -461,7 +465,7 @@ describe('Room actions screen', () => { .toBeNotVisible() .withTimeout(60000); await element(by.id('room-members-view-search')).tap(); - await element(by.id('room-members-view-search')).clearText(''); + await element(by.id('room-members-view-search')).clearText(); await waitFor(element(by.id(`room-members-view-item-${user.username}`))) .toExist() .withTimeout(60000); @@ -484,7 +488,7 @@ describe('Room actions screen', () => { it('should clear search', async () => { await element(by.id('room-members-view-search')).tap(); - await element(by.id('room-members-view-search')).clearText(''); + await element(by.id('room-members-view-search')).clearText(); await waitFor(element(by.id(`room-members-view-item-${user.username}`))) .toExist() .withTimeout(60000); diff --git a/e2e/tests/room/04-discussion.spec.js b/e2e/tests/room/04-discussion.spec.ts similarity index 97% rename from e2e/tests/room/04-discussion.spec.js rename to e2e/tests/room/04-discussion.spec.ts index 6125ecf6..5d2c8fad 100644 --- a/e2e/tests/room/04-discussion.spec.js +++ b/e2e/tests/room/04-discussion.spec.ts @@ -1,5 +1,7 @@ -const { navigateToLogin, login, mockMessage, tapBack, searchRoom, platformTypes } = require('../../helpers/app'); -const data = require('../../data'); +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; @@ -12,7 +14,7 @@ const navigateToRoom = async () => { }; describe('Discussion', () => { - let textMatcher; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true }); ({ textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/room/05-threads.spec.js b/e2e/tests/room/05-threads.spec.ts similarity index 97% rename from e2e/tests/room/05-threads.spec.js rename to e2e/tests/room/05-threads.spec.ts index ae3d8def..1abba664 100644 --- a/e2e/tests/room/05-threads.spec.js +++ b/e2e/tests/room/05-threads.spec.ts @@ -1,5 +1,7 @@ -const data = require('../../data'); -const { +import { expect } from 'detox'; + +import data from '../../data'; +import { navigateToLogin, login, mockMessage, @@ -7,10 +9,11 @@ const { sleep, searchRoom, platformTypes, - dismissReviewNag -} = require('../../helpers/app'); + dismissReviewNag, + TTextMatcher +} from '../../helpers/app'; -async function navigateToRoom(roomName) { +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); @@ -23,7 +26,7 @@ async function navigateToRoom(roomName) { describe('Threads', () => { const mainRoom = data.groups.private.name; - let textMatcher; + let textMatcher: TTextMatcher; before(async () => { ({ textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/room/06-createdmgroup.spec.js b/e2e/tests/room/06-createdmgroup.spec.ts similarity index 92% rename from e2e/tests/room/06-createdmgroup.spec.js rename to e2e/tests/room/06-createdmgroup.spec.ts index 785943bd..773c837e 100644 --- a/e2e/tests/room/06-createdmgroup.spec.js +++ b/e2e/tests/room/06-createdmgroup.spec.ts @@ -1,8 +1,8 @@ -const data = require('../../data'); -const { navigateToLogin, login, platformTypes } = require('../../helpers/app'); +import data from '../../data'; +import { navigateToLogin, login, platformTypes, TTextMatcher } from '../../helpers/app'; describe('Group DM', () => { - let textMatcher; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/room/07-markasunread.spec.js b/e2e/tests/room/07-markasunread.spec.ts similarity index 83% rename from e2e/tests/room/07-markasunread.spec.js rename to e2e/tests/room/07-markasunread.spec.ts index 4fc088eb..da95c899 100644 --- a/e2e/tests/room/07-markasunread.spec.js +++ b/e2e/tests/room/07-markasunread.spec.ts @@ -1,8 +1,10 @@ -const data = require('../../data'); -const { navigateToLogin, login, searchRoom, sleep, platformTypes } = require('../../helpers/app'); -const { sendMessage } = require('../../helpers/data_setup'); +import { expect } from 'detox'; -async function navigateToRoom(user) { +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'))) @@ -12,7 +14,7 @@ async function navigateToRoom(user) { describe('Mark as unread', () => { const user = data.users.alternate.username; - let textMatcher; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); diff --git a/e2e/tests/room/08-roominfo.spec.js b/e2e/tests/room/08-roominfo.spec.ts similarity index 95% rename from e2e/tests/room/08-roominfo.spec.js rename to e2e/tests/room/08-roominfo.spec.ts index 437b79d2..d59ac2e0 100644 --- a/e2e/tests/room/08-roominfo.spec.js +++ b/e2e/tests/room/08-roominfo.spec.ts @@ -1,9 +1,11 @@ -const data = require('../../data'); -const { navigateToLogin, login, tapBack, sleep, searchRoom, platformTypes } = require('../../helpers/app'); +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) { +async function navigateToRoomInfo(type: string) { let room; if (type === 'd') { room = 'rocket.cat'; @@ -25,7 +27,7 @@ async function navigateToRoomInfo(type) { .withTimeout(2000); } -async function swipe(direction) { +async function swipe(direction: Detox.Direction) { await element(by.id('room-info-edit-view-list')).swipe(direction, 'fast', 0.8); } @@ -34,8 +36,8 @@ async function waitForToast() { } describe('Room info screen', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); @@ -174,6 +176,7 @@ describe('Room info screen', () => { 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(); @@ -182,6 +185,7 @@ describe('Room info screen', () => { }); 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'); @@ -194,6 +198,7 @@ describe('Room info screen', () => { 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(''); @@ -226,6 +231,7 @@ describe('Room info screen', () => { 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(); @@ -245,6 +251,7 @@ describe('Room info screen', () => { 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(); @@ -264,6 +271,7 @@ describe('Room info screen', () => { 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(); diff --git a/e2e/tests/room/09-jumptomessage.spec.js b/e2e/tests/room/09-jumptomessage.spec.ts similarity index 95% rename from e2e/tests/room/09-jumptomessage.spec.js rename to e2e/tests/room/09-jumptomessage.spec.ts index 5fa4dad9..c2aea7ff 100644 --- a/e2e/tests/room/09-jumptomessage.spec.js +++ b/e2e/tests/room/09-jumptomessage.spec.ts @@ -1,7 +1,9 @@ -const data = require('../../data'); -const { navigateToLogin, tapBack, login, searchRoom, sleep, platformTypes } = require('../../helpers/app'); +import { expect } from 'detox'; -async function navigateToRoom(roomName) { +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'))) @@ -12,8 +14,8 @@ async function navigateToRoom(roomName) { .withTimeout(5000); } -let textMatcher; -let alertButtonType; +let textMatcher: TTextMatcher; +let alertButtonType: string; async function clearCache() { await waitFor(element(by.id('room-view'))) @@ -123,6 +125,7 @@ describe('Room', () => { 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)) @@ -194,7 +197,7 @@ describe('Room', () => { }); }); -const expectThreadMessages = async message => { +const expectThreadMessages = async (message: string) => { await waitFor(element(by.id('room-view-title-thread 1'))) .toExist() .withTimeout(5000); diff --git a/e2e/tests/team/01-createteam.spec.js b/e2e/tests/team/01-createteam.spec.ts similarity index 94% rename from e2e/tests/team/01-createteam.spec.js rename to e2e/tests/team/01-createteam.spec.ts index 1f956024..38708c51 100644 --- a/e2e/tests/team/01-createteam.spec.js +++ b/e2e/tests/team/01-createteam.spec.ts @@ -1,11 +1,13 @@ -const data = require('../../data'); -const { navigateToLogin, login, platformTypes } = require('../../helpers/app'); +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; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tests/team/02-team.spec.js b/e2e/tests/team/02-team.spec.ts similarity index 96% rename from e2e/tests/team/02-team.spec.js rename to e2e/tests/team/02-team.spec.ts index 47a3213d..382ed1dd 100644 --- a/e2e/tests/team/02-team.spec.js +++ b/e2e/tests/team/02-team.spec.ts @@ -1,7 +1,9 @@ -const data = require('../../data'); -const { navigateToLogin, login, tapBack, sleep, searchRoom, platformTypes } = require('../../helpers/app'); +import { expect } from 'detox'; -async function navigateToRoom(roomName) { +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'))) @@ -9,7 +11,7 @@ async function navigateToRoom(roomName) { .withTimeout(5000); } -async function openActionSheet(username) { +async function openActionSheet(username: string) { await waitFor(element(by.id(`room-members-view-item-${username}`))) .toExist() .withTimeout(5000); @@ -48,7 +50,13 @@ async function waitForToast() { await sleep(1000); } -async function swipeTillVisible(container, find, direction = 'up', delta = 0.3, speed = 'slow') { +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 { @@ -67,8 +75,8 @@ describe('Team', () => { const user = data.users.alternate; const room = `private${data.random}-channel-team`; const existingRoom = data.groups.alternate.name; - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); @@ -388,7 +396,7 @@ describe('Team', () => { .toBeNotVisible() .withTimeout(60000); await element(by.id('room-members-view-search')).tap(); - await element(by.id('room-members-view-search')).clearText(''); + await element(by.id('room-members-view-search')).clearText(); await waitFor(element(by.id(`room-members-view-item-${user.username}`))) .toExist() .withTimeout(60000); diff --git a/e2e/tests/team/03-moveconvert.spec.js b/e2e/tests/team/03-moveconvert.spec.ts similarity index 94% rename from e2e/tests/team/03-moveconvert.spec.js rename to e2e/tests/team/03-moveconvert.spec.ts index 25843490..75e400ec 100644 --- a/e2e/tests/team/03-moveconvert.spec.js +++ b/e2e/tests/team/03-moveconvert.spec.ts @@ -1,10 +1,10 @@ -const data = require('../../data'); -const { navigateToLogin, login, tapBack, searchRoom, sleep, platformTypes } = require('../../helpers/app'); +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 => { +const createChannel = async (room: string) => { await waitFor(element(by.id('rooms-list-view-create-channel'))) .toBeVisible() .withTimeout(5000); @@ -40,7 +40,7 @@ const createChannel = async room => { .withTimeout(60000); }; -async function navigateToRoom(room) { +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'))) @@ -48,7 +48,7 @@ async function navigateToRoom(room) { .withTimeout(5000); } -async function navigateToRoomActions(room) { +async function navigateToRoomActions(room: string) { await navigateToRoom(room); await element(by.id('room-header')).tap(); await waitFor(element(by.id('room-actions-view'))) @@ -57,8 +57,8 @@ async function navigateToRoomActions(room) { } describe('Move/Convert Team', () => { - let alertButtonType; - let textMatcher; + let alertButtonType: string; + let textMatcher: TTextMatcher; before(async () => { await device.launchApp({ permissions: { notifications: 'YES' }, delete: true }); ({ alertButtonType, textMatcher } = platformTypes[device.getPlatform()]); diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json new file mode 100644 index 00000000..1c51cdad --- /dev/null +++ b/e2e/tsconfig.json @@ -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"] +} diff --git a/package.json b/package.json index 01d501cb..c7a57f1e 100644 --- a/package.json +++ b/package.json @@ -165,6 +165,7 @@ "@types/i18n-js": "^3.8.2", "@types/jest": "^26.0.24", "@types/lodash": "^4.14.171", + "@types/mocha": "^9.1.1", "@types/react": "^17.0.14", "@types/react-native": "0.68.1", "@types/react-native-background-timer": "^2.0.0", @@ -205,6 +206,7 @@ "react-test-renderer": "17.0.2", "reactotron-redux": "3.1.3", "reactotron-redux-saga": "4.2.3", + "ts-node": "^10.9.1", "typescript": "^4.3.5" }, "jest": { @@ -244,6 +246,7 @@ } }, "detox": { + "test-runner": "mocha", "runner-config": "e2e/.mocharc.json", "specs": "e2e/tests", "configurations": { diff --git a/yarn.lock b/yarn.lock index 260f0069..72959fa8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3407,6 +3407,13 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@discoveryjs/json-ext@^0.5.3": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" @@ -4604,7 +4611,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== -"@jridgewell/trace-mapping@^0.3.0": +"@jridgewell/trace-mapping@0.3.9", "@jridgewell/trace-mapping@^0.3.0": version "0.3.9" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== @@ -5841,6 +5848,26 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + "@types/anymatch@*": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -6124,6 +6151,11 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== +"@types/mocha@^9.1.1": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" + integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== + "@types/node-fetch@^2.5.7": version "2.6.2" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" @@ -6762,6 +6794,11 @@ acorn-jsx@^5.3.1: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@^6.4.1: version "6.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" @@ -6772,7 +6809,7 @@ acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.5.0: +acorn@^8.4.1, acorn@^8.5.0: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -7049,6 +7086,11 @@ arg@4.1.0: resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.0.tgz#583c518199419e0037abb74062c37f8519e575f0" integrity sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg== +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -9146,6 +9188,11 @@ create-react-context@0.3.0: gud "^1.0.0" warning "^4.0.3" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cross-fetch@^3.0.4: version "3.1.5" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" @@ -9626,6 +9673,11 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -14279,6 +14331,11 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -19589,6 +19646,25 @@ ts-interface-checker@^0.1.9: resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -20212,6 +20288,11 @@ uuid@^8.0.0, uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-compile-cache@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" @@ -20827,6 +20908,11 @@ yargs@^17.3.1: y18n "^5.0.5" yargs-parser "^21.0.0" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"